# Sesjonsplan D7 — speilings-sesjoner + egne funn (C1.1–C4.0 · delt kø D-A–D-E) > **⚠️ SUPERSEDED 2026-07-16:** erstattet av > [`2026-07-16-sesjonsplan-paritet.md`](2026-07-16-sesjonsplan-paritet.md) (operatør-mandat > full MAF-paritet; §4-listen «Overføres IKKE hit» er OPPHEVET og re-klassifisert der). > C-sesjonene C1.1/C2.0/C2.5/C2.7/C2.8/C3.2/C3.5/C4.0 er videreført i den nye planen. > Dokumentet under beholdes uendret som historikk. > > **Status:** ~~GJELDENDE~~ sesjonsplan for dette repoet. Forfattet av kryssmodell-reviewen > 2026-07-10 (Fable 5) — funn-referanser (C-F2/C-F3/C-F4/C-F5/C-F7, C-N1–C-N4, C-P1) peker > til [reviewen](review-2026-07.md); MAF-referanser (F1–F14, D-A–D-E, S2.x/S3.x/S4.x) peker > til hovedrepoets `docs/review-2026-07.md` og `docs/plan/2026-07-10-sesjonsplan-fase2-6.md`. > > **Beslutnings-køen D-A–D-E er DELT med MAF-søskenet** (identisk semantikk som MAF-planens > §2): beslutningene tas ÉN gang av operatøren, materialiseres som commons-amendments, og > gjelder begge repo via PULL-ONLY subtree. Dette repoet planlegger INGEN egen variant av > køen — kun bygg-sesjoner gated på den. **C1.1/C2.0/C2.5 er byggbare NÅ** (ingen > beslutnings-avhengighet). > > Prinsipp (uendret fra I-programmet): hver sesjon er én-sesjons-stor, offline, gratis > (ScriptedClient), TDD (Iron Law), og Opus-eksekverbar med «Les STATE.md og følg > instruksjonene». Ingen live-kjøringer: D6 står — S10 var programmets ene; ny spend krever > eksplisitt operatør-godkjenning. ## 1. Den delte beslutnings-køen (operatør — tas i hovedrepoet, gjelder begge) | Beslutning | Innhold (MAF-planens §2, uendret) | Blokkerer HER | |---|---|---| | **D-A** | Spec-amendments i commons: (1) nominal-gate + band-invariant (F2/C-F2); (2) kostbaseline-stage (F3/C-F3); (3) `/`-lenker → bundle-rot (F4/C-F4); (4) per-verdict seeding (F5/C-F5); (5) Magentic-tekst (MAF-only) | C2.7, C2.8, C3.2, C4.0 | | **D-B** | Fase-2-scope vs frossen ingest-målbilde (live-kilde, doc-konnektor, MCP-grant) | ingenting her (MAF-scope; D7 speiler evt. ingest-spec-amendments når de lander i commons) | | **D-C** | Vektor-store (§4.5): valg + DELT lagringsformat (.npy + jsonl er anbefalingen) | evt. C-semretrieval (ikke spesifisert her ennå) — se koblings-flagget under | | **D-D** | Concurrency-/feilmodell | ingenting her i dag (ingen portefølje-sti); blir gate hvis D7 får portefølje-speil | | **D-E** | Mål-semantikk + stack-paritet for ekte kjøring | M2-konfig på MAF-siden; her kun paritetsspørsmålet (§4.6) | **Koblings-flagg til den delte køen (fra C-P1, MÅ tilbake til hovedrepoet):** D-C som planlagt (cosine over tekst-embeddings) kolliderer med frossen method-spec §3 Steg 1 («structural, never textual»). D-C må enten få et D-A-punkt som amender ranking-regelen bevisst, eller re-scopes til strukturelle features. Uten det er S3.1 (MAF) og enhver D7-speiling uimplementerbar spec-konformt. **Commons-regel (alle spec-amendments):** skrives i `portfolio-optimiser-commons`, pulles hit med `git subtree pull --prefix=shared commons main --squash`. ALDRI subtree push. **Sammenligningsprotokoll-konsekvens:** etter en D-A-amendment re-pinnes/pulles subtree i BEGGE repo og BEGGE suiter kjøres — aldri én side alene. Endres golden-bytene, re-fryses de koordinert i commons (D-A eier det); begge repo konsumerer fasit uendret. ## 2. Byggbare NÅ (ingen beslutnings-avhengighet) ### C1.1 Method-spec-integritetsvakt (C-N1) - **Mål:** §11-raden «Spec integrity» håndheves lokalt — spec-drift i subtree-synken fanges her. - **Scope:** ny `tests/test_method_spec_loadbearing.py` etter `test_ingest_spec_loadbearing.py`- mønsteret: (1) spec-fila finnes; (2) forbidden-toolkits-liste (samme som ingest-vaktens); (3) §12-kontraktsfelt-dekning for feltene DENNE implementasjonen konsumerer (`decision`, `rationale`, `id`, `proposal_features`, `affected_codes`, `measure_type`, `claimed_saving_nok`, `description`, IR-feltene, golden-feltene, `type`, vokabular-verdiene). KUN testkode — ingen src-endring, ingen spec-endring. - **TDD:** testen er selv vakten — RØD-bevis via mutert spec-KOPI i tmp_path (test-parametrisert mot kopi, aldri mot `shared/`): fjern et felt fra §12 → rød; injiser toolkit-navn → rød; slett fila → rød. - **Verifisering:** `uv run pytest tests/test_method_spec_loadbearing.py` grønn; full gate (pytest/ruff/mypy) grønn; detach-bevis (mutasjons-parametrene) dokumentert i testen selv. ### C2.0 Steg-7 kjøresti-inngang (C-N2) - **Mål:** en skipbar inngang komponerer §5-sekvensen (merge inbox → seed → fold → run), så «a later run ingests it» er sant om en leverbar sti — ikke bare om primitivene. - **Scope:** ny `run.py` (offline-testbar komposisjonsfunksjon `compose_run_context(bundle_dir, inbox_dir=None, k=...)` + tynn CLI med `--bundle/--inbox/--out` som gjenbruker contracts/meter/artifacts). `run_s10.py` forblir URØRT (fasit-sti, S10-artefaktene er frosne). README-avsnittet om inboxen oppdateres til å peke på den nye inngangen. IKKE: ny live-kjøring (CLI-en testes kun med ScriptedClient; SDK-klienten wires men eksekveres ikke i suiten). - **TDD:** RØD: dom droppet i inbox-mappe → inngangens komponerte kontekst MÅ bære dommens markør (detach-punkt: fjern merge-kallet i komposisjonen → rød); kontroll: tom/ manglende inbox → base-kontekst uendret; RØD: rolledelingen — inngangen skriver ALDRI til inboxen (byte-sammenligning før/etter). - **Nøkkelantakelse (testes først):** komposisjonen kan gjenbruke `fold_experience`/ `merge_inbox_into_store` uendret — ingen ny søm, kun wiring. - **Verifisering:** ny testfil grønn; detach → rød; full gate grønn; `grep -n "inbox" README.md` viser claim som nå matcher en skipbar sti. ### C2.5 Inbox-herding + SDK-versjonsvakt (C-F7, C-N3, C-S3-rester) - **Mål:** inboxen slutter å være en uvalidert injeksjonsflate; SDK-attributt-premissene får en vakt som tvinger bevisst re-verifisering ved oppgradering. - **Scope:** (1) `merge_inbox_into_store`/`load_inbox`: decision-vokabular-sjekk (ukjent decision → SKIP, fortsatt tolerant, aldri raise — §4.2-vokabularet {approved, rejected, approved_with_adjustment} på fil-laget), konfigurerbart tak på rationale-lengde + antall filer per merge (fail-fast ved overskridelse, aldri stille kutt); (2) pin `claude-agent-sdk>=0.2,<0.3` i pyproject; (3) versjonsvakt-test som feiler med handlingsrettet melding når installert SDK-versjon ikke matcher pinnet serie (premissene i `sdk_client.py:12-17` må re-verifiseres bevisst); (4) vurder `_total_tokens`-strictness (delsum ved felt-drift — dokumentér valget i docstring). - **TDD:** RØD: inbox-fil med `decision: "hva-som-helst"` når ALDRI storen (detach vokabular-sjekken → den entrer → rød — reviewens kjørte bevis blir testens fixture); RØD: rationale > tak → skip/feil per valgt semantikk; RØD: versjonsvakt mot fake-versjon. - **Verifisering:** nye tester grønne + detach → rød; full gate grønn; eksisterende step7-suite uendret grønn (tolerant-lasting består). ## 3. Speilings-sesjoner (gated: D-A + commons-pull — startes IKKE før amendment er pullet) > Felles mal (= MAF-planens S2.7/S3.2/S4.0-mal): amendment lander i commons → subtree-pull → > failing test først (moteksemplene fra reviewen ER test-fixturene) → impl → detach-bevis → > full gate → golden-regresjon uendret (eller koordinert re-frosset i commons FØRST). ### C2.7 Validator-stramming (C-F2; gated: D-A pkt. 1) - **Scope:** (a) strukturell blokk `claimed > nominal_feasible` → `Rejection` (i tillegg til p90); (b) IR-invariant: hvert band MÅ omslutte itemets `unit_cost` (Pydantic `model_validator`). IKKE: kostbaseline (C4.0). - **Premiss (VERIFISERT 2026-07-10 av reviewer):** golden- og fixture-kompatibel her — alle ikke-tomme bands omslutter unit_cost; golden-claim 30 000 ≤ nominal 90 000. - **TDD:** RØD: reviewens moteksempel #1 (claim 100k, nominal 90k, band [0.70,1.40]) → MÅ bli `Rejection`; RØD: band [1.8,2.2] rundt unit_cost 1.0 → `ValidationError` ved konstruksjon; detach nominal-blokken → moteksempel-testen rød. - **Filer:** `validator.py`, `ir.py`, `tests/test_validator.py`, `tests/test_ir.py`; `tests/test_bygg_energi_mikro.py` uendret grønn (regresjonsbevis). - **Verifisering:** `uv run pytest tests/test_validator.py tests/test_ir.py tests/test_bygg_energi_mikro.py` grønn; golden uendret; full gate grønn. ### C2.8 OKF `/`-lenke-mapping (C-F4; gated: D-A pkt. 3) - **Scope:** ledende `/` i cross-link-mål mappes til bundle-rot i `navigate_bundle`; boundary-sjekken består fail-closed (subkatalog-policy følger amendmentens ordlyd). - **TDD:** RØD: bundle med `](/tiltak.md)` → tiltaket navigeres og renders (detach mappingen → kun index → rød); RØD: `](/../escape.md)` → fortsatt skippet (boundary består); eksisterende skip-tester oppdateres KUN slik amendmenten krever. - **Filer:** `okf.py`, `tests/test_okf.py`. **Merk:** MAF-siden mangler i dag en tilsvarende bygg-sesjon for F4 — flagget i reviewen §1 C-F4; operatøren bør legge den til der. - **Verifisering:** nye tester grønne + detach → rød; full gate grønn; golden-bundelen navigerer uendret. ### C3.2 Per-verdict seeding (C-F5; gated: D-A pkt. 4) - **Scope:** `seed_store_from_bundle` leser features fra verdict-filas EGEN frontmatter (nye valgfrie felt `affected_codes`/`measure_type`/`claimed_saving_nok`; fallback = dagens bundle-projeksjon for bakoverkompatibilitet); `promote` skriver feltene. Multi-kandidat- fixture repo-lokalt (aldri i `shared/` uten commons-endring). - **TDD:** RØD: to kandidater i én bundle → dom om B når ALDRI As hypotese-prompt via retrieval på As features (detach per-verdict-nøklingen → feil-folding → rød — reviewens F5-bevis blir fixturen); eksisterende step1/step7/step8 uendret grønne (fallback). - **Filer:** `experience.py`, `promotion.py`, `tests/test_step1_expel_loadbearing.py`, `tests/test_step8_promotion_loadbearing.py`, ny fixture + tester. - **Verifisering:** nye tester grønne + detach → rød; full gate grønn. ### C4.0 Kostbaseline-forankring (C-F3; gated: D-A pkt. 2) - **Scope:** baseline-projeksjon i bundle (`cost-baseline.json`, commons-amendment/fixture) + fail-closed avstemmings-stage i `validate_proposal` (ukjent kode → Rejection; quantity/unit_cost utenfor toleranse → Rejection; toleranse konfig). Baseline-argumentet VALGFRITT (None = dagens oppførsel) så eksisterende suite står — men kjøresti-inngangen (C2.0) SETTER den når fila finnes i bundelen. Ingest-laget er den naturlige produsenten av projeksjonen (egen liten oppfølging hvis commons definerer format). - **TDD:** RØD: reviewens F3-moteksempel (diktet kode, 10 MNOK) → Rejection «unknown cost code» (detach avstemmingen → validated → rød); kontroll: ekte baseline-linje validerer som før; golden-bundelen (uten baseline-fil) validerer uendret. - **Filer:** `validator.py`, `okf.py`/`ir.py` (loader, fail-fast ved malformet fil — tolerant ved fraværende), commons-fixture, nye tester. - **Verifisering:** nye tester grønne + detach → rød; golden uendret; full gate grønn. **MÅ være grønn før enhver eventuell fremtidig live-kjøring i dette repoet.** ## 4. Valgfri / lav prioritet (ubesluttet — foreslått, ikke godkjent) - **C3.5 Budsjett-guard (C-N4):** pre-call-sjekk i loop-laget (nekt kall når rest-tak < 0) + eksplisitt run-total USD-grense over `SdkModelClient.total_cost_usd`. Mest verd rett før en eventuell ny live-kjøring; ingen gate. **Overføres IKKE hit (MAF-spesifikt):** S2.0-portefølje, S2.1-outbox (output-laget finnes her: `artifacts.py`), S2.2 MCP-konnektor, S2.3 doc-konnektor, S2.4 http-herding, S3.1/S3.3/ S3.4, S4.1/S4.2-Foundry, S5.x, M1–M3. `extending.md` står: ingen D7-HTTP/MCP-økt planlagt. ## 5. Anbefalt sekvens 1. **C1.1 → C2.5 → C2.0** (autonome, ingen gate — i den rekkefølgen: vakt først, herding, så ny kjøresti-inngang som drar nytte av herdet inbox) 2. **Operatør: D-A** (i hovedrepoet; ta C-P1-koblingsflagget med i samme bolk) → commons- amendment → subtree-pull HER 3. **C2.7 → C2.8 → C3.2 → C4.0** (etter pull; C2.7 først — minst avhengigheter, størst spec-verdi) 4. Etter hver amendment-bølge: **begge repo** re-pinnes/pulles og **begge suiter** kjøres (sammenligningsprotokollen) — aldri én side alene.