portfolio-optimiser/docs/plan/2026-07-10-sesjonsplan-fase2-6.md
Kjell Tore Guttormsen 37547fe292
refactor(examples): replace sector-specific example material with generic, fictitious examples
The context sets, the packaged knowledge bases and the example bundles are
replaced by one fictitious example set about IT operations in an invented
organisation: three context sets (serverrom-2027, driftsavtale-2027 and the
two-base drift-og-avtale-2027), two synthetic knowledge bases under
src/portfolio_optimiser/data/kunnskapsbaser and two example bundles under
src/portfolio_optimiser/data/bundles. Numbers, codes and structural values in
tests and fixtures are kept; names, ids and wording change. Dated measurement
documents that only recorded runs on the replaced material are deleted.

Gate figures measured on the new set are not comparable with earlier ones.
The exclusion gate from the previous commit is green: 0 tracked files hit
outside the shared/ subtree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 15:04:21 +02:00

44 KiB
Raw Blame History

Sesjonsplan — Fase 2 → offline-fullførings-grense (S2.0–S5.3 · D-A–D-E · M1–M3)

Status: GJELDENDE sesjonsplan. Forfattet som re-plan-forslag av kryssmodell-reviewen 2026-07-09 (Fable 5); promotert til gjeldende plan 2026-07-10 på operatør-instruks. Roadmapen (2026-07-06-reell-kjoring-analyse-plan.md) er revidert med kryssreferanser hit. Revidert 2026-07-14: beslutningene D-F–D-I (kunnskapsinnholdsmodell, OKF-modul/fabrikk/evaluator, oppsett/brukervennlighet, verdibevis/kostnadsstyring) ble truffet i operatør-samtale og er flettet inn her (§2-oppføringer + nye sesjoner S3.5/S3.6/S5.4 + S5.3-utvidelse); fasit i revisjonspakke D-F–D-I. Funn-referanser (F1–F14, P1–P6, U-1–U-4) peker til reviewen. Beslutnings-sesjonene D-A–D-E er fortsatt ÅPNE (operatør-kø): bygg-sesjoner gated på dem starter ikke før beslutning foreligger; S2.0/S2.1/S2.5 er byggbare NÅ (ingen beslutnings-avhengighet). Endringer mot roadmapen er merket [ENDRET] / [NY]. Frosne dokumenter (målbilde, ingest-målbilde, method-spec) er IKKE endret — amendments skjer kun via D-A/D-B + commons (PULL-ONLY).

Prinsipp: hver bygg-sesjon er én-sesjons-stor, offline, gratis (skriptede klienter), TDD (Iron Law), og Opus-eksekverbar med kun «Les STATE.md og følg instruksjonene». Kost/tenant/ ekspert-gatede steg er operatør-milepæler (M1–M3), aldri autonome Opus-sesjoner.


1. Endringer mot roadmapen (oppsummert)

Roadmap Endring Begrunnelse
Fase 2 «MCP wiret i kjørestien» [ENDRET] → MCP-ingest-konnektor (ny kildefamilie i manifestet), aldri kjøresti-wiring P2: method-spec §3 forbyr query-time retrieval; CLAUDE.md-invariant
Fase 2 «live-kilde-herding, inkrementell re-ingest» [ENDRET] → gated på beslutning D-B; default-scope er herding av http-konnektoren mot mock (timeouts/retry/feilkategorier), IKKE live kilde/inkrementell P1/U-3: frossen ingest-målbilde §8/§11/§12 forbyr dette; bevisst amendment kreves
Fase 3 «concurrent fan-out» [ENDRET] → krever beslutning D-D først (determinisme-modell) + fikse F1/F6 FØR concurrency Concurrent==sekvensiell er i dag selvmotsigende (delt store, RMW-index)
Fase 4 [ENDRET] → splittes i offline-byggbar del (S4.0–S4.2, autonome sesjoner) + operatør-milepæler (M1/M2) Mandat-skille
Fase 5 [ENDRET] → forutsetter outbox (S2.1) som roadmapen ikke nevner P4: output-laget (målbilde §3) er ubygget
— [NY] S2.0 (portefølje-læringssløyfe), S2.1 (outbox), S2.5 (inbox-herding), S2.7 (validator-stramming), S4.0 (kostbaseline-forankring) Injisert av funn F1, P4, F7/F11, F2, F3
— [NY] Beslutnings-sesjoner D-A–D-E FØRST §4-restene + spec-amendments må avgjøres før bygg

Funn → sesjon-mapping: F1→S2.0 · F2→D-A+S2.7 · F3→D-A+S4.0 · F4→D-A (spec) · F5→D-A+S3.2 · F6→D-D+S3.3 · F7→S2.5 · F8→S4.0 · F9→D-E+S2.0(guard) · F10→S3.4 · F11→S2.5 · F12→S2.0 · F14→D-A (tekst) · P1→D-B · P4→S2.1 · P6→S4.1/S5.2/S5.3.

Commons-regel (gjelder alle spec-amendments): shared/ er PULL-ONLY subtree. Endringer i method-spec/ingest-spec/bundle-layout skrives i portfolio-optimiser-commons og pulles hit (git subtree pull --prefix=shared commons main --squash). D7-søskenet må speile senere — UTENFOR dette repoets sesjoner; flagges i hver berørt sesjon.


2. Beslutnings-sesjoner (FØRST — operatør + kort AI-brief, ingen kode)

D-A — Spec-amendments i commons (method-spec)

  • Avgjør: (1) validator nominal-gate + IR-invariant low ≤ unit_cost ≤ high (F2 — golden- kompatibel, verifisert); (2) kostbaseline-avstemmings-stage (F3); (3) /-prefiksede cross-links mappes til bundle-rot (F4/U-1); (4) per-verdict seeding-nøkkel (F5/U-4); (5) tekst-justering «Magentic eksperimentell» → «planleggingstung/uprøvd utenfor Magentic-One» (F14; kun begrunnelse, valget står).
  • Output: godkjent/avvist per punkt + utkast til commons-endringer. Blokkerer: S2.7, S3.2, S4.0.

D-B — Fase 2-scope vs frossen ingest-målbilde

  • Avgjør: (1) amendes ingest-målbildet bevisst (live-kilde/inkrementell/§11), eller nedskopes roadmap-B til mock-herding (P1/U-3 — anbefalt: nedskop nå, live utsettes til M3-forberedelse); (2) §4.4 første live-kilde (anbefalt: SQL/database — read_sql er allerede den mest herdede konnektoren, read-only by construction); (3) dokument-konnektor-avgrensning: PDF-tekst via pypdf (ny dep) nå, DOCX utsatt; (4) MCP-kildefamiliens nettverks-/subprosess-grant-form.
  • Output: Fase 2-scope-erklæring + evt. målbilde-amendment. Blokkerer: S2.2, S2.3, S2.4.

