docs(qa): the repo's intention, stated as claims the operator can correct

The demo-week brief was written by a session that read its way to the
intention through documents other sessions had written. Two of its frames
were overturned by the primary sources inside one conversation, so the
operator stopped planning and commissioned this: read the primary sources
directly, state the understanding back as numbered claims, and capture the
corrections where they survive.

Six gaps in the picture the brief rests on, all measured rather than argued:

- The intention has a SECOND axis that STATE's list of five primary sources
  never named. review-2026-07 (F1-F14) and sesjonsplan-fase2-6 (S2.0-S5.4,
  D-A-D-I, M1-M3) are where most of the repo's 31 modules come from: 20
  S-numbers, 18 with hits in src/+tests/. A plan written from the five named
  sources alone would describe a repo with eight steps and miss two thirds
  of what is there.
- D-H's DECIDED demo path ("clone -> unzip -> factory builds -> loop runs")
  is factory-dependent, and the factory (D-G/T0, `okf-toolkit`) does not
  exist -- measured, not assumed. The brief's "anyone who downloads the repo
  can run exactly the same" IS that path.
- The realistic example's content model is already decided (D-F): knowledge
  types with required source citation, strict separation from the verdicts.
  The commission to commons must reference it, not invent one.
- The demo is the programme's level-2 publishing proof (D-I), with an
  honesty ceiling agreed in advance and a README update as its consequence.
- The shared spec covers the loop + ingest and NONE of the surplus: mandate,
  notify, ledger, value report, cost simulation, dimension, portfolio
  budget, concurrency, preflight all measure 0 mentions. The comparison is
  therefore of the SPEC'd core, not of this repo.
- Step 5 is not a presentation-layer concern: `generate_via_llm` consumes
  the intermediate rejection internally, and today's demo validates on the
  first attempt, so the refinement never triggers. Steps 2 and 6 ARE
  printable from data RunResult already carries.

Two inventory numbers spot-checked independently (759 collected; the offline
simulation re-run, output identical). Nothing here is sourced from STATE.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvjgY5NBg16D7kgQf14s6B
This commit is contained in:
Kjell Tore Guttormsen 2026-08-06 13:09:29 +02:00
commit 8ecfa96934

View file

