portfolio-optimiser/docs/plan/2026-08-09-egnethetsreview-plan.md
Kjell Tore Guttormsen 33f0a6857d docs(plan): §0 splits the week into two tracks — complete v1 by Thursday, and the demo
Operator decision 2026-08-09. Track 1 (complete v1, incl. other repos):
S1.a = P1 step-7 inbox, S1.b = P2 content gate, S1.c = release cut
(1.0.0 synced in four places, CHANGELOG, [project.scripts] moved in from
P9, tag only AFTER a green dress rehearsal). Other-repo accounting is
measured: commons already ordered with the Tuesday deadline and a
reserve, okf/guard/po-claude need nothing — no new coord message. Each
post carries a named degradation so v1 stays honestly complete at every
level. Track 2 (convincing demo): P3 + P4 + rehearsal + one spoken
mandate sentence, optional stderr-noise muting before the freeze. The
O4-vs-tag conflict is flagged for the operator, not decided.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019xhQpH4oQBaf8dxCkXuB8Z
2026-08-06 23:30:01 +02:00

211 lines
15 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.

# Egnethetsreview → plan — funnene gjort varige, én økt av gangen
> **Hva dette er.** Fable-reviewen (2026-08-09, kjørt fra
> `2026-08-09-fable-egnethetsreview-prompt.md`) leverte funnene sine i et chat-transkript som
> forsvinner. Dette dokumentet er den varige formen: hvert funn i klarspråk, med belegget som
> produserte det, rangert som en plan `STATE.md` peker inn i økt for økt. Chatten kan glemmes —
> alt som trengs står her.
>
> **Slik brukes den:** `STATE.md`s «👉 NESTE»-blokk peker alltid på det ØVERSTE ulukkede
> P-punktet her. En økt lukker et punkt → setter ✔ med commit-hash HER → overskriver STATE.md →
> neste økt leser videre. **Demo-uke-planen (`2026-08-06-demo-uke-plan.md`) og innholdsgate-planen
> (`2026-08-09-innholdsgate-og-aerlighet.md`) BESTÅR uendret** — denne planen føyer review-funnene
> inn i samme løp og flytter ingenting som er besluttet (O1O4 står).
>
> **Voyage:** småjobber (≤1 økt, kjent sti) kjøres direkte med `/tdd`-disiplin. Full
> Voyage-syklus (`/trekbrief → /trekplan → /trekexecute → /trekreview`) brukes der et punkt er
> merket **[Voyage]** — punktene med reell design-usikkerhet eller ≥2 økters bygging.
## 0. TO SPOR (operatørbeslutning 2026-08-09 — overordner rekkefølgen under)
Operatøren har delt uka i to spor. P-punktene under består, men hører nå hjemme slik:
### SPOR 1 — KOMPLETT VERSJON 1, klar til torsdag 13. (inkludert andre repo)
v1 = den **målte kjernen** (alle åtte steg wiret, 42 load-bearing-testfiler, 766/770 grønn —
inventaret i `2026-08-06-v1-inventory.local.md`) + to lukkinger + release-kuttet:
| Post | Innhold | Kost | Nedgradering hvis tid/kvote ryker |
|---|---|---|---|
| S1.a = **P1** | Steg 7-innboksen inn i demoløpet | 1 økt | ærlig etikett (0,1 økt) |
| S1.b = **P2** | Innholdsgaten (Spor B) | 12 økter | NEI-varianten i ærlighets-teksten (ferdigskrevet) |
| S1.c (ny) | **Release-kuttet:** versjon `1.0.0` synket FIRE steder (`pyproject`/`__init__`/`uv.lock`/`test_smoke`) + CHANGELOG (`[Unreleased]` → 1.0.0; Steg-5-API-endringen står alt der) + `[project.scripts]`-entry (flyttet HIT fra P9 — release-hygiene, målbilde §11 pkt. 7) + tag `v1.0.0` på begge remotes ETTER grønn generalprøve | 1 økt (ons kveld) | tag fredag i stedet — aldri tag før grønn generalprøve |
**Andre repo — hva som faktisk MÅ gjøres der (målt, ikke antatt):**
- **commons:** energieksemplet MED `cost-baseline.json` — ALLEREDE bestilt (frist tir 11.,
coord `20260806T112037Z…`); GO/NO-GO tirsdag står. Reserven (mikro) gjør at v1 ALDRI
blokkeres av commons: **rammeverket er v1, innholdet er data.**
- **llm-ingestion-okf:** ingenting — pinnet `v0.3.2` gjennom v1 (målt at den holder).
- **guard-repoet:** ingenting — `v0.3.4` finnes, stdlib-only; wiringen skjer HER (S1.b).
- **po-claude:** PARKERT (ramme B) — v1 er MAF-siden alene, og det SIES i release-notatet.
**Ingen ny coord-melding trengs.** Alt andre-repo-arbeid er enten bestilt eller ikke nødvendig.
**Flagget konflikt (operatøren eier den):** O4 sier README-løftet kommer ETTER demoen (frelør).
Anbefaling: tag `v1.0.0` onsdag med nøktern README-status; nivå-2-påstanden inn i README fre/lør
som besluttet. Beviset først, påstanden etterpå — det gjelder også taggen.
**EKSPLISITT UTE av v1 (sies i release-notatet, ikke i en fotnote):** CLI-porteføljetak (P6),
commons-amendmentene (P7), metode-skillen (P8), bestiller-flaten (åpen beslutning i STATE),
bundle-fabrikken (O1), søsken-repoet (parkert), okf `v0.4.0`+.
### SPOR 2 — KOMPLETT OG OVERBEVISENDE DEMO av alle åtte steg
= **P3** (GO-dag + kostnads-sjekk-prøven) + **P4** (fresh-clone-/stderr-/golden-kriterier + to
ærlighets-setninger) + generalprøven + én **muntlig** mandat-setning (bestillingsflyten er svaret
på «kan vi styre hva som analyseres?» — `docs/bestille-en-kjoring.md`). Valgfritt før frys
(0,1 økt — inventarets kosmetikk-funn «leser som en feil i en sal»): demp de fire
stderr-støylinjene i `simulation.main` (logging-/warnings-filter; rører ikke stdout, altså ikke
kriterium 6). Ellers nevnes de høyt.
**Økt-regnskap for uka i dette repoet:** S1.a (1) + S1.b (12) + S1.c (1) + P3 (0,25) +
P4/generalprøve (0,50,75) ≈ **3,754,75 økter.** Ved kvotepress er nedgraderingskolonnen
rekkefølgen — v1 forblir ærlig komplett på hvert nivå, den blir aldri stille ufullstendig.
## 1. Funnene i klarspråk
Reviewen fant ingen brann i koden: suiten er grønn (766 passed / 4 skipped), demo-outputen er
byte-identisk over to kjøringer, og alle åtte steg har sin merkede linje. Det den fant, er fire
steder der **demoen lover mer enn den viser**, og noen hull i sikkerhetsnettet rundt torsdag.
**Funn 1 — kostnads-sjekken har aldri kjørt på ekte innhold.**
Validatoren KAN avstemme et forslag mot prosjektets faktiske kostnadstall (S4.0), men sjekken
aktiveres bare når kunnskapsbasen shipper `cost-baseline.json` — og **ingen bundle i repoet har
den fila** (målt, §4 rad 3). I dagens demo regner validatoren derfor kun på tall forslaget selv
oppgir. Bestillingen til commons krever fila (bra) — men første gang sjekken møter ekte innhold
blir på leveransedagen, og avviker manus-tallene mer enn 5 % fra de leverte kostnadstallene,
avvises BÅDE det overdrevne og det korrigerte forslaget på scenen. Og reserven (mikro-eksemplet)
kan aldri få fila, så NO-GO-tilfellet trenger sin egen ærlige setning.
**Funn 2 — demoen sier «fil-innboks for ekspertdommer», men bruker den ikke.**
Steg 7-linja i demoen sier «lang fil-løkke». I virkeligheten leveres dommen som et
funksjonsargument — `simulate_learning_loop` kaller `run_project` uten `verdict_dir`
(§4 rad 4). Fil-innboksen finnes og er testet (`test_step7_async_loop_loadbearing.py`), men
demoen kjører den ikke. Dette er samme klasse som Steg 5 var før 7. august: **et steg som
omtales er ikke vist.**
**Funn 3 — «last ned og kjør» er aldri testet fra en fersk nedlasting.**
Ingen av de åtte demo-kriteriene kjører fra en ren klone. `uv.lock` finnes, så beviset er én
kommandosekvens — og den fanger miljøavhengigheter (`PORTFOLIO_SHARED_ROOT` re-peker
kunnskapsbasen!), utrackede filer og lokal `.venv`-drift.
**Funn 4 — små presisjonshull i det som sies og vises.**
Kjøring A kalles «fersk kunnskapsbase, ingen tidligere dommer», men bundelen shipper ett
dom-frø, og Kjøring B viser «2 dommer» der bare én kom fra sløyfa — én muntlig setning retter
det. Stderr-støyen (to warnings + to «forcing completion») er det første publikum ser.
**Etter demoen (feature-settet):**
- **Funn 5:** porteføljekjøring fra kommandolinja har ikke noe samlet token-tak — taket finnes i
biblioteket (`PortfolioMeter`, seks målte mutasjoner), men `main()` kobler det aldri på; koden
sier det selv (§4 rad 6).
- **Funn 6:** spec-gjelden mot commons/søskenet vokser — seks lokale semantikk-beslutninger er
uspeilet (D7-speiling ÅPEN i CLAUDE.md), og «rettferdig sammenligning» (A6) blir mindre sann
for hver av dem.
- **Funn 7:** «metoden som Agent Skill» er en CLAUDE.md-konvensjon uten realisering — kun
ekspert-personaen finnes (§4 rad 5).
- **Funn 8:** `[project.scripts]` mangler (release-hygiene, målbilde §11 pkt. 7).
- **Null-funn:** bytte av orkestrering (Sequential/Handoff/graf-laget/checkpointing) skal IKKE
gjøres — målt: debatten er i praksis en fast sekvens og Group Chat beholdes av byttekost-grunner,
gevinsten er kosmetisk, kostnaden er re-verifisering av hele offline-beviskjeden (§4 rad 78).
## 2. Plan FØR demoen (P1P4, i utførelsesrekkefølge)
### P1 — Steg 7-innboksen kobles på i demoen ☐
**[1 økt · Opus 5/high · TDD direkte · MÅ lande før onsdags-frysen]**
Rute persona-dommen gjennom en faktisk `verdict_dir`-katalog i `simulate_learning_loop`
sømmene finnes allerede (`run_project(verdict_dir=…)` + `write_verdict` er offentlig primitiv).
Ny load-bearing-test: detach innboks-lesingen → markør-/Steg 7-linja endres → RØD. Kriterium 6
(byte-identisk stdout) måles på nytt etterpå.
**Faller den på tid:** minimumsvarianten = ærlig etikett i `_run_trace_lines` («dom levert
direkte her; fil-innboksen er samme søm, bevist i test») + én muntlig setning. 0,1 økt.
### P2 — Spor B: innholdsgaten ☐
**[12 økter · Opus 5/high · TDD direkte · følger innholdsgate-planen §3§4 uendret]**
Reviewens skjerpelse, ellers ingen endring: §4-beslutning 2 (avvisning per dokument eller per
bundle?) tas FØR bygging, og innholdsgate-planens kriterium 5 (byte-uendret demo-stdout) måles
ETTER wiring. Målt frys-sikker: verken `run.py` eller `simulation.py` importerer `ingest`.
### P3 — Tirsdag 11.: GO/NO-GO + kostnads-sjekk-prøven ☐
**[0,25 økt, del av tirsdagsøkta · Opus 5/medium]**
Som demo-uke-planen — PLUSS to tillegg fra funn 1: (a) kjør demo-kriterium 1+2 (åtte
steg-linjer; REJECTED- og VALIDATED-linje for samme kandidat) mot den NYE bundelen allerede
tirsdag, ikke først onsdag; (b) skriv manus-registerets tall FRA den leverte
`cost-baseline.json`, aldri ved siden av den. Dette er første gang S4.0-forankringen kjører på
ekte innhold. **Prøve som feller feil:** kjør sim mot ny bundle med bevisst 10 %-avvik i
manuset → skal gi FORKASTET; korrigert → FORESLÅTT.
### P4 — Onsdag 12.: tre nye kriterier + to setninger, så generalprøve og FRYS ☐
**[0,5 økt, del av generalprøve-økta · Opus 5/low]**
1. **Fresh-clone-kriterium:** klon til scratch → `uv sync` → kjør simuleringen → diff mot
arbeidskopiens output. Beviser «last ned → kjør»-påstanden.
2. **Stderr pinnes:** de fire kjente linjene er fasit; nye advarsler etter subtree-pull fanges.
3. **Golden-transkript:** sjekk inn demo-outputen som fasit-fil og diff mot den — selvidentitet
(kriterium 6) fanger ikke-determinisme, men ikke regresjon mellom onsdag og torsdag.
4. **To ferdigskrevne setninger** inn i ærlighets-teksten (mønsteret fra innholdsgate-planen §5):
NO-GO-varianten «kostnads-forankringen er ikke aktiv i reserve-eksemplet», og frø-setningen
«én av de to tidligere dommene i Kjøring B fulgte med eksempelet — den andre er den demoen
lærte».
## 3. Plan ETTER demoen (P5P10, i verdirekkefølge)
### P5 — README + nivå-2-påstanden (O4, fre 14.lør 15.) ☐
**[1 økt · Opus 5/medium]** Allerede besluttet (O4). Reviewens tillegg: G5-forbeholdet skal stå
i teksten som løftes — sammenligningen mot søskenet gjelder den spec-ede kjernen, ikke hele
dette repoet (mandat/hovedbok/portefølje-budsjett m.m. er utenfor spec-ene, målt 0 treff).
### P6 — Globalt token-tak inn i CLI-en ☐
**[1 økt · Opus 5/high · TDD direkte]** `--budget`-dør i `main()`: `PortfolioMeter` +
`read_spend`/`write_spend`-wiring + `BudgetRefused` inn i except-tuplen (TRAP-kommentaren i
`run.py` sier selv at den ikke fanges i dag). Feller: CLI-test med spend-fil nær taket +
`--portfolio` → strukturert refusal; detach flagget → rød.
### P7 — Amendment-pakken til commons — ÉN samlet bestilling ☐
**[1 økt · Fable 5/high (spec-review er formen) · leveres via coord-send, ALDRI arbeid i commons]**
D-A-restene samlet i én tekst: F2/F3-validator-semantikken, S3.2-seedingregelen,
S4.0-baseline-formatet, (p)-kvantiseringen, Steg-5-returtypen. Feller: amendmentet gir
spec-tester/goldens som binder semantikken på tvers av stackene — i dag kan søskenet følge
spec-en korrekt og likevel divergere fra dette repoet.
### P8 — Metoden som Agent Skill (B6) ☐ **[Voyage]**
**[/trekbrief først; bestilling til commons + liten konsum-søm her]** Målt: kun
`shared/skills/expert-reviewer/SKILL.md` finnes. Innholdet eies av commons (bestilling som
tekst); konsum-sømmen her er liten (MAF `SkillsProvider` er experimental — pin versjon).
[Voyage] fordi formen har reell design-usikkerhet — hva av metoden som skal være skript vs.
referanse er ikke avgjort.
### P9 — Småting ☐
**[0,5 økt samlet · Opus 5/low]** Kapabilitetskartets to korreksjoner (topologi-notatet fra
funn «null»: debatten er en fast sekvens, Group Chat beholdes av byttekost; checkpointing-raden
nedgraderes fra «ADOPT (later)» til «NEI med begrunnelse» — pass-nivå-gjenopptakelse er allerede
levert via spend-fila). *(`[project.scripts]` er flyttet inn i v1-release-kuttet, §0 S1.c.)*
### P10 — Eksplisitt NULL (ingen økt) ✔
Ingen Sequential-swap, ingen Handoff, ingen graf-adopsjon, ingen checkpointing. Står her så
ingen senere økt «oppdager» dem på nytt. Falsifisering av selve null-beslutningen: forsvinner
«forcing completion»-linjene en dag uten bytte, var topologi-analysen feil.
## 4. Belegg (kommandoene bak påstandene, målt 2026-08-09 på HEAD `c96ef90`)
| # | Påstand | Kommando → resultat |
|---|---|---|
| 1 | Suiten grønn | `uv run pytest -q` → 766 passed / 4 skipped (111 s) |
| 2 | Demo deterministisk + 8 steg | to kjøringer, stdout adskilt fra stderr, `diff` → tom; `grep -cE "^ *Steg [1-8]"` → 8. (Første måling viste avvik — det var målefeil: `2>&1` blandet inn stderr; mkdtemp-linja går bevisst til stderr, `simulation.py:531-534`) |
| 3 | Ingen bundle har kostbaseline | `ls shared/examples/bygg-energi-mikro/` → 8 filer, ingen `cost-baseline.json`; bestillingen (coord `20260806T112037Z…`) krever den per ny bundle |
| 4 | Steg 7 vises uten fil-innboksen | `simulation.py:328-366`: `run_project` kalles uten `verdict_dir`; dommen er argumentet `verdict_input` (`:322`); etiketten «lang fil-løkke» står i `:478` |
| 5 | Metode-skill finnes ikke | `find shared -name "SKILL.md"` → kun `expert-reviewer` |
| 6 | CLI-porteføljen uten pass-tak | `run.py:1679-1686`: budget-stop-armen «currently UNREACHABLE from here»; `BudgetRefused` (RuntimeError) utenfor except-tuplen |
| 7 | Debatten er en fast sekvens | `workflow.py:97-108`: round-robin-selector, terminerings-nett = `max_rounds*2+1` = 7 > 3 dispatcher → fyrer aldri; «forcing completion» ×2 i hver kjøring (målt) |
| 8 | MAF-alternativene gir ikke gevinst | introspeksjon installert orchestrations 1.0.0: ingen innebygd round-robin (kun docstring-eksempel `_group_chat.py:149-151`); `SequentialBuilder.__init__` tar `checkpoint_storage` direkte; Handoff = modelldreven ruting |
| 9 | `[project.scripts]` mangler | `grep -n scripts pyproject.toml` → 0 treff |
| 10 | Spor B er frys-sikker | `grep -n "ingest" src/portfolio_optimiser/{run,simulation}.py` → kun docstring-omtaler, ingen import |
## 5. Ukens kalender (hvor punktene lander)
| Dag | Innhold |
|---|---|
| søn 9.man 10. | **P1** (Steg 7-innboksen) + **P2** (Spor B økt 1, evt. 2) |
| tir 11. | **P3**: GO/NO-GO på commons-innholdet + kostnads-sjekk-prøven |
| ons 12. | **P4**: nye kriterier + setninger → generalprøve → **FRYS****S1.c: release-kuttet + tag `v1.0.0`** |
| tor 13. | **DEMO = v1 vises** |
| fre 14.lør 15. | **P5**: README (O4) |
| deretter | **P6 → P7 → P8 → P9**, ett punkt per økt; STATE.md peker på øverste åpne |