portfolio-optimiser/docs/plan/2026-07-14-commons-amendment-utkast.md

488 lines
30 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.

# Commons-amendment-utkast — kunnskapsinnholdsmodell + utvidelses-policy (2026-07-14)
> **Status:** UTKAST til operatør-godkjenning. Kilde: [revisjonspakke D-FD-I](2026-07-14-revisjonspakke-DF-DI.md)
> §1 (D-F) + §2 (D-G). Dette dokumentet er en **komplett, innlimings-klar** amendment til de to
> delte spec-ene i `portfolio-optimiser-commons` (`method-spec.md` + `ingest-spec.md`). Ingenting er
> committet i commons, og `shared/` i dette repoet er **ikke** rørt — overføringen er manuell,
> PULL-ONLY, i egen økt ETTER at operatøren har godkjent teksten under.
>
> **Provenance:** amendment-tekst = AI-forfattet (Fable 5, 2026-07-14), forankret i faktisk lest
> spec + kode (`method-spec.md`, `ingest-spec.md`, `okf.py`, `dimension.py`,
> `test_method_spec_loadbearing.py`). Beslutningene bak (D-F/D-G) er operatørens, protokollert i
> revisjonspakka. Spec-teksten er engelsk (RFC-2119, framework-nøytral — samme regel som resten av
> de delte spec-ene, håndhevet av `test_method_spec_is_framework_neutral`). Rammetekst er norsk.
## 0. Slik brukes utkastet
Fire leveranser, i den rekkefølgen operatøren bør lese dem:
1. **§1 — Innholdsmodell-amendment til `method-spec.md`** (engelsk spec-tekst i innlimings-blokker):
tre nye konsepttyper, separasjonsregelen, dimensjonskatalog-kontrakten, cross-check-utvidelser.
2. **§2 — Bibliotek-materialisering som ny ingest-kildefamilie `library`** (eget under-utkast til
`ingest-spec.md`, med korrekt §-referanse).
3. **§3 — Trinnvis-lesing-analysen** (revisjonspakka §6 nøkkelantakelse): kan sammendrag-først
spesifiseres UTEN å endre `method-spec.md` §3 Step 1s render-kontrakt? **Eksplisitt JA/NEI +
begrunnelse forankret i siterte spec-linjer.**
4. **§4 — Utvidelses-policy** (D-G pkt. 1) og **§5 — Konsekvens-liste** (spec-integrity-test,
D7-speiling, golden-suite).
Hver engelsk innlimings-blokk er avgrenset med `--- BEGIN SPEC INSERT ---` / `--- END SPEC INSERT ---`
og merket med nøyaktig hvilken §-plassering den hører til, slik at overføringen til commons er
mekanisk. Tabeller er ekte markdown (ikke code-fenced) så de rendrer i commons uendret.
---
## 1. Innholdsmodell-amendment til `method-spec.md`
**Plassering:** ny toppseksjon `## 13. The knowledge library (content-model extension)` (bakerst, så
eksisterende §-numre ikke forskyves — `_REQUIRED_MARKERS` i integrity-testen er presence-asserts, se
§5), pluss tre målrettede inserts i eksisterende seksjoner (§2, §10, §12) og render-kontrakt-endringen
i §3 Step 1 (den siste hører til §3-analysen, se **§3** under).
### 1.1 Ny toppseksjon — de tre konsepttypene + separasjonsregelen
Rasjonale (norsk, ikke del av innlimingen): D-F pkt. 1 krever kunnskapstyper for *tiltaksmønstre,
erfaringsnotater, faglige råd*, alt med **påkrevd kildebelegg**. D-F pkt. 3 krever **streng separasjon
fra dommene**: biblioteket flyter via `bundle_context`, korreksjonene KUN via den gatede folden — aldri
blandet. Typene er kontekst-lag-innhold (`method-spec.md` §2: "This layer holds project documents,
methodology, verified literature, constraints..."), altså **kun lesestoff for forslagsstilleren** (D-F
pkt. 2 — validatorens regler røres ikke).
--- BEGIN SPEC INSERT (method-spec.md → new `## 13.`) ---
## 13. The knowledge library (content-model extension)
The context layer (§2) MAY carry a **knowledge library**: curated, source-attested domain
knowledge about how savings are found within a dimension (§13.3), shared across the projects of a
portfolio and materialized into each project bundle (the ingest `library` source family — ingest
spec §4a). The library is **read-only input to the proposer**: it feeds hypothesis generation as
context, and it MUST NOT alter the deterministic validator's rules (§4), which remain the sole
authority over the numbers. Coupling the library to the validator is explicitly out of scope for
this version.
Three library concept types are defined. Each is an ordinary OKF concept file (§2, §3 Step 1) — the
only additions are required frontmatter fields:
- **`type: measure-pattern`** — a reusable cost-saving *pattern*: what the measure is, the
parameters that drive its modelled saving, and the realization caveats a proposer should know.
- **`type: experience-note`** — an operational *experience* (the writable part of tacit knowledge):
what happened when such a measure was carried out, and the gotchas. Genuinely tacit knowledge is
NOT forced here — it is captured by the verdicts' rationale prose (§4), the learning loop's
existing channel.
- **`type: expert-advice`** — an expert *heuristic or recommendation* scoped to a dimension.
**Required frontmatter (all three types):**
| Field | Rule |
|---|---|
| `type` | One of `measure-pattern`, `experience-note`, `expert-advice`. |
| `title` | Single-line human-readable title (the `## {type}: {title}` heading, §3 Step 1). |
| `description` | A **single-line** summary of the file — this is the one-line summary the read-context's summary tier renders (§3 Step 1, the library-tier rule). REQUIRED and non-empty. |
| `dimension` | The catalog dimension `id` (§13.3) this knowledge is scoped to. MUST match a catalog entry; an unknown dimension is a fail-fast error (§13.3). |
| `sources` | The source attestation: a non-empty list of citations, each identifying a verifiable source (a reference plus a locator — URL, document id, or file+span). A library file with an **empty or missing `sources`** MUST be rejected at materialization (§13.2). |
| `provenance` | Who authored the file and its verification status (e.g. machine-authored-with-source-verification vs. expert-authored). Machine-authored content MUST be labelled as such (§1 honesty rule). |
`tags` and `timestamp` are OPTIONAL and follow the existing bundle convention. Unknown frontmatter
fields are preserved (§3 Step 1, OKF robustness rule).
**Source attestation (normative).** Every library concept file MUST carry at least one verifiable
source in `sources`. This mirrors the provenance discipline of §9 ("at least one citation into the
source documents"): unsourced domain claims MUST NOT enter the library. Enforcement is fail-fast at
materialization (ingest spec §4a/§8a), never a runtime check inside the loop.
### 13.1 The separation rule (unwaivable)
The knowledge library and the verdict layer reach the hypothesis prompt through **two disjoint
carriers that are never crossed**:
- Library files (`measure-pattern`, `experience-note`, `expert-advice`) are context-layer content.
They reach the prompt **ONLY** via context rendering (§3 Step 1's read-context) — **never** via
the experience fold. They are not `type: verdict`, so seeding (§3 Step 1) never turns them into
store entries, and retrieval never ranks over them.
- Prior verdicts reach the prompt **ONLY** via the gated experience fold (§3 Step 1) — **never** via
context rendering (the existing verdict-layer exclusion). This is unchanged.
The two directions are symmetric and both load-bearing: an organisation's realization-rate
corrections (verdicts) MUST NOT leak into the read-context, and library knowledge MUST NOT be
injected as if it were an approved verdict. Conflating the carriers would either re-leak the gated
learning signal or inject un-gated "approved" knowledge around the promotion gate (§6) — the
self-contamination the layer separation exists to prevent (§2).
--- END SPEC INSERT ---
### 1.2 Dimensjonskatalog-kontrakten (D-F pkt. 5)
Rasjonale (norsk): D-F pkt. 5 krever en **dimensjonskatalog som konfig**, skjema-validert fail-fast,
med feltene *id, label, allowed_measure_types, allowed_code_prefixes*. Dette er **eksakt** den
eksisterende `Dimension`-modellen (`src/portfolio_optimiser/dimension.py`) — amendmenten løfter den fra
"konstrueres kun i tester" (revisjonspakka §0 F-INT-1) til en spec'et startup-kontrakt, uten å endre
feltene. Katalogen hører til startup-kontrakt-disiplinen i §10 ("ALL configuration MUST be
schema-validated fail-fast at startup").
--- BEGIN SPEC INSERT (method-spec.md → new `### 13.3` under §13, and an §10 cross-reference) ---
### 13.3 The dimension catalogue (startup contract)
A **dimension** is one cost axis a project is reduced along (energy, paving, ...). A conforming
implementation MUST define a **dimension catalogue**: configuration, schema-validated fail-fast at
startup (§10), listing the dimensions the run recognises. Each entry:
| Field | Rule |
|---|---|
| `id` | Stable dimension identifier (string). Library files reference it via `dimension:` frontmatter (§13). |
| `label` | Human-readable label; non-empty. |
| `allowed_measure_types` | The set of `measure_type` values that belong to this dimension. |
| `allowed_code_prefixes` | The set of affected-code prefixes constraining the dimension; MAY be empty (no code constraint). |
**Scoping gate (normative):** a candidate measure *belongs* to a dimension iff its `measure_type` is
in `allowed_measure_types` **and** either `allowed_code_prefixes` is empty **or** at least one
affected code starts with an allowed prefix. *(reference: `dimension.admits`.)*
**Catalogue reference (normative):** every library file's `dimension:` MUST resolve to a catalogue
`id`; a library file scoped to an unknown dimension is a fail-fast materialization error (ingest
spec §4a). The framework SHIPS an example catalogue (the energy dimension); the deploying
organisation owns its own catalogue.
--- END SPEC INSERT ---
--- BEGIN SPEC INSERT (method-spec.md → append one bullet to `## 10. Startup contracts`) ---
- the dimension catalogue (§13.3), when the run uses a knowledge library — each entry REQUIRING
`id`, `label`, and `allowed_measure_types` (with `allowed_code_prefixes` defaulting to empty).
--- END SPEC INSERT ---
### 1.3 §2-insert (peker fra arkitektur-seksjonen) + §12 cross-check-rader
Rasjonale (norsk): §2 lister kontekst-lagets innhold; den bør nevne biblioteket eksplisitt så
separasjonsregelen er synlig der de tre lagene defineres. Og §12 cross-check-tabellen er
**completeness-håndhevet** av integrity-testen (`test_spec_documents_every_contract_field` — hvert
felt koden konsumerer må stå i spec-en som `` `felt` ``). Når D-F bygges vil koden konsumere de nye
feltene; radene under sikrer at test 3 forblir grønn da (se §5).
--- BEGIN SPEC INSERT (method-spec.md → append to the context-layer bullet in `## 2.`) ---
The context layer MAY additionally carry a **knowledge library** (§13): source-attested
`measure-pattern` / `experience-note` / `expert-advice` files. Like all context-layer content the
library reaches the prompt only by navigation/rendering (§3 Step 1), never through the experience
fold — and, symmetrically, verdicts never reach it through rendering (§13.1).
--- END SPEC INSERT ---
--- BEGIN SPEC INSERT (method-spec.md → append rows to the `## 12. Cross-check table`) ---
| Field | Contract | Section |
|---|---|---|
| `description` | library concept frontmatter (summary tier) | §13, §3 Step 1 |
| `dimension` | library concept frontmatter / dimension catalogue reference | §13, §13.3 |
| `sources` | library concept frontmatter (source attestation) | §13 |
| `provenance` | library concept frontmatter | §13 |
| `id`, `label` | dimension catalogue entry | §13.3, §10 |
| `allowed_measure_types`, `allowed_code_prefixes` | dimension catalogue entry | §13.3 |
| `measure-pattern`, `experience-note`, `expert-advice` | knowledge-library OKF types | §13 |
--- END SPEC INSERT ---
> Merk (norsk): `description`, `type` og `measure_type` er allerede i §12; radene over er additive og
> peker de NYE bruksstedene. Ved innliming: slå `description`-raden sammen med den eksisterende hvis
> commons foretrekker én rad per feltnavn (integrity-testen krever bare at `` `description` ``
> finnes, ikke antall rader).
---
## 2. Bibliotek-materialisering som ingest-kildefamilie `library` (`ingest-spec.md`)
**Plassering:** ny kildefamilie `type: "library"` i `ingest-spec.md` §4 (polymorf på `source.type`,
ved siden av `file`/`sql`/`http`), pluss en materialiserings-regel i §5 og en gate-regel i §8. Skrevet
som eget under-utkast med korrekt §-referanse, jf. oppdraget.
Rasjonale (norsk): D-F pkt. 4 sier det delte dimensjonsbiblioteket **materialiseres inn** i hver
prosjekt-bundle via ingest-mønsteret (`generated: true`, manifest-ref, re-materialisering eier egne
filer) — **ikke** kryssbundle-lenker (navigasjonen forblir flat/same-dir), **ikke** manuell
duplisering. Ingest-spec §1 er allerede rammen: "data reaches the model ONLY via OKF bundles ...
materializes the extract as a bundle". `library` er en ny kilde i den rammen. Den skiller seg fra
`file`/`sql` på ett punkt: den materialiserer **kuraterte kunnskaps-konseptfiler** (prosa med
frontmatter), ikke rader i en tabell — parallelt med hvordan `http` har sin egen body-render-regel.
--- BEGIN SPEC INSERT (ingest-spec.md → new `### 4a. The `library` source family` under §4) ---
### 4a. The `library` source family (extension)
`type: "library"` materializes a **curated dimension library** (method spec §13) into a project
bundle: shared, source-attested `measure-pattern` / `experience-note` / `expert-advice` files. It
reuses the whole ingest contract (deterministic, zero model calls §1; provenance stamping §7;
index generation §6; replacement semantics §3/§5). It exists so shared cross-project knowledge is
**materialized in**, not cross-linked and not hand-duplicated (navigation stays flat/same-dir, OKF
§3 Step 1 rule).
**`source` fields** (in addition to the common `id`, §4):
- Field `root`: the directory the curated library entries resolve against. Path resolution MUST be
boundary-checked against `root`, fail-closed (the OKF path rule) — an extraction can never read
outside the catalogue.
**`extractions` — each entry** for a `library` source (all required):
| Field | Meaning |
|---|---|
| `id` | Unique within the manifest, matching `[a-z0-9][a-z0-9-]*`; names the generated file (`library-{id}.md`, §5a). |
| `title` | Single-line title; becomes the `title` frontmatter and the index link label (§6). |
| `query` | A relative path (within `root`) to one curated library entry (a markdown file with frontmatter). |
| `okf_type` | The generated file's OKF `type`. MUST be one of `measure-pattern`, `experience-note`, `expert-advice` (case-insensitive) and MUST NOT be `verdict` (§3 verdict-layer reservation). |
| `dimension` | The dimension catalogue `id` (method spec §13.3) the entry is scoped to. Stamped as the generated file's `dimension` frontmatter. |
| `max_rows` | Required positive integer cap; for `library`, the cap on entries drawn from a single curated file (§8). |
**Source attestation is enforced here (normative).** A curated entry whose frontmatter carries an
empty or missing `sources` list (method spec §13) MUST be rejected fail-fast at manifest/source
validation — the machine-generated library never ships unsourced domain claims. This is the
content model's teeth at ingest time, mirroring §8's other fail-fast caps.
--- END SPEC INSERT ---
--- BEGIN SPEC INSERT (ingest-spec.md → new `### 5a. `library` materialization` under §5) ---
### 5a. `library` materialization (deterministic)
For a `library` source, each extraction produces one concept file named `library-{extraction id}.md`
(the `library-` prefix keeps the namespace disjoint from `index.md`, `ingest-*`, and
`promoted-verdict-*`, §3). Materialization is deterministic and takes the same three explicit inputs
as §5 (manifest, target bundle, `ingested_at`).
- **Frontmatter** — the curated entry's own OKF frontmatter (`type` = the extraction's `okf_type`,
plus `title`, `description`, `dimension`, `sources`, `provenance` per method spec §13), extended
with the ingest provenance layer (§7): `source_system`, `source_query`, `ingested_at`,
`ingest_manifest`, `generated: true`. The provenance layer is ADDITIVE — it never overwrites the
curated `description`/`sources`/`provenance` fields (two separate contracts, never mixed, §7).
- **Body rendering** — the curated entry's markdown body verbatim (LF-only, exactly one trailing
newline). Unlike `file`/`sql` (a table) or `http` (a fenced block), a library entry is already
authored prose; it is carried through unchanged.
- **Replacement semantics (§3/§5):** library files carry the ingest stamp, so re-materialization
replaces EXACTLY the ingest-owned files and MUST NOT touch curated or promoted files. A
`library-{id}.md` collision with an unstamped existing file MUST fail — never overwrite curated
content.
- **Index generation (§6):** each generated file gets one index cross-link
`- [{title}](library-{id}.md)`, preserving all curated and promoted links verbatim.
--- END SPEC INSERT ---
--- BEGIN SPEC INSERT (ingest-spec.md → cross-check table `## 12.`, append rows) ---
| Field | Contract | Section |
|---|---|---|
| `root` | manifest source (`library`) | §4a |
| `dimension` | manifest extraction (`library`) / generated frontmatter | §4a, §5a |
| `okf_type` | manifest extraction (`library`, restricted set) | §4a, §3 |
--- END SPEC INSERT ---
> Merk (norsk): `root`, `title`, `query`, `okf_type`, `max_rows`, `id` finnes allerede i §12
> (delt med `file`/`sql`/`http`); kun de genuint nye radene (`root` for library-source, `dimension`)
> er additive. `library` arver §11-load-bearing-sømmene (provenance-stamping, navigerbarhet,
> verdict-reservasjon, re-ingest-lag-sikkerhet) uendret — en ny golden-case
> `examples/ingest-golden-library/` legges til (endrer ikke `file`/`sql`-goldens; se §5).
---
## 3. Trinnvis-lesing-analysen (revisjonspakka §6 nøkkelantakelse)
**Spørsmål (revisjonspakka §6):** kan sammendrag-først / fulltekst-ved-behov (D-F pkt. 6)
spesifiseres UTEN å endre `method-spec.md` §3 Step 1s render-kontrakt — «index body + hver konseptfil
som `## {type}: {title}`-seksjon»?
### 3.1 Konklusjon: **NEI** — det krever en minimal, bakoverkompatibel Step-1-amendment.
Ikke gjettet — forankret i to siterte spec-linjer og render-koden.
**Bevis 1 — render-kontrakten mandaterer full body per konseptfil.** `method-spec.md` §3 Step 1:
> «The rendered read-context is the index body (the summary) followed by each non-index concept file
> as a `## {type}: {title}` section; empty sections are dropped.» (method-spec.md:7677)
Referanse-implementasjonen fyller den seksjonen med **hele** filkroppen — `bundle_context` i
`okf.py:150-151`:
> `title = f.frontmatter.get("title", f.name).strip('"')`
> `sections.append(f"## {f.type or 'document'}: {title}\n{f.body}")` — `f.body` er hele body.
Med 1530 tiltak i biblioteket (D-F pkt. 7) er «render hver konseptfil sin fulle body» **nettopp**
prompt-drukningen D-F pkt. 6 avviser («Dagens 'render alt navigert' skalerer ikke»). Å rendre
sammendrag først (én linje per fil) og full tekst kun for et utvalg er per definisjon *ikke* det
kontrakten sier i dag → kontrakten må endres.
**Bevis 2 — den eneste alternative bæreren for «fulltekst ved behov» er forbudt.** «Ved behov»
antyder at agenten henter full tekst ved forespørsel. Men et query-time retrieval-verktøy mot bundelen
er **eksplisitt forbudt** i samme Step 1:
> «Prior verdicts reach the hypothesis prompt ONLY via the gated experience fold below — never via
> context rendering, and **never via a query-time retrieval tool pointed at the bundle** (which would
> re-leak the verdict layer).» (method-spec.md:7881)
Forsterket, arkitektur-definerende, i `ingest-spec.md` §1:
> «The method spec (§3 Step 1) forbids query-time retrieval against the bundle. ... **data reaches
> the model ONLY via OKF bundles** ... not RAG, not live lookups inside the agent loop, no retrieval
> tools in the run path.» (ingest-spec.md:2125)
Så «fulltekst ved behov» kan **ikke** realiseres som et agent-kalt oppslagsverktøy. Det etterlater
kun én lovlig mekanisme: et **deterministisk, pre-run utvalg** av hvilke filer som får full body —
og det er nettopp en endring av render-kontrakten.
**At det finnes presedens** (som gjør amendmenten liten, ikke prinsipielt ny): `bundle_context` har
allerede et deterministisk `dimension`-filter (`okf.py:133, 146-149`) — «only concept files whose
frontmatter `dimension` matches ... are rendered». Det beviser at arkitekturen allerede tåler et
deterministisk pre-run-utvalg over hvilke filer som rendres, uten retrieval-verktøy. (Sidefunn: det
filteret finnes i KODEN, men står ikke i method-spec §3 Step 1 i dag — en udokumentert utvidelse
amendmenten samtidig bør folde inn i spec-en, jf. utvidelses-policyen §4.)
### 3.2 Foreslått minimal Step-1-amendment (in-place i §3 Step 1)
Endrer KUN seksjons-**innholdet** for bibliotek-tier-filer; beholder index-først, `## {type}: {title}`-
overskriften, verdict-eksklusjonen og no-retrieval-invarianten. **Default (ingen bibliotek-tier-filer)
er byte-identisk med dagens oppførsel** — så eksisterende bundler (f.eks. `bygg-energi-mikro`) rendres
uendret og eksisterende tester forblir grønne (§5).
--- BEGIN SPEC INSERT (method-spec.md → REPLACE the render bullet in §3 Step 1) ---
- The rendered read-context is the index body (the summary) followed by each non-index concept file
as a `## {type}: {title}` section. A **library-tier** concept file (§13:
`measure-pattern` / `experience-note` / `expert-advice`) contributes only its single-line
`description` frontmatter as the section body by default — the **summary tier**, one line per
library file, so the library can grow large without prompt-drowning. Its **full body** is rendered
ONLY for the bounded subset chosen by a DETERMINISTIC pre-run selector (e.g. the candidate's
dimension, §13.3) — never by a query-time retrieval tool pointed at the bundle (the no-retrieval
invariant above). Non-library concept files render their full body as before. Empty sections are
dropped. *(reference: with no library-tier files present, this is byte-identical to rendering
every concept file's full body — the pre-existing behaviour.)*
--- END SPEC INSERT ---
> Norsk presisering: «deterministisk pre-run selector» = samme klasse som det eksisterende
> `dimension`-filteret (kandidatens dimensjon avgjør hvilke bibliotekfiler som får full body).
> Ingen ny modell-runde, intet oppslagsverktøy, ingen ny løkke — utvalget skjer FØR generering, på
> IR-projeksjonens kandidat-features (som allerede er tilgjengelig pre-hypotese, §3 Step 1 fold).
> Verdict-eksklusjonen er urørt: bibliotek-tier er en delmengde av `context_files` (aldri
> `type: verdict`), så `test_bundle_context_excludes_verdict_layer` + empty-store-kontrollen forblir
> røde-ved-detach som før.
---
## 4. Utvidelses-policy (D-G pkt. 1)
**Plassering:** ny normativ note, enten som `### 2a. Relationship to Google OKF v0.1` i `method-spec.md`
§2, eller som delt avsnitt i begge spec-enes §1. Kort, normativ.
Rasjonale (norsk): D-G pkt. 1 — «standard-kompatibel»; egne utvidelser (innboks-konseptet,
ingest-sikkerhet, evaluator-felt) dokumenteres **eksplisitt som utvidelser** av Google OKF v0.1 og
**pensjoneres** hvis standarden senere dekker dem. Ingen permanent fork.
--- BEGIN SPEC INSERT (method-spec.md → new `### 2a. Relationship to Google Open Knowledge Format v0.1`) ---
### 2a. Relationship to Google Open Knowledge Format v0.1
The bundle format is **Google Open Knowledge Format (OKF) v0.1**. This method adds capabilities ON
TOP of the base format; each such capability is a **local extension**, not part of the standard, and
MUST be documented as one:
- the **verdict layer** and the **promotion gate** (§2, §6): `type: verdict` files, the
`promoted-verdict-*` filename namespace, and the neutral-label index rule;
- the **inbox/outbox folder contract** (§5): the async long-loop file interface;
- the **ingest provenance layer** and the **security frame** (ingest spec §7§9):
`generated`/`ingest_manifest`/`source_system`/`source_query`/`ingested_at`, and the network
opt-in;
- the **knowledge library** and the **dimension catalogue** (§13);
- **evaluator fields** (future work): any conformance/sufficiency scoring frontmatter a bundle
evaluator introduces.
**Retirement rule (normative):** if a future OKF version standardises an equivalent of a local
extension, the implementation MUST migrate to the standard mechanism and RETIRE the local extension —
no permanent divergence from the format. Extensions MUST NOT change the meaning of any base-format
field; they only add reserved types, reserved filename namespaces, and additive frontmatter, all of
which base-format consumers preserve as unknown fields.
--- END SPEC INSERT ---
---
## 5. Konsekvens-liste
### 5.1 Spec-integrity-testen (`tests/test_method_spec_loadbearing.py`)
Verifisert mot faktisk lest test. Amendmenten er konstruert for å holde alle fem testene grønne:
- **`test_method_spec_exists_with_required_structure` (test 1):** asserter at `_REQUIRED_MARKERS`
(`## 1.``## 12.` + `### Step 1..8` + `MUST`) FINNES. Markørene er presence-asserts, ikke
forbud mot ekstra seksjoner → ny `## 13.` og `### 2a` bryter ingenting. Render-bullet-endringen i
§3 Step 1 beholder `### Step 1 — ` intakt. **Grønn.**
- **`test_method_spec_is_framework_neutral` (test 2):** grep-guard mot `_FRAMEWORK_NAMES` (MAF,
Claude, Azure, Foundry, OpenAI, Ollama, ...) over BEGGE spec-ene + persona-treet. All engelsk
spec-tekst i §1§4 er bevisst framework-nøytral (ingen leverandørnavn; «a query-time retrieval
tool», ikke et produktnavn). **Grønn — forutsatt at innlimingen ikke introduserer et
leverandørnavn.** (Sjekk før commons-commit: `grep -nE '<_FRAMEWORK_NAMES>' method-spec.md
ingest-spec.md` → 0 treff.)
- **`test_spec_documents_every_contract_field` (test 3):** completeness-drevet fra REELLE artefakter
+ serializer — hvert felt koden konsumerer må stå som `` `felt` `` i spec-en. **I dag konsumerer
ingen kode D-F-feltene (D-F er ikke bygget)** → test 3 krever dem ikke ennå. Men §1.3s
cross-check-rader (`description`, `dimension`, `sources`, `provenance`, `id`, `label`,
`allowed_measure_types`, `allowed_code_prefixes`, de tre typene) sikrer at når koden lander
(dimensjonskatalog-loader, bibliotek-frontmatter-modell), er feltene ALLEREDE dokumentert → test 3
forblir grønn i byggeøkta. **Grønn nå; forhånds-dekket for byggetid.**
- **`test_ingest_spec_exists_with_required_structure` (test 4):** asserter `_INGEST_REQUIRED_MARKERS`
(`## 1.``## 12.`) + verdict-reservasjonen (`` `type: verdict` `` + `promoted-verdict-`) +
`` `ingested_at` ``. Nye `### 4a`/`### 5a` bryter ingen markør; `library`-`okf_type` STYRKER
reservasjonen (MUST NOT be `verdict`). **Grønn.**
- **`test_ingest_spec_documents_every_contract_field` (test 5):** drevet fra `ManifestV1` +
source-modellenes `model_fields`. **I dag finnes ingen `LibrarySource`-modell** → test 5 krever
ikke `library`-feltene ennå. §2s cross-check-rader (`root`, `dimension`, `okf_type`) forhånds-dekker
byggetid, akkurat som test 3. **Grønn nå; forhånds-dekket.**
**Netto:** amendmenten er ren dokument-endring i commons; ingen av de fem integrity-testene i DETTE
repoet blir røde av å hente den ned (pull), fordi ingen NY kode konsumerer feltene før byggeøkta —
og da er feltene allerede dokumentert.
### 5.2 D7-søsken-speiling (flagges, utenfor scope her)
Amendmenten endrer de **delte** spec-ene begge stacker bygger fra. Per D-G pkt. 2 er OKF-formatlaget
nå bevisst delt/speilet (endrer D7s «from spec alone» for formatlaget). Konsekvens: når method-spec
+ ingest-spec får denne innholdsmodellen, må **begge** implementasjoner re-implementere fra den nye
spec-en — særlig Claude-SDK-søskenet, hvis `okf.py` (A2, revisjonspakka §0.2) i dag mangler skrive-
halvdelen. **Dette utkastet leverer KUN spec-teksten; selve speilingen/byggingen er senere økt** (D-F
innplassering: Fase 3-bolken; toolkit-repo blokkerer fabrikk-avhengige deler). Flagget her, ikke
utført.
### 5.3 Golden-suiten uberørt (begrunnet)
- **`method-spec.md` §7 golden-suite** fryser VALIDATOR-utfallet (`validator` + `learning_surface`)
over IR-projeksjonen (`validator-input.json`). Innholdsmodellen legger til kontekst-lag-typer +
en summary-tier-render + dimensjonskatalog + `library`-ingest — **ingen** av dem rører
IR-projeksjonen, validator-semantikken eller `learning_surface`. `golden.json` +
`test_bygg_energi_mikro.py` er derfor uendret grønne.
- **Render-endringen** påvirker `bundle_context`-output, men den er **ikke** golden-frosset (golden
fryser validator-tall, ikke read-context-strengen). De load-bearing invariantene som FINNES på
render (verdict-eksklusjon + empty-store-kontroll) bevares eksplisitt av amendmenten (§3.2:
bibliotek-tier er ikke-verdict, default byte-identisk). **Grønn.**
- **`ingest-spec.md` §11 golden-extractions** er per-kildetype. `library` legger til en NY case
(`examples/ingest-golden-library/`); `file`/`sql`-goldens er uendret. **Grønn.**
---
## 6. Verifisering (utkastets egne kriterier)
Testbare sjekker FØR commons-commit (etter operatør-godkjenning, i overførings-økta):
1. **Framework-nøytralitet:** `grep -nE
'\bagent[_ -]framework\b|\bMAF\b|\bClaude\b|\bAnthropic\b|\bMicrosoft\b|\bAzure\b|\bFoundry\b|\bOpenAI\b|\bOllama\b|\bLangChain\b|\bAutoGen\b|\bSemantic Kernel\b|\bCrewAI\b|\bMagentic\b'`
over de amendede spec-ene → **0 treff** (samme regex som `_FRAMEWORK_NAMES`).
2. **Struktur intakt:** `grep -n '### Step 1 — ' method-spec.md` → treff (render-bullet-endringen brøt
ikke Step-1-overskriften); `grep -n '## 13. The knowledge library' method-spec.md` → treff.
3. **Verdict-reservasjon styrket:** ingest-spec `library`-`okf_type` MUST NOT be `verdict` er
verbatim i teksten (`grep -n 'MUST NOT be `verdict`' ingest-spec.md` → treff).
4. **Cross-check-completeness forhånds-dekket:** hvert nytt felt (`sources`, `dimension`,
`provenance`, `allowed_measure_types`, `allowed_code_prefixes`, `root`) står som `` `felt` `` i
riktig spec (så integrity-test 3/5 blir grønn i byggeøkta).
5. **Ingen kodeendring i denne økta:** `git status` i portfolio-optimiser viser kun den nye
`docs/plan/2026-07-14-commons-amendment-utkast.md`; `shared/` urørt; full suite fortsatt grønn.
**Nøkkelantakelse (revisjonspakka §6), avgjort:** trinnvis-lesing **kan IKKE** spesifiseres uten å
endre §3 Step 1s render-kontrakt (§3.1, forankret i method-spec.md:7681 + ingest-spec.md:2125 +
okf.py:150-151). Den minimale, bakoverkompatible amendmenten er levert (§3.2) — merket som del av
commons-amendmenten, slik pakka §6 krever ved NEI.