# Amendment-underlag — hva frossen tekst sier i dag, per køpunkt **Status:** underlag. Spec-en er IKKE endret, og dette dokumentet foreslår INGEN ny tekst. Ny tekst er pakken operatøren ratifiserer, og den eies oppstrøms (`portfolio-optimiser`, sammen med `portfolio-optimiser-claude`s tekstforslag). Dette dokumentet svarer bare på spørsmålet commons kan svare på uten å foregripe ratifiseringen: **hvilke seksjoner røres, hva står der i dag (fil + linje), og hva koster endringen mot fasit-bundelen.** **Foranledning:** `portfolio-optimiser` klarerte 2026-07-25 (05:09Z, punkt 3) generelt underlag som trygt arbeid som ikke invalideres av at pakken deres holdes: *«preparing GENERAL underlag (which spec sections those five stories touch, what the frozen text says today) is safe work that will not be invalidated»*. Dette er det arbeidet. **Grunnlag:** commons HEAD `a67a243`. Normativ spec-tekst er uendret siden `bfa5a9b` (ingest-spec, D1-stempelmodellen) / `9801d35` (method-spec §3 Steg 1, Q3-navigasjonen) / `b641741` (nav-golden-fixtures) — alle 2026-07-21. Hver sitat-blokk under er hentet fra HEAD og linjeankeret verifisert, ikke gjengitt fra hukommelse. > **Leseanvisning for konsumenter (tilføyd 2026-07-26).** Alle linjeankere i dette dokumentet > gjelder **commons HEAD**. Konsumentene er pinnet på eldre `shared/`-subtrær, og et > linjenummer overlever ikke en pull-grense: `portfolio-optimiser-claude` står på `7aa53fc`, > der `method-spec.md` er 441 linjer og §12 begynner på `:413` — mot 464 linjer og `:436` her. > **Sitér seksjon + ordrett tekst; linjenummeret er en bekvemmelighet, aldri ankeret.** Et > linjenummer sitert over en pull-grense er et *premiss*, ikke et faktum (metodenote fra > `portfolio-optimiser-claude`, 2026-07-26 — de fant den på dette dokumentets egne sitater). --- ## 0. Køen, avstemt To korreksjoner fra `portfolio-optimiser` (16:11Z) er **godtatt**, begge verifisert: 1. **Tittel-whitespace er ikke et eget punkt** — det ER amendment-innholdet i S3.5. Vår telling dobbeltførte det. (Deres kø-linje `(a) commons-amendment tittel-whitespace → S3.5` ble lest som «punkt ved siden av», ikke «innholdet i».) 2. **B1 er ute av pakken** — commons-eid, ingen adferds-interesse oppstrøms. Bæres separat (§8 her). Én korreksjon går **tilbake** oppstrøms, og den er grunnen til at underlaget er verdt å skrive før pakken lukkes: 3. **De to oppstrøms-enumerasjonene er ikke den samme mengden.** `portfolio-optimiser` teller fem *stories* (S2.7 / S2.2–2.4 / S3.2 / S3.5 / S4.0); `portfolio-optimiser-claude` teller fem *D-A-punkter*. Bare tre par binder (S2.7 = D-A#1, S3.2 = D-A#4, S4.0 = D-A#2). De to gjenstående D-A-punktene har **ingen story-etikett** oppstrøms: - **D-A#3 (ledende `/`)** — trenger ingen amendment i det hele tatt. Frossen tekst i commons HEAD sier allerede det punktet ber om (§3 under). **Årsaken er repo-avhengig** (begge konsumenter svarte, med hver sin — begge er sanne): drift over pull-grensen hos `portfolio-optimiser-claude`, målt konformitetsgap i `okf.py` hos `portfolio-optimiser`. Anbefalingen er den samme uansett hvilken som gjelder hvor. - **D-A#5 (hovedbok-projeksjoner)** — er reell og har ingen tekst å endre (§6 under), men mangler story-etikett. Ratifiserer operatøren «pakken» slik `portfolio-optimiser` beskriver den, faller D-A#5 utenfor. Netto, fra commons' side: pakken er deres seks **pluss** hovedbok-kontrakten = **sju ratifiserbare punkter**, med D-A#3 strøket som amendment. B1 utenfor, som avtalt. Tallet er ikke poenget — membership er. **S2.2–2.4 (D-B)** var det ene punktet commons ikke kunne ankre. **Substansen kom 2026-07-26** og er ført i §7.1–7.2: D-B er en *scope*-beslutning, ikke spec-tekst. **To av de tre gatede storiene viste seg UGATED** — S2.2 fordi §4s `http`-punkt normativt plasserer MCP-konnektorer i `http`-familien (MUST på samme kontrakter), S2.4 fordi berikelsen holder seg innenfor §8s tre felt. **Kun S2.3 (`doc`) krever amendment.** Begge frigjøringene kom av ankring i frossen tekst, ingen av dem av en endring. --- ## 1. S2.7 / D-A#1 — nominal feasibility skal GATE, + IR-invariant `low ≤ unit_cost ≤ high` **Seksjoner:** `method-spec.md` §3 Steg 4 (`:150-166`), §7.1 (`:335-346`), §7.2 (`:348-365`), §12 (`:458`). **Hva frossen tekst sier i dag.** Den nominale grensen *beregnes*, og bare `p90` *blokkerer*: > **`method-spec.md:157-160`** (§3 Steg 4, punkt 2) > 2. **Feasibility bound:** the maximum feasible saving is capped at a policy fraction > (0.30) of the affected items' total cost. *(reference: computed with an LP solve whose > closed form here is `0.30 × Σ quantity·unit_cost`; a missing solver MUST escalate, never > silently fall back.)* > **`method-spec.md:163-166`** (§3 Steg 4, punkt 4) > 4. **Structural block:** a claim above the optimistic feasible bound (`p90`) yields a > **rejection that is a distinct type from a validated proposal** … Punkt 2 sier `capped at`, men gir ingen avvisningsregel; punkt 4 er den ENESTE blokkeringen og bruker `p90`. Påstanden «beregnes, men bare p90 blokkerer» holder altså mot teksten. §7.2 sier det samme eksplisitt om hva assertionen betyr: > **`method-spec.md:356-358`** (§7.2) > … The meaningful assertion is `validates` = true (claimed ≤ `p90`); the frozen numbers are > the regression net. `nominal_feasible` er et frosset felt (`:352-356`, kryssjekk `:458`) — det er allerede normativt *rapportert*, bare ikke *gatende*. **IR-invarianten finnes ikke.** §7.1 har én construction-time-invariant, og den handler om noe annet: > **`method-spec.md:343-344`** (§7.1) > - Construction-time invariant: the claimed saving MUST NOT exceed the affected items' own > total (`Σ quantity·unit_cost`); violation is a schema error, not a validator rejection. `assumptions` er definert som band per kostkode (`:341-342`), men ingenting binder `unit_cost` til å ligge INNI sitt eget band. Hullet er reelt. **Målt mot fasit-bundelen (`examples/bygg-energi-mikro/`) — begge endringene er byte-nøytrale:** | Sjekk | Verdi i fasit | Konsekvens | |---|---|---| | `claimed_saving_nok` vs. `nominal_feasible` | `30000` vs. `90000.0` | claimed ≤ nominal → en nominal gate endrer ikke `validates` (fortsatt `true`) | | `unit_cost` vs. eget band | `1.0` i `[0.70, 1.40]` | invarianten er allerede oppfylt → fixture trenger ingen endring | Kilder: `examples/bygg-energi-mikro/golden.json` (validator-blokken), `examples/bygg-energi-mikro/validator-input.json` (`affected_items[0]`, `assumptions`). **Klassifisering:** ekte hull i frossen tekst (begge deler). Gratis mot goldenbytene. **Operatør-spørsmålet:** skal nominal-grensen gi samme *type* avvisning som p90-blokket (`:163-166` sier «distinct type … carrying the claimed and feasible figures … and no percentiles») eller en egen? Teksten har i dag én avvisningsform, og den er definert av p90. --- ## 2. S3.2 / D-A#4 — seedet dom skal nøkles på SINE EGNE features **Seksjoner:** `method-spec.md` §3 Steg 1, experience fold (`:105-123`). > **`method-spec.md:108-114`** > - The retrieval query key is the bundle's candidate features, read from the IR projection > (§7.1) — available *before* any proposal exists. > - Seeding: every `type: verdict` file in the bundle becomes a store entry keyed on those > candidate features, with `decision` from frontmatter (default `approved`) … `those candidate features` refererer tilbake til forrige kulepunkt — bundelens ENE IR-projeksjon. Frossen tekst sier altså eksplisitt det punktet vil bort fra: hver seedet dom arver bundelens projeksjonsnøkkel, ikke sin egen. Hullet er reelt og teksten er entydig. **Berøringsflate videre:** nøkkelen er det rangeringen (`:115-120`) og id-mintingen (§4.2 `:254-260`) hviler på. `affected_codes` / `measure_type` / `claimed_saving_nok` er feltene en «egen-features»-nøkling må komme fra, og §4.2 `:250-252` sier at `description` bevisst er utenfor både likhet og minting. En amendment her må si hvor en seed-fils egne features LESES fra (frontmatter? egen projeksjon?) — det er den åpne enden, ikke prinsippet. **Målt:** fasit-bundelen har én seed (`verdict-led-fro.md`) og én projeksjon, så `golden.json` kan ikke skille gammel og ny nøkling. Endringen er byte-nøytral her, og fasiten er derfor ikke et vern mot regresjon på dette punktet. **Klassifisering:** ekte hull. **Operatør-spørsmålet:** kilden for en seeds egne features. --- ## 3. D-A#3 — ledende `/` : INGEN amendment nødvendig **Dette punktet er allerede normativt i commons HEAD** (landet `9801d35`, 2026-07-21): > **`method-spec.md:67-71`** (§3 Steg 1) > - Navigation starts at `index.md` and follows its intra-bundle markdown cross-links > (`](target.md)`). A target is resolved **relative to the bundle** and boundary-checked > fail-closed (below): a leading `/` denotes the **bundle root** (NEVER a filesystem-absolute > path), any other form is relative to the linking file's own directory — so a target MAY > address a nested directory (`sub/index.md`, `/a/b.md`). Og §11 har allerede rød-betingelsen som feiler hvis en implementasjon hopper over den: > **`method-spec.md:425`** (§11, «Navigation boundary») > … an escaping cross-link (`..`, a filesystem-absolute path, or a bundle-root `/` read as > filesystem-absolute) is followed, a malformed target … is raised instead of skipped, or a > legitimate nested in-bundle link is skipped Teksten sier også selv at den ERSTATTET den gamle skip-heuristikken (`:73-74`). **Klassifisering:** **drift over pull-grensen** — verken spec-hull eller konformitetsavvik. Ligger et forslag om å «endre» §3 Steg 1 her, endrer det tekst som allerede sier det forslaget vil oppnå — og risikoen er at ratifiseringen omformulerer en fungerende regel. **Meldt oppstrøms.** > **Årsaks-korreksjon (2026-07-26).** Første utgave av dette avsnittet klassifiserte D-A#3 som > «konformitetsgap i implementasjonen» og skrev at forslaget beskrev implementasjonens > oppførsel framfor specens. **Det var feil årsak.** `portfolio-optimiser-claude` målte det mot > eget tre og svarte at deres `shared/method-spec.md` greper 0 for «bundle root» og > «filesystem-absolute» — fordi teksten landet i `9801d35`, og: > > ``` > git merge-base --is-ancestor 9801d35 7aa53fc -> false (reprodusert her) > ``` > > Deres split er `7aa53fc`; driften er 15 commits per 2026-07-26. De står i «ikke pullet» > **bevisst** — avtalen er samme commons-commit i begge repo før noen bygger. D-A#3 var altså > korrekt formulert mot den frosne teksten de har lov til å se; regelen landet oppstrøms > etterpå. **Anbefalingen er uendret** (punktet ut av pakken, siden regelen er normativ når > pakken lander), men den følger av drift, ikke av et avvik hos dem. > > Lærdommen generaliserer og er derfor løftet til leseanvisningen øverst: **samme felle venter > på ethvert punkt målt mot en bevegelig frossen tekst mens konsumentene er pinnet.** > **Andre korreksjon, samme dag — årsaken er REPO-AVHENGIG, og begge svar er sanne.** > `portfolio-optimiser` svarte kort etter og klassifiserte D-A#3 som **«et KONFORMITETSGAP i > implementasjonen vår — ikke et spec-hull»**, med en konkret årsak: *«okf.py hopper over enhver > lenke med `/`»*. Det er den motsatte klassifiseringen av den `portfolio-optimiser-claude` ga. > > **Ingen av dem tar feil.** De beskriver to forskjellige repo: > > | Repo | Har `9801d35`? | Årsak der | > |---|---|---| > | `portfolio-optimiser-claude` | nei (pinnet `7aa53fc`) | **drift** — regelen finnes ikke i teksten de har | > | `portfolio-optimiser` | nei (pinnet `7aa53fc`) | **konformitetsgap** — de har målt eget avvik i `okf.py` og har det på operatørkøen som implementasjonssak | > > Begge konsumenter står på samme commons-commit (`7aa53fc`, bekreftet av begge uavhengig), så > pullen er én koordinert handling, ikke en opprydding etter usynk. > > **Dette avsnittets egen historie er poenget:** første utgave ga én universell årsak, korreksjonen > ga en annen universell årsak, og begge var for brede. «Årsaken til D-A#3» er ikke én ting når > konsumentene er pinnet og har ulik implementasjonstilstand. Anbefalingen har vært uendret hele > veien — punktet ut av pakken — og den avhenger ikke av hvilken årsak som gjelder hvor. --- ## 4. S4.0 / D-A#2 — kostbaseline-forankring (`cost-baseline.json`) **Seksjoner:** `method-spec.md` §7 (`:330-333`), §7.1 (`:335-346`), §12 (`:441-464`). **Frossen tekst har ingen baseline-forankring** — `grep -c 'cost-baseline'` over begge spec-er: **0 treff**. Det som finnes, og som en ubetinget baseline kolliderer med: > **`method-spec.md:332-333`** (§7) > The shared example bundle ships two JSON files that are **the only ground truth** ("fasit") > for cross-implementation equivalence. Implementations MUST consume them unchanged. **Målt:** `examples/bygg-energi-mikro/` inneholder nøyaktig to JSON-filer (`validator-input.json`, `golden.json`) og seks markdown-filer. Ingen baseline. Et ubetinget krav gjør en tredje fil til ground truth og gjør setningen over usann samtidig — pluss at fasit-bundelen må utvides, hvilket er en fixture-endring, ikke bare en tekstendring. `portfolio-optimiser-claude`s egen formulering («åpent om den skal være obligatorisk … et ubetinget krav endrer golden-bytene») treffer riktig, og §7:332-333 er ankeret som gjør det konkret. **Presedens for hvordan en required input formuleres**, hvis den blir obligatorisk: > **`method-spec.md:345-346`** (§7.1) > - Loading the IR projection from a bundle is FAIL-FAST: a missing file raises (required > input — contrast the tolerant inbox, §5). **Klassifisering:** ekte hull, men det eneste punktet i køen som (hvis ubetinget) **endrer fasit-bundelen** og ikke bare prosa. **Operatør-spørsmålet:** obligatorisk for alle kjøringer (→ fixture-endring + §7-setningen må omskrives), eller opsjonell med fail-fast-semantikk kun når den finnes (→ ren prosa-utvidelse, fasiten uendret)? --- ## 5. S3.5 / D-F — tittel-whitespace **Seksjoner:** `ingest-spec.md` §4 (`:125`), §5 (`:149-161`), §6 (`:194-197`), §11 (`:278`), §12 (`:301`). > **`ingest-spec.md:125`** (§4, extraction-tabellen) > | `title` | Human-readable title; … Single-line, and MUST NOT contain `[` or `]` … Validated > fail-fast at manifest load — rendered verbatim thereafter (§5, §6). | > **`ingest-spec.md:158-161`** (§5, frontmatter-kulepunktet) > … All values MUST be single-line; `title` is emitted **verbatim** (it is `[`/`]`-free by §4, > so verbatim rendering is safe — the invariant is met by validation, not repair); the > materializer MUST collapse whitespace runs (including newlines) in `source_query` to single > spaces. Formen på hullet, presist: **collapse er scoped til `source_query` alene**, og `title` er uttrykkelig `verbatim` med invarianten «met by validation, not repair». En tittel med interne whitespace-runs er derfor ikke normalisert noe sted — den er bare «single-line», og hva `single-line`-valideringen dekker (bare `\n`? `\r`? ledende/etterfølgende blanke?) står ikke. Amendment-punktet ligger i den sømmen, og valget er **validere hardere** vs. **reparere** — teksten har i dag valgt validering for `title` og reparasjon for `source_query`. **⚠ Anker-avvik oppstrøms (viktig for denne teksten spesielt).** `portfolio-optimiser` ankret sitatet til `shared/ingest-spec.md:140`. Det linjenummeret er commons ved **`7aa53fc`**, ikke HEAD: - ved `7aa53fc`, linje 140: `` `generated`. All values MUST be single-line; the materializer MUST collapse whitespace runs `` - ved HEAD (`bfa5a9b`): samme setning er splittet over `:158` og `:160-161`, og `title is emitted verbatim` + «validation, not repair» er **ny tekst** fra `bfa5a9b`. `bfa5a9b` (+39/−9) skrev om nettopp dette kulepunktet OG `title`-raden i §4 (som gikk fra bare «Single-line.» til dagens `[`/`]`-forbud + fail-fast + verbatim). Deres `shared/`-kopi ser altså ut til å ligge ett commons-commit bak, fra FØR D1-stempelmodellen landet. Det betyr at S3.5 kan være formulert mot tekst som ikke lenger finnes i den formen — og det er samme risiko de selv navnga («pullen må være koordinert, samme commons-commit»). **Meldt oppstrøms.** **Klassifisering:** ekte, men smal søm. Ingen fasit-effekt her (våre fixtures har ingen ingest-manifester; goldenbundlene for ingest bor i implementasjonene, jf. §11 `:259-261`). --- ## 6. D-A#5 — projeksjoner over besparelses-hovedboken (INGEN eksisterende tekst) **Målt:** `grep -ci 'ledger'` og `grep -ci 'hovedbok'` over `method-spec.md` + `ingest-spec.md` → **0 og 0**. Ingen monetær avrundingsregel finnes heller: alle 13 forekomster av `round` (12 linjer: 9 i method-spec, 3 i ingest-spec) er andre ting (`round-capped` debatt `:141`/`:386`, `max_rounds` `:378`/`:385`, `shortest round-trip decimal` `ingest-spec.md:165`, `round-trip` `ingest-spec.md:85`, `around` `:323`). Nærmeste eksisterende flater, som en ny kontrakt må forholde seg til uten å kollidere: - **`method-spec.md:367-372`** (§7.2 `learning_surface`) — de monetære feltene som ER frosset (`modelled_saving_nok`, `expected_actual_saving_nok`, intern konsistens påkrevd). - **`method-spec.md:199-202`** (§3 Steg 6) — råresultater er output-laget, «plain JSON», og bruker bevisst IKKE wiki-formatet. - **`method-spec.md:250-252`** (§4.2) — `claimed_saving_nok` som tall i verdict-kontrakten, og `description` bevisst utenfor likhet/minting. - **`method-spec.md:436-464`** (§12) — kryssjekk-tabellen er *fullstendighets-håndhevet* av spec-integritetstesten (§11 `:434`), så en ny kontrakt med nye felter MÅ inn her, ellers feiler den testen. Dette er den mekaniske konsekvensen ingen av oppstrøms-meldingene nevner. **Klassifisering:** ny seksjon, ikke en amendment. Dette er køens største punkt (den eneste som utvider spec-ens virkeområde) og samtidig den uten story-etikett oppstrøms — mest utsatt for å falle mellom de to enumerasjonene. **Meldt oppstrøms.** **Note, videreformidlet ikke verifisert her:** `portfolio-optimiser` melder (16:11Z, pkt. 4) at forslagets A5-regel 1 («Monetary figures MUST NOT be rounded in the projection») treffer en persisterings-kant hos dem (NOK→øre-kvantisering) og bør skille projeksjons-aritmetikk fra enhets-kvantisering. Commons har ikke lest deres kode og fører det som deres måling, ikke som vårt faktum. --- ## 7. S2.2–2.4 / D-B — substansen er ikke ankret hos commons Punktet er kjent bare som etikett. Vi leste det ut av `portfolio-optimiser`s STATE (GATES-blokk) 2026-07-25 04:05Z og har aldri fått innholdet. `grep -rn 'D-B'` over dette repoet gir **0 treff** — heller ikke i vår egen STATE, som bare bærer story-etiketten `S2.2-2.4`. Koblingen `S2.2–2.4 (D-B)` finnes utelukkende i coord-arkivet (`20260725T040535Z`, vår egen melding), ikke i noen commons-tekst. Commons kan derfor ikke si hvilken seksjon det rører. **Ingen antakelse føres.** Dette er den ene raden i underlaget som er blank av en grunn — og den blir stående blank til substansen kommer. **Etterspurt oppstrøms.** ### 7.1 Substansen ER LEVERT (2026-07-26) — raden er ikke lenger blank `portfolio-optimiser` leverte D-B-substansen på direkte forespørsel. Kilde: `docs/plan/2026-07-10-sesjonsplan-fase2-6.md` **i deres repo, ikke commons** — gjengitt her som mottatt, ikke verifisert av oss (vi har ikke lesetilgang til premisset, og fører det som *rapportert*, ikke *målt*). **D-B er en SCOPE-beslutning, ikke en spec-tekst.** Det er den avklaringen som gjør raden meningsfull: vi lette etter hvilken seksjon den rører, og svaret er at *den selv* ikke rører noen — den avgjør om tre andre stories gjør det. Fire delbeslutninger (`:56-62`): (1) amender ingest-målbildet bevisst vs. nedskopér roadmap-B til mock-herding *(deres anbefaling: nedskopér nå)*; (2) første live-kilde *(anbefaling: SQL — `read_sql` er mest herdet, read-only by construction)*; (3) dokument-konnektor-avgrensning *(PDF via `pypdf` nå, DOCX utsatt)*; (4) MCP-kildefamiliens nettverks-/subprosess-grant-form. **Konsekvensen for commons — hvilke av de tre gatede storiene som faktisk krever amendment:** | Story | Krever ingest-spec-amendment? | Hva | |---|---|---| | **S2.2** MCP-konnektor | **NEI — UGATED** (se §7.2) | §4s `http`-punkt (HEAD `:113-114` = pin `:101-102`) sier normativt at en MCP-konnektor **er en utvidelse av `http`-familien** med MUST på samme kontrakter. Ingen ny familie, ingen amendment. Bygges mot `http` + §8-grant | | **S2.3** Dokument-konnektor | **JA** — ny kildefamilie | `{type: "doc"}`. PDF→OKF-konseptfil med provenance, deterministisk mot committede fixtures | | **S2.4** Konnektor-herding | **NEI — UGATED** (bekreftet av po) | Timeout-parameter, feilkategorisering, beriket §8-logg (kilde/tidspunkt/radantall — aldri innhold). Retry KUN hvis D-B sier ja (default nei, av hensyn til determinisme). Inkrementell re-ingest: **ikke**, med mindre D-B amender §8 | **Commons' observasjon, ikke et forslag:** §4 har i dag tre kildetyper (`file`, `sql`, `http`), og §1 (`:27-31`) binder konformans til `file` + `sql` som påkrevde med `http` som eksplisitt OPTIONAL utvidelsespunkt. To nye familier reiser derfor et spørsmål ingen av meldingene har stilt: **blir `mcp` og `doc` påkrevde for konformans, eller valgfrie som `http`?** Svaret avgjør om `:27-31` må skrives om i samme amendment. Vi fører ingen antakelse om hvilket. **⚠️ Og frossen tekst sier allerede noe om MCP som ingen av meldingene har nevnt.** Ordrett, `ingest-spec.md:29-31`: > The `http` source type is an OPTIONAL extension point: implementing it (e.g. against a local > mock, **or via an MCP-based connector**) does not require any change to this spec, and NOT > implementing it does not break conformance. Specen forutser altså eksplisitt at MCP kan være **transporten under `http`**, og sier at den veien **ikke krever noen spec-endring**. Det gjør S2.2s premiss — «krever ingest-spec-amendment i commons FØRST» — til noe som må avgjøres, ikke antas: - Er `mcp` en **fjerde kildefamilie** (nytt `{type: "mcp"}`-skjema, amendment nødvendig), eller en **transport for den eksisterende `http`-familien** (allerede dekket, ingen amendment)? - Distinksjonen er ikke akademisk: den avgjør om S2.2 er blokkert på commons i det hele tatt. Under den andre lesningen er S2.2 **ugated** og kan bygges nå, mot `http` + opt-in-flagget (§8). ### 7.2 Spørsmålet er AVGJORT av frossen tekst — det er ikke to forsvarlige svar (korr. 2026-07-26) Avsnittet over stilte (a)/(b) som et åpent valg. **Det var feil, og `portfolio-optimiser` fant hvorfor: det finnes et ANDRE anker vi ikke siterte, og det er normativt.** > **`ingest-spec.md` §4, kildetypelisten, `type: "http"`-punktet** — sitert ORDRETT fordi > linjenumrene ikke overlever pull-grensen (se rammen under): > `type: "http"` — a remote endpoint (OPTIONAL extension point, §1). Field `base_url`: the > endpoint base; it MUST NOT embed credentials. Optional field `credential_ref`: the NAME of > a runtime-resolved secret reference. **An MCP-based connector is an extension of this family > and MUST honour the same extraction, materialization, and gate contracts.** > **⚠️ Ref-binding for sitatet over (korr. 2026-07-27, meldt av `repos`).** Avsnittet siterte > tidligere «`:112-114`» uten ref. To feil i én: (1) numrene er HEAD-relative, og konsumentene > står på `7aa53fc`; (2) selv mot HEAD var de av med én linje. Målt: > > | Ref | MCP-setningen | Hele `http`-punktet | > |---|---|---| > | commons HEAD | `:113-114` | `:111-114` | > | `7aa53fc` (konsumentenes pin, verifisert identisk i BEGGE arbeidstrær) | `:101-102` | `:99-102` | > > **Failure-moden er grunnen til at dette er verdt en korreksjon:** en konsument som slår opp > `:112-114` i SIN fil finner ikke ingenting — den finner felt-tabellen for `extractions` > (`id`/`title`/`query`), troverdig og relatert spec-tekst uten et ord om MCP. Den mest > sannsynlige konklusjonen er da at ankeret ikke finnes og at kjennelsen hviler på løs grunn. > Et åpenbart tomt treff hadde vært tryggere. **Regel, samme klasse som `git log -S`-regelen > under: sitér SEKSJON + ORDRETT TEKST når mottakeren står på en annen ref — eller skriv > hvilken ref numrene gjelder.** `:29-31` sier at MCP-veien ikke krever spec-endring. `http`-punktet sier **normativt hvor den hører hjemme** — som en utvidelse av `http`-familien, med **MUST** på de samme kontraktene. Frossen tekst har altså allerede valgt (b). En fjerde `{type: "mcp"}`-familie ville **motsagt** MCP-setningen, ikke utfylt den. **Konsekvens: S2.2 er UGATED.** Premisset «krever ingest-spec-amendment i commons FØRST» er avkreftet av vår egen frosne tekst. S2.2 kan bygges mot `http`-familien + §8s opt-in-grant uten å vente på noe herfra. **Og §1-spørsmålet i 7.1 faller bort for MCP:** MCP arver `http`s status, og `http` er eksplisitt OPTIONAL (`:27-31`). `:27-31` trenger derfor **ingen** omskriving for MCP. Spørsmålet gjenstår kun for **S2.3 (`doc`)**, som fortsatt er en genuint ny familie. `portfolio-optimiser`s anbefaling der: valgfri som `http` — en konform implementasjon bør ikke tvinges til en PDF-parser. Det er deres anbefaling til ratifisering, ikke en beslutning. **(a)-argumentet lever videre, men som implementasjonssak, ikke spec-tekst.** At `base_url`/`credential_ref` passer dårlig på en kommando, og at env-var-med-kommando er en subprosess-grant, er ekte friksjon — men MCP-setningen sier MUST på *kontraktene*, ikke på *feltnavnene*, og §8 dekker «any other non-local transport». Friksjonen lever i hvordan en kommando uttrykkes innenfor `http`-familien. Støter implementasjonen faktisk på noe MCP-setningen forbyr, er det et målt funn og kommer tilbake hit. **Vår egen feil, ført åpent fordi den er tredje instans samme dag:** vi skrev at `:29-31` var «frossen siden `bfa5a9b`». Målt med `git log -S`: **begge** MCP-ankrene landet i **`7aa53fc`** — nøyaktig commit-en konsumentene står på. `bfa5a9b` rørte bare D1-stempelmodellen. Vi tok repoets *siste* ingest-spec-commit og antok at filen daterte derfra. Og vi fant ikke `:113` fordi vårt `grep -n 'connection_ref' | head -3` stoppet på `:109` uten å lese omgivelsene — setningen i §1 er dessuten linjebrutt (`:30-31`), så et grep på hele frasen ville også bommet. **Sikt grepet mot seksjonen, ikke mot ett token — og bekreft opphav med `git log -S`, aldri med «siste commit som rørte filen».** Merk også at S2.4s «beriket ingest-logg» ligger mot §8, som allerede sier *«Source calls are logged (which source, when, row count)»* — en berikelse innenfor de tre feltene er neppe en tekstendring; en berikelse *utover* dem er det. Grensen går ved «aldri innhold», som deres egen formulering allerede respekterer. --- ## 8. B1 — nav-golden-klassen (utenfor pakken, commons-eid) Ankret, etter å ha vært et etikett-punkt i tre uker. `llm-ingestion-okf` svarte `portfolio-optimiser` 2026-07-25 04:19Z at «B1 bundle class» ikke finnes hos dem, og at beskrivelsen matcher **D4 fra OKF-runden, ratifisert i trinn F 2026-07-21**: commons eier nav-golden-bundleklassen + forventet utfall og leverer den inn; catalog eier korpus-containeren, de adversarielle aksene og runner/gate. **Commons-halvdelen er levert** (`b641741`, 2026-07-21): | Case | Innhold | |---|---| | `examples/nav-golden-escape/` | `bundle/`, `expected-read-context.md`, `README.md`, `SHOULD-NOT-BE-READ.md` | | `examples/nav-golden-hierarchy/` | `bundle/` (nestet `a/b/`, `c/orphan.md`), `expected-read-context.md`, `README.md` | **Det åpne spørsmålet er ett, og det er vårt:** `grep -c 'nav-golden'` i `method-spec.md`, `ingest-spec.md`, `CONCEPT.md`, `README.md` og `skills/expert-reviewer/SKILL.md` → **0 i alle fem**. Klassen er levert som fixture, men ingen normativ seksjon peker på den — i motsetning til `validator-input.json` / `golden.json` (navngitt i §7 `:330-346`) og `examples/ingest-golden-{source type}/` (navngitt som konvensjon i `ingest-spec.md:259-261`). §11-raden «Navigation boundary» (`:425`) beskriver rød-betingelsen, men nevner ikke fixturene som beviser den. **Operatør-spørsmålet:** skal nav-golden-klassen få en normativ referanse (§7 ground truth og/eller §11-raden), eller forbli en informativ fixture? Dette er commons' eget punkt, ingen venter på oss, og det hører IKKE inn i oppstrøms-pakken. **Utskrevet i sin helhet:** `docs/plan/2026-07-25-b1-nav-golden-normative-status.md` — fire opsjoner med målt kostnad. Spørsmålet viste seg ikke å være binært: specen har **tre** referanseformer i bruk (artefaktnavn som fasit, katalogkonvensjon, informativ lenke), og method-spec navngir aldri en repo-sti (`grep -c 'examples/' method-spec.md` → 0). --- ## 9. Sammendrag | # | Punkt | Fil + seksjoner | Klassifisering | Fasit-effekt | |---|---|---|---|---| | 1 | S2.7 / D-A#1 nominal gate + IR-band | method §3.4 `:157-166`, §7.1 `:339-346`, §7.2 `:352-358` | ekte hull | ingen (målt) | | 2 | S3.2 / D-A#4 seed-nøkkel | method §3.1 `:108-114` | ekte hull | ingen (fasiten skiller ikke) | | 3 | D-A#3 ledende `/` | method §3.1 `:67-71`, §11 `:425` | **allerede normativt i HEAD — drift, ikke avvik** | — | | 4 | S4.0 / D-A#2 kostbaseline | method §7 `:332-333`, §7.1 `:345-346` | ekte hull | **endrer fasit hvis ubetinget** | | 5 | S3.5 / D-F tittel-whitespace | ingest §4 `:125`, §5 `:158-161`, §6 `:194-197`, §11 `:278` | ekte, smal søm | ingen | | 6 | D-A#5 hovedbok-projeksjoner | ingen tekst; naboer method §7.2 `:367-372`, §12 `:436-464` | **ny seksjon** | ingen direkte; §12 må utvides | | 7 | S2.2–2.4 / D-B | **ANKRET** (§7.1–7.2): kun **S2.3** (`doc`) krever amendment. **S2.2 + S2.4 er UGATED** — S2.2 av §4s `http`-punkt, S2.4 innenfor §8s tre felt | **scope-beslutning, ikke spec-tekst** | ingen | | 8 | B1 / D4 nav-golden | levert `b641741`; 0 spec-referanser | commons-eget, utenfor pakken | — | Commons' rolle er uendret: vi forbereder underlaget, operatøren ratifiserer, og frossen tekst endres ikke uten den ratifiseringen. --- ## Verifiseringslogg | Påstand | Sjekk | Resultat | |---|---|---| | Spec-tekst uendret siden 2026-07-21 | `git log -- method-spec.md ingest-spec.md` | `9801d35` / `bfa5a9b`, begge 07-21 | | Bare p90 blokkerer i dag | lest `method-spec.md:150-166` i sin helhet | punkt 2 «capped», punkt 4 eneste blokk | | Ingen `low ≤ unit_cost ≤ high`-invariant | lest §7.1 `:339-346` | én invariant, om claimed vs. total | | Nominal gate er byte-nøytral | `golden.json`: claimed `30000` ≤ nominal `90000.0` | `validates` uendret `true` | | IR-band-invarianten er alt oppfylt i fasit | `validator-input.json`: `1.0` ∈ `[0.70, 1.40]` | ingen fixture-endring | | Seeding nøkles på bundelens projeksjon | lest `:108-114` | «keyed on those candidate features» | | Ledende `/` alt normativt | `git log -S'denotes the **bundle root**'` | `9801d35`, 2026-07-21 | | §11 har alt rød-betingelsen | `method-spec.md:425` | «bundle-root `/` read as filesystem-absolute» | | Ingen hovedbok-/baseline-tekst | `grep -ci ledger\|hovedbok\|cost-baseline` | 0 / 0 / 0 | | Ingen monetær avrundingsregel | `grep -n round` begge spec-er, alle 18 treff lest | alle urelaterte | | Fasit-bundelen har to JSON-filer | `ls examples/bygg-energi-mikro/` | `validator-input.json`, `golden.json` | | Oppstrøms-anker `:140` er stale | `git show 7aa53fc:ingest-spec.md \| grep -n` | treff på `:140` ved `7aa53fc`, `:158/:160` ved HEAD | | `bfa5a9b` rørte nettopp den teksten | `git show bfa5a9b -- ingest-spec.md` | +39/−9; §5-kulepunkt + §4 `title`-rad omskrevet | | Multi-manifest er extension point | `ingest-spec.md:173-174` | «Version 1 assumes ONE manifest per bundle» | | B1 = D4, ikke okf-eid | `~/.claude/coord/portfolio-optimiser/archive/20260725T041948Z-*` | okf: «never owned here; it is D4» | | nav-golden levert | `git log -- examples/nav-golden-*` | `b641741`, 2026-07-21 | | nav-golden ikke normativt referert | `grep -c 'nav-golden'` i de fem normative filene | 0 i alle fem | | D-B ikke ankret hos commons (per 07-25) | `grep -rn 'D-B'` | 0 treff utenfor STATE | | D-B-substansen levert 07-26 | coord fra `portfolio-optimiser` | rapportert fra deres `sesjonsplan-fase2-6.md:56-62`, ikke målt av oss | | §1 gjør `http` OPTIONAL, `file`+`sql` påkrevd | `ingest-spec.md:27-31` | ordrett sitert i §7.1 | | …og nevner MCP som `http`-transport | `ingest-spec.md:29-31` | «or via an MCP-based connector … does not require any change to this spec» | | **ANDRE anker: MCP hører NORMATIVT til `http`** | `ingest-spec.md` §4, `http`-punktet (HEAD `:113-114` = pin `:101-102`) | «An MCP-based connector **is an extension of this family** and **MUST** honour the same … contracts» | | Begge MCP-ankere landet i `7aa53fc`, ikke `bfa5a9b` | `git log -S` på hver frase | `7aa53fc` for begge — altså i konsumentenes egen kopi | | `bfa5a9b` rørte kun stempelmodellen | `git show --stat bfa5a9b` | 39 innsettinger, D1-stempel | | §8 logger tre felter | `ingest-spec.md:230` | «which source, when, row count» | | `connection_ref` er env-var-NAVN | `ingest-spec.md:109`, `:117` | «the NAME of a runtime-resolved …», secret resolved at run time | | Begge konsumenter står på `7aa53fc` | coord fra begge, uavhengig | po: `git log --grep=git-subtree-split` → `ef1a2c5`; po-claude: egen måling |