portfolio-optimiser/shared/docs/plan/2026-07-25-b1-nav-golden-normative-status.md

238 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# B1 / D4 — skal nav-golden-klassen ha en normativ referanse?
**Status: AVGJORT OG UTFØRT 2026-07-31 — operatøren valgte O1** (form C: informativ kataloglenke
fra `README.md`). Utført i samme økt; se **§5.1**. Underlaget under står uendret som grunnlaget
vedtaket ble tatt på.
Opprinnelig status: operatør-spørsmål. Dette dokumentet endrer **ingen** normativ tekst og foreslår
ingen. Det svarer på det commons kan svare på uten å foregripe en ratifisering: hva som
allerede er avgjort, hva tilstanden er i dag (fil + linje), hvilke referanseformer specen
faktisk har, og hva hver av dem koster å ta i bruk her.
**Grunnlag:** commons HEAD `29ad8ca`. Normativ spec-tekst uendret siden `9801d35`
(method-spec) / `bfa5a9b` (ingest-spec), fixturene siden `b641741` — alle 2026-07-21. Alle
linjeankere under er lest fra HEAD, ikke gjengitt fra hukommelse.
**Avgrensning:** dette er commons' eget punkt. Det står **utenfor** amendment-pakken
(`portfolio-optimiser` bekreftet 2026-07-25 at B1 ikke har adferds-interesse oppstrøms), og
ingen venter på oss. Det kan avgjøres når som helst, også etter pakken.
---
## 1. Det som allerede er avgjort — ikke oppe til vurdering
D4 fra OKF-runden, ratifisert i trinn F 2026-07-21, deler arbeidet i to:
- **commons eier** nav-golden-bundleklassen og det forventede utfallet, og leverer den inn.
- **catalog eier** korpus-containeren, de adversarielle aksene og runner/gate.
`llm-ingestion-okf` bekreftet 2026-07-25 04:19Z at klassen aldri var deres, og at beskrivelsen
matcher D4. Commons-halvdelen er **levert** i `b641741`:
| Case | Innhold | Rolle |
|---|---|---|
| `examples/nav-golden-hierarchy/` | `bundle/` (nestet `a/b/`, `c/orphan.md`), `expected-read-context.md`, `README.md` | positiv: ni Q3-beslutninger utøves |
| `examples/nav-golden-escape/` | `bundle/`, `expected-read-context.md`, `README.md`, `SHOULD-NOT-BE-READ.md` | negativ: porten må kunne gå rød |
Splitten, eierskapet og fixturenes innhold er altså ikke spørsmålet. Spørsmålet er hva
spec-teksten sier om dem — i dag: ingenting.
---
## 2. Tilstanden i dag, verifisert
Ingen normativ fil nevner klassen. Ikke «få treff» — null, i hver enkelt:
| Fil | `grep -c 'nav-golden'` |
|---|---|
| `method-spec.md` | 0 |
| `ingest-spec.md` | 0 |
| `CONCEPT.md` | 0 |
| `README.md` | 0 |
| `skills/expert-reviewer/SKILL.md` | 0 |
Fixturene er dermed i dag rene artefakter: de finnes, de er dokumentert i sine egne
`README.md`-filer, og ingenting utenfor katalogen deres viser til dem.
**Merk om sjekken:** `grep -rn 'nav-golden' *.md` gir i dag **3** treff, alle i `STATE.md`
(LOCAL-ONLY, gitignored, ikke-normativ). Underlagets verifiseringslogg
(`2026-07-25-amendment-underlag.md:350`) noterte «0 treff» på nettopp den kommandoen, og den
reproduserer ikke lenger. Påstanden er uendret sann — sjekken var for vid. Korrigert i samme
commit som dette dokumentet.
---
## 3. Specen har tre referanseformer, ikke én
Dette er kjernen, og grunnen til at spørsmålet ikke er binært. «Normativ referanse» er ikke
én ting i dette repoet — tre distinkte former er allerede i bruk, med forskjellig
bindingskraft:
| | Form | Hvor den er brukt | Hva den binder |
|---|---|---|---|
| **A** | **Artefaktnavn som fasit** | method-spec §7 `:332-333`: *«The shared example bundle ships two JSON files that are the only ground truth ("fasit") … Implementations MUST consume them unchanged»* | navngir `validator-input.json` / `golden.json`; konformans-krav på verdiene |
| **B** | **Katalogkonvensjon + oppføringstabell** | ingest-spec §11 `:259-267`: *«Golden extraction format: one directory per case, convention `examples/ingest-golden-{source type}/`»* + tabell over påkrevde oppføringer | navngir et **format** for en case-klasse, ikke enkeltcaser |
| **C** | **Informativ kataloglenke** | `README.md:19``examples/bygg-energi-mikro/`, beskrevet som *«a small dev fixture»* | oppdagbarhet; null konformansvekt |
nav-golden har i dag **ingen** av de tre. Det er den presise mangelen — skarpere enn «0 treff».
**En egenskap ved method-spec som begrenser opsjonsrommet:** den navngir **aldri en katalogsti
i repoet**. `grep -c 'examples/'` → 0, `grep -c 'bygg-energi-mikro'` → 0. Den navngir filnavn
(`validator-input.json`, `golden.json`, `test_okf.py`) og aldri hvor de bor. De ti
`/`-holdige tokenene i filen er lenke-syntaks *inne i* en bundle (`sub/index.md`, `/a/b.md`),
ikke repo-stier. En form B-referanse i method-spec ville være den **første** repo-stien i det
dokumentet.
---
## 4. Spørsmålet
**Skal nav-golden-klassen gis en normativ referanse, og i så fall i hvilken form?**
Underspørsmål som følger med, uansett svar: hvis klassen blir normativ, må serialiserings-
sammenligningen pinnes? (Se O2 og O3 under — det er den ene konsekvensen som ikke er
kosmetisk.)
---
## 5. Opsjonene, med målt kostnad
| | Opsjon | Berørt tekst | Frossen tekst endres? | Reverserbar |
|---|---|---|---|---|
| **O0** | Forbli informativ fixture (status quo) | ingen | nei | — |
| **O1** | Form C: lenke fra `README.md` | `README.md:19`-blokken | nei (README er ikke normativ) | trivielt |
| **O2** | Form B: katalogkonvensjon i method-spec §11 | ny avsnitt/rad ved `:425` | **ja**, tillegg | middels |
| **O3** | Form A: løft til fasit i §7 | `§7:332-333` **og** `§1:23` | **ja**, omskriving av tellende påstand | dyrt |
### O0 — forbli informativ fixture
Ingen endring. Fixturene er fortsatt levert, catalog kan fortsatt bygge runner/gate på dem,
og D4s commons-halvdel er fortsatt oppfylt (D4 krevde levering, ikke normativ referanse).
Kostnaden er at bindingen mellom §11-raden `:425` og beviset for den bare finnes i catalogs
runner og i fixturenes egne README-er — ingen spec-tekst sier at de hører sammen.
### O1 — form C, lenke fra README
Billigst mulige forbedring av oppdagbarhet. `README.md` er katalog, ikke kontrakt, så ingen
implementasjon får en ny plikt. Løser ikke bindingsproblemet i O0; gjør det bare synlig.
### O2 — form B, katalogkonvensjon i method-spec §11
Den formen som passer klassen best: en nav-golden-case *er* en formatklasse (`bundle/` inn,
`expected-read-context.md` ut), akkurat som ingest-golden er det. Naturlig plassering er ved
**Navigation boundary**-raden `:425`, som i dag beskriver rød-betingelsen og siterer
referansetesten `test_okf.py (navigation boundary)`, men ikke navngir noe korpus som beviser
den.
Tre konkrete kostnader, alle verifisert:
1. **Første repo-sti i method-spec** (se §3). Enten aksepteres det som et bevisst brudd, eller
så må konvensjonen formuleres uten sti — og da mister den det meste av verdien.
2. **Oppføringstabellen blir ikke uniform.** ingest-goldens tabell (`:262-267`) har fire
påkrevde oppføringer og ingen valgfrie. nav-golden-casene har **ulike** oppføringssett:
escape-casen trenger `SHOULD-NOT-BE-READ.md` som bevisst ligger *utenfor* `bundle/` (den
er lokkematen `../SHOULD-NOT-BE-READ.md` peker på), hierarchy-casen har ingen slik fil. En
felles konvensjon må derfor ha en valgfri rad — noe ingest-golden ikke har presedens for.
3. **Serialiseringen er ikke pinnet.** Dette er den reelle. `nav-golden-hierarchy/README.md`
sier eksplisitt: *«The spec does not pin whitespace beyond this shape; a gate MAY compare
byte-exact or after trailing-whitespace normalization.»* ingest-goldens motstykke er
pinnet: `:267` *«compared file by file, byte for byte»* og §11-raden `:280` *«any byte …
diverges»*. Gjør man nav-golden normativ i form B uten å ta stilling, arver klassen en
`MAY` der søsterklassen har en `MUST` — to konforme porter kan da være uenige om samme
fixture. Enten pinnes sammenligningen, eller så uttales `MAY`-en som bevisst.
### O3 — form A, løft til fasit i §7
Dyrest, og kostnaden er ikke størrelsen på diffen, men at to **tellende** påstander må
skrives om:
- `§7:332-333`: *«The shared example bundle ships **two** JSON files that are **the only**
ground truth»* — «two» og «the only» er begge usanne i det øyeblikket en tredje ground
truth finnes. I tillegg er setningen scoped til **én** bundle («the shared example
bundle»), mens nav-golden-casene er *andre* bundler.
- `§1:23`, konformansledd 2: *«reproduces the shared golden suite's decided outcomes (§7) on
the shared example bundle»* — samme entallsbinding, i selve konformansdefinisjonen.
O3 er altså ikke et tillegg, men en utvidelse av hva «fasit» betyr i denne specen, fra én
bundle til en mengde. Det er en reell arkitekturbeslutning, ikke en redaksjonell.
Serialiseringspoenget fra O2 punkt 3 gjelder her med full tyngde: en fasit med en `MAY` i
sammenligningsregelen er ikke en fasit.
### 5.1 Svaret, og hva som faktisk ble gjort (2026-07-31)
**Vedtatt: O1** — form C. Én oppføring i `README.md`s «Contents (growing)»-liste, i samme form
som `examples/bygg-energi-mikro/``:19`, som lenker begge casene og peker på deres egne
`README.md`-filer for detaljene.
**Frossen tekst er ikke rørt, og klassen har ikke fått bindingskraft.** Verifisert etter
endringen: `grep -c 'nav-golden'` gir fortsatt **0** i `method-spec.md`, `ingest-spec.md`,
`CONCEPT.md` og `skills/expert-reviewer/SKILL.md`. Bare `README.md` gikk fra 0 til treff, og
README er katalog, ikke kontrakt (§3, form C: «oppdagbarhet; null konformansvekt»). Ingen
implementasjon har fått en ny plikt. `git status` viste `README.md` som eneste endrede fil.
**Oppføringen sier eksplisitt at den er informativ**, og at sammenligningsregelen ikke er pinnet
— nettopp for å hindre den ene misforståelsen O1 kunne skapt: at en lenke fra rot-README gjør
klassen til fasit i den forstand method-spec §7 bruker ordet.
**Det O1 med vilje IKKE løser** (uendret fra §5s beskrivelse): bindingsproblemet i O0 står. Ingen
spec-tekst sier at §11-raden `:425` og disse fixturene hører sammen — O1 gjør mangelen synlig,
ikke borte. Å lukke den krever O2/O3 og en ratifiseringsrunde.
**Serialiseringsspørsmålet er fortsatt åpent, og er uavhengig av dette vedtaket** (§6): to
implementasjoner som sammenligner ulikt vil være uenige om nav-golden enten specen nevner klassen
eller ikke. Det kan avgjøres separat og tidligere, og O1 verken løser eller foregriper det.
---
## 6. Hva commons vil peke på (ikke en anbefaling)
Én asymmetri er verdt å ha for hånden når spørsmålet avgjøres: **O0 og O1 er reverserbare,
O2 og O3 er det ikke på samme måte.** Frossen tekst i dette repoet endres bare ved
ratifisering, og en normativ referanse som senere skal fjernes koster en ny runde. Motsatt
koster det ingenting å utsette O2/O3 — fixturene er levert, catalog kan bygge på dem uansett,
og ingen implementasjon blokkeres av at referansen mangler.
Serialiseringsspørsmålet (O2 punkt 3) er derimot **uavhengig** av om referansen kommer: to
implementasjoner som sammenligner ulikt vil være uenige om nav-golden enten specen nevner
klassen eller ikke. Det kan avgjøres separat, og tidligere.
---
## 7. Det som ikke er commons' å avgjøre
- **Runner og gate** — catalogs eierskap per D4. Om porten sammenligner byte-eksakt eller
normalisert er catalogs implementasjonsvalg *inntil* specen pinner det; da blir det vårt.
- **De adversarielle aksene** og korpus-containeren — catalog.
- Ingenting her berører amendment-pakken. Køpunkt 17 i
`2026-07-25-amendment-underlag.md` står uendret.
---
## 8. Det som ikke endres uansett utfall
Fixturene selv. `b641741` er levert og korrekt, og ingen av opsjonene over foreslår å røre
`bundle/`, `expected-read-context.md` eller case-README-ene. Spørsmålet gjelder utelukkende
om — og hvordan — spec-teksten viser til dem.
---
## Verifiseringslogg
| Påstand | Sjekk | Resultat |
|---|---|---|
| Fixturene levert 2026-07-21 | `git log --oneline -- examples/nav-golden-*` | `b641741`, eneste commit |
| Ingen normativ fil nevner klassen | `grep -c 'nav-golden'` per fil | 0 / 0 / 0 / 0 / 0 |
| Den siterte sjekken reproduserer ikke | `grep -rn 'nav-golden' *.md` | 3 treff, alle `STATE.md` |
| method-spec navngir ingen repo-sti | `grep -c 'examples/' method-spec.md` | 0 |
| method-spec navngir ikke fasit-bundelen | `grep -c 'bygg-energi-mikro' method-spec.md` | 0 |
| `/`-tokenene er lenke-syntaks, ikke stier | `grep -oE '\`[^\`]*/[^\`]*\`' method-spec.md`, alle 10 lest | `sub/index.md`, `/a/b.md`, `./a.md`, `/` |
| §7 sier «two» og «the only» | `method-spec.md:332-333` | ordrett sitert over |
| §1 binder konformans til én bundle | `method-spec.md:23` | «on the shared example bundle» |
| §11-raden navngir ingen fixture | `method-spec.md:425` | seam + rød-betingelse + `test_okf.py` |
| ingest-golden er en katalogkonvensjon | `ingest-spec.md:259-267` | «one directory per case, convention …» + 4-rads tabell |
| ingest-golden er byte-pinnet | `ingest-spec.md:267`, `:280` | «byte for byte» / «any byte … diverges» |
| nav-golden er IKKE byte-pinnet | `examples/nav-golden-hierarchy/README.md:31-33` | «a gate MAY compare byte-exact or after … normalization» |
| Escape-casen har fil utenfor `bundle/` | `ls examples/nav-golden-escape/` | `SHOULD-NOT-BE-READ.md` er søsken av `bundle/` |
| README er eneste kataloglenke | `grep -n 'examples/' README.md` | `:19`, `bygg-energi-mikro` |
| B1 = D4, ikke okf-eid | `~/.claude/coord/portfolio-optimiser/archive/20260725T041948Z-*` | okf: «never owned here; it is D4» |
| Spec-tekst uendret siden 07-21 | `git log --oneline -- method-spec.md ingest-spec.md` | `9801d35` / `bfa5a9b` |