D7 mirror candidate (p) `to_ore`, measured offline with the mutation harness. `to_ore` does not exist here (0 of 80 .py files in src+tests; positive control: `unit_cost` found in 19). Our money axis is the accumulated USD spend, and its conversion is the rounding to six decimals — present in FOUR literal copies with no named source (run.py:159, run_s10.py:110 and :130, costsim.py:125) while the share rounding one file over DOES have one (`_SHARE_DIGITS`). The sibling's drift form is present. Three of the four copies are never executed: replacing the whole expression with `999.0` left all 984 green at each. Their green under a detach was never evidence about the rounding — it was "not measured" (ansikt 4 on the apparatus). The default branch WAS pinned; the value branch was not. The one path that decides with the cost — the C3.5 pre-call USD belt — is a permanent no-op: `max_cost_usd` is set in 0 of 27 src modules (positive control: `max_budget_usd_per_call` is found by the same scan). The gate is built; no path hands it a cap. Seven mutations, all VALUE-PROVED with collateral controls green in both runs. No src change: folding the copies is a refactor, wiring the run-total cap is a feature. The tests pin today's boundary so neither lands silently. 984 -> 997 (strict superset, 0 lost node ids). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
463 lines
32 KiB
Markdown
463 lines
32 KiB
Markdown
# Målte funn, køer og gater (flyttet ut av STATE.md 2026-08-18)
|
||
|
||
> Bakgrunn: `STATE.md` er current state-of-play og har et tak på ~120 linjer. Den 18.08 lå
|
||
> fila på 149. Operatørbeslutningen samme dag var å flytte tre punkter hit og la STATE
|
||
> beholde ÉN peker per punkt på formen `fil § Overskrift` — et grep-bart paragraf-anker,
|
||
> aldri et linjenummer. **Ingenting er slettet:** state er flyttet, ikke fjernet.
|
||
>
|
||
> Alt under er MÅLERESULTATER med en dato, ikke fakta om verden. Datoen står ved hver
|
||
> påstand, og en påstand herfra er et premiss som skal verifiseres på nytt før den handles
|
||
> på — særlig tall som råtner (versjoner, testantall, oppstrøms-tilstand).
|
||
|
||
## Negative funn
|
||
|
||
Steder som ER undersøkt for en manglende søm, og hvor svaret var «ingen søm å feste». De er
|
||
ferdig avklart i økt 17–22 og skal **ikke re-måles** — enumerert her nettopp for at ingen
|
||
senere økt skal bruke tid på dem igjen:
|
||
|
||
- `test_preflight` (9 tilfeller)
|
||
- `test_zero_model_calls`
|
||
- `notify` :224
|
||
- `ir` :69
|
||
- `validator` :56
|
||
- `step1_expel` :99
|
||
- cli_paritet-parene
|
||
- `method_spec` + `ingest_spec` (6 tilfeller — merk: **ikke lenger dekkende**, se under)
|
||
- alle 8 fra økt 22
|
||
|
||
**Korreksjon 2026-08-18 (økt 32):** `ingest_spec`-oppføringen gjaldt den §12-ankrede vakten.
|
||
Økt 32 målte et hull den enumereringen ikke fanget — enhver seksjon §1–§11 kunne tømmes uten
|
||
at én test i suiten ble rød (10 av 11 seksjoner; §7 var eneste overlapp, via O2-ratchet-en).
|
||
Hullet er lukket med `_STRUCTURE_MARKERS` i `tests/test_ingest_spec_loadbearing.py` (commit
|
||
`40b4631`). Lærdommen er generell: **et negativt funn har et scope, og scopet er den
|
||
spørringen som ble kjørt** — ikke fila den ble kjørt mot.
|
||
|
||
## D7-speilingskøen
|
||
|
||
Åtte kandidater for speiling mellom D7-søsknene. **Ingen er besluttet** — de står som
|
||
kandidater, ikke som planlagt arbeid. **Seks er målt, 2 står igjen:**
|
||
|
||
- ~~S2.7~~ — **MÅLT 2026-09-07, se under**
|
||
- ~~S3.2~~ — **MÅLT 2026-09-12, se under**
|
||
- ~~S4.0~~ (`126807a`) — **MÅLT 2026-09-13, se under**
|
||
- ~~(p) `to_ore`~~ — **MÅLT 2026-09-13, se under**
|
||
- ~~(a)/(i) `unquote_scalar`~~ — **MÅLT 2026-08-31, se under**
|
||
- `mandate.py`
|
||
- A5 — TO halvdeler
|
||
- ~~B4 `ToolCallRecorder`~~ — **BESVART 2026-08-25, se under**
|
||
|
||
**B4 spurte OSS:** gir Claude-SDK-siden serveridentiteten gratis? MAF får verktøynavn UTEN
|
||
server-prefiks. Åpent hos søskenet: MAF S3.4 (F10).
|
||
|
||
### B4 — svaret er NEI (målt 2026-08-25, offline, mot `claude-agent-sdk` 0.2.139)
|
||
|
||
`create_sdk_mcp_server` emitterer det **bare** verktøynavnet. Serveridentiteten finnes — på
|
||
`McpSdkServerConfig["name"]` og `Server.name` — men den er **disjunkt fra hvert navn
|
||
verktøylista bærer**. Strengen `mcp__` forekommer i **0 av 24** Python-filer i pakken
|
||
(positiv kontroll: `create_sdk_mcp_server` blir funnet av samme spørring, så spørringen KAN
|
||
finne). Konstruksjonssiden namespacer altså ingenting: en `ToolCallRecorder` hengt der ser
|
||
`record_call`, ikke `mcp__tool_call_recorder__record_call`, og må få servernavnet fortalt.
|
||
Det er **samme pris som søskenet betaler**.
|
||
|
||
**Ærlig grense — hva målingen IKKE sier.** Den navnerommede formen `mcp__<server>__<tool>`
|
||
eksisterer: den bygges inne i CLI-en som følger med SDK-en (`_bundled/claude`, 178 literale
|
||
`mcp__`-forekomster, konstruksjonen på formen `` `mcp__${…}__${…}` ``). Det er **lest av
|
||
artefaktet, ikke observert i en kjøring hos oss** — å se den emittert krever en live
|
||
`query()`, som både D6-kostnadsregelen og suitens offline-invariant forbyr. Funnet er derfor
|
||
scopet til den sømmen vi faktisk kan bygge på: den in-process konstruksjonssiden. Prefikset
|
||
finnes på et lag vi bevisst ikke kjører, og et lag vi ikke kjører er ikke en søm vi kan feste
|
||
en recorder i.
|
||
|
||
**Pinnet av** `tests/test_sdk_tool_namespace_loadbearing.py` (4 tester). Value-beviset er
|
||
kjørt, ikke påstått: SDK-en ble mutert til å namespace ved konstruksjon (`"name":
|
||
f"mcp__{name}__{tool_def.name}"`) — **grønn før, 3 av 4 røde etter**, og den ene som forble
|
||
grønn er nettopp populasjons-kontrollen, som den skal. SDK-fila ble restaurert byte-identisk
|
||
(sha256 verifisert begge veier).
|
||
|
||
**Datering (D7-rammen):** dette er arbeid ETTER 2026-08-09 og skal **ikke** leses som
|
||
uavhengig konvergens selv om svaret er identisk med søskenets.
|
||
|
||
### (a)/(i) `unquote_scalar` — svaret er JA, den var ÉN regel, men pinnet bare i kanten (målt 2026-08-31)
|
||
|
||
Kandidaten står i køen fordi søskenet vokste en navngitt `unquote_scalar` etter at en
|
||
**duplisert konvertering hadde driftet** — to steder som fjernet anførselstegn fra en
|
||
frontmatter-skalar, etter to regler. Speilings-spørsmålet er derfor ikke «har vi funksjonen»,
|
||
men det søskenets defekt faktisk stiller: **er den ÉN regel hos oss, og er selve regelen
|
||
load-bearing?**
|
||
|
||
**Populasjonen først.** `unquote_scalar` finnes ikke hos oss: **0 treff av 76 undersøkte
|
||
`.py`-filer** i `src`+`tests` (positiv kontroll: samme spørring finner `parse_frontmatter` i
|
||
`okf.py`), og `unquote` finnes ikke i repoet utenfor `.venv`. Vår motpart er
|
||
`okf._strip_matching_quotes` — **én definisjon, ett kallsted** (`_parse_frontmatter_and_body`).
|
||
Søskenets drift-form finnes altså ikke her.
|
||
|
||
**Men regelen var dekket bare i kanten.** Med `scripts/mutation_harness.py`, nevner `tests/`
|
||
(hele suiten, 950 tester), hver kjøring sha256-restaurert:
|
||
|
||
- Å detache regelen helt (`return value[1:-1]` → `return value`) er **RØD** —
|
||
`test_okf.py::TestFrontmatter::test_unknown_fields_preserved_and_quotes_stripped` fanger den.
|
||
- Hver av de tre **klausulene** var **grønn-men-død**: å svekke lengdevakten (`>= 2` → `>= 1`),
|
||
å droppe matching-kravet (`value[0] == value[-1] and`), og å utvide quote-settet med en
|
||
symmetrisk delimiter (backtick) lot hele suiten stå grønn.
|
||
|
||
Samme klasse som `_STRUCTURE_MARKERS`-hullet i økt 32: sømmen var NAVNGITT og kant-dekket, som
|
||
ikke er det samme som dekket. **Pinnet av** `tests/test_okf_unquote_loadbearing.py` (5 tester,
|
||
950 → 955). Value-beviset er kjørt, ikke påstått: hver klausul-test er grønn før og rød etter
|
||
nøyaktig sin egen mutasjon, med populasjons-kontrollen grønn i begge (mutasjonen landet ikke
|
||
for bredt), og ledd 3 pinnet på linje via `--red-at`.
|
||
|
||
**EN MÅLETRAP, MÅLT — ny lærdom om harnesset.** Første forsøk på klausul 3 utvidet settet med
|
||
`'['`. Suiten forble grønn, hvilket leses som «klausulen er ikke dekket» — men mutasjonen er en
|
||
**no-op**: `'['` kan aldri tilfredsstille matching-kravet, siden `[` ikke er `]`. Flow-form-
|
||
verdier er altså beskyttet av **matching-klausulen, ikke av quote-settet**, og en grønn kjøring
|
||
under den mutasjonen var aldri bevis om quote-settet i det hele tatt. **Harnesset kan ikke
|
||
skille en oppførsels-bevarende mutasjon fra en udekket søm — begge kommer ut som «stayed
|
||
GREEN».** En mutasjon må vises å endre oppførsel før dens grønne leses som et hull. Dette er
|
||
Verifiseringsloven ansikt 4 anvendt på selve måleapparatet: et negativt resultat fra en
|
||
spørring som ikke KAN finne, er ikke null — det er ikke målt.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at flow-verdier passerer **urørt** er ikke
|
||
flow-DEKODING, og fila legger ingen til: `tags: [a, b]` forblir strengen `"[a, b]"`. Den
|
||
linje-orienterte parseren har ingen nesting-modell ved design (§1 ærlighets-regelen). Den
|
||
additive flow-dekoderen er søskenets B4-arbeid i `portfolio-optimiser` og er bevisst **ikke**
|
||
bygget her; testene pinner dagens grense slik at det arbeidet ikke kan lande stille på denne
|
||
siden.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
### S2.7 — gaten er ÉN regel, og den var pinnet i ARITMETIKKEN, ikke i BESLUTNINGEN (målt 2026-09-07)
|
||
|
||
Kandidaten står i køen fordi søskenet strammet validatoren i to halvdeler: (a) en strukturell
|
||
blokk på `claimed > nominal_feasible`, og (b) en IR-invariant `low ≤ unit_cost ≤ high`. **Begge
|
||
halvdeler er GATET her** på D-A pkt. 1 + commons-pull (paritetsplanens rad 12), og defekten de
|
||
svarer på er bekreftet på vår side som C-F2 (`docs/review-2026-07.md`). Speilings-spørsmålet som
|
||
KAN besvares offline i dag er derfor et annet: **er dagens grense — «den ENE numeriske gaten er
|
||
p90» — load-bearing?**
|
||
|
||
**Populasjonen først.** En claim er numerisk avgrenset i nøyaktig TO steder i `src/`, med hver
|
||
sin spec-rolle: skjema-invarianten (claim ≤ items-total, §7.1, `ir.py:50`) og validator-gaten
|
||
(claim ≤ p90, §3 Steg 4, `validator.py:68`). `_FEASIBLE_FRACTION` forekommer kun i `validator.py`,
|
||
og det finnes ingen annen Monte Carlo eller `quantiles`-beregning i pakken (positiv kontroll:
|
||
samme spørring finner `validate_proposal` i `loop.py:284`). Søskenets drift-form — to gater som
|
||
har glidd fra hverandre — finnes altså ikke her.
|
||
|
||
**Men dekningen deler seg rent på tvers av regelen.** Med `scripts/mutation_harness.py`, nevner
|
||
`tests/` (hele suiten, 955 tester), hver kjøring sha256-restaurert:
|
||
|
||
- Å detache gaten helt (`if … > p90:` → `if False:`) er **RØD** — `test_validator.py` fanger den.
|
||
- Alt gaten **REGNER UT** er RØDT, og goldenen er grunnen: policy-taket (`0.30` → `0.31`),
|
||
band-grenen (ignorér bands), band-endepunktenes rekkefølge, MC-seeden, p90-kuttpunkt-indeksen
|
||
og `nominal_feasible`-formelen reddet alle suiten.
|
||
- Alt gaten **BESLUTTER MED** er **grønn-men-dødt**: å bytte grensen til `p10`, å bytte den til
|
||
`nominal_feasible`, og å løsne `>` til `>=` lot alle 955 testene stå grønne.
|
||
|
||
Det skillet ER funnet, og det er skarpere enn «sømmen er tynn»: goldenen fryser hvert tall
|
||
validatoren PRODUSERER, og kan derfor ikke hjelpe med det ene den ikke observerer — hvilken
|
||
grense gaten LESER. Konsekvensen er konkret: **å bytte `p90` mot `nominal_feasible` ER den gatede
|
||
S2.7-halvdel (a), og den ville landet med suiten grønn**, før D-A er besluttet.
|
||
|
||
**Pinnet av** `tests/test_validator_gate_loadbearing.py` (8 tester, 955 → 963). Value-beviset er
|
||
kjørt, ikke påstått: hver klausul-test er grønn før og rød etter nøyaktig sin egen mutasjon, med
|
||
golden-tallene grønne i BEGGE kjøringer — som mekanisk viser at mutasjonen flyttet BESLUTNINGEN,
|
||
ikke aritmetikken. De to IR-testene er pinnet med `--red-at` mot invariantens egen feilmelding,
|
||
fordi de dør i en hjelpefunksjon og ikke i testkroppen.
|
||
|
||
**Mutasjonene ble vist å endre oppførsel FØR deres grønne ble lest som hull** (fellen fra økt 39).
|
||
Alle tre grensetilfellene er nåbare og ble kjørt: en claim nøyaktig PÅ p90 finnes (degenerert
|
||
band, `0.30 × 1000 == 300.0`), og med goldenens eget band valideres en claim på 100 000 mens
|
||
`nominal_feasible` er 90 000 — C-F2s første moteksempel, reprodusert live på p90 = 121 057.09,
|
||
sammen med det andre (claim 55 000 mot nominal 30 000, p90 = 65 058.49). Begge tallene er
|
||
identiske med review-ens, som bekrefter at defekten er spec-båren.
|
||
|
||
**To ting målingen ga i tillegg.** (1) Populasjonskontrollen (AST) ble bevist mot en
|
||
**oppførselsbevarende** mutasjon — `> p90` utvidet til `> p10 and > p90`, som er logisk identisk
|
||
når `p10 ≤ p90` — og alle tre oppførselskontrollene forble grønne. En ny gate-plassering er
|
||
usynlig for enhver oppførselstest; det er nettopp derfor AST-kontrollen står der. (2) Under
|
||
containment-mutasjonen forble golden-testen **grønn**, hvilket mekanisk bekrefter review-ens
|
||
påstand om at S2.7 halvdel (b) er golden-kompatibel når D-A lander.
|
||
|
||
**Nytt utover C-F2:** IR-en har heller ingen ORDNING på band-endepunktene. `(1.40, 0.70)`
|
||
aksepteres; `random.uniform(1.40, 0.70)` trekker fortsatt fra [0.70, 1.40], så området korrumperes
|
||
ikke — men den seedede strømmen vandres baklengs, hvilket er en ANNEN p90 (målt: 120 456.91 mot
|
||
121 057.09). Et band hvis betydning avhenger av argument-rekkefølgen er ennå ikke et band.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at en claim over `nominal_feasible` validerer i
|
||
dag er ingen godkjenning av oppførselen; C-F2 kaller den en MAJOR spec-nivå-defekt, og fiksen er
|
||
GATET, ikke avvist. Testene pinner grensen slik at det gatede arbeidet MÅ ankomme som en synlig
|
||
rød test og en beslutning, aldri som et stille bytte. Ingen `src/`-endring er gjort, ingen
|
||
spec-tekst rørt, og fasiten er ikke berørt.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
### S3.2 — id-en er pinnet, NØKLINGEN er ikke, og de to nøklings-stiene er uenige (målt 2026-09-12)
|
||
|
||
Kandidaten står i køen fordi søskenet fikset flerkandidat-ExpeL-seeding: frøet skal lese den
|
||
dømte kandidaten fra verdict-filas EGEN frontmatter (promoteringen skriver den), med dagens
|
||
nøkling som fallback. Feature-halvdelen av den defekten er bekreftet her som C-F5
|
||
(`docs/review-2026-07.md`) og **GATET** på D-A pkt. 4 + commons-pull (paritetsplanens rad 14),
|
||
mens id-halvdelen alt er løst: en lastet `verdict_id` leses VERBATIM (§4.2). Speilings-
|
||
spørsmålet som KAN besvares offline i dag er derfor: **er dagens grense — «id-en kommer fra
|
||
FILA, nøklingen kommer fra BUNDELEN» — load-bearing i BEGGE halvdeler?**
|
||
|
||
**Populasjonen først.** En dom nøkles i nøyaktig TO steder i `src/`, med hver sin spec-rolle:
|
||
bundle-frøet (`experience.py:146`, §3 Steg 1 — nøklet på bundelens ENE IR-projeksjon) og
|
||
fil/inbox-stien (`inbox.py:105`, §4.2 — nøklet på dommens egne `proposal_features`). Ingen
|
||
tredje konstruksjon finnes (AST-målt over hele pakken; positiv kontroll: samme AST-spørring
|
||
finner `VerdictStore`-konstruksjon i tre moduler, så spørringen KAN finne). **Og her finnes
|
||
søskenets drift-form — i motsetning til S2.7 og `unquote_scalar`:** de to stiene nøkler ETTER
|
||
ULIKE REGLER.
|
||
|
||
**Dekningen deler seg rent mellom id og nøkling.** Med `scripts/mutation_harness.py`, nevner
|
||
`tests/` (hele suiten, 963 tester), hver kjøring sha256-restaurert:
|
||
|
||
- Å detache sømmen (frøet itererer ingenting) er **RØD**; det samme er type-filteret,
|
||
decision-defaulten og `description`-lesningen.
|
||
- **ID-halvdelen er pinnet på BEGGE sider:** å re-minte i stedet for å lese frontmatter-id-en
|
||
er RØD (`test_step8`), og å droppe mint-fallbacken — slik at ikke-promoterte dommer nøkles på
|
||
en tom id — er også RØD.
|
||
- **NØKLINGS-halvdelen er grønn-men-død.** Å bytte bundle-projeksjonen mot tomme features lot
|
||
alle 963 stå grønne, og det gjorde også den gatede fiksens EGEN form (les kandidaten fra
|
||
verdict-filas frontmatter, fallback dagens nøkling). **Ingenting i suiten observerte hva en
|
||
seedet dom er nøklet PÅ.**
|
||
- Én klausul i rasjonalet var grønn-men-død i tillegg: kravet om BEGGE læringsfeltene før
|
||
markøren emitteres. Svekket til enten-eller forble suiten grønn — og konsekvensen er en
|
||
ærlighets-defekt (§1): markøren navngir da det fraværende feltet som `None`.
|
||
|
||
**Mutasjonene ble vist å endre oppførsel FØR deres grønne ble lest som hull** (fellen fra økt
|
||
39). Tom nøkling senker den seedede dommens similarity mot sin egen bundle-projeksjon fra 1.00
|
||
til 0.15 — observerbart, og rangerings-relevant i det øyeblikket en andre oppføring finnes.
|
||
C-F5s rest-defekt er reprodusert live: to promoterte dommer om ULIKE kandidater (LED vs.
|
||
ventilasjon) seedes begge nøklet på bundelens ENE projeksjon, så en spørring som bærer
|
||
ventilasjons-kandidatens egne features scorer BEGGE til 0.0 og avgjøres av hex-id-rekkefølge,
|
||
ikke av struktur.
|
||
|
||
**NYTT UTOVER C-F5 — nøklingen er sti-avhengig, og dermed rekkefølge-avhengig.** Samme dom —
|
||
samme kandidat, samme mintede id (`c8c97c9d992229dc`), altså samme first-write-wins-slot —
|
||
nøkles på `VENT-AGG-01`/250 000 via inbox-stien og på `ENERGI-TOTAL-EL`/30 000 via bundle-frøet.
|
||
Hvilken nøkling som overlever avgjøres av LASTE-REKKEFØLGEN, ingenting annet. Og fiksen kan
|
||
ikke være ensidig: `promote` skriver `verdict_id` og `description`, men **ingen** kandidat-felt
|
||
(målt frontmatter-nøkkelsett: `decision`, `description`, `provenance`, `tags`, `title`, `type`,
|
||
`verdict_id`) — hvilket er grunnen til at fiksens egen form er en **no-op mot enhver fixture i
|
||
repoet i dag**, og derfor måtte måles mot en fixture som bærer feltene.
|
||
|
||
**Pinnet av** `tests/test_experience_keying_loadbearing.py` (11 tester, 963 → 974, strengt
|
||
supersett: 0 tapte node-id-er). Value-beviset er kjørt, ikke påstått: hver test er grønn før og
|
||
rød etter nøyaktig sin egen mutasjon, med fold-markøren grønn i BEGGE kjøringer — som mekanisk
|
||
viser at mutasjonen flyttet NØKLINGEN, ikke sømmen. To sammensatte tester ble SPLITTET fordi en
|
||
rød test bare beviser sin FØRSTE assert (§1-halvdelen er i tillegg pinnet med `--red-at None`).
|
||
|
||
**To kontroller utover oppførselen.** (1) Populasjonskontrollen (AST) ble bevist mot en
|
||
oppførselsbevarende mutasjon — en tredje, ubrukt `VerdictRecord`-konstruksjon — med alle
|
||
oppførselstestene grønne. (2) Å heve projeksjons-lesningen INN i seedings-loopen er likeledes
|
||
oppførselsbevarende (tre oppførselskontroller grønne), og er samtidig første halvdel av den
|
||
gatede fiksen; derfor er formen pinnet strukturelt (`load_validator_input` kalles nøyaktig ÉN
|
||
gang i `seed_store_from_bundle`) eller ikke i det hele tatt.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at alle dommer i en bundle deler ÉN nøkling i
|
||
dag er ingen godkjenning; C-F5 kaller den en MAJOR spec-nivå-defekt, og fiksen er GATET, ikke
|
||
avvist. Testene pinner grensen slik at det gatede arbeidet MÅ ankomme som en synlig rød test og
|
||
en D-A pkt. 4-beslutning — samme ratchet-rolle `test_ingest_stamp_conformance_loadbearing.py`
|
||
har oppstrøms. Ingen `src/`-endring er gjort, ingen spec-tekst rørt, og **fasiten er ikke
|
||
involvert i nøklingen i det hele tatt** — hvilket er nettopp derfor den ikke kunne hjelpe.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
### S4.0 — baselinen er lastet, og den er strukturelt utenfor dommerens rekkevidde (målt 2026-09-13)
|
||
|
||
Kandidaten står i køen fordi søskenet forankrer `affected_items` mot en kostbaseline. Defekten
|
||
er bekreftet her som C-F3 (`docs/review-2026-07.md`, MAJOR, spec-nivå: en diktet kostlinje
|
||
validerer en 2,9 MNOK-claim), og fiksen — en fail-closed avstemmings-stage — er **GATET** på
|
||
D-A pkt. 2 + et commons-amendment for `cost-baseline.json` (paritetsplanens rad 19).
|
||
Speilings-spørsmålet som KAN besvares offline i dag er derfor: **er dagens grense — «hvert
|
||
kosttall validatoren dømmer på stammer fra forslaget selv» — load-bearing?**
|
||
|
||
**Populasjonen først.** En `SavingsProposal` blir til i nøyaktig TRE steder, med hver sin
|
||
proveniens: det modell-forfattede parset (`loop.py:89`), bundelens baseline-projeksjon
|
||
(`ir.py:64`) og det re-leste system-outputet (`hitl.py:132`). AST-målt over alle 27
|
||
`src/*.py` (positiv kontroll: samme spørring finner `validate_proposal`s ENE kallsted,
|
||
`loop.py:284`). **Kun den FØRSTE når validatoren.** Det er C-F3 uttrykt som en måling.
|
||
|
||
Baselinen LASTES på hver komposisjonssti — `run.py:123`, `run_s10.py:71`, `experience.py:132`
|
||
— og det eneste feltet noen leser direkte av den er `project_id` (fire steder). Alt annet
|
||
forlater lastingen gjennom `CandidateFeatures.from_proposal`, som leser kodene, `measure` og
|
||
claimen. **`quantity`, `unit_cost` og usikkerhets-bandene er skjema-validert og deretter
|
||
aldri lest igjen av noe.** Fiksens egen input ligger altså i minnet i samme
|
||
`ComposedRunContext` som dommen felles fra, og ingen sti fører den dit.
|
||
|
||
**Målingene.** Med `scripts/mutation_harness.py`, nevner `tests/` (hele den gamle suiten,
|
||
974 tester), hver kjøring sha256-restaurert fra disk:
|
||
|
||
- **M1 — baselinen erstattes med den svakeste skjemagyldige varianten** (kodene, `measure`,
|
||
claimen og `project_id` bevart; `quantity`/`unit_cost` flatet, band tømt): tre nye tester
|
||
RØDE, og **alle 974 gamle GRØNNE i begge kjøringer**. Bundelens kosttall kan byttes ut på
|
||
run-stien uten at én eneste eksisterende test merker det.
|
||
- **M2 — `ComposedRunContext.ir_projection: SavingsProposal` → `object`**: AST-testen RØD,
|
||
alle oppførselstester GRØNNE. En stille innsnevring av det bårne feltet er usynlig for
|
||
oppførsel — og ville slettet den eneste kostbaselinen på run-stien.
|
||
- **M3 — S10-stien slutter å kalle `load_validator_input`** (oppførselsbevarende alias):
|
||
loader-populasjonen RØD, `test_s10_run_layer.py` + `test_preflight.py` GRØNNE.
|
||
- **M4 — validatoren får en `baseline`-parameter** (den gatede fiksens signatur, default
|
||
`None`): signatur-ratchet-en RØD, **goldenen GRØNN** — som mekanisk bekrefter at S4.0s
|
||
signatur-halvdel er golden-kompatibel når D-A pkt. 2 lander.
|
||
- **M5 — kallstedets argument blir et keyword**: proveniens-kontrollen RØD, oppførselen
|
||
uendret.
|
||
- **M6 — fail-closed kodesett-gate i validatoren** (fiksens EGEN form, hardkodet baseline):
|
||
grense-testen RØD, **goldenen GRØNN i begge**.
|
||
- **M7 — retrieval slutter å lese kodene**: disjunkthets-testen RØD, golden + validator GRØNNE.
|
||
|
||
**En måletrap unngått — mutasjonen må vises å endre oppførsel, ikke bare å være skrevet**
|
||
(økt 39, her i motsatt retning). Første M1-forsøk flatet kostlinjene til `1.0 × 1.0` og
|
||
gjorde `test_run_entrance_loadbearing.py` RØD. Det så ut som dekning, men var det ikke:
|
||
total 1,0 < claim 30 000 bryter IR-invarianten (`ir.py:46`), så mutasjonen var en
|
||
**konstruksjonsfeil**, ikke en baseline-fjerning, og rødheten attribuerte til pydantic.
|
||
Harnessets kollateral-kontroll fanget den. Den korrekte mutasjonen holder invarianten — og
|
||
da er alle 974 grønne.
|
||
|
||
**NYTT UTOVER C-F3 — bundelen BÆRER en kostbaseline, og retrieval ser den allerede.** C-F3
|
||
formulerer defekten som «ingenting i bundle-formatet bærer en kostbaseline å avstemme mot».
|
||
Målt her er det for sterkt: `validator-input.json` bærer `ENERGI-TOTAL-EL` à 300 000 NOK, og
|
||
den lastes på hver run-sti. C-F3s kjørte bevis er reprodusert med review-ens egne tall (claim
|
||
2 900 000, degenererte percentiler 3 000 000) og skjerpet: det diktede kostgrunnlaget er
|
||
**33,3× hele bundelens baseline**, claimen er **9,67× byggets totale årlige energikost**, og
|
||
den diktede koden har **null overlapp** med bundelens kodesett. Det overlappet BEREGNES —
|
||
`CandidateFeatures` bruker det til å rangere erfaring. **Systemet holder altså beviset som
|
||
ville avslørt dikteringen, bruker det på rangering, og aldri på å dømme.** Defekten er ikke
|
||
at baselinen mangler; den er at den ikke er koblet til dommeren.
|
||
|
||
**Hvor bredt fiksen slår ut (en telling, ikke et load-bearing-bevis — derfor ikke harnesset,
|
||
men git-verifisert restaurering):** med fiksens form hardkodet til bundelens kodesett er **30
|
||
av 974** røde. Fiksen er altså bredt synlig i suiten, ikke stille. Ærlig grense: det tallet er
|
||
målt på en HARDKODET baseline; den ekte fiksen ville lest bundelens baseline per kjøring, og
|
||
hver testfixtures egen baseline ville da definert sitt eget kodesett — så 30 er et tak på
|
||
støyen, ikke et estimat på arbeidet.
|
||
|
||
**Pinnet av** `tests/test_cost_baseline_loadbearing.py` (10 tester, 974 → 984, strengt
|
||
supersett: 0 tapte node-id-er). To testpar er SPLITTET fordi en rød test bare beviser sin
|
||
FØRSTE assert: kostlinjene fra bandene, og valideringen av den diktede linja fra dens
|
||
magnitude.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at baselinen ankommer intakt er ingen påstand
|
||
om at den BRUKES; det gjør den ikke, og C-F3 står som MAJOR. Testene pinner grensen slik at
|
||
det gatede arbeidet MÅ ankomme som en synlig rød test og en D-A pkt. 2-beslutning — samme
|
||
ratchet-rolle `test_ingest_stamp_conformance_loadbearing.py` har oppstrøms. Ingen
|
||
`src/`-endring er gjort, ingen spec-tekst rørt, og goldenen kan ikke hjelpe: den fryser hva
|
||
validatoren REGNER UT av et forslag, og baselinen er ikke en input til den beregningen i det
|
||
hele tatt. De to magnitude-/disjunkthets-påstandene er dessuten faktapåstander om
|
||
bundle-fixturen og deler anker med goldenen — de er konsistens-tester, ikke uavhengige
|
||
søm-bevis, og er merket som det over.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig
|
||
konvergens.
|
||
|
||
|
||
### (p) `to_ore` — regelen finnes i FIRE kopier, tre av dem kjøres aldri, og gaten den skulle tjene er slått av (målt 2026-09-13)
|
||
|
||
Kandidaten står i køen fordi søskenet vokste en navngitt `to_ore` etter at en **pengekonvertering
|
||
hadde driftet i to kopier** — `run.py` re-implementerte `ledger.to_ore` privat, og de to kopiene
|
||
møttes på hver sin side av én målsammenligning (`_goal_limit_if_reached`). Søskenets beslutning ble
|
||
«kvantiser per linje, summer heltall», pinnet med `assert run_mod.to_ore is ledger_mod.to_ore`.
|
||
Speilings-spørsmålet er derfor ikke «har vi funksjonen», men: **er vår pengekonvertering ÉN regel,
|
||
og er den load-bearing der den beslutter noe?**
|
||
|
||
**Populasjonen først.** `to_ore` finnes ikke hos oss: **0 treff av 80 undersøkte `.py`-filer** i
|
||
`src`+`tests` (positiv kontroll: samme spørring finner `unit_cost` i 19 av dem, så spørringen KAN
|
||
finne). Vi har ingen NOK→øre-akse i det hele tatt — vår pengeakse er den akkumulerte
|
||
USD-forbruket `total_cost_usd`, og vår konvertering er avrundingen til seks desimaler. Den finnes
|
||
i **fire literale kopier uten navngitt kilde**: `run.py:159` (`_client_cost_usd`), `run_s10.py:110`
|
||
og `:130` (de to persisterings-kallstedene) og `costsim.py:125` (per-celle-estimatet). Én fil
|
||
unna gjør det samme pakket det motsatte: `valuereport.py` avrunder gjennom `_SHARE_DIGITS`.
|
||
**Søskenets drift-form finnes altså her** — i den halvdelen som ikke har fått sin ene kilde.
|
||
|
||
**Og driften har et møtested.** På en `cost_usd`-stopp skriver ETT kall begge tall: `stop.json`
|
||
bærer `observed` fra `BudgetExceeded` — den **rå** verdien gaten sammenlignet — mens `usage.json`
|
||
bærer `cost_usd` **avrundet**. To tall for samme størrelse, fra samme kall, etter to regler.
|
||
|
||
**Men det skarpeste funnet er at tre av de fire kopiene aldri kjøres.** Med
|
||
`scripts/mutation_harness.py`, nevner `tests/` (hele den gamle suiten, 984 tester), hver kjøring
|
||
sha256-restaurert fra disk — og med positivkontrollen først: å erstatte HELE avrundingsuttrykket
|
||
med konstanten `999.0` lot **alle 984 stå grønne** på `run.py:159`, `run_s10.py:110` og `:130`.
|
||
Grenene utøves aldri med en kost. Deres grønne under en detach var derfor aldri bevis om
|
||
avrundingen — det var «ikke målt» (økt 39, Verifiseringsloven ansikt 4 på måleapparatet). Kun
|
||
`costsim.py` var dekket. **DEFAULT-en var derimot pinnet:** `getattr(client, "total_cost_usd",
|
||
None)` → `0.0` er rød i `test_run_entrance_loadbearing.py`. Nøkkelen var pinnet i sitt navn og fri
|
||
i sin verdi (økt 41) — her: default-grenen pinnet, verdi-grenen ukjørt.
|
||
|
||
**Gaten som skulle bruke tallet er slått av på hver eneste sti.** `max_cost_usd` settes i **0 av
|
||
27 `src`-moduler** (positiv kontroll: samme AST-skann finner `max_budget_usd_per_call`, som ER
|
||
wiret). Alle fire `BudgetMeter(...)`-konstruksjoner i `src` tar default `None`, og
|
||
`guard_before_call` returnerer før den sammenligner. C3.5-beltet er altså ikke-no-op **kun i sin
|
||
egen enhetstest**. Samme klasse som S4.0, ett hakk verre: der var feltet lastet og utenfor
|
||
dommerens rekkevidde; her er dommeren bygget og ingen sti gir den et tak.
|
||
|
||
**SYV mutasjoner, alle VALUE-PROVED** (grønn før / rød etter, hver med kollateral-kontroll grønn i
|
||
begge kjøringer); anker → erstatning ordrett:
|
||
|
||
- **M1 — avrundingen detaches** (`run.py`): `return None if cost is None else round(float(cost), 6)`
|
||
→ `return None if cost is None else float(cost)`. To RØDE (kvantiseringen og «ikke den rå
|
||
verdien», splittet); kontroll `test_the_value_branch_is_reached_at_all` GRØNN i begge.
|
||
- **M2 — sifferantallet drifter** (`run.py`): `return None if cost is None else round(float(cost), 6)`
|
||
→ `return None if cost is None else round(float(cost), 2)`. Kvantiserings-testen RØD; samme
|
||
kontroll GRØNN.
|
||
- **M3 — beltet leser den AVRUNDEDE kosten** (`loop.py`, søskenets drift innført):
|
||
`meter.guard_before_call(spent_usd)` → `meter.guard_before_call(round(spent_usd, 6))`.
|
||
Stopp-testen RØD; kontrollen «den avrundede ville ikke ha stoppet» GRØNN i begge.
|
||
- **M4 — stop-eventet rapporterer den avrundede** (`budget.py`):
|
||
`raise BudgetExceeded("cost_usd", self._max_cost_usd, spent_usd)` →
|
||
`raise BudgetExceeded("cost_usd", self._max_cost_usd, round(spent_usd, 6))`. `observed`-testen
|
||
RØD; at beltet fortsatt STOPPER GRØNN — rødheten attribuerer til rapporteringen, ikke til gaten.
|
||
- **M5 — én kopi drifter til et annet sifferantall** (`costsim.py`):
|
||
`cost = round(estimated_tokens * price.usd_per_mtok / _TOKENS_PER_MTOK, 6)` → samme med `, 2)`.
|
||
Siffer-settet RØDT; kopi-tellingen GRØNN (mutasjonen endrer siffer, ikke antall).
|
||
- **M6 — én kopi foldes bort** (`run_s10.py`, fiksens retning):
|
||
` cost_usd=round(client.total_cost_usd, 6),` → ` cost_usd=client.total_cost_usd,`.
|
||
Kopi-tellingen RØD; siffer-settet og modul-settet GRØNNE.
|
||
- **M7 — noen wirer run-total-taket** (`run.py`, ratchet-en): ` run_label = run_id or out_dir.name`
|
||
+ ` meter = BudgetMeter(contracts.termination)` → samme med
|
||
` meter = BudgetMeter(contracts.termination, max_cost_usd=1.0)`. Fraværs-testen RØD;
|
||
positivkontrollen og «en meter uten tak stopper aldri» GRØNNE.
|
||
|
||
**Fixturen fiksen LESER, bygget** (økt 41). `ScriptedClient` bærer ingen `total_cost_usd` i det
|
||
hele tatt, og det er nettopp derfor hver eksisterende run-sti-test bare utøver den ærlige
|
||
null-grenen. `CostingScriptedClient` legger på en — 0.1234567891 USD, mer presisjon enn regelen
|
||
beholder, så den persisterte verdien forteller hvilket tall som ble skrevet. Belte-testene bruker
|
||
en forbruks-verdi som ligger STRENGT MELLOM taket og sin egen avrunding (0.10000004 mot tak 0.1,
|
||
`round(…, 6) == 0.1`): rå verdi stopper, avrundet slipper gjennom. Uten den konstruksjonen er M3 en
|
||
no-op og ville sett ut som en udekket søm.
|
||
|
||
**Pinnet av** `tests/test_cost_usd_quantization_loadbearing.py` (13 tester, 984 → 997, strengt
|
||
supersett: 0 tapte node-id-er). Tre testpar er SPLITTET fordi en rød test bare beviser sin FØRSTE
|
||
assert: «kvantisert til seks desimaler» fra «ikke den rå verdien», «beltet stopper» fra «stoppet
|
||
bærer den rå verdien», og siffer-settet fra kopi-tellingen.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Ingen `src/`-endring er gjort, og det er en beslutning, ikke
|
||
en forglemmelse. Å gi de fire kopiene én navngitt kilde er en refaktorering, ikke en fiks på en målt
|
||
defekt; å wire run-total-taket inn i inngangen er en FEATURE — et CLI-flagg og et kontraktsfelt, med
|
||
`--help`/README-paritetsvakten bak seg — og per-kall-taket `max_budget_usd_per_call` binder allerede
|
||
et live forbruk gjennom SDK-en. Testene sier heller ikke at dagens tilstand er ønskelig: de sier at
|
||
den er MÅLT, og de gjør hver av de tre endringene synlig som en rød test i stedet for en stille
|
||
landing. Kopi-tellingen er dessuten en tekstlig AST-egenskap, ikke et oppførselsbevis — den fanger
|
||
en femte kopi og et endret sifferantall, ikke en femte kopi skrevet på en annen form (`f"{x:.6f}"`,
|
||
`Decimal`). Og `run_s10.py` er byte-frossen og importeres aldri i suiten: dens to kallsteder er
|
||
pinnet ved AST, ikke ved kjøring, hvilket er den sterkeste sømmen som finnes mot en fil vi ikke
|
||
kjører.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
Rammen rundt køen: å lese søskenets kode er tillatt (`3bdf7f0`), men kopiering skal kun skje
|
||
der det tjener løsningen, aldri som snarvei. **Uavhengighets-beviset er DATERT** t.o.m.
|
||
2026-08-09; arbeid etter den datoen kan ikke leses som uavhengig konvergens.
|
||
|
||
## D-A-gater og fasit-berøring
|
||
|
||
- **D-A#5 mangler story-etikett oppstrøms** — avklar med MAF før teksten låses. En ny
|
||
hovedbok-kontrakt MÅ inn i §12s kryssjekktabell i SAMME amendment; ellers blir tabellen
|
||
ufullstendig i det øyeblikket kontrakten finnes.
|
||
- **D-A#2 rører fasiten.** commons er meldt at vår §12-vakt keyer på ordrett `| `generated` |`
|
||
⇒ et amendment som ERSTATTER raden gjør oss RØDE. Det er **by design**: en fasit-endring
|
||
skal koste en synlig rød test, ikke gli gjennom.
|
||
- **Gates:** D-F/D-G → K13 · D-B → K14/K15 · D-E · okf-toolkit-§8 · delbarhet av ledger-/
|
||
outbox-format. R-9 er valgfri.
|