portfolio-optimiser/docs/plan/2026-08-06-intensjons-qa.md
Kjell Tore Guttormsen 3313e9dcaa docs(qa): the four decisions the QA surfaced, with what constrains them
The 20 claims went un-corrected, so they stand as confirmed. What the operator
actually decided were the four choices the QA exposed: hand-built example with
the factory path explicitly deferred, step 5 built and shown live, commons
ordered with a fallback, README after the demo rather than before.

Two measurements are recorded because they bound the order, not because they
are interesting: bundle_context renders every navigated file's full body, and
summary-first reading is not built -- so the full 15-30 measure library would
put 40-90k characters into every hypothesis prompt. The order is size-capped
for that reason and says so.

Also recorded: simulate_learning_loop already takes the bundle directory as a
parameter, so new content plugs into an existing seam. The cost is the scripted
replies, which are written against the LED case.
2026-08-06 13:20:52 +02:00

311 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
---
## G. Operatørens svar (2026-08-06) — de fire beslutningene planen bygger på
Påstandene A1C8 ble lagt fram og **ingen ble korrigert** → alle 20 står som bekreftet, slik
dokumentets egen regel sier. Det operatøren derimot avgjorde, var de fire valgene QA-en avdekket:
**O1 (svar på G2) — FERDIGBYGD EKSEMPEL.** Energi-eksemplet bygges for hånd og sjekkes inn i
commons. **Fabrikk-stien (D-G/T0 `okf-toolkit`) er eksplisitt utsatt** og er ute av 13.-august-stien.
Demoen viser fortsatt «last ned → kjør» — men innholdet er kuratert, ikke fabrikkert, og det er dét
som skal sies høyt. Konsekvens: D-Hs demo-sti pkt. 4 er **delvis oppfylt** i denne demoen, og
avviket hører i ærlighets-avsnittet, ikke i en fotnote.
**O2 (svar på C7) — STEG 5 BYGGES OG VISES LIVE.** Ny søm som slipper den mellomliggende
avvisningen ut av `generate_via_llm`, pluss et nytt skriptet avvis-så-korriger-forløp i
simuleringen. Estimert én økt. Begrunnelsen er fristen selv: kravet er ALLE ÅTTE STEG, og et steg
som bare omtales er ikke vist. Testbevis-varianten og den muntlige varianten ble vurdert og valgt bort.
**O3 (svar på E2) — BESTILL NÅ MED FRIST 11. AUGUST, OG PLANLEGG RESERVE.** Bestillingen sendes til
commons i dag via `coord-send`; planen får et fall-tilbake her (kjør demoen på `bygg-energi-mikro`)
som utløses hvis eksemplet ikke er hentbart 11. august. Ingen jobber i commons' repo fra denne taben.
**O4 (svar på G4) — README OPPDATERES ETTER DEMOEN (14.15. august).** Rekkefølgen D-I krever holdes:
beviset først, påstanden etterpå. Planen reserverer tid, men README røres ikke før torsdag.
### Målinger gjort etter beslutningene (grunnlag for bestillingens størrelse)
```
$ uv run python -c "okf.navigate_bundle('shared/examples/bygg-energi-mikro') → bundle_context"
context_files: 4 · chars: 12005 · ≈ 3001 tokens
kilder-realiseringsgap.md (reference) 3519 · bygg-kontor-nord.md (project) 1594
tiltak-led-retrofit.md (hypothesis) 3007 · metode-ipmvp-a.md (methodology) 1759
```
To konsekvenser bestillingen MÅ bære, begge målt og ingen av dem valgfrie:
- **`bundle_context` rendrer HELE brødteksten i hver navigert fil** (`okf.py:206233`), og
**trinnvis sammendrags-lesing (D-F pkt. 6) er ikke bygget.** D-F pkt. 7s fulle ambisjon —
1530 tiltak i ett bibliotek — ville derfor gitt 4090 000 tegn (1022 k tokens) inn i HVER
hypotese-prompt, under harde token-tak. `dimension`-filteret hjelper ikke, siden alt her er
samme dimensjon. Bestillingen må derfor være **størrelses-kappet**, og det fulle biblioteket
forblir den «egne senere innholds-produksjonsjobben» D-F pkt. 7 selv navngir.
- **D-F pkt. 4 løser dette strukturelt:** delt bibliotek *materialiseres inn i hver
prosjekt-bundle*. Flere prosjekter = flere bundles, ikke én stor. Det holder per-kjøring-
konteksten nede OG gir porteføljestien (bølger, budsjett, hovedbok) noe ekte å kjøre på.
**Innplasserings-funn (godt nytt for planen):** `simulate_learning_loop(bundle_dir, …)`
(`simulation.py:183`, kalt `:293`) tar bundle-katalogen som **parameter** og kopierer den til en
arbeidskatalog. Et nytt eksempel plugges altså inn i en eksisterende søm. **Men** de skriptede
svarene er skrevet mot LED-caset, så nytt innhold krever nytt manus — den koblingen er planens
egentlige kostnad ved O1, ikke selve bundle-innlesingen.
### Fortsatt ubesvart (ikke blokkerende — anbefaling gjelder ved taushet)
- Dette dokumentet til den offentlige speilingen? **Anbefaling: nei** (intern analyse).
- Tracking av `.claude/projects/`? **Anbefaling: nei** (uendret fra tidligere økter).