portfolio-optimiser/docs/plan/2026-08-06-demo-uke-plan.md
Kjell Tore Guttormsen cd011c4ac7 docs(plan): demo week, with the one real build separated from the presentation
Seven of the eight steps already have their data in RunResult and need a print;
one does not exist at all. Putting that distinction in a table is the point of
this plan -- it turns "show all eight steps" from an unbounded week into one
build on Friday and presentation work over the weekend.

The go/no-go on Tuesday is deliberate. The content is being built in another
repo on a deadline nobody here controls, so the week is designed to survive it
not arriving rather than to hope it does. The content-keyed reply selector
lands Monday, before the content, for the same reason: a new project should
then be a data entry rather than a hand-written script under time pressure.

Honesty framing is section 1 rather than a footnote, because the demo's own
subject is a system that refuses to claim more than it proves.
2026-08-06 13:23:19 +02:00

128 lines
8.1 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.

# Demo-uke — alle åtte steg live torsdag 13. august 2026
> **Grunnlag:** `2026-08-06-intensjons-qa.md` (påstander A1C8, funn G1G6, beslutninger O1O4).
> Rammene A/B/C fra briefen står. Denne planen legger til dagsrekkefølge, den ene kodejobben,
> og et go/no-go-punkt som gjør uka robust mot at innholdet ikke kommer.
## 0. Låst — ikke gjenåpne
| | Beslutning |
|---|---|
| **A** | «Live» = sanntids-gjennomgang, skriptet under panseret. Preflight/Foundry er UTE av kritisk sti. |
| **B** | MAF-siden alene. Søsken-repoet er parkert. |
| **C** | Det realistiske eksemplet bygges i commons, i en egen tab. |
| **O1** | Ferdigbygd eksempel. Fabrikken (D-G/T0 `okf-toolkit`) er eksplisitt utsatt. |
| **O2** | Steg 5 bygges og vises live. |
| **O3** | Bestilt commons 2026-08-06 med frist 11. august; reserve planlagt. |
| **O4** | README oppdateres ETTER demoen (14.15. august), ikke før. |
Bestillingen er levert: `20260806T112037Z-2648131757-from-portfolio-optimiser.md`.
## 1. Hva demoen ÆRLIG er — formuleringen er avtalt på forhånd
D-I setter publiserings-påstanden til **nivå 2**: realistisk case, modellerte tall, aldri salgsspråk
over beleggsnivået. Tre ting sies høyt i demoen, ikke i en fotnote:
1. **Agent-svarene er skriptet.** Dette beviser dataflyten, den deterministiske ryggraden og at
læringssløyfa lukkes — ikke at en levende modell ville produsert nettopp dette forslaget.
(Banneret sier det allerede i dag; det skal stå, ikke pyntes bort.)
2. **Innholdet er håndkuratert, ikke fabrikkert.** Den besluttede demo-stien (D-H pkt. 4) går via en
bundle-fabrikk som ikke er bygget. Vi viser «last ned → kjør», men et menneske lagde innholdet.
3. **Tallene er modellerte, ikke målte.** Ingen pilot har validert dem i drift.
Dette er ikke en unnskyldning som svekker demoen — det er selve grunnregelen repoet er bygget på
(A5: koden får ikke påstå mer enn den gjør). En demo som overselger bryter med det den demonstrerer.
## 2. De åtte stegene → hva som faktisk vises
`RunResult` bærer allerede `retrieved`, `debate_output`, `checker_verdict`, `outcome`
(`ValidatedProposal | Rejection`), `verdict` og `coverage`. Presentasjonen er ~30 `print`-linjer
(`simulation.py:295326`). Derfor er sju av åtte steg **presentasjonsarbeid**, og ett er ekte bygg:
| Steg (`method-spec` §3) | Vises som | Status i dag | Arbeid |
|---|---|---|---|
| 1 — Forstå konteksten | navigerte filer + ExpeL-folden (`retrieved`) | markør-linja antyder det | `print` |
| 2 — Hypotese | forslaget med parametere | data finnes, printes ikke | `print` |
| 3 — Debatt (maker-checker) | begge deltakere + `checker_verdict` | checker printes | `print` |
| 4 — Valider / falsifiser | validator-linja med P90 | **printes** ✔ | — |
| 5 — Forbedre, informert og bundet | avvisning → korrigert forslag | **ikke mulig** | **BYGG** |
| 6 — Forkast eller foreslå | typet `outcome` | data finnes, printes ikke | `print` |
| 7 — Svar på tilbakemelding | persona-dom + fil-innboksen | dommen printes | `print` |
| 8 — Promoter godkjent kunnskap | promotert fil + index-lenke | **printes** ✔ | — |
**Steg 5 er den eneste ekte kodejobben.** `generate_via_llm` forbruker den mellomliggende
avvisningen internt (`last`) og returnerer bare sluttresultatet — og i dagens demo-kjøring
validerer forslaget på FØRSTE forsøk, så forbedringsløkka trigges aldri. Det kreves to ting:
en søm som slipper avvisnings-historikken ut, og et nytt skriptet forløp der forslaget først
blir avvist og deretter korrigert.
## 3. Dagsplan
**Fredag 7. august — steg 5-sømmen (den ene kodejobben).**
Slipp avvisnings-historikken ut av `generate_via_llm` uten å endre løkkas tak (`max_attempts` +
`meter.tick_round` står urørt — «forbedre til god nok» uten tak er forbudt). Nytt skriptet
avvis-så-korriger-forløp. Ny load-bearing-test: RØD når sømmen kobles fra. Ligger først i uka
med vilje — det er den eneste jobben som kan overraske, og den har fem dagers slakk bak seg.
**Lørdag 8. søndag 9. august — presentasjonslaget.**
De fem `print`-tilleggene over, formet som én lesbar gjennomgang med steg-nummer i margen.
Ingen ny logikk. Målet er at en tilhører kan følge hvert steg uten at du forklarer hva de ser på.
**Mandag 10. august — gjør manuset innholds-drevet.**
`ScriptedChatClient` tar en `reply_selector` over `(prompt_blob, role)` — den ser altså prompten
og KAN nøkle svaret på kandidaten i stedet for å ha ett hardkodet svar. Bygg det **nå, før
innholdet kommer**: da er et nytt prosjekt en data-oppføring, ikke et nytt manus skrevet for hånd
under tidspress. Dette er ukas viktigste risikoreduksjon.
**Tirsdag 11. august — GO/NO-GO på innholdet.**
Er commons-leveransen hentbar? `git subtree pull --prefix=shared commons main --squash`, så
kjør. **JA:** pek `simulate_learning_loop` på den nye bundelen, utvid selector-dataene, mål
rendret kontekst-størrelse per bundle. **NEI:** lås mikro-eksemplet som demo-innhold og si det i
ærlighets-avsnittet. Beslutningen tas tirsdag, ikke onsdag kveld.
**Onsdag 12. august — generalprøve, så fryse.**
Kjør hele gjennomgangen to ganger. Identisk output begge ganger (determinisme er et poeng, ikke en
detalj). Full suite grønn. Etter generalprøven: ingen endringer i kjørestien.
**Torsdag 13. august — demo.**
**Fredag 14. lørdag 15. august — README (O4).** Nivå-2-påstanden løftes ETTER at beviset finnes.
## 4. Risiko
| Risiko | Utslag | Tiltak |
|---|---|---|
| Commons rekker ikke 11. august | Tynt innhold | Reserve låst tirsdag; bestillingen sier eksplisitt at det er en reserve, ikke en krise |
| Nytt innhold krever nytt manus | 2 dager håndarbeid under press | Innholds-drevet `reply_selector` bygges mandag, FØR innholdet kommer |
| Prompten sprenges av stor bundle | Token-tak slår inn midt i demoen | Bestillingen er størrelses-kappet på målt grunnlag (~25 000 tegn/bundle); mål på nytt tirsdag |
| Steg 5-sømmen tar lengre tid | Ett steg mangler | Ligger fredag; fallback er testbevis-varianten (vurdert og valgt bort, men den finnes) |
| `docs/presentasjon-*.html` eies av annen sesjon | Konflikt | Røres aldri; alltid eksplisitt filliste ved `git add` |
## 5. Verifisering
Konkrete kriterier, ikke «sjekk at det virker»:
1. `uv run python -m portfolio_optimiser.simulation` → exit 0, og outputen har **én merket linje per
steg 18**. Verifiseres med `... | grep -cE "^ *Steg [1-8]"` → 8.
2. Steg 5 er synlig som **to** forslag: ett avvist med grunn, ett korrigert som validerer.
Verifiseres ved at outputen inneholder både en `REJECTED`- og en `VALIDATED`-linje for samme kandidat.
3. Ny load-bearing-test for steg 5-sømmen blir **RØD** når sømmen kobles fra. Måles mot HELE suiten,
med kontroll, restaurert fra scratchpad-kopi + `shasum -c`.
4. `uv run pytest -q` grønn (baseline i dag: 759 kollektert, 755 passed / 4 skipped).
5. `uv run ruff check .` + `uv run mypy src` rene.
6. Generalprøve onsdag: to kjøringer, **byte-identisk** output (`diff <(kjøring1) <(kjøring2)` tom).
7. Ved commons-leveranse: rendret kontekst per bundle måles med `okf.bundle_context` og skal ligge
under ~25 000 tegn. Over det → bruk færre bundles, ikke større prompt.
8. `shared/examples/bygg-energi-mikro/` og `nav-golden-*` er **uendret** etter subtree-pull
(`git diff --stat` på de stiene → tomt). Goldenene er load-bearing.
## 6. Nøkkelantakelser som skal testes, ikke antas
- **«Sju av åtte steg er ren presentasjon.»** Testes fredag/lørdag: hvis et av de fem `print`-tilleggene
viser seg å kreve ny logikk, er det samme klasse funn som C7 og skal meldes med en gang.
- **«`reply_selector` kan nøkle på kandidaten.»** Signaturen er `(prompt_blob, role) -> str`, så
prompten er tilgjengelig — men at kandidaten er entydig identifiserbar i blobben er ikke verifisert.
Testes mandag, på mikro-eksemplet, før innholdet kommer.
- **«Ny bundle plugges inn som parameter.»** `simulate_learning_loop(bundle_dir, work)` tar katalogen
som argument (`simulation.py:183`, kalt `:293`) — verifisert i dag. Det som IKKE er verifisert, er at
en bundle med flere kandidater kjører gjennom uendret; det er S3.2-stien, og den testes tirsdag.