portfolio-optimiser/docs/plan/2026-08-12-demo-runbook.md
Kjell Tore Guttormsen 818b55ae09 docs: frys-gaten kjøres TO ganger, og CHANGELOG-datoen leses av commiten
Tre retteser fra advisor-review, alle propagert til BEGGE kilder (runbook +
plan + STATE) — en oppskrift som står ulikt to steder er nøyaktig drift-klassen
denne økta har lukket.

1. GATEN KJØRES TO GANGER. Sekvensen er X (prøve) -> Y (runbook) -> Z
   (CHANGELOG-stempel) -> tag. En gate kjørt kun ved X måler en tilstand som
   ikke lenger finnes når taggen settes; bare et andre kall RETT FØR git tag
   beviser at det TAGGEDE treet er det prøvde. Samme kommando, annet tidspunkt.

2. DATOEN LESES AV COMMITEN SOM TAGGES: git log -1 --format=%cs, ikke date +%F.
   Veggklokka er ikke etterprøvbar og kan avvike fra commiten på en sen
   kveldsøkt; %cs gjør CHANGELOG, tag-objektet og commiten enige også hvis
   dagen sklir til torsdag morgen. Målt: %cs på HEAD gir 2026-08-10.

3. PORTEFØLJE-SVARET SNEVRET INN. Raden lovet "ja, den kan kjøre en hel
   portefølje" med et forbehold om CLI-taket. Spørsmålet den besvarer er
   bredere enn det vi har prøvekjørt denne uka: run_portfolio er testet, men
   demoen kjører ett prosjekt og CLI-porteføljestien er ikke prøvd. Raden sier
   nå hva biblioteket har, at demoen ikke viser det, og at porteføljestien ikke
   skal tilbys som live demonstrasjon.

Verifisert: null "date +%F" igjen i noen av de tre kildene; %cs-oppskriften i
alle tre; placeholders fortsatt 3; docs/-gaten grønn (10 passed).
2026-08-10 21:24:48 +02:00

12 KiB
Raw Blame History

Demo-runbook — torsdag 13. august 2026

Én side å ha i hånda på scenen. Kjøresekvens · hva som sies hvor · abortstien.

Status: beslutnings-innholdet er skrevet mandag 10. august (økt 7) — alt som er kjennbart uten frysen. Onsdag 12. fyller ut de målte feltene og krysser av nederst. Runbooken er lesestoff, ikke kjøresti: den ligger under docs/, som er unntatt frys-gaten, så den kan skrives og fylles ut uten å røre det frosne treet.

Onsdagens utfyllings-sjekk (kjør FØR demoen):

grep -n '<<[A-ZÆØÅ-]*>>' docs/plan/2026-08-12-demo-runbook.md    # → TOMT

Ikke tomt = runbooken er et utkast, ikke en runbook. Et uutfylt felt er samme drift-klasse som plan-radene økt 4, 5 og 6 hver for seg fant: et dokument som instruerer om noe som ikke stemmer.


0. Målte felt — fylles onsdag

Felt Verdi Hvor det kommer fra
Frosset commit X <<X-HASH>> git rev-parse HEAD rett etter grønn generalprøve ×2
Tag <<TAG-BEKREFTET>> git tag -l v1.0.0 etter push til origin
Generalprøve ×2 <<PROEVE-DATO-TID>> tidspunktet begge kjøringene var grønne

Alt annet i dette dokumentet er målt mandag 10. august mot det pinnede transkriptet (tests/golden/demo-transcript.stdout, 61 linjer) og står uendret.


1. Kjøresekvensen

Kommandoen — kjør denne, ingen andre flagg:

uv run python -m portfolio_optimiser.simulation

Forventet: exit 0, 61 linjer stdout, 4 linjer stderr.