D-C — Vektor-store (§4.5)

  • Grunnlag (delegert research, kildeført i review §6): ved 100–5 000 dokumenter er ANN unødvendig; eksakt søk er deterministisk og offline-testbart. Rangering: 1) numpy brute-force (BSD, universelle wheels, delt format .npy+jsonl er enklest for begge stacker), 2) sqlite-vec 0.1.9 (eksakt KNN, MIT/Apache, x86_64-wheel OK — men pre-v1.0, pin), 3) faiss-cpu (x86_64-wheel krever macOS 15+ — sjekk sw_vers først). LanceDB: dealbreaker (ingen Intel-Mac-wheel); ChromaDB/DuckDB-VSS: frarådet (tunge deps / eksperimentell VSS).
  • Avgjør: valg (anbefalt: numpy) + delt lagringsformat med SDK-søskenet + embeddings-kilde for ekte kjøring (Azure OpenAI embeddings vs lokal — kun konfig; tester bruker alltid fake-embedder).
  • Output: beslutning D8. Blokkerer: S3.1.

D-D — Concurrency- og feil-modell (Fase 3)

  • Avgjør: (1) determinisme-modell for concurrent fan-out — anbefalt: bølge-modell (kjøringer i en bølge ser samme store-snapshot; deterministisk merge-barriere mellom bølger; sekvensiell == bølgestørrelse 1); (2) én-skriver-regel eller fil-lås for index/ledger (F6); (3) feilpolicy ved delvis feil midt i portefølje (anbefalt: collect-and-continue, per-run-feil i PortfolioResult, aldri tap av fullførte runs — i dag kastes alt, review §3).
  • Output: concurrency-kontrakt. Blokkerer: S3.3, S3.4.

D-E — Mål-semantikk-rest + stack-paritet

  • Avgjør: (1) prosent-måls baseline-kilde (F9: subset-avhengig i dag; bundle-prosjekter har baseline 0) — anbefalt: eksplisitt baseline_ore i GoalContract/GoalConfig, aldri implisitt sum; (2) §4.6 stack-paritet for den ekte kjøringen (MAF, SDK eller begge — operatørens kost-avveining; liveness-asymmetri-erklæringen i sammenligningsprotokollen §3 består uansett).
  • Output: semantikk-beslutning. Blokkerer: del av S2.0 (guard-form), M2-konfig.

D-F–D-I — BESLUTTET 2026-07-14 (operatør-samtale, intensjonsanalyse). Til forskjell fra D-A–D-E over er disse fire allerede avgjort; fasit-protokoll + innplassering i revisjonspakke D-F–D-I. Frosne dokumenter er IKKE endret ennå — amendments skjer via commons (PULL-ONLY) i egne økter. Oppføringene under oppsummerer beslutningen + hva den blokkerer/åpner (ikke hele fasiten).

D-F — Kunnskapsinnholdsmodell [BESLUTTET 2026-07-14]

  • Status: BESLUTTET 2026-07-14. Fasit: revisjonspakke §1.
  • Kjerne: ny delt innholdsmodell i commons (kunnskapstyper tiltaksmønstre/erfaringsnotater/faglige råd, alle med påkrevd kildebelegg) — KUN lesestoff for forslagsstilleren, validatorens regler urørt. Streng separasjon fra dommene (bibliotek via bundle_context; korreksjoner KUN via ExpeL-folden). Delt dimensjonsbibliotek materialiseres inn i hver bundle via ingest-mønsteret (generated: true, flat navigasjon — ikke kryssbundle-lenker); dimensjonskatalog som skjema-validert konfig; trinnvis lesing (sammendrag-først) er nytt krav.
  • Blokkerer/åpner: gated på commons-amendment FØRST (PULL-ONLY; D7-speiling flagges) → åpner S3.5 (koordineres med S3.2). Realistisk energi-innhold (§1 pkt. 7) = egen senere innholds- produksjonsjobb, ikke del av S3.5. Fabrikk-avhengige deler venter på toolkit-repoet (D-G).

