test(baseline): the baseline was loaded, and the judge could never reach it
S4.0, the fifth D7 mirroring candidate, measured with scripts/mutation_harness.py
against the real tree. C-F3 says "nothing in the bundle format carries a cost
baseline to reconcile against". Measured, that is too strong: validator-input.json
carries ENERGI-TOTAL-EL at 300 000 NOK and it is loaded on every run path. The
defect is not that the baseline is missing -- it is that no path connects it to
the judge.
A SavingsProposal comes into being in exactly three places (model-authored parse,
bundle baseline, re-read output; AST-measured over all 27 src files, positive
control: the same query finds validate_proposal's one call site). Only the first
reaches the validator. The only field read off the baseline directly is
project_id; the quantities, unit costs and uncertainty bands are schema-validated
and never read again.
Seven mutations, every one green-before/red-after with the restore sha256-verified
from disk:
M1 baseline swapped for the weakest schema-valid variant -- 3 targets RED,
all 974 pre-existing tests GREEN in both runs
M2 the carried annotation narrowed to object -- AST ratchet RED, behaviour GREEN
M3 the S10 path stops loading the baseline -- loader population RED
M4 the validator gains a baseline parameter -- signature ratchet RED, golden GREEN
M5 the call-site argument becomes a keyword -- provenance control RED
M6 fail-closed code-set gate (the gated fix's own shape) -- boundary RED, golden GREEN
M7 retrieval stops reading the codes -- disjointness RED
M4 and M6 leaving the golden green is itself the finding that S4.0 is
golden-compatible when D-A pkt. 2 lands.
A measuring trap was caught by the harness rather than by memory: the first M1
flattened the cost lines to 1.0x1.0, which broke the IR invariant (claim 30 000 >
total 1.0) and turned the run-entrance tests red. That redness attributed to
pydantic, not to the seam. The collateral control refused the proof.
New beyond C-F3: the fabricated line's code set is DISJOINT from the bundle's, and
retrieval computes that disjointness to rank experience. The system holds the
evidence that would expose the fabrication and spends it on ranking, never on
deciding.
No src/ change -- the fix is GATED on D-A pkt. 2 plus a commons amendment. Tests
pin the boundary so the gated work must arrive as a visible red test.
974 -> 984, strict superset, 0 node ids lost.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
1041687d31
commit
b955bf274e
2 changed files with 307 additions and 2 deletions
|
|
@ -35,11 +35,11 @@ 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. **Fire er målt, 4 står igjen:**
|
||||
kandidater, ikke som planlagt arbeid. **Fem er målt, 3 står igjen:**
|
||||
|
||||
- ~~S2.7~~ — **MÅLT 2026-09-07, se under**
|
||||
- ~~S3.2~~ — **MÅLT 2026-09-12, se under**
|
||||
- S4.0 (`126807a`)
|
||||
- ~~S4.0~~ (`126807a`) — **MÅLT 2026-09-13, se under**
|
||||
- (p) `to_ore` — TO kallsteder
|
||||
- ~~(a)/(i) `unquote_scalar`~~ — **MÅLT 2026-08-31, se under**
|
||||
- `mandate.py`
|
||||
|
|
@ -265,6 +265,94 @@ involvert i nøklingen i det hele tatt** — hvilket er nettopp derfor den ikke
|
|||
**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.
|
||||
|
||||
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue