Ran `repo-standard` (v0.1.1, class `standalone`) and fixed everything it flagged as ERROR, plus the WARN links that were genuinely dead. README first screen: - opening line is now byte-identical to the forge description, so description == catalog == README is machine-checkable (badges moved below). - `## Install` (required for class `standalone`): clone + `uv sync`, stated as clone-only because the shared spec, persona skill and example bundles under `shared/` are read from the working tree at run time. `uv run pytest` named as the verification, with the fact that no CI runner exists said out loud rather than implied by a badge. - `## Non-goals` (required): the five limits already binding in CLAUDE.md — not a compliance product, not a portfolio-level reallocator, not autonomous decision-making, not turnkey, not a model benchmark. Dead relative links (measured, not guessed): - `docs/plan/2026-07-10-sesjonsplan-fase2-6.md` pointed at `../2026-07-14-revisjonspakke-DF-DI.md` six times; the file sits in `docs/plan/`, not `docs/`. (The sibling `../review-2026-07.md` links are correct and untouched.) - the Fase-1 spike brief linked repo-root-relative from `.claude/projects/…/`; re-anchored with `../../../`. The one remaining README ERROR was a gate false positive: `checkInternalLinks` resolves targets against `git ls-files`, which lists files only, so a link to a directory can never resolve. `[shared/](shared/)` now points at `shared/README.md` — a better target anyway, since that file carries the pull-only subtree rule. Not fixed here: the classifier lives in another repo. Remaining WARNs are all inside `shared/`, deliberately untouched: it is a pull-only commons subtree, and the nav-golden files are byte-level fixtures that gate `test_nav_golden_*` — four of them are OKF bundle-internal links, and the `/etc/passwd` ones are the negative escape fixture doing its job. Suite green: 630 passed, 4 skipped (markdown-only diff; no test touched). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ri3aVJPfynCZtHRhesCzUH
44 KiB
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_sqler allerede den mest herdede konnektoren, read-only by construction); (3) dokument-konnektor-avgrensning: PDF-tekst viapypdf(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_versfø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_orei 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 (arbeidstittelokf-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 srcgrø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 ireference_projects.json) +verdict_dir-parameter tres gjennomrun_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 underdata/),tests/test_portfolio.py, nytests/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 undersrc/portfolio_optimiser/data/, aldri ishared/). - 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_ider 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, nyoutbox.py(ren stdlib+pydantic — MAF-fri? Nei: importerer validator-typer som er rene; holdagent_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/Rejectioner 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
mcpi 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, mirrorconnection_ref) → subtree pull → impl iingest.py. Transport: stdio-klient viamcp-pakken (allerede dep). Per-run-grant: gjenbrukallow_network-mønsteret med nytt eksplisitt flagg (per D-B). Test: in-process fixture-server (gjenbrukdatasource.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-fixtureexamples/ingest-golden-mcp/(i commons — flagg),docs/extending.md-avsnitt. - TDD: RØD: manifest med
type: mcputen 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 motpython -m-fixture med eksplisitt merking). - Verifisering:
uv run pytest tests/test_ingest_mcp*.pygrø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"};pypdfsom 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) iIngestError-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;
grepbekrefter 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 tilsimulation.pyog importér i conftest; velg det som ikke gir src→tests-import); (3) MAF-versjonsvakt: test som feiler med handlingsrettet melding hvisagent_framework.__version__ikke matcher pinnet versjon (tvinger bevisst re-verifisering av privat-API-premissene ved oppgradering); (4) pinagent-framework-core>=1.9.0,<2i pyproject. - Avhengigheter: ingen.
- Filer:
verdicts.py,conftest.py,simulation.py,pyproject.toml,tests/test_verdicts.py, nytests/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 itemetsunit_cost(low ≤ unit_cost ≤ high) — Pydanticmodel_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.pygrø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 ishared/. - 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_freeutvidet tilsemretrieval.pygrø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_verdictskriver 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 underdata/), 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=3gir BYTE-identisk aggregat + store-innhold somconcurrency=1på 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 --countel. 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 iBudgetMiddleware(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 ibundle_context: sammendrag-først (én linje per kunnskapsfil), fulltekst hentes ved behov. Streng separasjon håndheves: bibliotek viabundle_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 avtest_okf_is_maf_free), nydimension_catalog.py(loader, fail-fast),ingest.py(bibliotek-kildefamilie), commons-spec + eksempel-katalog (i commons — flagg), repo-lokal bibliotek-fixture underdata/, 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 viabundle_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 ishared/) til energi-innholdet materialiseres. - Verifisering: nye tester grønne + hvert detach-punkt → rød;
test_okf_is_maf_freeutvidet 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/BudgetMiddlewarefra 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.costsimgir 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_itemsavstemmes 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) + frareference_domain.cost_itemspå road-stien; ny avstemmings-stage ivalidate_proposal(kode finnes ikke i baseline → Rejection; quantity/unit_cost utenfor toleranse → Rejection; toleranse konfig); metode-registry: metode-caps keyes via dimensjon/konfig, ikke strengenenergy_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_ENDPOINTsatt + 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å iresolve_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_MAPsti) 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 azuregir 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); CLIpython -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 (mirrorallow_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-reportpå 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. SettPORTFOLIO_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_projectmot 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):
- D-A, D-B (kan tas i samme operatør-bolk; D-C/D-D/D-E kan vente)
- S2.0 → S2.1 → S2.5 (ingen beslutnings-avhengighet — kan starte FØR/parallelt med D-runden)
- S2.7 (etter D-A + commons-pull) · S2.2 → S2.3 → S2.4 (etter D-B)
- 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)
- S4.1 (når som helst) → M1 (operatør) · S4.0 → S4.2 → M2 (operatør)
- 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.