D-G — OKF: felles modul, fabrikk, evaluator [BESLUTTET 2026-07-14]

  • Status: BESLUTTET 2026-07-14. Fasit: revisjonspakke §2 (+ kryssrepo-inventar §0.2).
  • Kjerne: standard-kompatibel OKF (F4//-lenkeformen rettes — forsterker D-A pkt. 3), egne utvidelser dokumenteres eksplisitt som utvidelser. Felles OKF-kode JA (endrer D7s «from spec alone» bevisst; gir Claude-repoet skrive-halvdelen A2 mangler i dag). Nytt tredje signatur-repo (arbeidstittel okf-toolkit): delt les/naviger/skriv-kjerne + conformance-testsett + bundle-evaluator
    • bundle-fabrikk. Rekkefølge: modul + formatprøve først (fjerner 6-steders-duplikasjonen), fabrikk + evaluator deretter mot energi-caset.
  • Blokkerer/åpner: toolkit lever i EGET repo utenfor denne sesjonskøen → ekstern avhengighet (T0) som blokkerer fabrikk-avhengige deler av D-F/D-H. Guard forblir eget sikkerhets-repo (avhengighet).

D-H — Oppsett og brukervennlighet [BESLUTTET 2026-07-14]

  • Status: BESLUTTET 2026-07-14. Fasit: revisjonspakke §3.
  • Kjerne: oppsett gjøres ALLTID av et lite team (teknisk + fag); leveransen er en oppskrift (dokumentert prosess), ikke en veiviser (B9-onboarding + guidet dom-kommando FORKASTET). Fagpersonen leverer filer i egne formater — aldri skjema/JSON; fabrikken (D-G) AI-oversetter fri-format-dommer til strengt format, godkjenning i praksis = stikkprøver med provenance-peker til ekspertens originalfil. Demo-sti: klon → unzip energi-eksempel i bundle-innboks → fabrikk bygger → hele sløyfa kjører. Obsidian/VS Code som lese-løsning først.
  • Blokkerer/åpner: oppskrift-dokumentet (§3 pkt. 1) legges til S5.3 som dokumentleveranse; dom-oversettelse + demo-sti er fabrikk-avhengige (D-G/T0), blokkert til toolkit finnes.

D-I — Verdibevis + kostnadsstyring [BESLUTTET 2026-07-14]

  • Status: BESLUTTET 2026-07-14. Fasit: revisjonspakke §4.
  • Kjerne: publiserings-påstand = nivå 2 (realistisk case, modellerte tall, aldri salgsspråk over beleggsnivået); nivå 3 (ekte pilot) er åpen invitasjon. Verdirapport per kjøring (kjerne): hovedbok-basert modellert→korrigert→realisert, målprogresjon, tallfestet læringseffekt, kost-mot-verdi. Kostnadssimulering FØR kjøring (MÅ-krav): what-if over modell-mappet (modeller × effortnivåer), prisdata som skjema-validert konfig (aldri hardkodet), kvalitetsutsagn merket som veiledning med kilde.
  • Blokkerer/åpner: åpner S5.4 (verdirapport, etter S2.1-outbox + ledger) og S3.6 (kostnadssimulering, fri/offline). README oppdateres FØRST når nivå-2-beviset finnes (pkt. 1).

3. Opus-sesjons-specs (offline, autonome)

Felles for alle: Iron Law (failing test først); uv run pytest / uv run ruff check . / uv run mypy src grønne ved slutt; skriptede klienter (null modell-kost); commit per sesjon i repoets Conventional-Commit-stil; STATE.md overskrives ved sesjonsslutt.

S2.0 [NY] Portefølje-læringssløyfe + ærlighets-fiks (F1, F12, P5, F9-guard)

  • Mål: en dom på prosjekt k når prosjekt k+1s hypotese-PROMPT i run_portfolio — og ingen docstring påstår mer enn koden gjør.
  • Scope: per-prosjekt bundle_dir (valgfritt felt i reference_projects.json) + verdict_dir-parameter tres gjennom run_portfolio → run_project. Percent-goal-guard: eksplisitt feil (ValueError) når percent-mål settes og baseline er 0. CHANGELOG oppdateres (Fase 1 + denne). IKKE bygges: concurrency, semantisk henting, outbox.
  • Avhengigheter: ingen (første bygg-sesjon).
  • Filer: run.py, reference_domain.py, data/reference_projects.json (+ evt. mini-bundle fixture under data/), tests/test_portfolio.py, ny tests/test_portfolio_learning_loadbearing.py, CHANGELOG.md.
  • TDD: (1) RØD: test der prosjekt k får dom (via delt store, bundle-sti) og k+1s genererings-prompt MÅ inneholde dommens id+markør — detach-punkt: fjern bundle_dir-trådingen i run_portfolio → rød (i dag ER den rød — det er poenget). (2) RØD: empty-store-kontroll. (3) RØD: percent-mål + baseline 0 → ValueError.
  • Nøkkelantakelser: bundle-fixture kan gjenbruke bygg-energi-mikro-form uten commons-endring (test: legg fixture under src/portfolio_optimiser/data/, aldri i shared/).
  • Verifisering: uv run pytest tests/test_portfolio_learning_loadbearing.py → grønn; detach (revert tråding) → rød; full suite + ruff + mypy grønne; grep -n "cross-project learning" src/ viser docstring som nå stemmer med wiring.

S2.1 [NY] Outbox-persistens — output-laget materialiseres (P4)

  • Mål: hver kjørings forslag/avvisning/provenance persisteres som deterministisk JSON i en outbox-mappe (målbilde §3s output-lag), så utestående dommer kan spores (Fase 5) og live-artefakter fanges (sammenligningsprotokoll §4.2).
  • Scope: run_project(outbox_dir=..., run_id=...) (begge valgfrie; run_id er påkrevd når outbox er satt — ingen wall-clock-default). Skriver {run_id}-proposal.json / {run_id}-outcome.json (outcome-type, reason/percentiler, checker_verdict, provenance, verdict-id). Systemet SKRIVER outbox (lovlig: rolledelingen §3 gjelder inbox/wiki, ikke systemets eget output-lag — sitér method-spec §2 i docstring). IKKE bygges: ruting, varsling.
  • Avhengigheter: ingen (parallell med S2.0).
  • Filer: run.py, ny outbox.py (ren stdlib+pydantic — MAF-fri? Nei: importerer validator-typer som er rene; hold agent_framework-fri og legg til i _MAF_FREE_MODULES), tests/test_outbox_loadbearing.py.
  • TDD: RØD: kjøring med outbox_dir → forventet filpar finnes, byte-deterministisk (sort_keys, indent 2, LF); detach-punkt: fjern outbox-skrivingen → rød. Kontroll: uten outbox_dir skrives ingenting.
  • Nøkkelantakelser: ValidatedProposal/Rejection er JSON-serialiserbare via eksplisitt mapping (test først med begge utfallstyper).
  • Verifisering: ny testfil grønn; detach → rød; full gate grønn; to kjøringer med samme input+run_id → byte-identiske filer (diff).

S2.2 MCP-ingest-konnektor (gated: D-B) [ENDRET fra «MCP i kjørestien»]

  • Mål: en fjerde kildefamilie mcp i ingest-manifestet materialiserer OKF-filer fra en MCP-server — datainntak, aldri kjøresti.
  • Scope: ingest-spec-amendment i commons FØRST (skjema for {type:"mcp", id, server_ref, tool}; server_ref = navn på env-var med kommando, mirror connection_ref) → subtree pull → impl i ingest.py. Transport: stdio-klient via mcp-pakken (allerede dep). Per-run-grant: gjenbruk allow_network-mønsteret med nytt eksplisitt flagg (per D-B). Test: in-process fixture-server (gjenbruk datasource.build_mcp_server-kjernen mot committed docs — det AV-DEMOER extension-pointet). IKKE: fjern-servere, auth utover env-ref.
  • Avhengigheter: D-B (+ commons-pull).
  • Filer: ingest.py, tests/test_ingest_mcp*.py, golden-fixture examples/ingest-golden-mcp/ (i commons — flagg), docs/extending.md-avsnitt.
  • TDD: RØD: manifest med type: mcp uten grant → IngestError (grant-detach → rød); RØD: golden-materialisering mot fixture-server → byte-deterministisk bundle; RØD: verdict-reservasjonen gjelder også mcp-familien.
  • Nøkkelantakelser: mcp-klient kan drives i-prosess mot FastMCP uten socket (test som første steg — hvis ikke, subprosess mot python -m-fixture med eksplisitt merking).
  • Verifisering: uv run pytest tests/test_ingest_mcp*.py grønn; detach grant-sjekken → rød; full gate grønn.

S2.3 Dokument-konnektor (doc-familie; gated: D-B)

  • Mål: PDF-rapport → OKF-konseptfil med provenance, deterministisk mot committed fixtures.
  • Scope: ingest-spec-amendment (commons) for {type:"doc"}; pypdf som ny dep (D-B); tekst-ekstraksjon per side, fenced-verbatim-rendering (gjenbruk _render_fenced_block-regler), max_rows-cap, fail-fast på ikke-tekst-PDF. DOCX: IKKE (utsatt per D-B).
  • Avhengigheter: D-B; uavhengig av S2.2.
  • Filer: ingest.py, pyproject.toml (+pypdf), tests/test_ingest_doc*.py, golden-fixture med liten committed PDF.
  • TDD: RØD: golden byte-determinisme; RØD: kodefence-linje i ekstrakt → IngestError (gjenbruk http-regelen); RØD: cap-overskridelse → feil, aldri trunkering.
  • Nøkkelantakelser: pypdf-ekstraksjon er bit-stabil på tvers av versjoner for fixture-PDF-en (test: pin versjon; golden fanger drift).
  • Verifisering: nye tester grønne + detach → rød; full gate grønn.

S2.4 Konnektor-herding mot mock (gated: D-B) [ENDRET fra «live-kilde-herding»]

  • Mål: http-konnektoren tåler virkelighetens feilmoduser — bevist mot injisert transport, aldri live.
  • Scope: timeout-parameter på _urllib_get; feilkategorisering (transport/auth/decode) i IngestError-melding; ingest-logg beriket (§8: kilde, tidspunkt, radantall — aldri innhold); retry KUN hvis D-B sier ja (default nei — determinisme). Inkrementell re-ingest: IKKE (frossen §8) med mindre D-B amender.
  • Avhengigheter: D-B.
  • Filer: ingest.py, tests/test_ingest_http*.py.
  • TDD: RØD per feilmodus (canned transport som raiser URLError/timeout/feil-encoding) → presis IngestError; detach timeout → rød.
  • Verifisering: nye tester grønne; full gate grønn; grep bekrefter ingen nye socket-stier utenfor _urllib_get.

S2.5 [NY] Inbox- og robusthets-herding (F7, F11)

  • Mål: verdict-inboxen slutter å være en uvalidert injeksjonsflate, og offline-bevisets MAF-avhengighet får en versjonsvakt.
  • Scope: (1) load_verdicts_from_dir: decision-vokabular-sjekk (§4.2 — ukjent decision → SKIP, fortsatt tolerant, aldri raise), tak på rationale-lengde + antall filer per merge (konfigurerbart, fail-fast ved overskridelse — aldri stille kutt); (2) konsolider de fire _inner_get_response-duplikatene (conftest ×3 + simulation) til én delt scripted-klient (plassering: tests/-hjelper + simulation beholder sin — eller flytt til simulation.py og importér i conftest; velg det som ikke gir src→tests-import); (3) MAF-versjonsvakt: test som feiler med handlingsrettet melding hvis agent_framework.__version__ ikke matcher pinnet versjon (tvinger bevisst re-verifisering av privat-API-premissene ved oppgradering); (4) pin agent-framework-core>=1.9.0,<2 i pyproject.
  • Avhengigheter: ingen.
  • Filer: verdicts.py, conftest.py, simulation.py, pyproject.toml, tests/test_verdicts.py, ny tests/test_maf_version_guard.py.
  • TDD: RØD: inbox-fil med decision: "banana" → hoppes over (detach vokabular-sjekken → den entrer storen → rød); RØD: rationale > tak → skip + logg; versjonsvakt-testen rød mot en fake-versjon.
  • Verifisering: full gate grønn; grep -c "_inner_get_response" tests/ src/ viser redusert duplikat-antall.

S2.7 [NY] Validator-stramming (F2; gated: D-A + commons-pull)

  • Mål: den deterministiske validatoren håndhever sin egen stage-2-grense, og assumptions kan ikke forfattes forbi den.
  • Scope: (1) strukturell blokk claimed > nominal_feasible → Rejection (i tillegg til P90); (2) IR-invariant: hvert assumption-band MÅ omslutte itemets unit_cost (low ≤ unit_cost ≤ high) — Pydantic model_validator. Golden-kompatibilitet er verifisert i review (claim 30k ≤ 90k; band [0.70,1.40] ∋ 1.0). IKKE: kostbaseline-avstemming (S4.0), metode-registry (S4.0).
  • Avhengigheter: D-A pkt. 1 + commons-spec pullet.
  • Filer: validator.py, ir.py, tests/test_validator.py, tests/test_ir*.py (eller tilsvarende), tests/test_bygg_energi_mikro.py (uendret grønn — regresjonsbevis).
  • 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-punkt: fjern nominal-blokken → moteksempel-testen rød.
  • Nøkkelantakelser: ingen eksisterende test/fixture bruker band som ikke omslutter unit_cost — VERIFISERT 2026-07-09 av reviewer (skann av alle JSON-fixtures + inline-band-grep: null brudd; se review §6). Antakelsen er dermed et bekreftet premiss, ikke en risiko.
  • Verifisering: uv run pytest tests/test_validator.py tests/test_bygg_energi_mikro.py grønn; golden uendret; full gate grønn. Flagg: D7-søsken må speile (egen sesjon i søsken-repoet).

S3.1 Semantisk henting bak seam (gated: D-C) [roadmap C]

  • Mål: hentingen skalerer forbi feature-key-match uten å ofre determinisme/offline-testbarhet.
  • Scope (per D-C-anbefaling numpy): Retriever-protokoll; HybridRanker = dagens strukturelle score + cosine over lagrede vektorer (vekting konfig); vektor-lager = .npy + id-jsonl ved siden av verdict-storen; Embedder-protokoll med deterministisk fake i tester (hash-basert); ekte embeddings-klient (Azure/lokal) KUN som konfig-punkt, aldri kalt i tester. IKKE: ANN, ekstern DB, endring i shared/.
  • Avhengigheter: D-C; uavhengig av S2.x.
  • Filer: ny semretrieval.py (MAF-fri, i _MAF_FREE_MODULES), verdicts.py (retrieve-seam), run.py (opt-in), pyproject.toml (numpy), nye tester.
  • TDD: RØD: syntetisk stor base (500+ verdicts) der KUN cosine-komponenten kan rangere riktig dom øverst (strukturell score uavgjort ved konstruksjon) — detach cosine → rød; RØD: determinisme (to kjøringer → identisk rangering); RØD: fake-embedder-bit-stabilitet.
  • Nøkkelantakelser: numpy-dep er akseptabel i MAF-repoet (IKKE i shared/) — bekreftet av D7-grensen (semantikk-laget er stack-lokalt).
  • Verifisering: nye tester grønne + detach → rød; full gate grønn; test_okf_is_maf_free utvidet til semretrieval.py grønn.

S3.2 Multi-kandidat ExpeL-substrat (F5; gated: D-A pkt. 4 + commons-pull)

  • Mål: dommer nøkles på SIN kandidat, ikke bundelens ene IR-projeksjon.
  • Scope: seed leser features fra verdict-filas egen frontmatter (nye valgfrie felt: affected_codes/measure_type/claimed_saving_nok; fallback = dagens kandidat-nøkling for bakoverkompatibilitet); promote_verdict skriver disse feltene; multi-kandidat-bundle-fixture.
  • Avhengigheter: D-A + commons (spec §3 Steg 1 seeding-regel + bundle-eksempel).
  • Filer: verdicts.py, tests/test_step8_promotion_loadbearing.py, ny multi-kandidat-fixture (repo-lokal under data/), nye tester.
  • TDD: RØD: to kandidater i én bundle → dom om kandidat B når ALDRI kandidat As hypotese-prompt (detach per-verdict-nøklingen → rød fordi B-dommen feil-nøkles til A).
  • Verifisering: nye tester grønne; eksisterende step1/step7/step8-suite uendret grønn (fallback-kompatibilitet); full gate grønn. Flagg: D7-speiling.

S3.3 Concurrent fan-out (F6; gated: D-D) [roadmap C]

  • Mål: N kjøringer parallelt med bevart determinisme: concurrent == sekvensiell.
  • Scope (per D-D bølge-modell): run_portfolio(concurrency=k); bølge = inntil k prosjekter med samme store-SNAPSHOT; deterministisk merge-barriere (sortert på project_id) mellom bølger; feilpolicy collect-and-continue (RunResult-slot med feil-felt, fullførte runs bevares); én-skriver-regel for index/ledger håndheves (ingen promote/realize i kjørestien — allerede sant; assert + dok).
  • Avhengigheter: D-D, S2.0 (bundle-portefølje), helst S3.1 (men ikke hard).
  • Filer: run.py, tests/test_portfolio_concurrent_loadbearing.py.
  • TDD: RØD: concurrency=3 gir BYTE-identisk aggregat + store-innhold som concurrency=1 på 3-prosjekt-fixturen (detach barrieren → udeterministisk → rød over repetisjoner — kjør testen med fast rekkefølge-probe, ikke tidsavhengig); RØD: injisert feil i prosjekt 2 → prosjekt 1+3s resultater bevart.
  • Nøkkelantakelser: MAF-klienter er asyncio-samtidige i én loop (dokumentert modell er asyncio; OS-tråd-garanti er IKKE dokumentert — hold alt i én loop).
  • Verifisering: ny test grønn ×20 repetisjoner (pytest --count el. loop); full gate grønn.

S3.4 Kostnadsstyring på tvers (F10) [roadmap C]

  • Mål: et globalt token-tak over HELE porteføljepasset (og på tvers av pass), håndhevet FØR kall — ikke bare per kjøring etterpå.
  • Scope: PortfolioBudget (globalt tak + per-run-tak); pre-call-guard i BudgetMiddleware (nekt kall når rest < 0 — i tillegg til dagens post-charge); spend-persistens (deterministisk JSON, eksplisitt stamp-argument); oppstartsnekt når resttak < konfigurert minimum per kjøring.
  • Avhengigheter: D-D (deler feilpolicy), S3.3 (bølge-integrasjon) — kan bygges før S3.3 mot sekvensiell sti.
  • Filer: budget.py, run.py, tests/test_budget.py, ny loadbearing-test.
  • TDD: RØD: globalt tak krysses midt i passet → strukturert stopp med fullførte runs bevart (detach global-sjekken → passet løper forbi taket → rød); RØD: pre-call-guard nekter kallet (klient-mock som teller kall — kallet skal ALDRI skje).
  • Verifisering: nye tester grønne + detach → rød; full gate grønn.

S3.5 [NY] Innholdsmodell + fagbibliotek-materialisering (D-F; gated: commons-amendment)

  • Mål: delt kunnskapsinnholdsmodell (tiltaksmønstre/erfaringsnotater/faglige råd med kildebelegg) materialiseres inn i prosjekt-bundles som rent lesestoff for forslagsstilleren — uten å røre validatoren og uten å blande seg med dommene.
  • Scope (revisjonspakke §1 pkt. 1–6): (1) nye kunnskapstyper i delt spec (commons-amendment FØRST — PULL-ONLY, D7-speiling flagges); (2) dimensjonskatalog som skjema-validert konfig (id, label, allowed_measure_types, allowed_code_prefixes) + fail-fast loader — rammeverket shipper eksempel-katalog, deployer eier sin; (3) bibliotek-materialisering via ny ingest-kildefamilie (generated: true, manifest-ref, re-materialisering eier egne filer — flat/same-dir navigasjon, IKKE kryssbundle-lenker, IKKE manuell duplisering); (4) trinnvis lesing i bundle_context: sammendrag-først (én linje per kunnskapsfil), fulltekst hentes ved behov. Streng separasjon håndheves: bibliotek via bundle_context, organisasjonens korreksjoner KUN via ExpeL-folden. IKKE i scope: energi-innholdet i realistisk skala (§1 pkt. 7 = egen senere innholds-produksjonsjobb, avhengig leveranse); validator↔bibliotek-kobling (framtidig beslutning); toolkit-fabrikken (D-G, eget repo).
  • Avhengigheter: commons-amendment for innholdsmodellen (D-F-utkast operatør-godkjent + git subtree pull) FØRST; koordineres med S3.2 (multi-kandidat — deler seed/frontmatter-stien). Etter S2.0/S2.1/S2.5.
  • Filer: okf.py (trinnvis lesing / sammendrag-seam — MAF-fri, håndhevet av test_okf_is_maf_free), ny dimension_catalog.py (loader, fail-fast), ingest.py (bibliotek-kildefamilie), commons-spec + eksempel-katalog (i commons — flagg), repo-lokal bibliotek-fixture under data/, nye tester.
  • TDD: (1) RØD: dimensjonskatalog med ugyldig felt (ukjent allowed_measure_type-referanse) → fail-fast ved lasting — detach-punkt: fjern skjema-valideringen → passerer → rød; (2) RØD: materialisert bibliotek-fil når forslags-prompten via bundle_context (markør fraværende fra bundelen ellers) — detach materialiseringen → markøren forsvinner → rød; (3) RØD: trinnvis lesing gir sammendraget i navigert kontekst men IKKE fulltekst før eksplisitt henting — detach sammendrag-seamen → hele fullteksten stuffes inn → rød; (4) RØD: en bibliotek-fil MÅ ALDRI nå hypotese-prompten via dom-kanalen (separasjons-kontroll — biblioteket lekker aldri inn i ExpeL-folden).
  • Nøkkelantakelser: trinnvis-lesing-kravet (D-F pkt. 6) kan realiseres uten å bryte method-spec §3 Steg 1s render-kontrakt — HVIS ikke, er sammendrag-seamen del av commons-amendmenten (flagges eksplisitt, jf. revisjonspakke §6-nøkkelantakelsen). Bibliotek-fixture ligger repo-lokalt under data/ (aldri i shared/) til energi-innholdet materialiseres.
  • Verifisering: nye tester grønne + hvert detach-punkt → rød; test_okf_is_maf_free utvidet grønn; full suite + ruff + mypy grønne. Flagg: commons-amendment + D7-speiling (egen sesjon i søsken-repoet).

S3.6 [NY] Kostnadssimulering før kjøring (D-I pkt. 3; offline, ikke gated)

  • Mål: operatøren ser estimert kost for en portefølje-kjøring FØR den startes — what-if over modell-mappet (modeller × effortnivåer) — så kjøringskost blir en informert beslutning, ikke en overraskelse etterpå.
  • Scope (revisjonspakke §4 pkt. 3): python -m portfolio_optimiser.costsim (+ funksjons-API): estimér tokens/kost for en gitt portefølje under valgt modell + effortnivå; prisdata som skjema- validert konfig (kr/1k tokens per modell, med kilde- + dato-felt — ALDRI hardkodet; fail-fast ved manglende/ugyldig pris); kvalitets-avveininger per modellvalg merket som veiledning med kilde, aldri målt fakta uten belegg; output = estimat-tabell (per rolle/modell/effort) + kost-mot-verdi-felt klart for verdirapporten (S5.4). Deler tak-begreper med budsjettmaskineriet (PortfolioBudget / BudgetMiddleware fra S3.4), men estimerer FØR kall. Adopsjonssti dokumenteres (start liten → eskaler med tilliten). IKKE: live prisoppslag (nettverk), faktisk modellkall (rent offline), kvalitets-benchmarking.
  • Avhengigheter: ingen commons-avhengighet (offline, stack-lokalt); drar nytte av S3.4 (budsjett-typer) og mater S5.4 (verdirapport). Kan bygges før S3.5.
  • Filer: ny costsim.py (ren stdlib + pydantic — MAF-fri, legg i _MAF_FREE_MODULES), data/pricing.example.json (skjema + eksempelpriser med kilde/dato), budget.py (deling av tak-begreper), nye tester.
  • TDD: (1) RØD: konfig uten pris for en modell i mappet → fail-fast «missing price for » — detach-punkt: fjern pris-valideringen → estimatet gjettes → rød; (2) RØD: estimatet er deterministisk og skalerer med modell × effort (to modeller, samme portefølje → forskjellig, reproduserbart estimat) — detach effort-faktoren → identisk estimat → rød; (3) RØD: hardkodet pris i kildekode fanges av grep-guard (pris MÅ komme fra konfig).
  • Nøkkelantakelser: token-estimatet kan bygges fra portefølje-formen (antall prosjekter × runder × tak) uten et modellkall — deterministisk øvre-grense-estimat, ikke prediksjon; merkes eksplisitt som estimat i output.
  • Verifisering: nye tester grønne + detach → rød; uv run python -m portfolio_optimiser.costsim gir estimat-tabell uten nettverk (grep-guard: ingen socket-sti i modulen); full gate grønn.

S4.0 [NY] Validator-forankring mot kostbaseline (F3, F8; gated: D-A pkt. 2)

  • Mål: affected_items avstemmes fail-closed mot prosjektets faktiske kostbaseline — den deterministiske gaten kan ikke lenger mates med hallusinerte kostlinjer.
  • Scope: baseline-projeksjon i bundle (cost-baseline.json: code→{quantity, unit_cost} — commons-amendment) + fra reference_domain.cost_items på referanse-stien; ny avstemmings-stage i validate_proposal (kode finnes ikke i baseline → Rejection; quantity/unit_cost utenfor toleranse → Rejection; toleranse konfig); metode-registry: metode-caps keyes via dimensjon/konfig, ikke strengen energy_efficiency (F8). Baseline-argument er VALGFRITT i første omgang (None = dagens oppførsel) så eksisterende suite står — men run-stiene SETTER den.
  • Avhengigheter: D-A + commons; S2.x-ingest kan generere baseline-projeksjonen (soft).
  • Filer: validator.py, run.py, okf.py (baseline-loader, fail-fast), commons-fixture, nye tester.
  • TDD: RØD: reviewens F3-scenario (dikta kode XX, 10 MNOK) → Rejection «unknown cost code» (detach avstemmingen → validated → rød); kontroll: ekte baseline-linje validerer som før.
  • Verifisering: nye tester grønne + detach → rød; golden uendret; full gate grønn. Flagg: D7-speiling. MÅ være grønn før M2.

S4.1 Azure/Foundry-preflight (offline) [roadmap D, offline-delen]

  • Mål: alt som KAN valideres uten et modellkall, valideres før operatøren betaler for ett.
  • Scope: python -m portfolio_optimiser.preflight --profile azure: env-kontrakt (PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT satt + URL-form; deployment-navn ≠ REPLACE-WITH-*; modell-map-konsistens), credential-sjekk KUN som dokumentert manuelt steg (aldri auto-login). Nekter live-profil med placeholders (fail-fast også i resolve_model-stien). Dokumentér auth-oppskrift (Entra: az login / DefaultAzureCredential; FoundryChatClient tar project_endpoint+model+credential — verifisert mot MS Learn, se review §6). Env-override for model_map (PORTFOLIO_MODEL_MAP sti) så tenant-navn aldri committes.
  • Avhengigheter: ingen (uavhengig av Fase 2/3).
  • Filer: ny preflight.py, backends.py, contracts.py (placeholder-regel), tester.
  • TDD: RØD: placeholder-deployment + azure-profil → strukturert nekt (detach placeholder-sjekken → rød); RØD: manglende endpoint-env → aksjonérbar feilmelding.
  • Verifisering: uv run python -m portfolio_optimiser.preflight --profile azure gir korrekt nekt/OK uten nettverk (bevis: kjør med nettverk utilgjengelig antatt — ingen socket-kode i modulen, grep-guard); full gate grønn.

S4.2 Live-kjørings-drill + artefakt-fangst (offline) [roadmap D, offline-delen]

  • Mål: den ENE fremtidige live-kjøringen (M2) er ferdig-rigget: alt bygges, artefakter fanges, og drillen er øvd offline.
  • Scope: --live-dry-run-modus i main(): last kontrakter, bygg klienter, valider budsjett, STOPP før første modellkall (bevist med kall-tellende mock); kjøringskonfig-logg (modell-id, parametre, tak — sammenligningsprotokoll §4.3); outbox-fangst (S2.1) av proposal/checker/ validator/tokens per §4.2.
  • Avhengigheter: S2.1, S4.1.
  • Filer: run.py, preflight.py/main, tester.
  • TDD: RØD: dry-run mot mock-faktory → null chat-kall skjedde (detach stopp-punktet → kall telles → rød); RØD: artefakt-settet komplett i outbox.
  • Verifisering: nye tester grønne; full gate grønn.

S5.1 Verdict-ruting + sporing [roadmap E]

  • Mål: teamet ser hvilke forslag som venter på dom, og hvem som skal dømme.
  • Scope: pending-registry = outbox-forslag uten matchende inbox-dom (id-join); ruting-konfig dimension → ekspert (fail-fast skjema); CLI python -m portfolio_optimiser.hitl pending|route; ren fil-basert (ingen server). IKKE: varsling (S5.2), web-UI.
  • Avhengigheter: S2.1 (outbox); S2.0 (verdict_dir i portefølje).
  • Filer: ny hitl.py, tester.
  • TDD: RØD: forslag i outbox uten dom → listes utestående; dom lander i inbox → forsvinner (detach id-joinen → rød).
  • Verifisering: nye tester grønne; full gate grønn.

S5.2 Varsling — B11 fra stub til ekte [roadmap E]

  • Mål: notify= får leverbare implementasjoner uten å bryte ingen-stille-egress.
  • Scope: Notifier-protokoll + console/file/webhook-impl; webhook krever eksplisitt per-kjøring opt-in-flagg (mirror allow_network, ingest §8-mønsteret) + injiserbar transport (canned i tester — null socket i suiten); konfig fail-fast.
  • Avhengigheter: S5.1 (naturlig kobling), ellers uavhengig.
  • Filer: ny notify.py, run.py (seam består), tester.
  • TDD: RØD: webhook uten opt-in → nekt fail-fast (detach → rød); RØD: canned transport mottar korrekt payload; RØD: ingen socket-sti utenfor den injiserbare seamen (grep-guard à la _urllib_get).
  • Verifisering: nye tester grønne; full gate grønn.

S5.3 CLI-paritet + dokumentsync (P6, F12-rest)

  • Mål: operatøren kan drive ALT bygget (dimensjon, mål, ledger, bundle-portefølje, inbox, outbox) fra kommandolinja, og dokumentene påstår nøyaktig det koden gjør.
  • Scope: main() (+ evt. portfolio-subkommando): --dimension-config, --ledger, --goals, --bundle-dir, --verdict-dir, --outbox-dir; README/extending.md/CHANGELOG-sync; ærlighets-grep (ingen «learning loop»-claims på stier uten fold).
  • Scope (D-H pkt. 1, tillegg): oppsett-oppskrift som dokumentleveranse — dokumentert team-prosess (teknisk + fag) for å bygge en kunnskapsbase, med ærlig README-forventning (en god base tar 1–2 uker dedikert arbeid; kvaliteten på investeringen avgjør resultatet); IKKE en veiviser / B9-onboarding- intervju (FORKASTET).
  • Avhengigheter: S2.0, S2.1 (og drar nytte av alt over).
  • Filer: run.py, README.md, docs/extending.md, CHANGELOG.md, CLI-tester.
  • TDD: RØD: CLI-kjøring med goals+ledger på fixtures → GoalReached-stopp observerbar i output.
  • Verifisering: CLI-tester grønne; full gate grønn; manuell uv run python -m portfolio_optimiser.run …-røyk på fixtures dokumentert i STATE.

S5.4 [NY] Verdirapport per kjøring (D-I pkt. 2)

  • Mål: hver kjøring (og porteføljepass) produserer en deterministisk verdirapport — modellert → ekspert-korrigert → realisert per prosjekt/dimensjon, målprogresjon, tallfestet læringseffekt og kost-mot-verdi — som artefakt, uten et eneste modellkall.
  • Scope (revisjonspakke §4 pkt. 2): hovedbok-basert rapportgenerator over ledgeren + outbox (S2.1): (a) besparelses-kolonner modellert/korrigert/realisert per prosjekt + dimensjon; (b) målprogresjon mot GoalContract; (c) læringseffekt tallfestet — godkjenningsandel per kjøring + om modellert-vs- forventet-gapet krymper over kjøringer; (d) kost-mot-verdi («kjøringen kostet X, identifiserte kvalitetssikret modellert besparelse Y» — X fra S3.6-estimat / faktisk token-forbruk). Rapport = deterministisk artefakt (JSON + markdown-render; sort_keys / indent / LF / byte-stabil). Ærlighet: realiserte tall KUN der dom finnes; modellerte merkes som modellert (aldri salgsspråk over beleggsnivået, D-I pkt. 1). IKKE: web-dashboard, live-oppdatering, modellkall.
  • Avhengigheter: S2.1 (outbox — forslag/utfall-artefakter) + ledger (S2.0-læringssløyfe); konsumerer S3.6-kostestimat for kost-mot-verdi-feltet.
  • Filer: ny valuereport.py (ren stdlib + pydantic — MAF-fri, _MAF_FREE_MODULES), run.py (opt-in --value-report), nye tester.
  • TDD: (1) RØD: to kjøringer med økende godkjenningsandel → læringseffekt-metrikken stiger og gap-krympingen rapporteres — detach-punkt: fjern gap-beregningen → flat/feil → rød; (2) RØD: prosjekt uten dom → «realisert» er tomt/umerket, ALDRI lik modellert — detach ærlighets-grensen → realisert = modellert → rød; (3) RØD: byte-determinisme (samme ledger + outbox → identisk rapport, diff).
  • Nøkkelantakelser: ledgeren + outbox bærer allerede alt rapporten trenger (modellert fra proposal, korrigert/realisert fra dommene, kost fra token-forbruk / S3.6) — rapporten er ren projeksjon, ingen ny tilstand (test: bygg rapport fra committede fixtures uten kjøring).
  • Verifisering: nye tester grønne + detach → rød; run.py --value-report på fixtures gir byte-stabil rapport uten nettverk; full gate grønn.

4. Operatør-gatede milepæler (IKKE autonome Opus-sesjoner)

M1 — Foundry-tenant-oppsett + smoke (etter S4.1)

  • Forutsetninger: operatør oppretter i tenant: én Foundry-prosjekt-endpoint + ÉN Global-Standard-deployment av billig modell (gpt-4o-mini-/gpt-5-mini-klassen — én deployment dekker begge roller; research-verifisert). az login. Sett PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT + PORTFOLIO_FOUNDRY_DEPLOYMENT + model_map-override.
  • Manuelle steg: kjør preflight (S4.1) → grønn; kjør uv run pytest tests/test_foundry_profile_live.py.
  • Kost: ett trivielt kall (øre-nivå; pris ikke verifisert — sjekk Azure-priser først).

M2 — Første live-modell-kjøring, liten skala (etter S4.0 + S4.2 + M1)

  • Forutsetninger: S4.0 grønn (validator forankret — F3 lukket FØR ekte modell), harde tak satt lavt (f.eks. max_tokens 20k), outbox-fangst på.
  • Manuelle steg: én run_project mot energi-bundelen, azure-profil; artefakter arkiveres; utfall re-rulles IKKE (sammenligningsprotokoll §4.5).
  • Kost: én kjøring innenfor taket; dokumenteres i rapport med konfig-logg.

M3 — Fase 6-pilot (etter Fase 5 + M2 + D-B-amendment for live kilde)

  • Forutsetninger: én ekte kilde (per §4.4-beslutningen) herdet og materialisert med ekte provenance; én ekte fagekspert onboardet på inbox/outbox-kontrakten (samme mappe-grensesnitt som personaen); ruting+varsling (S5.1/S5.2) i drift; ingest-målbilde-amendment på plass (P1).
  • Manuelle steg: én dimensjon × ett prosjekt ende-til-ende; verifiser målbilde §7-sløyfa mot virkeligheten; FØRST deretter skalering mot N×10.

5. Avhengighetsgraf + anbefalt sekvens

flowchart TB
    subgraph DEC["Beslutnings-sesjoner (operatør)"]
        DA["D-A spec-amendments"]; DB["D-B Fase2-scope/ingest-målbilde"]
        DC["D-C vektor-store"]; DD["D-D concurrency"]; DE["D-E mål/paritet"]
    end
    S20["S2.0 portefølje-læring (F1)"]; S21["S2.1 outbox (P4)"]; S25["S2.5 inbox-herding (F7/F11)"]
    S27["S2.7 validator-stramming (F2)"]; S22["S2.2 MCP-ingest"]; S23["S2.3 doc-konnektor"]; S24["S2.4 http-herding"]
    S31["S3.1 semantisk henting"]; S32["S3.2 multi-kandidat (F5)"]; S33["S3.3 concurrent (F6)"]; S34["S3.4 kost på tvers (F10)"]
    S40["S4.0 kostbaseline-forankring (F3)"]; S41["S4.1 preflight"]; S42["S4.2 live-drill"]
    S51["S5.1 ruting/sporing"]; S52["S5.2 varsling"]; S53["S5.3 CLI-paritet"]
    S35["S3.5 innholdsmodell/bibliotek (D-F)"]; S36["S3.6 kostnadssimulering (D-I)"]; S54["S5.4 verdirapport (D-I)"]
    DFC["D-F commons-amendment (PULL-ONLY)"]; T0[["T0 toolkit-repo (eget repo — okf-toolkit)"]]
    M1{{"M1 tenant+smoke"}}; M2{{"M2 første live-kjøring"}}; M3{{"M3 pilot"}}

    DA --> S27; DA --> S32; DA --> S40
    DB --> S22; DB --> S23; DB --> S24; DB -. amendment .-> M3
    DC --> S31; DD --> S33; DD --> S34; DE --> M2
    S20 --> S33; S20 --> S51; S21 --> S42; S21 --> S51
    S41 --> M1; S40 --> M2; S42 --> M2; M1 --> M2
    S51 --> S52; S20 --> S53; S21 --> S53
    S33 --> M3; S34 --> M3; S52 --> M3; M2 --> M3; S31 --> M3; S32 --> M3
    DFC --> S35; S32 -. koordineres .-> S35
    S21 --> S54; S34 -. kost .-> S54; S36 -. kost-mot-verdi .-> S54
    T0 -. fabrikk .-> M3

Anbefalt sesjonssekvens (parallellitet mulig der grafen tillater; én fase = Voyage-syklus):

  1. D-A, D-B (kan tas i samme operatør-bolk; D-C/D-D/D-E kan vente)
  2. S2.0 → S2.1 → S2.5 (ingen beslutnings-avhengighet — kan starte FØR/parallelt med D-runden)
  3. S2.7 (etter D-A + commons-pull) · S2.2 → S2.3 → S2.4 (etter D-B)
  4. D-C, D-D, D-E → S3.1 → S3.2 → S3.4 → S3.3; S3.5 etter D-F commons-amendment + koordinert med S3.2; S3.6 fritt (offline, når som helst — mater S5.4)
  5. S4.1 (når som helst) → M1 (operatør) · S4.0 → S4.2 → M2 (operatør)
  6. S5.1 → S5.2 → S5.3 · S5.4 etter S2.1 + ledger → M3 (operatør; krever også D-B-amendment + ekte ekspert + toolkit-fabrikken T0)

Ekstern avhengighet (T0 toolkit-repo, eget repo — okf-toolkit, D-G): delt OKF-modul + conformance

  • bundle-evaluator + bundle-fabrikk lever i sitt eget signatur-repo, utenfor denne sesjonskøen. Fabrikk-avhengige deler av D-F/D-H (realistisk energi-innhold via fabrikken, ekspert-dom-oversettelse, demo-sti, M3-pilot) er blokkert til T0 finnes; S3.5/S3.6/S5.4 er valgt slik at de IKKE er fabrikk-gatede.

Offline-fullførings-grensen går etter S5.3/S5.4: alt over den linjen er gratis, autonomt og load-bearing-testbart (også de nye S3.5/S3.6/S5.4). To ikke-autonome forbehold blant det nye: S3.5s commons-amendment (operatør-godkjenning + PULL-ONLY) og T0 toolkit-repoet (eget repo). M1–M3 er fortsatt de eneste stegene som koster penger, krever tenant eller krever et menneske.