Stderr er fire linjer og skal være der: to ExperimentalWarning fra MAF (Skills + MemoryStore), en blanklinje, og (arbeidskopi: /tmp/po-sim-…). De to advarslene dempes ikke med vilje — de fyrer mens biblioteket importeres, og å dempe dem ville betydd at rammeverket bestemmer hva MAF får si til enhver konsument. Rund-tak-linjene («forcing completion») er dempet og skal ikke vises.

Hvis du vil vise at outputen er den frosne:

uv run python -m portfolio_optimiser.simulation > /tmp/demo.out 2>/dev/null
diff /tmp/demo.out tests/golden/demo-transcript.stdout        # → TOMT

(Konsoll-kommandoen portfolio-optimiser-demo gir byte-identisk stdout og virker like godt. -m-formen står her fordi den ikke antar noe om PATH. PYTHONIOENCODING=utf-8 er pinnet i testene; i en vanlig UTF-8-terminal trengs den ikke.)


2. Hva som sies — i rekkefølge, forankret i skjermlinjene

Linjenumrene under er linjene i det pinnede transkriptet, så du kan finne igjen stedet uten å lete.

Åpningen (skjermlinje 15, banneret står allerede der)

Banneret sier det selv. Les det, ikke pynt det bort, og legg til de tre ærlighets-punktene (demo-uke-planen §1 — nivå-2-påstanden, D-I):

  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.
  2. Innholdet er håndkuratert, ikke fabrikkert. Et menneske lagde kunnskapsbasen.
  3. Tallene er modellerte, ikke målte. Ingen pilot har validert dem i drift.

Dette er ikke en unnskyldning som svekker demoen — det er 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.

Ærlighets-avsnittet — leses opp ORDRETT (innholdsgate-planen §5, JA-varianten)

Spor B landet 2026-08-09, så det er JA-varianten som gjelder. NEI-varianten brukes ikke.

«To ting om innholdet dere ser. For det første: denne kunnskapsbasen er laget for hånd, ikke produsert av systemet. Det finnes en ingest-vei som henter eksterne kilder inn i formatet, men eksempelet her gikk ikke gjennom den, og den generiske fabrikken som skulle laget slike baser er ikke bygget — den er bevisst utsatt. For det andre, om sikkerhet: ingest-veien skanner nå innholdet før det skrives, med en egen sikkerhetskomponent, slik at forgiftet kildeinnhold ikke havner i basen.»

(Forbeholdet hvis noen graver: gaten er opt-inmaterialize_gated er den gatede inngangen, materialize er bevisst ugatet, og en kaller som vil ha gaten ber om den ved navn. Det står slik i CHANGELOG-ens Security-oppføring. Si det hvis det spørres; ikke som en fotnote i opplesningen.)

Kunnskapsbasen (skjermlinje 79)

Linje 9 er ærlighets-setningen om provenans — den står allerede på skjermen og skal ikke sies på nytt: «tallene er levert i kunnskapsbasen — utledet av fagkilder (Håndbok V124, NMFV), ikke av demo-manuset». Pek på den. Poenget er at kostbaselinen er erklært, og at validatorens stage 0 avstemmer forslagets kostlinjer mot den før løseren.

Kjøring A, steg for steg (skjermlinje 1133)

Skjerm Steg Det ene poenget
1215 1 — Forstå konteksten fem konseptfiler ble navigert, ikke søkt opp som tekstbiter; 0 tidligere dommer, og markøren er False — det er kontrollen som gjør Kjøring B beviselig
1619 2 — Hypotese forslaget med parametere og kostlinjer; påstått 2 100 000 NOK
2022 3 — Debatt to deltakere; checkeren gater resonnementet og sier VERDICT=APPROVE
2324 4 — Valider REJECTED — 2 100 000 overstiger P90 feasible 1 769 915. Dette er hele poenget: checkeren sa ja, tallene sa nei, og tallene vinner
2527 5 — Forbedre grunnen mates tilbake i neste forsøk, bundet av max_attemptsVALIDATED 445 500
2829 6 — Forkast eller foreslå typet utfall forlater kjøringen (validator=validated, checker=approve)
3033 7 — Tilbakemelding (kort løkke) ekspert-personaen godkjenner med realiseringskorreksjon (0.79)

