test(experience): the id was pinned, the keying was not - and the two paths disagree

S3.2 measured with scripts/mutation_harness.py, denominator tests/ (963), every
run sha256-restored. The mirroring question answerable offline: is today's
boundary - "the id comes from the FILE, the keying comes from the BUNDLE" -
load-bearing in both halves?

The id half is pinned on both sides (re-minting RED, dropping the mint fallback
RED). The keying half is green-but-dead: empty features and the gated C3.2 fix's
own shape each left all 963 green. Nothing observed what a seeded verdict is
keyed on. One rationale clause too: requiring BOTH learning fields, whose
either-or form emits a marker naming the absent field as None (honesty, §1).

New beyond C-F5: the sibling's drift form DOES exist here. A verdict is keyed in
exactly two places by different rules - the bundle seed (bundle-wide) and the
file/inbox path (per-verdict) - so the same verdict id lands in the same
first-write-wins slot with a keying decided by LOAD ORDER. And promote writes no
candidate features at all, which is why the fix's shape is a no-op against every
fixture in the repo and had to be measured against one carrying the fields.

Pinned by tests/test_experience_keying_loadbearing.py (11 tests, 963 -> 974,
strict superset, 0 node ids lost). No src/ change: C-F5 is GATED on D-A pkt. 4,
and these tests exist so the gated work must arrive as a visible red test and a
decision. Two behaviour-preserving mutations carry their own controls (a third
VerdictRecord site; hoisting the projection read into the loop). Dated under the
D7 frame: work after 2026-08-09, never independent convergence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-12 23:40:07 +02:00
commit 1041687d31
2 changed files with 430 additions and 2 deletions

View file

@ -35,10 +35,10 @@ 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. **Tre er målt, 5 står igjen:**
kandidater, ikke som planlagt arbeid. **Fire er målt, 4 står igjen:**
- ~~S2.7~~ — **MÅLT 2026-09-07, se under**
- S3.2
- ~~S3.2~~ — **MÅLT 2026-09-12, se under**
- S4.0 (`126807a`)
- (p) `to_ore` — TO kallsteder
- ~~(a)/(i) `unquote_scalar`~~ — **MÅLT 2026-08-31, se under**
@ -191,6 +191,80 @@ 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.
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.