Nytt dokument docs/kunnskapsbase-for-en-kjoring.md (norsk, for fagperson + teknisk person): fire kategorier etter hva de FØLGER (prosjekt / fagområde / organisasjon / bestilling), elleve avgjørelsesspørsmål, innholdstype-tabell (eier, leveringsform, rolle i loopen, hva skjer hvis den mangler), og veglys-eksempelet ende til ende mot den innsjekkede basen. Alt er målt, ikke antatt: type-vokabularet (6 typer i drift; de 4 ikke-reserverte er KONVENSJON, nevnt i ingen spec), metode-filene er tre ulike filer (40/81/98 linjer), og fire live-dry-runs på kopier av veglys-basen — uten validator-input.json rc 1, uten cost-baseline.json rc 0 UTEN MELDING, korrupt baseline rc 1. Ingen artefakt (provenance/outbox) bærer forankret/uforankret; foreslått som kodeendring i dokumentets §7, ikke bygget (Iron Law). Oppskriften (knowledge-base-recipe.md) beholder prosess/roller og lenker hit; README Docs-lista får én rad; dokumentet er klassifisert i _LIVE_DOCS (gaten er fail-closed på uklassifiserte dok). extending.md er utdatert på ett punkt (sier ingen eksempelbase shipper cost-baseline.json) — flagget i §6, ikke rettet her. shared/ urørt. 874 passed / 5 skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XJhpbb4acREp56CaQ5bwXV
44 KiB
Kunnskapsbasen for én konkret kjøring
Dette dokumentet er for fagpersonen som skal planlegge en kjøring mot et konkret prosjekt, og for den tekniske personen som skal bygge kunnskapsbasen den kjøringen leser. Den første jobben er alltid den samme: sette sammen en kunnskapsbase som gir riktig kontekst for nettopp denne kjøringen. Det er den jobben som beskrives her — fra bestillingen til en base som er klar til å kjøres.
Tre dokumenter står rundt dette:
- knowledge-base-recipe.md (engelsk) beskriver prosessen: de to rollene, de fire fasene (inventar → skjelett → frø → iterer) og den ærlige forventningen om at en god base tar 1–2 uker. Det gjentas ikke her. Dette dokumentet svarer på det oppskriften ikke svarer på: hvordan går man fra en gitt oppgave til en riktig sammensatt base?
- bestille-en-kjoring.md beskriver oppdragsfila — det som kommer inn til kjøringen. Dette dokumentet møter den i den andre enden: basen oppdraget skal leses mot.
- ekspert-svar.md beskriver dommen — det som kommer ut, og som gjør neste base bedre.
Merkekonvensjon. Hver teknisk påstand i dokumentet er enten VERIFISERT (med filen, linjen eller kommandoen som viser det — samlet i verifiseringsloggen nederst) eller ANTATT (en tolkning eller en anbefaling som ikke følger av noe målt). Konvensjoner som bare er observert i eksempelbasene, ikke normert i spesifikasjonen, er merket KONVENSJON. Ingenting her er en påstand om at en levende modell ville resonnert godt over basen; det er en påstand om hva basen må inneholde for at kjøringen skal kunne starte, lese riktig og dømme mot ekte tall.
Det korte svaret
1. Hvilke kategorier trengs? Fire, og de skiller seg på hva de følger:
| Kategori | Følger | Hvem eier den |
|---|---|---|
| Prosjektlaget | prosjektet / anlegget | prosjekteier og driftsorganisasjon |
| Faglaget | fagområdet (veglys, tunnel, bygg …) | fagmiljøet |
| Erfaringslaget | organisasjonen, over tid | fagekspertene som avgir dommer |
| Kjøringslaget | denne ene bestillingen | bestilleren |
Det er én kunnskapsbase per prosjekt (VERIFISERT: shared/method-spec.md §2). Prosjekt-,
fag- og erfaringslaget ligger i basen. Kjøringslaget ligger ved siden av — det er instruksen
for én kjøring og lagres aldri som kunnskap. Faglaget deles logisk på tvers av prosjekter i samme
fagområde, men kopieres fysisk inn i hver base — se §2.
2. Hvilke innholdstyper? Seks markdown-typer og to tallfiler. Tabellen i
§4 sier for hver av dem hvem som eier den, hvilken form fagpersonen leverer
den i, hva loopen bruker den til, og hva som skjer hvis den mangler. Den viktigste raden er
cost-baseline.json: mangler den, starter kjøringen uten et ord — og validatoren dømmer da bare
mot tall forslaget selv oppga (VERIFISERT ved kjøring, §4.1).
3. Hvordan ser det ut for et veiprosjekt? §5
går gjennom en veglysportefølje langs fylkesveg, fra oppdragsfila til en base som består
kjøreklar-sjekken. Basen det ender i finnes og kjører (VERIFISERT: shared/examples/veglys-fv-soer/
er den demoen bruker).
1. Hva kjøringen leser, og hvorfor det avgjør hva basen må inneholde
Hva basen må inneholde er ikke en smakssak. Det følger av hvordan loopen leser den.
Kjøringen navigerer, den søker ikke. Den starter i index.md, følger lenkene derfra, og
leser hver fil den når. Det som står i brødteksten til index.md kommer først og ordrett inn
i det agentene leser; deretter kommer hver lenket fil som en egen seksjon ## <type>: <tittel>
med hele brødteksten. Det finnes ingen stikkordssøk og ingen «relevante utdrag» — en fil leses
helt, eller ikke i det hele tatt (VERIFISERT: shared/method-spec.md §3 Steg 1;
src/portfolio_optimiser/okf.py bundle_context). Tre konsekvenser for den som bygger basen:
- En fil uten lenke fra
index.mdfinnes ikke for kjøringen. Det gjelder også en fil som ligger i riktig mappe med riktig type (VERIFISERT:shared/ingest-spec.md§2: «a generated concept file without an index link is unreachable»). - En lenke ut av basen følges aldri. Målet må ligge inne i basens egen mappe; en lenke til en nabobase eller et delt fagbibliotek hoppes stille over, uten feilmelding (VERIFISERT: method-spec §3 Steg 1, «a target resolving outside the bundle is skipped»). Det er grunnen til at faglaget kopieres inn, ikke lenkes til.
- Mengde er ikke kvalitet. Alt som lenkes leses i sin helhet, så ti sider støy koster like mye oppmerksomhet som ti sider substans. Hold filene stramme (ANTATT: en anbefaling, ikke et krav i koden).
Én type holdes alltid utenfor lesekonteksten: type: verdict. Tidligere dommer kommer aldri
inn som vanlig tekst. De hentes for seg, nøklet på kandidaten, og legges foran hypoteseprompten
som «tidligere dommer om lignende tiltak» (VERIFISERT: method-spec §3 Steg 1 «Experience fold»;
okf.py context_files ekskluderer typen). Kandidaten de nøkles på leses fra
validator-input.json — ikke fra bestillingen, og ikke fra hva agentene ender med å foreslå
(VERIFISERT: src/portfolio_optimiser/run.py:634-638). Det er derfor den fila er påkrevd.
Ved siden av markdown-filene ligger to tallfiler. validator-input.json må finnes — uten den
nekter kjøringen å starte (VERIFISERT ved kjøring, §4.1).
cost-baseline.json er valgfri, og det er nettopp problemet: uten den starter kjøringen som om alt
var i orden.
Målt på veglys-basen: mappa har 9 filer. Én er index.md, én er dommen, to er tallfiler —
og 5 er det kjøringen faktisk navigerer inn som kontekst (VERIFISERT:
tests/golden/demo-transcript.stdout linje 13, «navigerte konseptfiler (5)»).
Teknisk note. Formatet basen bygges i heter Open Knowledge Format (OKF); i koden og spesifikasjonene kalles basen en bundle. Hver fil har en frontmatter (
----blokk) dertype:er det ene påkrevde feltet. Koden leser svært få av de andre feltene:title(til seksjonsoverskriften og prosjektnavnet),dimension(når kjøringen er avgrenset til én kostakse), og på dom-filerdecision,description,realization_rate,expected_actual_saving_noksamt den valgfrie nøkkel-trioenaffected_codes/measure_type/claimed_saving_nok. Felt somresource,measure_id,tags,gap_sourceogokf_versioni eksemplene leses ikke av koden — de er dokumentasjon for mennesker (VERIFISERT:grepoversrc/portfolio_optimiser/gir null treff på dem). De er likevel verdt å skrive: de gjør basen lesbar i Obsidian/VS Code, som er lesegrensesnittet i dag.
2. Kategoriene: hva følger hva
| Kategori | Innhold | Følger | Gjenbruk på tvers av prosjekter |
|---|---|---|---|
| Prosjektlaget | index.md · type: project · type: hypothesis · validator-input.json · cost-baseline.json |
prosjektet | Nei. Skrives per prosjekt, fra prosjektets egne tall. |
| Faglaget | type: methodology · type: reference |
fagområdet | Logisk ja, fysisk nei: kopieres inn i hver base og tilpasses. |
| Erfaringslaget | type: verdict (frø-dommer og promoterte dommer) · dom-innboksen utenfor basen |
organisasjonen, over tid | Ja, gjennom dommene: en dom om et lignende tiltak i et annet prosjekt hentes inn når kandidatene ligner strukturelt. |
| Kjøringslaget | oppdragsfila (--mandate) · dimensjonsavgrensning (--dimension-config) · eksterne tjenester (--mcp-config) · tak (runder/tokens) |
denne ene bestillingen | Nei. Instruks for én kjøring; «den lagrer seg ikke som kunnskap» (bestille-en-kjoring.md). |
Deles metode- og litteraturlaget på tvers? Svaret er todelt, og begge halvdeler er målt.
Logisk er det samme fagstoff: alle tre eksempelbasene (kontorbygg, veglys, tunnel) bærer en
metode-ipmvp-a.md og en kilder-*.md, og alle tre bygger på samme M&V-rammeverk (IPMVP Option
A). Fysisk er det tre ulike filer: 40, 81 og 98 linjer, med hver sin tittel — «for veglys — og
hvorfor de andre opsjonene er stengt», «for tunnelstyring — anlegget måler inngangssignalet, ikke
energien» (VERIFISERT: wc -l + diff over de tre). Begge veiprosjekt-basene sier det selv i
index.md: «metode- og kildelaget er materialisert inn her, ikke lenket på tvers av bundler».
Grunnen er teknisk og ufravikelig: navigasjonen følger aldri en lenke ut av basen
(§1). Men det er også
faglig riktig: metoden for veglys er ikke metoden for tunnel. I veglys er ex-post stengt fordi
anlegget mangler måler; i tunnel er ex-ante stengt fordi anlegget ble bygget før noen målte
(VERIFISERT: de to index.md-filene). En delt fil ville måttet si begge deler og dermed ingen av
dem.
Praktisk betyr det (ANTATT, anbefaling): fagmiljøet eier en mal per fagområde; hver base får en tilpasset kopi; når malen endres, er det en kjent jobb å gå gjennom kopiene. To kopier drifter — det er prisen, og den skal være uttalt, ikke skjult.
Prosjektlaget er det som byttes ut. Begge veiprosjekt-basene er bygget med fiktivt prosjektlag
og ekte litteraturlag, og sier selv hvordan de er ment brukt: «en produksjons-deployer erstatter
prosjektlaget med en ekte kunnskapsbase og beholder litteraturlaget» (VERIFISERT: begge
index.md). Det er nøyaktig kategoriskillet over, skrevet fra eksemplenes side.
Erfaringslaget er reservert. Ingen automatisk kilde kan skrive en type: verdict-fil inn i
basen; den eneste veien dit er en promotering av en dom et menneske har godkjent, eller en
håndskrevet frø-dom (VERIFISERT: shared/ingest-spec.md §3, «The verdict layer is RESERVED»).
Grunnen står i spesifikasjonen: hver dom-fil i basen leses som en godkjent dom, så en
datakilde som kunne skrive dem ville sprøytet maskingenererte «godkjenninger» rett inn i
læringen.
Hvem eier hva
| Rolle | Leverer | Leverer ikke |
|---|---|---|
| Prosjekteier / drift | prosjektlaget: anleggsdata, kostlinjer, rammer, kandidat-tiltak | fag-metoden, dommene |
| Fagmiljøet | faglaget: målemetode, verifisert litteratur, kjente gap-mekanismer | prosjekttall |
| Fageksperten(e) | dommer — frø-dommer før første kjøring, innboks-dommer etter | innhold i basen direkte (de skriver innboksen; systemet leser) |
| Bestilleren | oppdragsfila: hensikt, tilnærminger, suksesskriterium | tall i basen; bestillingen styrer hva som vurderes, aldri hva som godkjennes |
| Den tekniske personen | bygger basen fra det de andre leverer: markdown, lenker, tallfilene, ev. ingest-manifest | fagvurderinger |
Fagpersonene leverer filer i sine egne formater — regneark, notater, PDF-er — aldri JSON eller skjema (knowledge-base-recipe.md, «Who does what»). Oversettelsen til basens format er den tekniske personens jobb, og i dag er den manuell (§6).
3. Avgjørelsesdelen: spørsmålene du stiller fagpersonen
Hvert spørsmål avgjør én konkret del av basen. Still dem i denne rekkefølgen; svaret på de fire første avgjør om kjøringen i det hele tatt kan starte.
1. Hvilket prosjekt eller anlegg gjelder det, og hva skal det hete?
Svaret blir prosjekt-ID-en. Den må være identisk tre steder — kommandolinjen,
validator-input.json og cost-baseline.json — ellers nektes kjøringen (VERIFISERT:
run.py _project_from_bundle, «bundle project_id … != requested»). Velg en ID uten mellomrom og
æøå; eksemplene bruker formen VEGLYS-FV-SOER (KONVENSJON).
Hvis svaret er «flere anlegg»: én base per prosjekt. En portefølje er flere baser, kjørt i
porteføljemodus.
2. Hvilke kostlinjer kan tiltakene komme til å treffe — og har vi faktiske tall for dem?
Svaret blir cost-baseline.json: én linje per kostkode, med mengde og enhetspris. Hver kostkode
et forslag viser til må finnes her, og mengden og prisen forslaget oppgir må ligge innenfor
toleransen (BASELINE_TOLERANCE_DEFAULT = 0.05, altså 5 %) rundt baselinens verdi — ellers
avvises forslaget (VERIFISERT: src/portfolio_optimiser/validator.py _reconcile_against_baseline).
Derfor må fila dekke alle linjene bestillingens tilnærminger kan treffe, ikke bare den ene
kandidaten som er projisert.
Hvis svaret er «vi har ikke tallene»: kjøringen går likevel, og det er faren — se
§4.1. Skaff tallene, eller skriv inn i bestillingens
suksesskriterium at kjøringen er uforankret, så ingen leser et VALIDATED-utfall som mer enn det
er (ANTATT: en arbeidsregel, ikke noe koden håndhever).
3. Hvilket tiltak er «det ene» vi projiserer?
Basen holder én kandidat i validator-input.json: tiltaket, kostlinjene det virker på, den
modellerte besparelsen og usikkerhetsbåndet. Denne kandidaten er nøkkelen til tidligere
dommer — det er dens kostkoder, tiltakstype og beløpsstørrelse som avgjør hvilke dommer fra
tidligere kjøringer som hentes inn (VERIFISERT: method-spec §3 Steg 1, rangeringsformelen;
run.py:634-638). Den er ikke det som valideres i kjøringen — det er forslaget agentene lager
(VERIFISERT: generate.py:491 validerer kandidaten fra modellen).
Hvis fagpersonen vil ha flere tiltak vurdert: det går gjennom bestillingen (spørsmål 5), og
hvert tiltak bør ha sin egen type: hypothesis-fil i basen. Men nøkkelen til tidligere dommer er
fortsatt den ene projiserte kandidaten — se
§6.
4. Hvilke harde rammer gjelder?
Minstekrav som setter et gulv ingen besparelse kan gå under, ting som ikke kan endres, budsjett-
og anskaffelsesrammer. Svaret skrives inn i type: project-fila. Veglys-eksempelet har fire:
lystekniske minstekrav, vedlikeholdsfaktoren, at nattslukking ikke kan antas, og at tiltak
vurderes inne i porteføljen (VERIFISERT: shared/examples/veglys-fv-soer/veglys-fv-soer.md,
«Rammer»). Agentene leser dem som tekst; koden håndhever dem ikke (ANTATT: det følger av at
koden bare leser title fra fila, men er ikke målt mot en levende modell).
5. Hvilke tilnærminger vil du ha vurdert, og hvorfor?
Svaret blir oppdragsfila — se bestille-en-kjoring.md. description-feltet
mates ordrett inn til modellen; det er der fagkunnskapen om hvorfor tiltaket er verdt å prøve
gjør en forskjell. Hver tilnærming bør ha et motstykke i basen: en type: hypothesis-fil med
parametere, modellert besparelse og kjent usikkerhet (KONVENSJON: begge veiprosjekt-basene har
én hypothesis-fil per kandidat-tiltak; koden krever det ikke).
6. Hvordan måles og verifiseres en besparelse i dette faget?
Svaret blir type: methodology-fila. Den forteller agentene hvorfor modellert og faktisk
besparelse kan sprike, og hvilken måleopsjon som er åpen for dette anlegget. For veglys er svaret
«IPMVP Option A, ved eliminasjon» fordi anlegget mangler måler (VERIFISERT: veglys
metode-ipmvp-a.md).
Hvis fagmiljøet har en mal: kopier og tilpass. Tilpasningen er ikke pynt — den delen som
forklarer hvilke opsjoner som er stengt for dette anlegget er prosjektspesifikk.
7. Hva vet litteraturen om gapet mellom modellert og faktisk besparelse her?
Svaret blir type: reference-fila. Skill skarpt mellom det som er målt i vårt eget land/regime
og det som er lånt fra andre program — veglys-eksempelet deler fila i «Del A — norsk materiale»
og «Del B — lånt materiale», og sier hvorfor: «Å blande de to ville gjort et lånt tall til en
norsk måling» (VERIFISERT: kilder-veglys-realisering.md).
Hvis svaret er «det finnes ingen norsk måling»: skriv det. Et navngitt evidenshull er innhold;
et oppdiktet tall er forurensning.
8. Finnes det tidligere erfaring med lignende tiltak — en dom noen faktisk har avgitt?
Svaret blir en frø-dom: en type: verdict-fil med decision, en description som bærer
begrunnelsen, og der det finnes, realization_rate og expected_actual_saving_nok. Det er disse
feltene som når neste hypotese (VERIFISERT: verdicts.py _verdict_rationale).
Hvis svaret er nei: det er lovlig å starte med tom erfaring. Demoen starter slik — «fersk
kunnskapsbase, ingen tidligere dommer» (VERIFISERT: golden-transkriptet linje 11 og 14). Den
første ekte dommen kommer etter første kjøring, via innboksen.
9. Skal kjøringen avgrenses til én kostakse?
Hvis bestillingen gjelder for eksempel energi og ikke vedlikehold, settes en
dimensjonsavgrensning (--dimension-config). Da leser agentene bare filer som er merket med den
dimensjonen eller er umerket, og et forslag utenfor aksen avvises (VERIFISERT: run.py:517-519,
728-740; okf.py bundle_context). Filene merkes med dimension: i frontmatter.
Hvis svaret er nei: la det være. Ingen av eksempelbasene bruker dimension: (VERIFISERT:
grep gir null treff under shared/examples/).
10. Ligger kildene som data — regneark, database, tjeneste — eller som dokumenter?
Tabelldata kan hentes inn automatisk med et ingest-manifest: én JSON-fil som kobler en kilde
(CSV-katalog, SQL-database, HTTP-endepunkt eller MCP-tjeneste) til basen, og skriver én
markdown-fil per uttrekk (ingest-<id>.md) med provenance-stempel og lenke i index.md
(VERIFISERT: shared/ingest-spec.md §2, §4–§7). Manifestet kan aldri skrive en dom-fil, og det
kan aldri gi seg selv nettverkstilgang — den er et kjøreargument (VERIFISERT: §3, §8).
Det ingest IKKE gjør: skrive validator-input.json eller cost-baseline.json. Begge er
håndarbeid (VERIFISERT: extending.md, «An ingested bundle is not yet a runnable
bundle»). Dokumenter i fri form (PDF, notat) oversettes manuelt til markdown i dag.
11. Hvem skal avgi dommen etterpå — og etter hvilke kostkoder?
Svaret blir en innboks-mappe (--verdict-dir) eksperten skriver i, og eventuelt en rutingtabell
som sier hvilken ekspert som får hvilke forslag, etter kostkode-prefiks (VERIFISERT:
src/portfolio_optimiser/hitl.py, route). Innboksen skal være en annen mappe enn utboksen
kjøringen skriver til — de har motsatt eierskap (ekspert-svar.md).
4. Innholdstypene
| Innhold | Eies av | Fagpersonen leverer | Brukes i loopen til | Hvis den mangler |
|---|---|---|---|---|
index.md |
teknisk person, tekst fra prosjekteier | et avsnitt om hva prosjektet er og hvorfor dette fagområdet er valgt | brødteksten er det første agentene leser, ordrett; lenkene bestemmer hva som ellers leses | kjøringen nektes — «a bundle has no entry point without it» (VERIFISERT: method-spec §3 Steg 1) |
type: project |
prosjekteier / drift | anleggsregister, energibaseline, rammer — regneark og notat | kontekst: hva anlegget er, tallene det består av, gulvet ingen besparelse kan gå under | kjøringen starter; prosjektnavnet faller tilbake til ID-en (VERIFISERT: run.py _project_from_bundle); agentene resonnerer uten rammer (ANTATT) |
type: hypothesis |
prosjekteier + fagmiljø | kandidat-tiltak med parametere, modellert besparelse, hva som er usikkert, hva som er utledet | kontekst: forslagene agentene forbedrer i stedet for å finne opp; «Mapping til validatoren» forklarer tallfilene | kjøringen starter; forslagene står på oppdragsfilas description alene (ANTATT) |
type: methodology |
fagmiljøet | målemetode (M&V), hvilke opsjoner som er åpne og stengt for dette anlegget — notat eller mal | kontekst: hvorfor modellert ≠ faktisk, og hva som kan verifiseres etterpå | kjøringen starter; gap-resonnementet mangler i konteksten (ANTATT) |
type: reference |
fagmiljøet | verifisert litteratur med kilde og årstall; eget materiale skilt fra lånt | kontekst: tallgrunnlaget for realiseringsgrad og gap-mekanismer | kjøringen starter; en realiseringskorreksjon har ingenting å forankres i (ANTATT) |
type: verdict (frø) |
fageksperten | en tidligere dom: beslutning, begrunnelse, realiseringsgrad, forventet faktisk besparelse | ikke lest som kontekst; hentes som «tidligere dom» og legges foran hypoteseprompten | lovlig: første kjøring har null tidligere dommer (VERIFISERT: golden linje 14) |
validator-input.json |
teknisk person, tall fra prosjekteier | den ene projiserte kandidaten: kostlinjer, modellert besparelse, usikkerhetsbånd | prosjekt-ID-sjekk ved oppstart; nøkkelen tidligere dommer hentes med | kjøringen nektes, rc 1: «IR projection not found in bundle» (VERIFISERT ved kjøring, §4.1) |
cost-baseline.json |
prosjekteier / drift | prosjektets faktiske kostlinjer: kode → mengde × enhetspris | validatorens steg 0: hvert forslag avstemmes mot ekte linjer FØR noe annet regnes | kjøringen starter, rc 0, uten melding — gaten er uforankret (VERIFISERT ved kjøring, §4.1). Finnes fila men er feilformet: kjøringen nektes (VERIFISERT) |
| oppdragsfila | bestilleren | hensikt, tilnærminger med begrunnelse, suksesskriterium | hva som vurderes; kunngjøring før og oppgjør etter | kjøringen går uten bestilling: systemet foreslår selv; ingen kunngjøring, intet oppgjør per tilnærming |
| dom-innboksen | fageksperten | én JSON-fil per dom, etter kjøringen | merges inn før neste hypotese; lærer systemet noe | lovlig: ingen læring mellom kjøringene |
| dimensjonskonfig | bestilleren | hvilken kostakse kjøringen gjelder | avgrenser lesekontekst og avviser forslag utenfor aksen | lovlig: hele basen leses, ingen avvisning på akse |
| ingest-manifest | teknisk person | — (kobler en datakilde fagpersonen eier til basen) | skriver ingest-*.md med provenance før kjøringen |
lovlig: alt er håndkuratert |
| MCP-konfig | bestiller + teknisk person | hvilke interne tjenester agentene får spørre, med navngitte verktøy | oppslag under debatten; alt som kan kontaktes står i kunngjøringen | lovlig: null nettverkskall (VERIFISERT: bestille-en-kjoring.md) |
De fire typene project, hypothesis, methodology og reference er KONVENSJON: de står
i alle tre eksempelbasene, men ingen av de to spesifikasjonene nevner dem (VERIFISERT: grep
over shared/method-spec.md og shared/ingest-spec.md gir null treff). Spesifikasjonen normerer
bare at type er påkrevd, at index.md er inngangen, og at verdict er reservert. En base kan
bruke andre typenavn; de renderes som ## <type>: <tittel> uansett. Hold dere til de fire likevel
— lesbarhet på tvers av baser er verdt mer enn friheten (ANTATT).
4.1 Den skarpeste mangelen: cost-baseline.json
Før denne fila fantes resonnerte hver del av validatoren bare om tall forslaget selv oppga, så
«an internally consistent hallucination passes» (VERIFISERT: README.md, «How it is set up»).
Fila forankrer gaten i prosjektets ekte kostlinjer: hvert forslag avstemmes mot dem i et steg 0
før løseren, og to ting avvises — en kostkode prosjektet ikke har, og en ekte kode med mengde
eller enhetspris utenfor 5 % av baselinens verdi (VERIFISERT: validator.py:154-190, :210-214).
Men fila er valgfri på bundle-stien, og fraværet er stille. Målt 2026-08-21 med
--live-dry-run på fire kopier av veglys-basen, samme kommando, samme oppdragsfil:
| Variant | Utfall | rc | Melding |
|---|---|---|---|
| intakt | LIVE-DRY-RUN OK |
0 | — |
uten validator-input.json |
nektet | 1 | live-dry-run refused: IR projection not found in bundle: 'validator-input.json' |
uten cost-baseline.json |
LIVE-DRY-RUN OK |
0 | ingen |
korrupt cost-baseline.json (quantity: -1, unit_cost mangler) |
nektet | 1 | live-dry-run refused: 2 validation errors for CostBaseline … |
Kjeden som gir det utfallet: okf.load_optional_cost_baseline returnerer None når fila mangler
(VERIFISERT: okf.py:323-335), run.py:516 tar imot None, og validate_proposal hopper over
steg 0 når baselinen er None (VERIFISERT: validator.py:213). Det er med vilje — en base skrevet
før fila fantes skal fortsatt kjøre byte-identisk (VERIFISERT: CLAUDE.md, S4.0-raden). Men
ingenting i kjørestien sier at det skjedde: verken stdout, provenance eller utboksen bærer et
felt for forankret/uforankret (VERIFISERT: grep baseline over provenance.py og outbox.py
gir null treff). Den eneste flaten som skriver det høyt er demoen, som printer
«KUNNSKAPSBASE: … — uten kostbaseline» når fila mangler (VERIFISERT: simulation.py:791-802).
Konsekvensen for planleggingen: spørsmål 2 i §3
er det eneste spørsmålet der et «vet ikke» ikke stopper noe — og derfor det eneste der svaret må
dokumenteres utenfor systemet. En base uten cost-baseline.json bør ikke kalles kjøreklar av
noen som vet hva fila gjør (ANTATT: en arbeidsregel; koden lar deg kjøre).
5. Veiprosjektet Fylkesveg Sør: fra bestilling til kjøreklar base
Eksempelet følger en veglysportefølje langs fylkesveg. Basen det ender i er
shared/examples/veglys-fv-soer/, som er sjekket inn, kjører i demoen og er målt med
kjøreklar-sjekken under. Prosjektlaget i den basen er fiktivt — porteføljen finnes ikke —
mens litteraturlaget er ekte og kildebelagt (VERIFISERT: basens index.md). Det gjør den til et
godt eksempel på nøyaktig det skillet §2 handler om: et ekte
prosjekt bytter ut prosjektlaget og beholder resten.
5.1 Bestillingen
En driftsleder i fylkeskommunen vil vite hva LED-utskifting gir på de eldste strekningene, og om styring oppå det er verdt noe. Oppdragsfila (VERIFISERT: akseptert av kjøringen, kunngjøringen under er dens faktiske utskrift):
{
"objective": "Redusere energikostnaden i veglysporteføljen Fylkesveg Sør uten å gå under lystekniske minstekrav, med tiltak som kan bestilles i 2027.",
"approaches": [
{
"id": "led-trinn-1",
"label": "LED-utskifting av de 2 500 eldste HPS-punktene",
"description": "Drift melder at armaturene på de eldste strekningene er fra før 2005 og byttes hyppig; vi vil vite hva ren armaturutskifting gir før styring vurderes."
},
{
"id": "adaptiv-styring",
"label": "Adaptiv styring på de LED-utskiftede punktene",
"description": "Håndbok V124 tillater MF 0,85; vi tror nye anlegg overdimensjoneres og at marginen kan hentes ut med dimming, men har ingen måling."
}
],
"allow_own_proposals": true,
"success_criteria": "Minst ett tiltak som passerer validatoren og som driftsavdelingen kan stå inne for."
}
Bestillingen er den første målingen av basen: hver tilnærming nevner ting basen må kunne svare på — armaturalder, vedlikeholdsfaktor, lystekniske minstekrav, fravær av måling.
5.2 Spørsmålene, besvart for dette prosjektet
| # | Spørsmål | Svar for Fylkesveg Sør | Lander i |
|---|---|---|---|
| 1 | Prosjekt-ID | VEGLYS-FV-SOER — samme streng på kommandolinjen og i begge tallfiler |
alle tre |
| 2 | Kostlinjer med ekte tall | én linje: porteføljens årlige energikostnad, ENERGI-VEGLYS-EL, 4 386 150 kWh à 1,00 NOK. Investeringskostnad bevisst utelatt — ingen kilde gir NOK per lyspunkt |
cost-baseline.json |
| 3 | Den ene projiserte kandidaten | LED-utskifting trinn 1 (2 500 punkter, 114 → 70 W), modellert 445 500 NOK/år | validator-input.json |
| 4 | Harde rammer | lystekniske minstekrav (1,0 cd/m², 5 lx), MF ≤ 0,85, nattslukking kan ikke antas, tiltak vurderes inne i porteføljen | veglys-fv-soer.md |
| 5 | Tilnærminger | de to i oppdragsfila, pluss systemets egne | oppdragsfila + to hypothesis-filer |
| 6 | Målemetode | IPMVP Option A, ved eliminasjon: umålt anlegg stenger B, C og D | metode-ipmvp-a.md |
| 7 | Litteratur om gapet | norsk: baseline, regelverk og årsaken til at gapet ikke kan ses (mangler måler). Lånt: selve realiseringsgraden (amerikansk programlitteratur, 0,81) | kilder-veglys-realisering.md |
| 8 | Tidligere erfaring | én frø-dom: godkjent med realiseringskorreksjon, rate 0,81, merket som lån | verdict-veglys-fro.md |
| 9 | Avgrensning til kostakse | nei — porteføljen har én kostlinje | — |
| 10 | Kilder som data | nei — anleggsregisteret er levert som tall i et notat; alt er håndkuratert | — |
| 11 | Hvem dømmer | fylkets egen energirådgiver, etter kjøringen, via innboksen | --verdict-dir |
(Alle svar i kolonnen «Svar» er VERIFISERT mot filene i shared/examples/veglys-fv-soer/; kolonnen
«Lander i» er VERIFISERT mot filnavnene der.)
5.3 Hva fagpersonene leverer
| Leveranse | Fra | Form de leverer i | Blir til |
|---|---|---|---|
| Anleggsregister: antall lyspunkter, armaturtype, installert effekt | drift | uttrekk fra anleggsdatabasen, regneark | type: project (energibaseline) + raden i cost-baseline.json |
| Brenntimer og energipris | drift / økonomi | tabellverdi (Håndbok V124) + fakturagrunnlag | samme; prisbåndet i validator-input.json |
| Kravgrunnlag: lystekniske minstekrav, vedlikeholdsfaktor | fagmiljø vegbelysning | henvisning til NMFV og Håndbok V124 | «Rammer» i type: project |
| Kandidat-tiltak med parametere | drift + fagmiljø | notat: før/etter-effekt, antall, hva som er utledet | to type: hypothesis-filer |
| M&V-praksis for umålte anlegg | fagmiljø | mal for IPMVP, tilpasset | type: methodology |
| Litteratur om realiseringsgap, med kilde | fagmiljø | kildeliste med URL og årstall, merket norsk/lånt | type: reference |
| Tidligere vurdering av LED på småveg | energirådgiver | kort notat: «forvent ~80 % av modellert, fordi …» | type: verdict (frø) |
Leveranseformene er ANTATT — de er det en slik leveranse rimelig ser ut som, ikke noe eksempelbasen dokumenterer. Det som er VERIFISERT er hva hver leveranse blir til.
5.4 Basen som bygges
veglys-fv-soer/
├── index.md type: index inngangen; lenker til alt under
├── veglys-fv-soer.md type: project porteføljen, energibaselinen, rammene
├── tiltak-led-utskifting.md type: hypothesis kandidat 1 — den som er projisert
├── tiltak-adaptiv-styring.md type: hypothesis kandidat 2 — svakere kildebelagt, og merket slik
├── metode-ipmvp-a.md type: methodology Option A, og hvorfor de andre er stengt
├── kilder-veglys-realisering.md type: reference Del A norsk / Del B lånt
├── verdict-veglys-fro.md type: verdict frø-dommen — holdes ute av lesekonteksten
├── validator-input.json den projiserte kandidaten
└── cost-baseline.json prosjektets ene kostlinje
(VERIFISERT: ls shared/examples/veglys-fv-soer/ og grep '^type:' over filene.)
index.md gjør to jobber i denne basen. Den første er navigasjon: seks lenker, én per fil, med
type og én setning hver. Den andre er å si høyt hva som er fiktivt og hva som er ekte, og
hvorfor domenet er valgt — at realiseringsgraden i norsk veglys er «strukturelt usynlig» fordi
anlegget mangler måler. Begge deler går ordrett inn som det første agentene leser.
5.5 De to tallfilene — skrevet fra samme linje
Hele basens tallgrunnlag er én linje aritmetikk:
9 500 lyspunkter × 114 W × 4 050 t/år ÷ 1 000 = 4 386 150 kWh/år à 1,00 NOK = 4 386 150 NOK/år
cost-baseline.json bærer den som ENERGI-VEGLYS-EL: {quantity: 4386150, unit_cost: 1.0}.
validator-input.json bærer nøyaktig samme kode, mengde og pris i affected_items, pluss den
modellerte besparelsen for trinn 1 (2 500 × 44 W × 4 050 t ÷ 1 000 = 445 500 kWh ≈ 445 500 NOK)
og prisbåndet 0,70–1,40 NOK/kWh til risikosimuleringen (VERIFISERT: begge filene). De to er ikke
«innenfor toleranse» — de er identiske, fordi begge er skrevet fra samme linje. Det er slik
toleransen på 5 % skal lukkes: ved konstruksjon, ikke ved avstemming etterpå.
Én beslutning i mappingen er verdt å lære av: affected_items er hele porteføljens
energikostnad, ikke de 2 500 berørte punktenes eget forbruk. Hadde det vært det siste, ville
besparelsen vært 38,6 % av linjen — over validatorens 30 %-tak — og det riktige forslaget blitt
avvist av en gate som målte feil størrelse (VERIFISERT: tiltak-led-utskifting.md, «Mapping til
validatoren»). Kostlinjen skal være den linjen tiltaket virker på i regnskapet.
5.6 Frø-dommen
type: verdict
decision: approved_with_adjustment
realization_rate: 0.81
modelled_saving_nok: 445500
expected_actual_saving_nok: 360855
description: "… brenntimene er et nasjonalt tabellanslag, ikke en målt kurve, og anlegget
mangler måler — så avviket kan ikke oppdages i drift. Forventet faktisk besparelse settes til
81 % av modellert, lånt fra belysnings-programlitteratur og merket som lån. …"
provenance: "frø — AI-forfattet. Realiseringsgraden er LÅNT … Det finnes INGEN norsk ex-post-måling
for veglys. Erstattes av ekte HITL i produksjon."
(Utdrag; VERIFISERT: verdict-veglys-fro.md.) Det som når neste hypotese er description pluss
[realiseringsgrad=0.81; forventet_faktisk_NOK=360855] (VERIFISERT: verdicts.py
_verdict_rationale). provenance-feltet leses ikke av koden — men det er det som gjør at en
fagperson som åpner basen ser at dommen er et frø og raten et lån. I et ekte prosjekt erstattes
denne fila av energirådgiverens egen vurdering, i samme form.
5.7 Kjøreklar-sjekken
Det finnes ingen egen «valider basen»-kommando (§6). Det nærmeste er en tørrkjøring med bestillingen på plass:
uv run python -m portfolio_optimiser.run VEGLYS-FV-SOER \
--docs-dir shared/examples/veglys-fv-soer \
--bundle-dir shared/examples/veglys-fv-soer \
--mandate oppdrag.json \
--live-dry-run
Målt 2026-08-21 (VERIFISERT, rc 0):
Run mandate for VEGLYS-FV-SOER
Objective: Redusere energikostnaden i veglysporteføljen Fylkesveg Sør uten å gå under lystekniske minstekrav, med tiltak som kan bestilles i 2027.
Evaluates: 2 expert-proposed approach(es) + the system's own proposals
1. led-trinn-1 — LED-utskifting av de 2 500 eldste HPS-punktene
2. adaptiv-styring — Adaptiv styring på de LED-utskiftede punktene
Stops at: 3 rounds / 100000 tokens
Contacts: no external services
Success: Minst ett tiltak som passerer validatoren og som driftsavdelingen kan stå inne for.
VEGLYS-FV-SOER: LIVE-DRY-RUN OK (profile=local, models={'proposer': 'qwen3:4b', 'checker': 'qwen3:4b'}, max_rounds=3, max_tokens=100000, top_k=3) — ingen modellkall gjort (stoppet før første debate.run)
Hva OK beviser: basen åpner — index.md finnes, validator-input.json finnes og bærer
riktig prosjekt-ID, cost-baseline.json hvis den finnes er velformet, bestillingen er gyldig,
modellene er oppløst, takene er satt, og ingen ekstern tjeneste vil bli kontaktet. Alt dette
skjer før kuttet, uten et eneste modellkall (VERIFISERT: run.py:513-516 ligger før
dry-run-returen på :565-588).
Hva OK ikke beviser: at cost-baseline.json finnes (se §4.1
— sjekk det med ls), at lenkene i index.md når alle filene (en brutt lenke hoppes stille over),
eller at innholdet er godt. --docs-dir må oppgis, men leses ikke på bundle-stien (VERIFISERT:
run.py:513-530 bruker bare bundle_dir; :1504 krever flagget likevel). Pek den på samme
mappe.
Det offline ende-til-ende-beviset på denne basen er demoen:
uv run python -m portfolio_optimiser.simulation. Den kjører nøyaktig veglys-fv-soer, skriver
«KUNNSKAPSBASE: veglys-fv-soer — kostbaseline erklært (ENERGI-VEGLYS-EL 4386150 x 1)», navigerer
de fem konseptfilene, og viser at en dom avgitt etter kjøring A når kjøring B (VERIFISERT:
tests/golden/demo-transcript.stdout, linjene 7, 13 og 50). Agent-svarene i demoen er
skriptede; den beviser dataflyten, ikke modellens dømmekraft.
5.8 Etter kjøringen
Kjør med --outbox-dir og --run-id, så legger kjøringen igjen én artefakt per vurdert
tilnærming. hitl pending viser hva som venter på dom; energirådgiveren skriver dommen som
JSON-fil i innboksen etter ekspert-svar.md. Neste kjøring med --verdict-dir
leser den inn før hypotesen formes. Godkjennes den for promotering, blir den en ny
type: verdict-fil i basen — og basen er blitt én versjon klokere.
6. Ærlighetsdelen: hva som ikke finnes i dag
Ingenting under er en feil i koden. Det er grensen for hva som er bygget, og det skal stå her så dokumentet ikke lover mer enn det som kan leveres.
- Bundle-fabrikken er ikke bygget (operatørbeslutning D-G / T0). Det finnes ingen verktøy
som tar fagpersonens regneark og notater og lager en base. Oversettelsen til markdown,
lenkene i
index.mdog begge tallfilene er den tekniske personens håndarbeid (VERIFISERT: knowledge-base-recipe.md, «Future / factory-dependent»). - Fri-format-oversettelse av dommer finnes ikke. Frø-dommer skrives direkte i det strenge formatet (VERIFISERT: samme sted). Den tiltenkte flyten — eksperten leverer fri tekst, en oversetter lager den strukturerte dommen, som alltid peker tilbake på originalen — er beskrevet, ikke bygget.
- Ingest har ingen kommandolinje.
materializeer et Python-API (VERIFISERT: ingen__main__isrc/portfolio_optimiser/ingest.py), og «no bundle has yet been materialized from a live source» (VERIFISERT:README.md). Det som er målt er fil/CSV, SQL, HTTP og MCP mot innsjekkede fixtures. - Tidligere dommer hentes én gang per kjøring, for den projiserte kandidaten — ikke per
tilnærming i bestillingen (VERIFISERT:
run.py:634-638; énexpel_queryfor hele kjøringen). En bestilling med to tilnærminger mot to ulike kostlinjer får tidligere dommer hentet for den kandidatenvalidator-input.jsonbeskriver. - Det finnes ingen «er basen klar?»-kommando.
--live-dry-runbeviser at basen åpner; den sier ingenting om atcost-baseline.jsonmangler, og ingenting om brutte lenker.preflightsjekker Azure-konfigurasjon, ikke basen (VERIFISERT:preflight.pydocstring). - En uforankret kjøring etterlater ingen spor. Verken stdout,
provenanceeller utboksen sier om validatoren hadde en kostbaseline (VERIFISERT: §4.1). Dette dokumentet er i dag den eneste beskrivelsen av den egenskapen utenfor koden ogCLAUDE.md. - Eksempelbasene er ikke ekte prosjekter. Prosjektlaget er fiktivt; realiseringsgraden i alle
tre frø-dommene er lånt fra utenlandsk programlitteratur fordi ingen norsk ex-post-måling
finnes (VERIFISERT:
provenance-feltet i de tre dom-filene). - De fire innholdstypene er konvensjon, ikke spesifikasjon (§4).
docs/extending.mder utdatert på ett punkt: den sier at ingen eksempelbase shippercost-baseline.json. Det var sant da den ble skrevet (2026-08-05); begge veiprosjekt-basene har fått fila siden (VERIFISERT:ls, begge datert 2026-08-09). Rettelsen er ikke gjort her, for den hører hjemme i det dokumentet.- 1–2 uker. Oppskriften sier det, og ingenting i dette dokumentet korter det ned. Det som står her er hva ukene skal brukes til.
7. Hvis utforskningen skulle konkludere med kode
Den gjør det på ett punkt, og det er uttalt her i stedet for bygget: en kjøring som går uten
cost-baseline.json burde si det — i kunngjøringen, i provenance, eller begge. Demoen gjør det
allerede; kjørestien gjør det ikke. Det er en beslutning for eieren av repoet, ikke for dette
dokumentet.
8. Verifiseringslogg
| Påstand | Kilde | Status |
|---|---|---|
| Én base per prosjekt | shared/method-spec.md §2 («one curated … knowledge bundle per project») |
VERIFISERT |
Navigasjon fra index.md, flat rendering ## type: tittel, verdict ekskludert |
shared/method-spec.md §3 Steg 1; src/portfolio_optimiser/okf.py bundle_context, context_files |
VERIFISERT |
| Lenke ut av basen hoppes stille over | method-spec §3 Steg 1 | VERIFISERT |
| Fil uten index-lenke er unåbar | shared/ingest-spec.md §2 |
VERIFISERT |
| Verdict-laget reservert; ingest kan ikke skrive det | ingest-spec §3, §4 (okf_type MUST NOT be verdict) |
VERIFISERT |
Tidligere dommer nøkles på validator-input.json-kandidaten, én gang per kjøring |
run.py:634-638; verdicts.py bundle_candidate_features |
VERIFISERT |
Det som valideres er modellens forslag, ikke validator-input.json |
generate.py:491 |
VERIFISERT |
Seks type:-verdier i drift: index 3 · project 4 · hypothesis 5 · methodology 3 · reference 3 · verdict 3 |
grep -h '^type:' shared/examples/*/*.md | sort | uniq -c (2026-08-21) |
VERIFISERT |
| De fire ikke-reserverte typene er ikke nevnt i noen spesifikasjon | grep over shared/method-spec.md og shared/ingest-spec.md — null treff |
VERIFISERT |
| Metode-filene er tre ulike filer (40 / 81 / 98 linjer), materialisert per base | wc -l, diff; begge index.md («materialisert inn her») |
VERIFISERT |
Koden leser ikke resource, measure_id, gap_source, context_key, okf_version, tags |
grep over src/portfolio_optimiser/*.py — null treff |
VERIFISERT |
dimension: brukes av ingen eksempelbase |
grep -rn '^dimension:' shared/examples/ — null treff |
VERIFISERT |
Prosjekt-ID må stemme mellom kommandolinje og validator-input.json |
run.py _project_from_bundle |
VERIFISERT |
Prosjektnavn leses fra type: project-filas title, ellers ID |
samme | VERIFISERT |
| Steg 0 avviser ukjent kode og avvik > 5 % | validator.py:154-190; BASELINE_TOLERANCE_DEFAULT = 0.05 |
VERIFISERT |
Manglende cost-baseline.json → None → steg 0 hoppes over |
okf.py:323-335; run.py:516; validator.py:213 |
VERIFISERT |
| Fire tørrkjøringer: intakt rc 0 · uten IR rc 1 · uten baseline rc 0 uten melding · korrupt baseline rc 1 | kjørt 2026-08-21 på kopier i scratchpad, kommandoen i §5.7 | VERIFISERT |
| Ingen artefakt bærer forankret/uforankret | grep baseline src/portfolio_optimiser/provenance.py src/portfolio_optimiser/outbox.py — null treff |
VERIFISERT |
| Demoen printer forankringsstatus | simulation.py:791-802; golden linje 7 |
VERIFISERT |
--live-dry-run navigerer basen og laster begge tallfiler før kuttet |
run.py:513-516 vs :565-588 |
VERIFISERT |
--docs-dir påkrevd men ulest på bundle-stien |
run.py:513-530, :1504 |
VERIFISERT |
Demoen kjører veglys-fv-soer, navigerer 5 konseptfiler, henter 0 så 3 dommer |
tests/golden/demo-transcript.stdout linjene 7, 13, 14, 50 |
VERIFISERT |
Frø-rationale = description + [realiseringsgrad=…; forventet_faktisk_NOK=…] |
verdicts.py _verdict_rationale |
VERIFISERT |
| Dom-nøkkel-trioen: alle tre felt eller ingen | verdicts.py _features_from_verdict_frontmatter; README.md |
VERIFISERT |
| Veglys-tallene: 9 500 × 114 W × 4 050 t = 4 386 150 kWh; 445 500 NOK modellert; 10,2 % av total; 38,6 % av berørte punkter | veglys-fv-soer.md, tiltak-led-utskifting.md, begge JSON-filer |
VERIFISERT |
| Frø-dommen: rate 0,81, forventet 360 855, lånt | verdict-veglys-fro.md frontmatter |
VERIFISERT |
| Fabrikk og fri-format-oversettelse ikke bygget | docs/knowledge-base-recipe.md; docs/plan/2026-07-14-revisjonspakke-DF-DI.md §3 |
VERIFISERT |
| Ingest har ingen CLI; ingen base materialisert fra levende kilde | grep __main__ src/portfolio_optimiser/ingest.py — null treff; README.md «How it is set up» |
VERIFISERT |
Ingest skriver ikke validator-input.json / cost-baseline.json |
docs/extending.md, «Legg til en ingest-kilde» |
VERIFISERT |
docs/extending.md sier ingen eksempelbase shipper cost-baseline.json |
samme dokument; motbevist av ls shared/examples/{veglys-fv-soer,tunnel-hauglia}/ |
VERIFISERT (utdatert) |
| Leveranseformene i §5.3; anbefalingene merket ANTATT | — | ANTATT |