# 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** | `<>` | `git rev-parse HEAD` rett etter grønn generalprøve ×2 | | Tag | `<>` | `git tag -l v1.0.0` etter push til `origin` | | Generalprøve ×2 | `<>` | 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 1–5, 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-in** — `materialize_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 7–9) 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 11–33) | Skjerm | Steg | Det ene poenget | |---|---|---| | 12–15 | 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 | | 16–19 | 2 — Hypotese | forslaget med parametere og kostlinjer; påstått **2 100 000 NOK** | | 20–22 | 3 — Debatt | to deltakere; checkeren gater **resonnementet** og sier `VERDICT=APPROVE` | | 23–24 | 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 | | 25–27 | 5 — Forbedre | grunnen mates tilbake i neste forsøk, **bundet** av `max_attempts` → **VALIDATED 445 500** | | 28–29 | 6 — Forkast eller foreslå | typet utfall forlater kjøringen (`validator=validated, checker=approve`) | | 30–33 | 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 35–46) 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** (37–41): 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** (43–46): 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 48–54) 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 56–61) 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`](../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]" | tr -d ' ' | sort -u | wc -l` → **8** *(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 ..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, ikke skrevet på forhånd og ikke tatt fra veggklokka:** `git log -1 --format=%cs`. - [ ] **Datoen RE-LEST etter at stempel-commiten (Z) finnes, FØR taggen** — `git log -1 --format=%cs` på nytt → må være **IDENTISK** med den stemplede overskriften. Første lesning skjedde med HEAD på **Y** (runbook-commiten), og **Y blir aldri tagget**. Faller midnatt mellom Y og Z, stemplet du gårsdagens dato inn i commiten som faktisk tagges. Avvik = `git commit --amend` på overskriften, les på nytt, ikke tag før de er like. *(Sklir HELE sekvensen til torsdag morgen, er alt i orden — Y og Z er da samme dag. Det er bare midnatt MELLOM dem som brekker enigheten.)* - [ ] **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` alene** — `open/` 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.stdout` → **0**. 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.stdout` → **0**. 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.