Setningen som bærer demoen (skjermlinje 22 mot 24): «Checkeren godkjente resonnementet. Den deterministiske validatoren avviste tallet. To uavhengige falsifiserere, og det er den som regner som blokkerer.»

Mellom kjøringene (skjermlinje 3546)

To uavhengige tilbakemeldings-veier, én per tidsskala — og de bærer hver sin markør nettopp for at ingen av dem skal kunne ta æren for den andre:

  • Steg 7, lang løkke (3741): en ekspert legger en fil i innboksen etter kjøringen (realiseringsgrad=0.66). Rollene byttes aldri: systemet leser mappa, eksperten skriver den. Dager kan gå.
  • Steg 8, promotering (4346): den godkjente dommen løftes inn i wikien (realiseringsgrad=0.79). Gaten er fail-closed — kun en godkjent dom promoteres, rå agent-output aldri.

Kjøring B (skjermlinje 4854)

Kun det som endret seg vises. Begge markørene er True, og linje 51 sier hvor dommene kom fra: 1 av 3 fulgte med kunnskapsbasen, de øvrige 2 er dem demoen lærte i denne økten. Den splitten er regnet ut av kjøringen, ikke skrevet ned — derfor stemmer den også når basen en dag shipper flere dommer.

Utfallet er det samme tiltaket til samme beløp. Det er riktig og verdt å si høyt: læringen endret ikke svaret her, den endret grunnlaget svaret ble formet på.

Avslutningen (skjermlinje 5661)

Les blokken. Poenget er den siste setningen: ingen av de to veiene gikk gjennom minnet — begge gikk gjennom fil.

Mandat-setningen (MUNTLIG — ingenting av dette vises på skjermen)

Svaret på «kan vi styre hva som analyseres?»:

«Ja. En kjøring kan bestilles med en oppdragsfil: du skriver hva kjøringen er til for, og hvilke tilnærminger du vil ha vurdert — hver av dem får sin egen vurdering og sin egen linje i oppgjøret, og systemet kan i tillegg foreslå sitt eget. Men bestillingen styrer hva som vurderes, aldri hva som godkjennes: validatoren gjelder uendret, så ber du om noe tallene ikke bærer, blir det avvist — og avvisningen kommer tilbake til deg med begrunnelsen. Det er ikke vist i denne demoen; det er et eget flagg (--mandate), og det er dokumentert.»

Dokumentet er docs/bestille-en-kjoring.md. Søsterdokumentet for den andre enden — å avgi dommen etterpå — er docs/ekspert-svar.md.


3. Abortstien

Feiler live-kjøringen på scenen: ikke debug. Vis fila.

cat tests/golden/demo-transcript.stdout

Den fila er transkriptet — ordrett, uten normalisering — fra den frosne kjøringen. Si høyt hva den er:

«Dette er den frosne kjøringen fra onsdag, sjekket inn som fasit. Det dere ser er ikke en gjenfortelling, det er outputen ordrett — og at den er sjekket inn er grunnen til at jeg kan vise den nå.»

Ikke prøv å fikse noe under demoen. Miljøet er den sannsynlige årsaken (uv sync / feil katalog), og feilsøking på scenen koster mer enn fila.


4. Forventede spørsmål