@ -0,0 +1,254 @@
# Intensjons-QA — forståelsen av repoet, lagt fram som korrigerbare påstander
> **Hva dette er.** Operatøren stoppet planleggingen 2026-08-06 fordi briefen til demo-uken var
> skrevet av en økt som *leste seg til* intensjonen fra dokumenter andre økter hadde skrevet — og to
> av rammene ble snudd av primærkildene innenfor én samtale. Denne økten leste primærkildene selv og
> legger forståelsen fram som **påstander med kilde**, slik at det koster operatøren én linje å rette
> hver enkelt.
>
> **Slik brukes den:** svar med nummer. «A3 er feil — det er slik: …». Alt du ikke kommenterer,
> regnes som bekreftet og blir grunnlag for planen.
>
> **Ingen påstand her er hentet fra `STATE.md` eller fra hukommelse.** Hver påstand står med kilden,
> og hvert tall med kommandoen som produserte det.
## 0. Kilder lest i sin helhet, og målinger gjort
Lest i sin helhet i dag: `docs/plan/2026-06-26-maalbilde-agentic-loop.md` ·
`shared/method-spec.md` · `shared/ingest-spec.md` · `shared/CONCEPT.md` ·
`docs/plan/2026-07-03-sammenligningsprotokoll.md` · `docs/research/2026-06-23-prior-art-platform.md`
§11§15 · `docs/plan/2026-08-06-v1-inventory.local.md` · `docs/plan/2026-08-06-v1-demo-brief.local.md`.
Lest strukturelt (overskrifter + de avsnittene påstandene nedenfor hviler på):
`docs/review-2026-07.md` · `docs/plan/2026-07-10-sesjonsplan-fase2-6.md` · `docs/extending.md`.
Målinger kjørt i denne økten, på HEAD `520e741`:
```
$ uv run pytest -q --collect-only | tail -1
759 tests collected in 0.49s # = inventarets 755 passed + 4 skipped ✔
$ uv run python -m portfolio_optimiser.simulation # exit 0, offline, uten nøkkel/nettverk ✔
# output identisk med inventarets gjengivelse
$ ls ~/repos | grep -iE "okf|toolkit|commons|portfolio"
_okf-interim _okf-upstream llm-ingestion-okf llm-ingestion-pipeline-security
portfolio-optimiser portfolio-optimiser-claude portfolio-optimiser-commons
# MERK: ingen okf-toolkit (se G2)
$ grep -ci -- "<begrep>" shared/method-spec.md shared/ingest-spec.md
mandate 0/0 · notify 0/0 · ledger 0/0 · "value report" 0/0 · "cost simulation" 0/0 ·
dimension 0/0 · "portfolio budget" 0/0 · concurren 0/0 · preflight 0/0 # se G5
```
To inventar-tall er altså stikkprøvet uavhengig (test-antall, simuleringen), og begge holdt.
---
## A. Intensjonen — hva repoet skal være
**A1. Metoden er produktet, ikke koden.** Leveransen er en metode: sverm av agenter genererer
kandidat-tiltak → obligatorisk deterministisk validator avgjør tallene → fageksperter dømmer via
HITL → systemet lærer av dommene. *(målbilde §1; `method-spec` §1)*
**A2. Problemet er *inne i* hvert prosjekt, aldri på tvers.** Porteføljen er uavhengige prosjekter;
å behandle porteføljen som ett system er eksplisitt anti-scope. *(målbilde §1; research §15.5 A8;
README «Not a portfolio-level reallocator»)*
**A3. Differensiatoren er læringssløyfa, og den krever et domene med lærings-overflate.** Energi
ble valgt fordi det finnes et ekte gap mellom det *beregnbare* (modellert besparelse) og det
*ekspert-kjennbare* (realiseringsgapet). FinOps ble forkastet som «for deterministisk» — der ville
sløyfa blitt dekorativ. *(målbilde §10 D-DOMENE; `CONCEPT.md` «Konkret»)*
**A4. Tillitsankeret er at agentene aldri får avgjøre verdien.** Validatoren er den ene
endpoint-frie dommeren, og den er obligatorisk og blokkerende — aldri en anbefalt plugin.
*(målbilde §6; `method-spec` §3 Steg 4; research §15.5 A5)*
**A5. Formålet er operatørens læring, men kvalitetskravet er publiseringsklart.** Grunnregelen er
at koden ikke får påstå mer enn den gjør — en docstring som lover læring over en usammenkoblet
sløyfe er i seg selv en defekt. *(målbilde §1; `method-spec` §1 «Honesty rule (unwaivable)»)*
**A6. Sluttleveransen på programnivå er en *rettferdig sammenligning* av to stacker på identisk
metode og identisk datagrunnlag — men hver implementasjon skal også stå selvstendig som brukbar.**
*(målbilde §1; `sammenligningsprotokoll` §1§2)*
**A7. Liveness-asymmetrien er en låst programbeslutning, ikke et kostnadsvalg som kan revurderes.**
MAF-siden kjøres ALDRI mot ekte modell; dens bevis er et skriptet offline-bevis av plumbing,
deterministisk ryggrad og lukket læringssløyfe. Claude-siden kjører ÉN minimal ekte API-kjøring som
programmets eneste genuine modell-atferdsbevis. Erklæringen gjengis **ordrett** i sluttrapporten.
*(`sammenligningsprotokoll` §3 — dette er kilden som snudde min forrige ramme)*
**A8. Rammeverket er rent teknisk.** Deployeren eier DPIA/ROS/behandlingsformål; vi bygger kun de
tekniske forutsetningene (lokal-only default, provenance, ingen stille egress) + disclaimer.
*(målbilde §6; `method-spec` §1 «Boundary»; `ingest-spec` §1)*
**A9. Det delte eksemplet er felles og bygges én gang.** OKF-bundles + golden-suite +
ekspert-persona er delt kjerne mellom de to repoene; `shared/` her er pull-only subtree av
`portfolio-optimiser-commons`. *(målbilde §8§9; CLAUDE.md konvensjoner)*
---
## B. Prosessen — hvordan arbeidet faktisk styres
**B1. Det finnes to nivåer, med vilje.** Program-nivå = målbildet (definerer «ferdig», endres
sjelden). Fase-nivå = én Voyage-syklus per inkrement (`/trekbrief → /trekresearch → /trekplan →
/trekexecute → /trekreview`), der `/trekreview` er anti-drift-mekanismen. *(målbilde §0)*
**B2. Spec-ene er normative og skrevet for å kunne implementeres «from this spec alone».** De er
framework-nøytrale ved regel, håndhevet av guard-tester. Det er dét som gjør en rettferdig
sammenligning mulig i det hele tatt. *(`method-spec` topptekst + §11; `ingest-spec` topptekst)*
**B3. «Ferdig» er definert som load-bearing-tester, ikke som features.** En søm regnes ikke som
bygget før en test **feiler** når sømmen kobles fra — «grønn-men-død» er den navngitte fellen.
*(målbilde §6§7; `method-spec` §11 med 12 påkrevde rød-betingelser)*
**B4. Ingen ubegrenset løkke, noe sted, og tak kreves ved oppstart.** All konfig valideres fail-fast
FØR noen modellklient konstrueres. *(målbilde §6; `method-spec` §8 + §10)*
**B5. Kostnadsdisiplin er en designramme, ikke en preferanse.** Utvikling skjer offline/lokalt;
M1M3 er de eneste stegene som koster penger, krever tenant eller krever et menneske.
*(`sesjonsplan-fase2-6` §4 + §5-fotnote; CLAUDE.md)*
**B6. Metoden skal kunne konsumeres av andre som en Agent Skill, og ekspert-personaen ER en slik
skill.** `shared/skills/expert-reviewer/` er den ene delte artefakten begge stacker instansierer
reviewer-en fra; `shared/` forblir ren data. *(`method-spec` §4.3; CLAUDE.md)*
**B7. Datatilgangen har én arkitektonisk konsekvens som binder alt annet: data når modellen KUN
via OKF-bundles.** Ingen query-tid-retrieval mot bundelen, ingen RAG i kjørestien. Konnektorene
lever derfor i et deterministisk ingest-steg FØR optimalisereren. *(`ingest-spec` §1§2;
`method-spec` §3 Steg 1)*
---
## C. Hvilke features som faktisk finnes (målt, ikke antatt)
**C1. Alle åtte steg er wiret, og målbildets egen «ferdig»-definisjon er oppfylt for løkka.** De fem
load-bearing-testene målbilde §7 krever (steg 1, 3/4, 5, 7, 8) finnes som egne filer og suiten er
grønn (759 kollektert, 755 passed / 4 skipped). *(målbilde §7; inventaret + min egen måling)*
**C2. Simuleringen er det primære metode-beviset, den kjører, og den er allerede demo-formet.**
`uv run python -m portfolio_optimiser.simulation` kjører offline til exit 0 og viser to kjøringer
adskilt av en promotering, der markøren `realiseringsgrad=0.79` er `False` i Run A og `True` i Run B.
*(målt i dag; `simulation.py`-docstring)*
**C3. Ingest-laget er reelt, men implementasjonen bor i et ANNET repo.** `llm-ingestion-okf` er en
deklarert runtime-dep («the shared implementation of `shared/ingest-spec.md`»), og dette repoets
`ingest.py` (202 linjer) er konsument-sømmen over den. Fire golden-ekstraksjoner finnes lokalt
(`file`, `sql`, `http`, `mcp`). *(`pyproject.toml`; `examples/ingest-golden-*`)*
**C4. Repoet er vesentlig større enn de åtte stegene.** 31 moduler / 7871 linjer i `src/`, 88
testfiler, 42 load-bearing-filer — mot `method-spec` §11s 12 påkrevde sømmer. Overskuddet er ekte
kapasiteter: mandat (`mandate.py`), outbox (`outbox.py`), hovedbok (`ledger.py`), verdirapport
(`value_report.py`), kostnadssimulering (`costsim.py`), semantisk henting (`semretrieval.py`),
dimensjons-gating (`dimension.py`), HITL-ruting (`hitl.py`), varsling (`notify.py`),
portefølje-budsjett (`budget.py`), concurrent fan-out, Foundry-preflight (`preflight.py`),
MCP-verktøy i kjørestien (`mcp_tools.py`). *(inventaret; docstring-måling i denne økten)*
**C5. Det finnes ingen konsoll-kommando.** `[project.scripts]` er tom/fraværende i `pyproject.toml`
— alt kjøres som `uv run python -m …`. Målbilde §11 pkt. 7 fører `[project.scripts]` opp som
release-hygiene, og det er ikke gjort. *(målt: `grep -n scripts pyproject.toml` → ingen treff)*
**C6. Eksempelet som finnes i dag er mikro, og hele det delte laget er lite.** `shared/` har 45
filer, hvorav eksempel-bundelen `bygg-energi-mikro` er 8 filer (én kandidat, ett frø-verdict).
Simuleringen kjører dessuten i en temp-katalog, ikke på noe som ligger igjen i repoet.
*(målt; inventaret pkt. 2)*
**C7. Steg 2 og 6 kan gjøres synlige fra data som allerede finnes; steg 5 kan det IKKE.** Hele
presentasjonen er ~30 `print`-linjer (`simulation.py:295326`) over et `RunResult` som bærer
`outcome` (typet `ValidatedProposal | Rejection`), `verdict`, `retrieved`, `debate_output`,
`checker_verdict` og `coverage`. Men `generate_via_llm` returnerer bare sluttresultatet — den
mellomliggende avvisningen (`last`) forbrukes internt og forlater aldri funksjonen. **Og i demoen i
dag validerer forslaget på FØRSTE forsøk**, så forbedrings-løkka trigges ikke i det hele tatt.
Å vise steg 5 krever derfor både en ny søm og et nytt skriptet avvis-så-korriger-forløp — ikke
bare en `print`. *(målt i `simulation.py`, `run.py:115133`, `generate.py:134196`)*
**C8. Kosmetikken i inventaret er bekreftet.** To `GroupChatOrchestrator reached max_rounds=3;
forcing completion.`-linjer og to MAF `ExperimentalWarning`-linjer skrives FØR banneret.
*(målt i dag, identisk med inventaret)*
---
## D. Fem gap i bildet briefen hviler på — det QA-en fant
Rammene A/B/C i briefen står. Det som var galt, var **bildet under dem**.
**G1. Intensjonen har en andre akse som ikke sto på listen over primærkilder.** STATE pekte på fem
kilder (målbilde, research §15, `method-spec`, sammenligningsprotokoll, `ingest-spec`). Ingen av dem
nevner roadmap-aksen — og det er DEN de fleste modulene i C4 kommer fra:
`docs/review-2026-07.md` (uavhengig kryssmodell-review, funn F1F14 langs fire akser) og
`docs/plan/2026-07-10-sesjonsplan-fase2-6.md` (S2.0S5.4, beslutningene D-AD-I, milepælene M1M3,
roadmap C/D/E). Målt kobling: 20 S-numre, 18 av dem med treff i `src/`+`tests/`. **Konsekvens:** en
plan skrevet fra de fem kildene alene ville beskrevet et repo med åtte steg, og ikke gjenkjent to
tredeler av det som står der.
**G2. Den besluttede demo-stien er fabrikk-avhengig, og fabrikken finnes ikke.** D-H (BESLUTTET
2026-07-14) definerer demo-stien ordrett: «klon → unzip energi-eksempel i bundle-innboks → fabrikk
bygger → hele sløyfa kjører». Fabrikken er D-G/T0 — et eget repo med arbeidstittel `okf-toolkit`,
som per måling **ikke eksisterer** (`ls ~/repos`). Sesjonsplanen sier eksplisitt at
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. Briefens krav «enhver som laster
ned repoet skal kunne kjøre nøyaktig det samme» ER den demo-stien. **Konsekvens:** planen må velge
eksplisitt — ferdigbygd bundle sjekket inn i commons (fabrikk ute av 13.-august-stien), eller
akseptere at stien er blokkert. Briefen min nevnte T0 ikke med ett ord.
**G3. Innholdsmodellen for det realistiske eksemplet er allerede besluttet.** D-F (BESLUTTET
2026-07-14, fasit i `2026-07-14-revisjonspakke-DF-DI.md` §1): 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 materialisert inn i
hver bundle via ingest-mønsteret, trinnvis lesing. Samme beslutning sier at **realistisk
energi-innhold er «egen senere innholds-produksjonsjobb»** — altså en allerede planlagt jobb i
programmet, ikke ny scope. **Konsekvens:** bestillingen til commons skal referere D-F, ikke definere
en innholdsmodell på nytt. En bestilling som finner opp sin egen struktur ville satt commons i
konflikt med sin egen beslutning.
**G4. Demoen er programmets nivå-2-bevis, med et forhåndsavtalt ærlighetstak.** D-I (BESLUTTET
2026-07-14): publiserings-påstanden er **nivå 2** — realistisk case, modellerte tall, aldri
salgsspråk over beleggsnivået; nivå 3 (ekte pilot) er en åpen invitasjon. Og: «README oppdateres
FØRST når nivå-2-beviset finnes». **Konsekvens:** 13. august er ikke bare en presentasjon, det er
milepælen som utløser en README-oppdatering — og formuleringene i demoen er bundet av et tak som
allerede er avtalt. Det gjør ærlighets-leveransen i ramme A til et *eksisterende* krav, ikke et nytt
påfunn.
**G5. Den delte spec-en dekker løkka + ingest — ingenting av C4-overskuddet.** Målt: `method-spec`
og `ingest-spec` nevner *ikke* mandat, varsling, hovedbok, verdirapport, kostnadssimulering,
dimensjon, portefølje-budsjett, concurrency eller preflight (0 treff hver). **Konsekvens for A6:**
sammenligningen er en sammenligning av den **spec-ede kjernen**, ikke av dette repoet. Et søsken
bygget «from spec alone» ville ikke hatt disse. Det er ikke nødvendigvis feil — men det er en
påstand om sammenligningens rekkevidde som må stå eksplisitt i sluttrapporten, og D7-speilings-
gjelden (CLAUDE.md: S2.7, S3.2, S4.0, (p), (a)/(i), `mandate.py`, A5, B4 — søskenet har ikke svart)
er den samme saken sett fra andre siden.
**G6 (mindre, men styrer en formulering).** S3.5 er i praksis ikke bygget: eneste treff i kode er en
kommentar i `hitl.py:169` om en «minimal MVP stand-in for the S3.5 dimension catalog», og S3.5 er
gated på et commons-amendment som per CLAUDE.md aldri kom. Dimensjonskatalogen er altså et
stand-in, ikke den besluttede delte modellen. *(målt: `grep -rn S3.5 src/ tests/`)*
---
## E. Det jeg IKKE kunne verifisere — ingen hull fylt med antakelser
1. **CHANGELOG-ens `[0.1.0]`** — ~30 tekniske påstander, allerede publisert, ikke uavhengig
kontrollert av noen. Jeg har ikke gått gjennom dem i denne økten.
2. **Commons' egen tilstand og beslutningskø.** Jeg ser bare de 45 filene subtree-en har hentet, og
`shared/docs/plan/` viser at commons har en aktiv egen beslutnings-prosess (ti plan-dokumenter,
nyeste 2026-08-02). Om commons har kapasitet 7.13. august, vet jeg ikke — og jeg kan ikke se det
herfra.
3. **Søsken-repoets faktiske tilstand.** `portfolio-optimiser-claude` eksisterer som katalog; hva
som er bygget der, har jeg ikke undersøkt (ramme B parkerer det uansett).
4. **Om `_okf-interim` / `_okf-upstream` er forløpere til T0** eller noe annet. Jeg har ikke sett i
dem — de ligger utenfor dette repoet.
5. **Realiserings-kostnaden av C7** (ny søm for steg 5) er ikke estimert; det hører i planen.
---
## F. Hva denne QA-en endrer for planleggingsøkten
Ikke rammene — de står. Men fire ting planen nå må gjøre som briefen ikke ba om:
1. **Behandle T0/fabrikken eksplisitt (G2):** velg ferdigbygd bundle, og si at fabrikk-stien er
utsatt — ellers planlegges det mot en blokkert avhengighet.
2. **Bestillingen til commons refererer D-F (G3)** i stedet for å definere innhold på nytt.
3. **Steg 5 er ikke presentasjonslag (C7):** ny søm + nytt skriptet forløp. Steg 2 og 6 er
presentasjon.
4. **Nivå-2-taket (G4)** blir demoens ærlighets-ramme, og README-oppdateringen er en konsekvens som
skal med i planen — eller eksplisitt utsettes.