Spørsmål Svar
«Hvorfor viste Kjøring A 0 tidligere dommer når basen shipper ett dom-frø?» Med vilje: Kjøring A kjøres mot en tom wiki. Uten den kontrollen kunne markøren i Kjøring B like gjerne kommet fra basen som fra læringen — kontrollen er det som gjør sløyfa beviselig, ikke bare påstått.
«Er dette en ekte LLM?» Nei — agent-svarene er skriptet, og det står i banneret. Det som er ekte er dataflyten, den deterministiske validatoren og at læringen faktisk går gjennom fil.
«Hva om modellen hallusinerer et tall?» Stage 0 avstemmer hver kostlinje mot prosjektets erklærte kostbaseline før løseren i det hele tatt kjører. Ukjent kostkode, eller en mengde/enhetspris utenfor toleransen, avvises — validering, aldri reparasjon.
«Kan den kjøre en hel portefølje?» Biblioteket har porteføljekjøring med bølge-modell og et globalt token-tak. Kommandolinja eksponerer ikke taket, og porteføljekjøring er ikke det denne demoen viser — den kjører ett prosjekt. Ikke tilby en live demonstrasjon av porteføljestien; den er ikke prøvekjørt denne uka.
«Er den generiske fabrikken for kunnskapsbaser med?» Nei, bevisst utsatt. Basen her er håndkuratert. Det er punkt 2 i åpningen.
«Hva med open/-speilet / hvor ligger koden?» Taggen v1.0.0 er satt på det private repoet. Det offentlige speilet synkes etter demoen, sammen med READMEen som forklarer commitene.

5. Krysses av onsdag 12. (etter generalprøve ×2)

  • Generalprøve ×2 grønn — golden-diff tom begge ganger
  • K1: grep -oE "^ *Steg [1-8]" <stdout> | tr -d ' ' | sort -u | wc -l8 (linje-tellingen gir 9 — kjent og forventet: Steg 7 har to linjer, én per tidsskala. Kjør kommandoen, ikke prosaen.)
  • X notert (git rev-parse HEAD) og skrevet inn i tabellen i §0
  • Frys-gaten grønn: git diff --stat <X>..HEAD -- . ':(exclude)docs/' ':(exclude)CHANGELOG.md' → TOMT
  • Runbooken fylt ut + grep -n '<<[A-ZÆØÅ-]*>>' docs/plan/2026-08-12-demo-runbook.md → TOMT
  • CHANGELOG-overskriften stemplet — datoen LESES av commiten som tagges, ikke skrevet på forhånd og ikke tatt fra veggklokka: git log -1 --format=%cs. Da er CHANGELOG, tag-objektet og commiten enige, også hvis dagen sklir til torsdag morgen.
  • Frys-gaten kjøres ÉN GANG TIL, rett før taggen — samme kommando som over. Steg 2 målte en tilstand som ikke lenger finnes: runbook-commiten (Y) og CHANGELOG-stempelet (Z) kom etterpå. Tom her = det taggede treet er beviselig det prøvde treet. Ikke tomt = IKKE tag.
  • git tag v1.0.0 + git push origin v1.0.0 (origin aleneopen/ er P5-vinduet)

Vedlegg — tre punkter som IKKE trenger en setning på scenen (målt 2026-08-10)

STATE bar tre «scene-kosmetiske» punkter. Alle tre er målt mot det pinnede transkriptet, og ingen av dem er synlige i demoen:

  1. 23700 NOK/aar når aldri skjermen. Personaens rationale er 389 tegn og beløpet står helt til slutt (ca. tegn 370); demoen klipper på 300 tegn, så linja ender på pga. overes…. Målt: grep -c "23700" tests/golden/demo-transcript.stdout0. STATEs formulering («printes fortsatt ordrett») var et premiss, ikke en måling. Det trengs altså ingen setning på scenen — kun hvis noen åpner selve persona-fila.
  2. 0.82 vs 0.79. 0.82 hører til bygg-eksempelets golden, ikke veglys-kjøringen. Målt: grep -c "0\.82" tests/golden/demo-transcript.stdout0.
  3. docs/ekspert-svar.md er en operatør-guide og leses ikke av demoen.

Punktene står fortsatt som post-demo-opprydding i sine egne spor; de er bare ikke noe torsdagen må bære.