feat(shared): S4 — re-introduce shared/ as subtree of portfolio-optimiser-commons
commons (ktg/portfolio-optimiser-commons @ 7d2b46c) is now the source of truth for the framework-neutral shared core; this repo consumes it via git subtree (--squash) at the unchanged shared/ path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AaQCFnfsh3tfq1VfzdJpoi
This commit is contained in:
commit
ecd83066fb
13 changed files with 960 additions and 0 deletions
75
shared/CONCEPT.md
Normal file
75
shared/CONCEPT.md
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
# Konseptet
|
||||||
|
|
||||||
|
*En beskrivelse i klartekst av hva dette prosjektet er og hvorfor det betyr noe — skrevet
|
||||||
|
for en ikke-spesialist, f.eks. en forretningsutvikler i et annet selskap. Framework-nøytral:
|
||||||
|
den beskriver metoden, ikke en bestemt implementasjon.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemet
|
||||||
|
|
||||||
|
Mange virksomheter driver en **portefølje av uavhengige prosjekter** samtidig —
|
||||||
|
byggeprosjekter, IT-tjenester, anlegg, produksjonslinjer. Inne i *hvert enkelt* prosjekt
|
||||||
|
ligger det skjulte kostnadsbesparelser: et materiale som kan byttes, en dimensjonering som
|
||||||
|
er unødig konservativ, en innkjøpsavtale som kan reforhandles. Å finne dem krever at en
|
||||||
|
erfaren fagperson setter seg grundig inn i nettopp dét prosjektet — og den kompetansen er
|
||||||
|
dyr og skalerer dårlig over en hel portefølje. Så besparelsene blir liggende igjen.
|
||||||
|
|
||||||
|
Generativ AI kan foreslå ideer, men en forretningsutvikler ser umiddelbart to hindre: du
|
||||||
|
kan ikke stole på tall en språkmodell *gjetter*, og modellen kjenner ikke din bransjes
|
||||||
|
faktiske regler og erfaring. Konseptet er bygget nettopp for å fjerne disse to hindrene.
|
||||||
|
|
||||||
|
## Slik virker det
|
||||||
|
|
||||||
|
For hvert prosjekt samles alt som er kjent om det — prosjektdokumenter, fagets
|
||||||
|
vurderingsmetodikk, relevant faglitteratur, og de harde rammene (budsjett, hva som ikke kan
|
||||||
|
endres, regulatoriske krav) — i en **kuratert kunnskapsbase per prosjekt**. Den er bygget på
|
||||||
|
en åpen, leverandørnøytral standard (Googles Open Knowledge Format), så den er portabel og
|
||||||
|
ikke innelåst i én leverandør.
|
||||||
|
|
||||||
|
Et lag med AI-agenter leser denne konteksten, foreslår konkrete tiltak og diskuterer dem mot
|
||||||
|
hverandre — én foreslår, en annen kritiserer. Men — og dette er kjernen — **agentene får
|
||||||
|
aldri avgjøre verdien selv.** Hvert tall sendes til en separat, **deterministisk
|
||||||
|
beregningsmotor** (matematisk optimering pluss risikosimulering) som regner ut den faktiske
|
||||||
|
besparelsen. AI-en foreslår; matematikken avgjør. Det er tillitsankeret som skiller dette
|
||||||
|
fra «spør en chatbot».
|
||||||
|
|
||||||
|
De tiltakene som overlever beregningen, legges fram for en **menneskelig fagekspert** som
|
||||||
|
gir en dom: godkjent, forbedre eller forkast.
|
||||||
|
|
||||||
|
## Det som gjør det verdifullt over tid
|
||||||
|
|
||||||
|
Her ligger differensieringen. Systemet **lærer av ekspertenes dommer.** Det er nesten alltid
|
||||||
|
et gap mellom hva en modell *beregner* og hva en erfaren fagperson faktisk *godkjenner* —
|
||||||
|
fordi eksperten vet hvordan tiltak oppfører seg i praksis, ikke bare i teorien. Systemet
|
||||||
|
fanger det gapet og mater det tilbake, så forslagene blir skarpere på *din* virksomhets
|
||||||
|
virkelighet, ikke generiske gjennomsnitt. Jo flere dommer, desto bedre.
|
||||||
|
|
||||||
|
Og det respekterer hvordan eksperter faktisk jobber: noen ganger svarer de der og da, andre
|
||||||
|
ganger går det dager eller uker. Eksperten legger rett og slett vurderingen sin i en
|
||||||
|
**mappe**, og systemet plukker den opp når den enn kommer. Ingen krav om sanntid, og ingen
|
||||||
|
trenger å sitte klar.
|
||||||
|
|
||||||
|
## Hva det er — og ikke er
|
||||||
|
|
||||||
|
Det er et **rent teknisk rammeverk**, ikke et ferdig compliance-produkt. Virksomheten som
|
||||||
|
tar det i bruk eier selv formål, personvern og styring; rammeverket leverer bare de tekniske
|
||||||
|
forutsetningene (kjøre lokalt, sporbarhet på hvert forslag, ingen data som lekker ut i det
|
||||||
|
stille). Det kan kjøre lokalt eller i skyen, og publiseres åpent så andre kan ta det i bruk.
|
||||||
|
|
||||||
|
## Hvorfor det bygges to ganger
|
||||||
|
|
||||||
|
Det samme konseptet bygges på **to ulike AI-agent-plattformer** — Microsofts Agent Framework
|
||||||
|
og Claudes Agent SDK — på nøyaktig samme eksempel, slik at de kan sammenlignes rettferdig.
|
||||||
|
Det gir både en åpen referanse andre kan kopiere, og et ærlig grunnlag for å vurdere hvilken
|
||||||
|
plattform som passer best til oppgaven.
|
||||||
|
|
||||||
|
## Konkret
|
||||||
|
|
||||||
|
Tenk energieffektivisering av en bygningsportefølje. Hvert bygg er et prosjekt med sine egne
|
||||||
|
tiltaksmuligheter (ventilasjon, belysning, isolasjon). Beregningsmotoren regner ut
|
||||||
|
*modellert* besparelse for en tiltakspakke under et budsjett. Men en energirådgiver vet at
|
||||||
|
modellert og faktisk besparelse sjelden er like — atferd, måleusikkerhet og samspill mellom
|
||||||
|
tiltak skaper et gap. Ekspertens dommer lærer systemet å lukke det gapet over tid. Det er
|
||||||
|
nettopp i et slikt fagfelt — der det finnes ekte ekspertskjønn *utover* ren beregning —
|
||||||
|
konseptet kommer til sin rett.
|
||||||
44
shared/README.md
Normal file
44
shared/README.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# shared/ — framework-neutral core
|
||||||
|
|
||||||
|
This directory holds the parts of the project that are **independent of any AI agent
|
||||||
|
framework** and are meant to be **shared, unchanged, between both reference
|
||||||
|
implementations**:
|
||||||
|
|
||||||
|
- **this repository** — the method built on Microsoft Agent Framework (MAF);
|
||||||
|
- **a sibling repository** (built later, in sequence) — the same method on the
|
||||||
|
**Claude Agents SDK**.
|
||||||
|
|
||||||
|
Sharing one identical core is what makes the two implementations a *fair comparison*:
|
||||||
|
both consume the same concept, the same example data, and the same expected outcomes,
|
||||||
|
so the only thing that differs is the agent framework itself.
|
||||||
|
|
||||||
|
## Contents (growing)
|
||||||
|
|
||||||
|
- [`CONCEPT.md`](CONCEPT.md) — the business concept, written for a non-specialist
|
||||||
|
(e.g. a business developer at another company).
|
||||||
|
- [`examples/bygg-energi-mikro/`](examples/bygg-energi-mikro/) — the first example knowledge
|
||||||
|
bundle (OKF / LLM-wiki): one office building, one LED-retrofit measure, with a seed expert
|
||||||
|
verdict encoding the realization gap and a golden-suite of expected validator outcomes. A
|
||||||
|
small **dev fixture** for exercising the agentic loop; a realistic full-scale example comes later.
|
||||||
|
- [`skills/expert-reviewer/`](skills/expert-reviewer/) — the **expert-reviewer persona** as a
|
||||||
|
framework-neutral Agent Skill: a `SKILL.md` persona prompt (energy-advisor / M&V role + the
|
||||||
|
realization-gap methodology the validator cannot compute) and a canonical
|
||||||
|
`references/example-verdict.json`. Both reference implementations instantiate the reviewer from
|
||||||
|
this one artifact; `shared/` stays pure data (each stack reads the JSON with its own loader).
|
||||||
|
- [`method-spec.md`](method-spec.md) — the **normative method specification**, framework-neutral
|
||||||
|
(the prose never names a concrete agent toolkit — enforced by a guard test): the 8-step loop,
|
||||||
|
the verdict JSON contract, the inbox/outbox folder contract, the promotion-gate semantics, the
|
||||||
|
IR projection + golden suite as the only ground truth, and the budget/provenance requirements.
|
||||||
|
The sibling implementation is built from this spec alone, without reverse-engineering the
|
||||||
|
reference code.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- **Nothing in here may import or depend on a specific agent framework.** If it does,
|
||||||
|
it does not belong in `shared/`.
|
||||||
|
- **Repo layout (decision R1, 2026-06-26):** the shared core lives here for now. When
|
||||||
|
work on the sibling repository begins, it will be extracted into its own repository
|
||||||
|
(e.g. `portfolio-optimiser-commons`) via `git subtree split`, and both implementation
|
||||||
|
repos will consume it. This defers cross-repo plumbing until it is actually needed.
|
||||||
|
|
||||||
|
See the target picture for the full architecture: `docs/plan/2026-06-26-maalbilde-agentic-loop.md`.
|
||||||
40
shared/examples/bygg-energi-mikro/bygg-kontor-nord.md
Normal file
40
shared/examples/bygg-energi-mikro/bygg-kontor-nord.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
type: project
|
||||||
|
title: "Kontorbygg Nord"
|
||||||
|
description: "Fiktivt næringsbygg (kontor) brukt som mikro-eksempel. Energibaseline og rammer for ett effektiviseringstiltak."
|
||||||
|
resource: BYGG-KONTOR-NORD
|
||||||
|
tags: [kontorbygg, energibaseline, naeringsbygg]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Kontorbygg Nord (BYGG-KONTOR-NORD)
|
||||||
|
|
||||||
|
Fiktivt kontorbygg. Tallene er **illustrative men forankret i typiske norske verdier** —
|
||||||
|
ikke et ekte bygg. En produksjons-deployer erstatter denne med en ekte kunnskapsbase.
|
||||||
|
|
||||||
|
## Energibaseline
|
||||||
|
|
||||||
|
| Størrelse | Verdi | Merknad |
|
||||||
|
|---|---|---|
|
||||||
|
| Oppvarmet bruksareal (BRA) | ~2 500 m² | [I] illustrativt |
|
||||||
|
| Totalt elforbruk | **300 000 kWh/år** | [I]; ~120 kWh/m²/år — typisk norsk kontor |
|
||||||
|
| Herav belysning | ~54 000 kWh/år (~18 %) | 200 armaturer × 90 W × 3 000 t/år |
|
||||||
|
| Variabel energikostnad | **1,00 NOK/kWh** ekskl. mva | [V-forankret] kraftpris + nettleie-energiledd + elavgift |
|
||||||
|
|
||||||
|
**Energiprisen** (1,00 NOK/kWh) er den marginale variable kostnaden et spart kWh faktisk
|
||||||
|
unngår, ekskl. mva (næring trekker fra mva). Sammensetning, forankret i SSB Q1 2026:
|
||||||
|
kraftpris tjenesteytende næringer ~0,80–1,12 NOK/kWh + nettleie energiledd ~0,10–0,13 +
|
||||||
|
elavgift 0,0713. Den varierer kraftig med prisområde (NO4 ~0,13 vs NO2 ~0,96 i kraftpris
|
||||||
|
alene) og sesong — derfor er den **konfigurerbar**, og usikkerheten håndteres i Monte
|
||||||
|
Carlo-steget (band 0,70–1,40 NOK/kWh). Se [kilder-realiseringsgap.md](kilder-realiseringsgap.md).
|
||||||
|
|
||||||
|
## Rammer (constraints)
|
||||||
|
|
||||||
|
- Tiltak vurderes **inne i** dette prosjektet (ikke på tvers av en portefølje).
|
||||||
|
- Budsjett og tekniske rammer eies av deployer; her holdes de minimale.
|
||||||
|
- Bygget driftes i normal kontortid; belysning styres delvis på timeplan (relevant for
|
||||||
|
realiseringsgapet — se [verdict-led-fro.md](verdict-led-fro.md)).
|
||||||
|
|
||||||
|
## Kandidat-tiltak
|
||||||
|
|
||||||
|
- [tiltak-led-retrofit.md](tiltak-led-retrofit.md) — LED-retrofit av belysning.
|
||||||
21
shared/examples/bygg-energi-mikro/golden.json
Normal file
21
shared/examples/bygg-energi-mikro/golden.json
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"_note": "Golden-suite (forventet utfall) for bygg-energi-mikro. To deler: (1) 'validator' fryser den deterministiske (seeded, _MC_SEED=20260624) outputen av validate_proposal pa validator-input.json — en regresjon som fanger utilsiktede endringer i validator/MC. Den MENINGSFULLE assertionen er validates=true (claimed < P90). (2) 'learning_surface' koder realiseringsgapet validatoren IKKE kan regne — ExpeL-froet fra verdict-led-fro.md. expected_actual = realization_rate * modelled.",
|
||||||
|
"validator": {
|
||||||
|
"outcome": "ValidatedProposal",
|
||||||
|
"validates": true,
|
||||||
|
"claimed_saving_nok": 30000,
|
||||||
|
"nominal_feasible": 90000.0,
|
||||||
|
"p10": 68543.08886748762,
|
||||||
|
"p50": 95443.98966314227,
|
||||||
|
"p90": 121057.08845805985,
|
||||||
|
"_percentile_meaning": "OVRE FEASIBLE GRENSE (30% av samplet energikostnad), IKKE LED-besparelsens fysiske band. Se tiltak-led-retrofit.md, 'Mapping til validatoren'."
|
||||||
|
},
|
||||||
|
"learning_surface": {
|
||||||
|
"modelled_saving_nok": 30000,
|
||||||
|
"realization_rate": 0.82,
|
||||||
|
"expected_actual_saving_nok": 24600,
|
||||||
|
"gap_source": "hours-of-use-overestimation",
|
||||||
|
"context_key": "kontorbygg; HOU-kilde=timeplan-stipulert",
|
||||||
|
"_meaning": "Det validatoren IKKE kan regne fra parameterne. ExpeL-frøet loopens steg 1 skal hente og anvende. Se verdict-led-fro.md."
|
||||||
|
}
|
||||||
|
}
|
||||||
42
shared/examples/bygg-energi-mikro/index.md
Normal file
42
shared/examples/bygg-energi-mikro/index.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
type: index
|
||||||
|
okf_version: 0.1
|
||||||
|
title: "Bygg-energi mikro-eksempel — kontorbygg, LED-retrofit"
|
||||||
|
description: "Minimal OKF-bundle for ett kontorbygg med ett energieffektiviseringstiltak (LED-belysningsretrofit). Utviklings-fixture for den agentiske loopen: kontekst → hypotese → deterministisk validering → ekspert-dom → læring."
|
||||||
|
tags: [energieffektivisering, M&V, IPMVP, mikro-eksempel, fixture]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bygg-energi mikro-eksempel
|
||||||
|
|
||||||
|
En **mikro OKF-bundle** (Open Knowledge Format): ett kontorbygg, ett kandidat-tiltak.
|
||||||
|
Den er liten med vilje — formålet er **rask småskala-testing og validering** av den
|
||||||
|
agentiske loopen gjennom hele utviklingsløpet. Et **realistisk fullskala-eksempel**
|
||||||
|
bygges senere (målbilde §8); dette er forløperen.
|
||||||
|
|
||||||
|
> Dette er en framework-nøytral artefakt (null kode-avhengighet). Den deles uendret
|
||||||
|
> mellom MAF- og Claude-SDK-implementasjonene. Se [shared/README.md](../../README.md).
|
||||||
|
|
||||||
|
## Hvorfor energieffektivisering
|
||||||
|
|
||||||
|
Domenet ble valgt for sin **lærings-overflate**: et reelt, dokumentert gap mellom det
|
||||||
|
en deterministisk validator kan *regne* (modellert besparelse fra parametere) og det en
|
||||||
|
fagekspert *kjenner* (faktisk realisert besparelse i drift). Det gapet — realiseringsgraden
|
||||||
|
— er det lærings-sløyfa (ExpeL) skal lære. Se [verdict-led-fro.md](verdict-led-fro.md).
|
||||||
|
|
||||||
|
## Innhold (progressiv disclosure)
|
||||||
|
|
||||||
|
- [bygg-kontor-nord.md](bygg-kontor-nord.md) — `type: project` — bygget og energibaseline.
|
||||||
|
- [tiltak-led-retrofit.md](tiltak-led-retrofit.md) — `type: hypothesis` — kandidat-tiltaket
|
||||||
|
(LED-retrofit) med alle parametere for den modellerte besparelsen.
|
||||||
|
- [metode-ipmvp-a.md](metode-ipmvp-a.md) — `type: methodology` — M&V-metoden (IPMVP Option A).
|
||||||
|
- [kilder-realiseringsgap.md](kilder-realiseringsgap.md) — `type: reference` — verifisert
|
||||||
|
litteratur om realiseringsgrad og dets årsaker.
|
||||||
|
- [verdict-led-fro.md](verdict-led-fro.md) — `type: verdict` — frøsatt ekspert-dom som koder
|
||||||
|
realiseringsgapet. **ExpeL-frøet** loopens steg 1 henter fra.
|
||||||
|
|
||||||
|
## Hvordan den kjøres i dag
|
||||||
|
|
||||||
|
`validator-input.json` er IR-projeksjonen den **eksisterende deterministiske validatoren**
|
||||||
|
konsumerer uendret (energitiltaket mappet inn i kost-IR-en); `golden.json` fryser det
|
||||||
|
forventede utfallet. Se [tiltak-led-retrofit.md](tiltak-led-retrofit.md) §«Mapping til validatoren».
|
||||||
46
shared/examples/bygg-energi-mikro/kilder-realiseringsgap.md
Normal file
46
shared/examples/bygg-energi-mikro/kilder-realiseringsgap.md
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
type: reference
|
||||||
|
title: "Realiseringsgrad og energy performance gap — verifisert litteratur"
|
||||||
|
description: "Kildebelagte tall for gapet mellom modellert og faktisk realisert besparelse, og dets systematiske årsaker. Grunnlaget for verdict-frøets realiseringsgrad."
|
||||||
|
tags: [realization-rate, performance-gap, M&V, evaluering, kilder]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Realiseringsgrad (realization rate) — verifisert litteratur
|
||||||
|
|
||||||
|
**Realiseringsgrad (RR)** = faktisk evaluert besparelse (ex-post) ÷ modellert/påstått
|
||||||
|
besparelse (ex-ante). RR < 1 betyr at drift leverte mindre enn modellen lovte. Avviket
|
||||||
|
kalles *energy performance gap*. Alle tall under er verifisert mot primærkilde [V].
|
||||||
|
|
||||||
|
| Nivå | Funn | Kilde |
|
||||||
|
|---|---|---|
|
||||||
|
| Program (regulatorisk default) | Default gross RR **0,90** for kWh/kW/therm; ex-ante «generally over-estimated» | CPUC Resolution E-4952 |
|
||||||
|
| Program (lys, drift lavere) | Operational adjustment ned til **81,1 %** (metrede driftstimer 15 % lavere); coincidence factor **0,566** vs antatt 1,0 | National Grid SBS 2010 (DNV KEMA) |
|
||||||
|
| Program (lys, drift høyere) | Hours-of-Use RR **106,5 %**; coincidence 72,2 % — gapet går **begge veier** | Massachusetts Impact Evaluation 2010 |
|
||||||
|
| Parameter (driftstimer) | Metret **3 053 t/år** vs antatt **3 772 t/år** (≈19 % lavere); CV ≈ 0,5 | Efficiency Maine 2021 |
|
||||||
|
| Portefølje | Commercial lighting **98 %** vs residential **61 %** vs total **93 %** | LADWP Retrospective FY15/16–19/20 |
|
||||||
|
| Bygg (grønne næringsbygg) | Predikert besparelse **1,5–3×** realisert; ~⅓ av LEED-bygg bruker mer energi | "Mind the energy performance gap", ScienceDirect |
|
||||||
|
| Måleterskel | Besparelse bør overstige **~10 % av baseline** for å skilles pålitelig fra støy | FEMP/RDH M&V-veiledning |
|
||||||
|
|
||||||
|
## Systematiske årsaker (hvorfor faktisk < modellert) [V]
|
||||||
|
|
||||||
|
1. **Driftstimer / Hours-of-Use** — dominerende. Timeplan-baserte estimat (det Option A
|
||||||
|
stipulerer) treffer sjelden metret brenntid (3 053 vs 3 772).
|
||||||
|
2. **Baseline- og værjustering** — over-predikert baseline blåser opp absolutt besparelse.
|
||||||
|
3. **Coincidence / diversity factor** — for effekt(kW): andel last under nett-topp ~0,57–0,72, ikke 1,0.
|
||||||
|
4. **HVAC interactive effects** — mindre spillvarme → endret kjøle-/varmebehov; «too small to measure», stipuleres.
|
||||||
|
5. **In-service rate, drift & persistens** — ikke alt installeres/forblir; styringer overstyres; degradering.
|
||||||
|
6. **Måleusikkerhet** — under ~10 %-terskelen drukner signalet i støy.
|
||||||
|
7. **Rebound / atferd** — mer lys på, lengre, fordi det «koster mindre».
|
||||||
|
|
||||||
|
## Kilder (URL)
|
||||||
|
|
||||||
|
- EVO IPMVP Generally Accepted M&V Principles (okt. 2018): https://evo-world.org/images/corporate_documents/IPMVP-Generally-Accepted-Principles_Final_26OCT2018.pdf
|
||||||
|
- DOE/NREL Uniform Methods Project, Ch. 2 Commercial & Industrial Lighting (NREL 68558): https://docs.nrel.gov/docs/fy17osti/68558.pdf
|
||||||
|
- Massachusetts Impact Evaluation of 2010 Prescriptive Lighting: https://ma-eeac.org/wp-content/uploads/Impact-Evaluation-of-2010-Prescriptive-Lighting-Installations-Final-Report-6-21-13.pdf
|
||||||
|
- National Grid SBS 2010 Prescriptive Lighting (DNV KEMA): https://www.nationalgridus.com/media/pdfs/our-company/eereports/2014-ngrid-sbs-impact-eval-final-prot.pdf
|
||||||
|
- Efficiency Maine Retail & Distributor Lighting 2021: https://www.efficiencymaine.com/docs/Retail-and-Distributor-Lighting-Final-Impact-Evaluation-Report-2021.pdf
|
||||||
|
- LADWP Retrospective Impact Evaluation FY15/16–19/20: https://www.ladwp.com/sites/default/files/2024-01/LADWP%20Retrospective%20Report%20FINAL%20V4.pdf
|
||||||
|
- CPUC Resolution E-4952: https://docs.cpuc.ca.gov/publisheddocs/published/g000/m232/k459/232459122.pdf
|
||||||
|
- "Mind the energy performance gap" (ScienceDirect): https://www.sciencedirect.com/science/article/abs/pii/S0921344918303860
|
||||||
|
- SSB Elektrisitetspriser (kraftpris tjenesteytende næringer, Q1 2026): https://www.ssb.no/energi-og-industri/energi/statistikk/elektrisitetspriser
|
||||||
40
shared/examples/bygg-energi-mikro/metode-ipmvp-a.md
Normal file
40
shared/examples/bygg-energi-mikro/metode-ipmvp-a.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
type: methodology
|
||||||
|
title: "IPMVP Option A — Retrofit Isolation, Key Parameter Measurement"
|
||||||
|
description: "M&V-metoden for å verifisere besparelsen fra ett isolert tiltak ved å måle nøkkelparameteren (effekt) og estimere resten (driftstimer)."
|
||||||
|
methodology: IPMVP
|
||||||
|
option: A
|
||||||
|
tags: [IPMVP, M&V, EVO, retrofit-isolation]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# M&V-metode: IPMVP Option A
|
||||||
|
|
||||||
|
**IPMVP** (International Performance Measurement and Verification Protocol) er
|
||||||
|
konsensus-rammeverket for å måle og verifisere energibesparelser, eid og vedlikeholdt av
|
||||||
|
**EVO** (Efficiency Valuation Organization). Kjerneinnsikten som begrunner hele
|
||||||
|
lærings-sløyfa står eksplisitt i protokollen [V]:
|
||||||
|
|
||||||
|
> *"Savings cannot be directly measured, because savings represent the absence of energy use."*
|
||||||
|
|
||||||
|
Besparelse er en **kontrafaktisk** størrelse — det finnes ingen måler for «det som ikke ble
|
||||||
|
brukt». Den *beregnes*: `Baseline-energi − Rapporterings-energi ± justeringer` (IPMVP Eq. 1).
|
||||||
|
|
||||||
|
## De fire opsjonene (EVO, offisielle navn) [V]
|
||||||
|
|
||||||
|
- **Option A — Retrofit Isolation: Key Parameter Measurement.** Måler nøkkelparameteren
|
||||||
|
(typisk effekt) på det berørte utstyret; øvrige parametere (typisk driftstimer) *estimeres*.
|
||||||
|
- **Option B — Retrofit Isolation: All Parameter Measurement.** Måler alle relevante parametere.
|
||||||
|
- **Option C — Whole Facility.** Besparelse fra byggets hovedmåler, med rutinejustering (vær/produksjon).
|
||||||
|
- **Option D — Calibrated Simulation.** Besparelse via simuleringsmodell kalibrert mot måledata.
|
||||||
|
|
||||||
|
## Hvorfor Option A for dette tiltaket [V]
|
||||||
|
|
||||||
|
EVOs egen tabell bruker nettopp et **lysarmatur-retrofit** som den kanoniske Option A-saken:
|
||||||
|
effekt før/etter måles (billig, presist), mens **driftstimer stipuleres** fra byggets
|
||||||
|
timeplan. Det gjør Option A enklest og billigst for ett isolert tiltak.
|
||||||
|
|
||||||
|
**Kritisk for lærings-overflaten:** parameteren Option A tillater å *estimere* — driftstimer
|
||||||
|
— er nøyaktig der realiseringsgapet oppstår. Den stipulerte timeplanen treffer sjelden den
|
||||||
|
faktiske, metrede brenntiden. Se [verdict-led-fro.md](verdict-led-fro.md) og
|
||||||
|
[kilder-realiseringsgap.md](kilder-realiseringsgap.md).
|
||||||
66
shared/examples/bygg-energi-mikro/tiltak-led-retrofit.md
Normal file
66
shared/examples/bygg-energi-mikro/tiltak-led-retrofit.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
type: hypothesis
|
||||||
|
title: "LED-retrofit av kontorbelysning"
|
||||||
|
description: "Bytte 200 lysrørarmaturer (3-rørs T8 troffer, ~90 W) til LED-paneler (~40 W). Kandidat-tiltak med modellert besparelse og usikkerhet."
|
||||||
|
resource: BYGG-KONTOR-NORD
|
||||||
|
measure_id: LED-RETROFIT-01
|
||||||
|
tags: [LED, belysning, retrofit, ECM]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tiltak: LED-retrofit av kontorbelysning
|
||||||
|
|
||||||
|
Bytte av 200 lysrørarmaturer (2×4 fluorescerende troffer) til LED-paneler. Dette er det
|
||||||
|
vanligste enkelt-ECM-et (Energy Conservation Measure) og IPMVPs egen kanoniske
|
||||||
|
Option A-illustrasjon — se [metode-ipmvp-a.md](metode-ipmvp-a.md).
|
||||||
|
|
||||||
|
## Parametere
|
||||||
|
|
||||||
|
| Parameter | Verdi | Status | Kilde/forankring |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Antall armaturer | 200 | [I] | mikro-skala valgt |
|
||||||
|
| Effekt før (T8 troffer m/ ballast) | 90 W | [V] | 3×32 W ≈ 90–96 W m/ ballastfaktor |
|
||||||
|
| Effekt etter (LED-panel) | 40 W | [V] | kommersielt 2×4 LED-panel ~40 W |
|
||||||
|
| Reduksjon per armatur (ΔW) | 50 W | beregnet | 90 − 40 |
|
||||||
|
| Driftstimer (HOU) | 3 000 t/år | [I] | forankret i metret 3 053 t (Efficiency Maine) |
|
||||||
|
| Variabel energipris | 1,00 NOK/kWh | [V-forankret] | se [bygg-kontor-nord.md](bygg-kontor-nord.md) |
|
||||||
|
|
||||||
|
## Modellert besparelse (ex-ante)
|
||||||
|
|
||||||
|
Lysligning (DOE/NREL Uniform Methods Project, Eq. 3):
|
||||||
|
`kWh = Σ (W_før − W_etter) × antall × HOU / 1000`
|
||||||
|
|
||||||
|
> ΔW = 90 − 40 = **50 W/armatur**
|
||||||
|
> kWh/år = 50 × 200 × 3 000 / 1 000 = **30 000 kWh/år**
|
||||||
|
> kr/år = 30 000 × 1,00 = **30 000 NOK/år**
|
||||||
|
|
||||||
|
HVAC-interaktiv effekt (effektivt lys → mindre spillvarme → endret kjøle-/varmebehov,
|
||||||
|
UMP Eq. 6) er ~+5 % i elektrisk kjølte bygg, men **utelatt fra kjernetallet** her
|
||||||
|
(konservativt; den lille interaktive justeringen er en ex-post-vurdering eksperten kan
|
||||||
|
legge til). Modellert kjernebesparelse: **30 000 kWh/år ≈ 30 000 NOK/år**.
|
||||||
|
|
||||||
|
## Usikkerhet (for Monte Carlo P10/P50/P90)
|
||||||
|
|
||||||
|
Den dominerende usikkerheten i en *energibesparelse* ligger i driftstimer (HOU), ikke
|
||||||
|
prisen — men den eksisterende validatorens Monte Carlo varierer enhetspris. I denne
|
||||||
|
mikro-mappingen brukes derfor **prisbandet 0,70–1,40 NOK/kWh** som usikkerhetsakse
|
||||||
|
(region/sesong, jf. [bygg-kontor-nord.md](bygg-kontor-nord.md)). Den fysiske HOU-usikkerheten
|
||||||
|
og — viktigere — den *systematiske* HOU-skjevheten håndteres i verdict-laget, ikke her.
|
||||||
|
|
||||||
|
## Mapping til validatoren (hvorfor `validator-input.json` ser ut som den gjør)
|
||||||
|
|
||||||
|
Den eksisterende deterministiske validatoren er en *feasibility-gate* (`claimed ≤ 30 % av
|
||||||
|
affected total`, Monte Carlo over enhetspris) bygd for kostnadskutt. Energitiltaket mappes
|
||||||
|
inn **uendret**:
|
||||||
|
|
||||||
|
- `affected_items = [{code: "ENERGI-TOTAL-EL", quantity: 300000 kWh/år, unit_cost: 1.00 NOK/kWh}]`
|
||||||
|
→ byggets **totale** årlige energikostnad (300 000 NOK). LED-besparelsen er ~10 % av den,
|
||||||
|
godt innenfor 30 %-cap-en.
|
||||||
|
- `claimed_saving_nok = 30000` → den modellerte LED-besparelsen.
|
||||||
|
- `assumptions = {"ENERGI-TOTAL-EL": [0.70, 1.40]}` → prisbandet for Monte Carlo.
|
||||||
|
|
||||||
|
**Ærlig begrensning:** validatorens P10/P50/P90 betyr her «øvre feasible grense» (30 % av
|
||||||
|
samplet energikostnad), *ikke* «LED-besparelsens fysiske band». Det er bevisst — den
|
||||||
|
domenetro besparelses-modelleringen og realiseringsgapet hører hjemme i verdict-laget
|
||||||
|
([verdict-led-fro.md](verdict-led-fro.md)), som er nettopp det lærings-sløyfa skal lære.
|
||||||
|
En energi-bevisst validator (ΔW × antall × HOU) er senere fase-arbeid, ikke dette fixturet.
|
||||||
16
shared/examples/bygg-energi-mikro/validator-input.json
Normal file
16
shared/examples/bygg-energi-mikro/validator-input.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"_note": "IR-projeksjon (ir.SavingsProposal) for det eksisterende deterministiske validatoren. Energitiltaket er mappet inn i kost-IR-en UENDRET: affected_items = byggets totale arlige energikostnad; claimed_saving_nok = modellert LED-besparelse (~10% av total, innenfor 30%-cap); assumptions = energipris-band (NOK/kWh) for Monte Carlo. Se tiltak-led-retrofit.md, seksjon 'Mapping til validatoren'.",
|
||||||
|
"project_id": "BYGG-KONTOR-NORD",
|
||||||
|
"measure": "LED-retrofit av 200 lysrorarmaturer (90 W -> 40 W) i kontorlokaler",
|
||||||
|
"affected_items": [
|
||||||
|
{
|
||||||
|
"code": "ENERGI-TOTAL-EL",
|
||||||
|
"quantity": 300000,
|
||||||
|
"unit_cost": 1.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"claimed_saving_nok": 30000,
|
||||||
|
"assumptions": {
|
||||||
|
"ENERGI-TOTAL-EL": [0.70, 1.40]
|
||||||
|
}
|
||||||
|
}
|
||||||
56
shared/examples/bygg-energi-mikro/verdict-led-fro.md
Normal file
56
shared/examples/bygg-energi-mikro/verdict-led-fro.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
type: verdict
|
||||||
|
title: "Ekspert-dom (frø): LED-retrofit — godkjent med realiseringskorreksjon"
|
||||||
|
description: "Frøsatt ekspert-dom som koder realiseringsgapet for LED-tiltaket. ExpeL-frøet loopens steg 1 henter fra: modellert besparelse korrigeres ned med realiseringsgraden eksperten kjenner fra drift."
|
||||||
|
resource: BYGG-KONTOR-NORD
|
||||||
|
measure_id: LED-RETROFIT-01
|
||||||
|
decision: approved_with_adjustment
|
||||||
|
realization_rate: 0.82
|
||||||
|
modelled_saving_nok: 30000
|
||||||
|
expected_actual_saving_nok: 24600
|
||||||
|
gap_source: hours-of-use-overestimation
|
||||||
|
context_key: "kontorbygg; HOU-kilde=timeplan-stipulert"
|
||||||
|
provenance: "frø — AI-forfattet, forankret i National Grid SBS 2010 (RR 0,81); erstattes av ekte HITL i produksjon"
|
||||||
|
tags: [verdict, realization-rate, ExpeL-seed, HITL]
|
||||||
|
timestamp: 2026-06-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ekspert-dom (frø): LED-retrofit
|
||||||
|
|
||||||
|
> **Dette er et frø**, ikke en ekte dom. I simulering gir en ekspert-persona slike dommer;
|
||||||
|
> i produksjon gir et menneske dem via samme mappe-grensesnitt. Frøet er forankret i
|
||||||
|
> verifisert litteratur ([kilder-realiseringsgap.md](kilder-realiseringsgap.md)), ikke
|
||||||
|
> oppdiktet. Det er **provenance-merket** og promoteres til wikien kun fordi en (simulert)
|
||||||
|
> ekspert har godkjent det (målbilde, steg 8 gated).
|
||||||
|
|
||||||
|
## Dommen
|
||||||
|
|
||||||
|
**Beslutning:** godkjent — med realiseringskorreksjon.
|
||||||
|
|
||||||
|
Den modellerte besparelsen (**30 000 NOK/år**) er teknisk korrekt fra parameterne, og
|
||||||
|
validatoren bekrefter at den er innenfor feasibelt område. Men i drift realiseres erfaringsvis
|
||||||
|
**~82 %** av en timeplan-stipulert LED-besparelse i kontorbygg → forventet faktisk
|
||||||
|
besparelse **≈ 24 600 NOK/år**.
|
||||||
|
|
||||||
|
## Begrunnelse (det validatoren ikke kan regne)
|
||||||
|
|
||||||
|
Realiseringsgapet her er **ikke** spredning i parameterne — det er en *systematisk skjevhet*
|
||||||
|
mellom de stipulerte parameterne og driftsvirkeligheten:
|
||||||
|
|
||||||
|
- **Driftstimer overvurdert (dominerende):** den antatte timeplanen (3 000 t) ligger over
|
||||||
|
faktisk metret brenntid — naturlig dagslys, tomme rom, sensorstyring. Jf. National Grid
|
||||||
|
(RR-bidrag 0,81 fra 15 % lavere metrede timer) og Efficiency Maine (3 053 vs 3 772 t).
|
||||||
|
- **In-service rate < 1:** ikke alle 200 armaturer er nødvendigvis montert/i drift ved
|
||||||
|
evaluering.
|
||||||
|
- **Atferd/persistens:** rebound (mer lys på fordi det «er gratis») og overstyrte styringer.
|
||||||
|
|
||||||
|
Du kan **ikke** regne deg til RR = 0,82 fra `{200, 90 W, 40 W, 3 000 t, 1,00 NOK/kWh}`.
|
||||||
|
Skjevheten er epistemikk parameterne ikke bærer — den finnes bare i akkumulert drifts-erfaring.
|
||||||
|
|
||||||
|
## Lærings-signalet (ExpeL)
|
||||||
|
|
||||||
|
Korreksjonen er **kontekstbetinget**: `context_key = "kontorbygg; HOU-kilde=timeplan-stipulert"`.
|
||||||
|
Neste kjøring, gitt en lignende hypotese i samme kontekst, skal hente denne dommen og
|
||||||
|
justere den modellerte ex-ante-besparelsen mot forventet ex-post (≈ 0,82×) — uten å vente
|
||||||
|
på 12 måneders måling. **Det er denne dataflyten — verdict inn i neste hypotese — loopens
|
||||||
|
steg 1 må wire (målbilde §5, §7). Dette frøet er testankeret.**
|
||||||
441
shared/method-spec.md
Normal file
441
shared/method-spec.md
Normal file
|
|
@ -0,0 +1,441 @@
|
||||||
|
# Method specification — portfolio cost-saving loop (framework-neutral)
|
||||||
|
|
||||||
|
> **Status:** normative. This document specifies the method both reference implementations
|
||||||
|
> build: an agentic loop that finds cost savings *inside* each project of a portfolio, with a
|
||||||
|
> mandatory deterministic validator, expert judgement in the loop, and learning from the
|
||||||
|
> verdicts. It is written so the method can be implemented **from this spec alone** — without
|
||||||
|
> reverse-engineering any existing implementation. The prose is framework-neutral by rule: it
|
||||||
|
> never names a concrete agent toolkit or vendor stack, and a guard test keeps it that way.
|
||||||
|
>
|
||||||
|
> The key words MUST, MUST NOT, SHOULD, and MAY are to be interpreted as in RFC 2119.
|
||||||
|
> Requirements are labelled normative; anything marked *(reference)* documents the reference
|
||||||
|
> implementation's concrete choice and is informative, not binding — except where the golden
|
||||||
|
> suite (§7) freezes it.
|
||||||
|
|
||||||
|
## 1. Scope and conformance
|
||||||
|
|
||||||
|
The method is the product: a swarm of agents generates candidate cost-saving measures for one
|
||||||
|
project at a time; a **deterministic validator decides the numbers** (mandatory, blocking);
|
||||||
|
domain experts judge the outcomes (human-in-the-loop); the system **learns from the verdicts**
|
||||||
|
across runs. A conforming implementation:
|
||||||
|
|
||||||
|
1. implements the 8-step loop of §3 with the contracts of §4–§10;
|
||||||
|
2. reproduces the shared golden suite's decided outcomes (§7) on the shared example bundle;
|
||||||
|
3. proves every load-bearing seam with a test that FAILS when that seam is detached (§11).
|
||||||
|
|
||||||
|
**Honesty rule (unwaivable):** no artifact — code, docstring, README, or report — may claim
|
||||||
|
more than the implementation does. Scripted stand-ins (synthetic clients, seeded verdicts)
|
||||||
|
MUST be labelled as such wherever their output is presented.
|
||||||
|
|
||||||
|
**Boundary:** this is a purely technical framework. The deploying organisation owns all
|
||||||
|
processing purposes and impact assessments; implementations provide only the technical
|
||||||
|
prerequisites (local-only operation, provenance, no silent egress) and a disclaimer.
|
||||||
|
|
||||||
|
## 2. Terms and architecture
|
||||||
|
|
||||||
|
Three layers, strictly separated (the separation is load-bearing — see §3 Step 1 and §6):
|
||||||
|
|
||||||
|
- **Context layer** — one curated, version-controlled knowledge bundle per project (an "LLM
|
||||||
|
wiki") in the open OKF format: a directory of markdown files with YAML frontmatter, one
|
||||||
|
required field `type`, a reserved `index.md` entry point, and intra-bundle cross-links.
|
||||||
|
This layer holds project documents, methodology, verified literature, constraints, **and
|
||||||
|
approved verdicts** (`type: verdict` files). It is what runtime reading and experience
|
||||||
|
retrieval draw from.
|
||||||
|
- **Output layer** — a run-scoped folder structure of raw results: proposals pending verdict,
|
||||||
|
rejections with reasons, and raw verdict files (plain JSON, one per file). Append-heavy,
|
||||||
|
**never part of the wiki**.
|
||||||
|
- **Promotion gate** — the only path from the output layer into the context layer (§6). Only
|
||||||
|
expert-approved knowledge crosses it.
|
||||||
|
|
||||||
|
Other terms: the **IR** is the typed intermediate representation of a candidate measure
|
||||||
|
(§7.1); the **store** is the in-memory collection of historical verdicts retrieval ranks over
|
||||||
|
(§4.2); the **fold** is the injection of retrieved prior verdicts into the hypothesis prompt
|
||||||
|
(§3 Step 1); the **two falsifiers** are the deterministic validator (numbers) and the debate
|
||||||
|
checker (reasoning) — they judge the same candidate and are never conflated (§3 Step 4, §9).
|
||||||
|
|
||||||
|
## 3. The loop (normative)
|
||||||
|
|
||||||
|
Eight steps. Steps 1–6 happen within one run; steps 7–8 close the learning loop across runs
|
||||||
|
separated in time.
|
||||||
|
|
||||||
|
### Step 1 — Understand the context (navigate, never stuff)
|
||||||
|
|
||||||
|
The agent read-context for a project MUST be built by **navigating** its OKF bundle with
|
||||||
|
progressive disclosure — never by stuffing the whole bundle (or keyword-retrieved chunks of
|
||||||
|
it) into the prompt:
|
||||||
|
|
||||||
|
- Navigation starts at `index.md` and follows its intra-bundle markdown cross-links
|
||||||
|
(`](target.md)`). Targets containing a path separator are out-of-bundle and MUST be
|
||||||
|
skipped. Repeated links are de-duplicated; order is deterministic (index first, then links
|
||||||
|
in first-seen order). *(reference: the link pattern is `\]\(([^)]+\.md)\)`)*
|
||||||
|
- A missing `index.md` is an error (a bundle has no entry point without it). A broken or
|
||||||
|
bundle-escaping cross-link MUST be tolerated — skipped, never raised (OKF robustness rule);
|
||||||
|
path resolution MUST be boundary-checked against the bundle directory, fail-closed.
|
||||||
|
- Frontmatter is the leading `---`-delimited block, parsed line-oriented as `key: value`
|
||||||
|
strings; the single required field is `type`; unknown fields MUST be preserved.
|
||||||
|
- The rendered read-context is the index body (the summary) followed by each non-index
|
||||||
|
concept file as a `## {type}: {title}` section; empty sections are dropped.
|
||||||
|
- **`type: verdict` files MUST be excluded from the read-context.** Prior verdicts reach the
|
||||||
|
hypothesis prompt ONLY via the gated experience fold below — never via context rendering,
|
||||||
|
and never via a query-time retrieval tool pointed at the bundle (which would re-leak the
|
||||||
|
verdict layer).
|
||||||
|
|
||||||
|
**Experience fold (ExpeL-style, the learning seam):** before generation, the candidate's
|
||||||
|
prior verdicts are retrieved from the store and folded into the hypothesis prompt:
|
||||||
|
|
||||||
|
- The retrieval query key is the bundle's candidate features, read from the IR projection
|
||||||
|
(§7.1) — available *before* any proposal exists.
|
||||||
|
- Seeding: every `type: verdict` file in the bundle becomes a store entry keyed on those
|
||||||
|
candidate features, with `decision` from frontmatter (default `approved`) and a rationale
|
||||||
|
built from the `description` frontmatter plus, when present, the structured learning
|
||||||
|
fields rendered as `[realiseringsgrad={realization_rate}; forventet_faktisk_NOK=
|
||||||
|
{expected_actual_saving_nok}]`.
|
||||||
|
- Ranking is **structural, never textual** — surface text MUST NOT contribute to similarity.
|
||||||
|
Similarity is the weighted sum `0.60 × Jaccard(affected-code sets) + 0.25 ×
|
||||||
|
[measure-type equality] + 0.15 × [same magnitude bucket]`, with magnitude buckets
|
||||||
|
`[0, 1e5), [1e5, 5e5), [5e5, 1e6), [1e6, ∞)` over the claimed saving and Jaccard of two
|
||||||
|
empty sets defined as 1. Retrieval returns the top-k by similarity, ties broken by verdict
|
||||||
|
id ascending (deterministic); k MUST be positive.
|
||||||
|
- The fold prepends the retrieved verdicts (id, decision, rationale per line) to the
|
||||||
|
generation context. The rationale is the carrier of the learning signal — the fold is what
|
||||||
|
lets an expert's realization-rate correction reach the next hypothesis.
|
||||||
|
|
||||||
|
### Step 2 — Hypothesise (structured candidate generation)
|
||||||
|
|
||||||
|
The proposer model is asked for exactly one candidate measure as a JSON object for the IR
|
||||||
|
(§7.1): `project_id`, `measure`, `affected_items` (list of `{code, quantity, unit_cost}`),
|
||||||
|
`claimed_saving_nok`, optional `assumptions`. A reply that fails to parse into the typed IR
|
||||||
|
MUST be retried (a blind parse-retry), never silently accepted or repaired downstream —
|
||||||
|
bounded by the budget meter (§8). `project_id` MAY be defaulted from the project when the
|
||||||
|
model omits it. IR schema invariants (§7.1) are enforced at construction, so a malformed
|
||||||
|
proposal can never exist as a value.
|
||||||
|
|
||||||
|
### Step 3 — Debate (maker-checker)
|
||||||
|
|
||||||
|
Candidate reasoning is debated by a two-role maker-checker pair — a `proposer` and a
|
||||||
|
`checker` — alternating turns, with the debate's converged proposer output feeding generation
|
||||||
|
(Step 2's context). Requirements:
|
||||||
|
|
||||||
|
- The debate MUST be round-capped (a hard maximum-rounds bound) with an additional
|
||||||
|
turn-count termination safety net above it; an unbounded debate is forbidden (§8).
|
||||||
|
- Debate state MUST be fresh per run — no conversation state may survive from one project
|
||||||
|
run into the next.
|
||||||
|
- The checker MUST be instructed to end its reply with exactly one verdict line:
|
||||||
|
`VERDICT: APPROVE` if the reasoning holds, or `VERDICT: REJECT - <short reason>` if not.
|
||||||
|
- An optional synchronous in-run review gate on the checker MAY be enabled (the short
|
||||||
|
feedback timescale, §3 Step 7); durable in-run checkpointing is NOT required.
|
||||||
|
|
||||||
|
### Step 4 — Validate / falsify (two falsifiers, same candidate)
|
||||||
|
|
||||||
|
**The deterministic validator gates the numbers — mandatory, blocking, never an optional
|
||||||
|
plugin.** It is the one endpoint-free judge that anchors the loop against swarm
|
||||||
|
self-confirmation. Semantics (frozen by the golden suite, §7.2):
|
||||||
|
|
||||||
|
1. Schema invariants already hold (IR construction, §7.1).
|
||||||
|
2. **Feasibility bound:** the maximum feasible saving is capped at a policy fraction
|
||||||
|
(0.30) of the affected items' total cost. *(reference: computed with an LP solve whose
|
||||||
|
closed form here is `0.30 × Σ quantity·unit_cost`; a missing solver MUST escalate, never
|
||||||
|
silently fall back.)*
|
||||||
|
3. **Risk simulation:** seeded Monte Carlo over uncertain unit costs yields `p10`/`p50`/`p90`
|
||||||
|
percentiles of the feasible saving (§7.2 fixes the procedure).
|
||||||
|
4. **Structural block:** a claim above the optimistic feasible bound (`p90`) yields a
|
||||||
|
**rejection that is a distinct type from a validated proposal** — carrying the claimed and
|
||||||
|
feasible figures in its reason, and no percentiles — so it can never be consumed as
|
||||||
|
validated.
|
||||||
|
|
||||||
|
**The checker gates the reasoning** (the second falsifier), parsed from the checker's LAST
|
||||||
|
surfaced debate output, case-insensitively; the reject marker takes precedence and its
|
||||||
|
trailing text is the reason. The gate is **opt-in-reject (fail-open)**: `VERDICT: APPROVE` or
|
||||||
|
a missing/unparseable marker never blocks — the validator remains the sole gate on such runs.
|
||||||
|
An explicit checker REJECT MUST override an otherwise-validated outcome into a rejection
|
||||||
|
(reason prefixed with the checker's reason). A validator rejection stands regardless of the
|
||||||
|
checker. The two falsifiers MUST be recorded separately (§9): the provenance field mirrors
|
||||||
|
ONLY the validator; the checker's decision (`approve` / `reject` / `absent`) is reported as
|
||||||
|
its own result field. Either the checker actually gates, or the debate must not be called
|
||||||
|
maker-checker.
|
||||||
|
|
||||||
|
### Step 5 — Refine, informed and bounded
|
||||||
|
|
||||||
|
When the validator rejects, the next attempt MUST be informed by the falsification: the
|
||||||
|
previous attempt's rejection **reason** is fed verbatim into the next attempt's prompt as a
|
||||||
|
revision instruction. Constraints (all normative):
|
||||||
|
|
||||||
|
- Only the *most recent* rejection reason is carried — never an accumulated history
|
||||||
|
(bounded prompt growth).
|
||||||
|
- Only the *reason* is carried — never the prior proposal JSON (the model must address the
|
||||||
|
falsification, not parrot the rejected candidate).
|
||||||
|
- The refinement loop runs under the EXISTING caps — the attempt bound (`max_attempts`,
|
||||||
|
reference default 3) and the token/round meter (§8). "Refine until good enough" without a
|
||||||
|
cap is forbidden; no new loop may be introduced.
|
||||||
|
- The only *per-attempt* falsifier in this loop is the deterministic validator. Seeding
|
||||||
|
generation with the checker's critique is a run-level concern outside this loop's scope.
|
||||||
|
- Attempt 1 MUST use the unchanged base prompt (the informed block appears only after a
|
||||||
|
rejection).
|
||||||
|
|
||||||
|
### Step 6 — Discard or propose
|
||||||
|
|
||||||
|
The run's outcome is either the validated proposal (with its percentiles) or a typed
|
||||||
|
rejection with its reason — never a bare failure. Raw results (proposals pending verdict,
|
||||||
|
rejections, captured verdict files) belong to the output layer (§2) as plain JSON — the raw
|
||||||
|
layer deliberately does NOT use the wiki format (that is reserved for promoted knowledge).
|
||||||
|
|
||||||
|
### Step 7 — Respond to feedback (two timescales)
|
||||||
|
|
||||||
|
- **Short loop:** an expert may review synchronously in-run (the optional Step-3 gate).
|
||||||
|
- **Long loop (the async file inbox):** days or weeks later, an expert (or, in simulation, a
|
||||||
|
persona) drops a verdict file into an inbox **folder**; a separate, later run picks it up
|
||||||
|
whenever it lands. The system MUST be fully resumable across runs separated in time — no
|
||||||
|
live-session assumption. Contract in §5. **Role split (unwaivable): the system READS the
|
||||||
|
inbox; the expert writes it.** A run MUST NOT persist its own captured verdict back into
|
||||||
|
the inbox (writing is the authoring primitive's and the promotion gate's job).
|
||||||
|
|
||||||
|
In simulation a dedicated expert persona plays the human; in production a human uses the
|
||||||
|
SAME folder interface. The persona is defined once, as a shared skill artifact (§4.3).
|
||||||
|
|
||||||
|
### Step 8 — Promote approved knowledge (optional + gated)
|
||||||
|
|
||||||
|
When an expert APPROVES an outcome, it may be promoted from the raw output layer into the
|
||||||
|
context layer as a `type: verdict` concept file, navigable by the next run's seeding
|
||||||
|
(closing the learning loop through the file system). Promotion is an **opt-in public
|
||||||
|
primitive** — it MUST NOT be wired into the run itself (the system reads context; the
|
||||||
|
gate/persona promotes). Full gate semantics in §6.
|
||||||
|
|
||||||
|
## 4. The verdict contract
|
||||||
|
|
||||||
|
Three machine-readable shapes carry expert judgement. All three share the decision
|
||||||
|
vocabulary rule: **the run-path decision is binary** — `approved` or `rejected`. The
|
||||||
|
adjusted-approval case (the signature case in practice: the measure is worth doing but the
|
||||||
|
modelled saving overstates the expected actual) is an `approved` decision whose `rationale`
|
||||||
|
records the correction. `approved_with_adjustment` exists ONLY in bundle-seed frontmatter
|
||||||
|
and in the promotion gate's accepted set (§6) — a run-path feedback contract MUST reject it.
|
||||||
|
|
||||||
|
### 4.1 Run-path feedback
|
||||||
|
|
||||||
|
The expert decision consumed by a run: `decision` ∈ {`approved`, `rejected`} (exactly two
|
||||||
|
values) and a non-empty `rationale` string. Validated fail-fast at startup (§10).
|
||||||
|
|
||||||
|
### 4.2 The verdict file (raw output layer / inbox)
|
||||||
|
|
||||||
|
One verdict per JSON file, named `{id}.json`. Top-level fields (all required):
|
||||||
|
|
||||||
|
| Field | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `id` | The learning-loop key (see minting, below). Read VERBATIM on load — never re-minted. |
|
||||||
|
| `decision` | The expert decision (§4 vocabulary). |
|
||||||
|
| `rationale` | Prose carrying the knowledge the validator cannot compute. |
|
||||||
|
| `proposal_features` | The structural features of the judged candidate (below). |
|
||||||
|
|
||||||
|
`proposal_features` fields: `affected_codes` (emitted as a SORTED list), `measure_type`
|
||||||
|
(string), `claimed_saving_nok` (number), `description` (string; surface text — deliberately
|
||||||
|
excluded from both similarity ranking and id minting).
|
||||||
|
|
||||||
|
**Id minting (normative):** `id` is the first 16 hex characters of the SHA-256 of the
|
||||||
|
canonical JSON `{"affected_codes": <sorted list>, "claimed_saving_nok": <number>,
|
||||||
|
"measure_type": <string>}` with keys sorted and separators `,`/`:` (no whitespace). The id
|
||||||
|
therefore keys on the **candidate measure**, not the verdict event: a structurally identical
|
||||||
|
proposal maps to the same id. Because raw JSON number formatting participates in the hash
|
||||||
|
(`30000` vs `30000.0` differ), a loaded verdict's `id` MUST be kept verbatim — re-minting
|
||||||
|
could diverge.
|
||||||
|
|
||||||
|
**Conflict semantics (chosen, documented):** the in-memory store is FIRST-write-wins per
|
||||||
|
`id` (repeated inbox merges are idempotent); the disk layers — inbox files and promoted wiki
|
||||||
|
files — are LAST-write-wins per file. Two verdicts about the same candidate share an id and
|
||||||
|
hence a filename. A full verdict-conflict taxonomy is deliberately deferred until real
|
||||||
|
experts produce conflicting verdicts.
|
||||||
|
|
||||||
|
### 4.3 The persona example artifact
|
||||||
|
|
||||||
|
The expert-reviewer persona is a shared skill: a persona prompt plus one canonical example
|
||||||
|
verdict JSON with fields `decision`, `marker`, and `rationale`. Requirements:
|
||||||
|
|
||||||
|
- `decision` MUST be a run-path value (§4.1); the canonical example is `approved`.
|
||||||
|
- `marker` MUST be a substring of `rationale` — it is the traceable payload (the realization
|
||||||
|
rate) a simulation follows from the persona's judgement into a later run's prompt.
|
||||||
|
- Implementations MUST source the persona judgement from this artifact at call time (a
|
||||||
|
loader, fail-fast on a missing/malformed file — it is required input), never from an
|
||||||
|
inlined copy. The persona prompt's prose never names a concrete agent toolkit.
|
||||||
|
|
||||||
|
## 5. The inbox/outbox folder contract
|
||||||
|
|
||||||
|
The long feedback loop's folder interface (§3 Step 7). Normative:
|
||||||
|
|
||||||
|
- **One verdict per file**, `{id}.json`, shape per §4.2. The authoring primitive creates the
|
||||||
|
directory if needed and writes deterministically *(reference: sorted keys, 2-space
|
||||||
|
indent)*.
|
||||||
|
- **Tolerant load** (the raw layer is written out of band; half-written or foreign files are
|
||||||
|
realistic): a missing folder yields zero verdicts; files that are not `.json`, fail to
|
||||||
|
parse, or lack a required top-level key (`id`, `decision`, `rationale`,
|
||||||
|
`proposal_features`) are SKIPPED, never raised. Contrast: required inputs (the IR
|
||||||
|
projection §7.1, the persona example §4.3) are fail-fast.
|
||||||
|
- **Deterministic order:** files are processed sorted by filename.
|
||||||
|
- **Merge, never replace:** a run ingests the inbox INTO its store (per-verdict add,
|
||||||
|
first-write-wins per id) BEFORE the Step-1 fold, so a passed-in store's existing verdicts
|
||||||
|
survive (cross-project threading) and repeated merges are idempotent.
|
||||||
|
- **Role split:** the system reads; the expert/persona writes (§3 Step 7).
|
||||||
|
|
||||||
|
## 6. The promotion gate
|
||||||
|
|
||||||
|
`promote` lifts one APPROVED verdict from the raw output layer into the OKF context layer.
|
||||||
|
Normative semantics:
|
||||||
|
|
||||||
|
- **Fail-closed:** a verdict whose `decision` is not in {`approved`,
|
||||||
|
`approved_with_adjustment`} MUST be refused with an error, writing and linking NOTHING.
|
||||||
|
Only human/persona-approved knowledge enters the wiki — never raw agent output
|
||||||
|
(self-contamination).
|
||||||
|
- **Provenance-stamped:** the promoted file records who approved, which experiment, and
|
||||||
|
when. The timestamp MUST be an explicit required argument — no wall-clock default — so
|
||||||
|
promotion is deterministic and reproducible.
|
||||||
|
- **Minimal promoted file:** frontmatter `type: verdict`, the `decision`, the verdict's
|
||||||
|
`rationale` as the `description` field (the learning signal as prose), the verbatim
|
||||||
|
verdict id, the provenance stamp, and tags. The promoted file MUST NOT reproduce a
|
||||||
|
hand-authored seed's structured learning fields (`realization_rate` etc.) — the raw
|
||||||
|
verdict model carries the signal only as rationale prose, and seeding (§3 Step 1) folds
|
||||||
|
the `description` in.
|
||||||
|
- **Navigability:** the file is written into the bundle (path-safe, fail-closed against
|
||||||
|
escaping names; filename `promoted-verdict-{token}.md` where the token is the id
|
||||||
|
sanitised to `[A-Za-z0-9._-]`, a degenerate token falling back to a content hash) and
|
||||||
|
linked from `index.md` — navigation follows only index cross-links, so an unlinked file
|
||||||
|
is unreachable. Linking MUST be idempotent (re-promotion never double-links).
|
||||||
|
- **Neutral label:** the index link label is FIXED and carries NO verdict signal. The index
|
||||||
|
body flows verbatim into the rendered read-context, so a descriptive label (e.g. the
|
||||||
|
rationale) would leak the learning signal around the gated fold.
|
||||||
|
- **Per-candidate growth:** ids key on candidate features (§4.2), so two approvals of the
|
||||||
|
same candidate share a filename — last-write-wins; the wiki grows one curated verdict
|
||||||
|
file per distinct candidate, not one per verdict event.
|
||||||
|
- *(reference limitation)* the index read-modify-write is not atomic — single-process use
|
||||||
|
is assumed for the MVP.
|
||||||
|
|
||||||
|
## 7. Ground truth: IR projection and golden suite
|
||||||
|
|
||||||
|
The shared example bundle ships two JSON files that are **the only ground truth** ("fasit")
|
||||||
|
for cross-implementation equivalence. Implementations MUST consume them unchanged.
|
||||||
|
|
||||||
|
### 7.1 The IR projection (`validator-input.json`)
|
||||||
|
|
||||||
|
The candidate measure projected into the typed cost-IR the validator consumes:
|
||||||
|
|
||||||
|
- `project_id` (string), `measure` (string), `affected_items` — a non-empty list of
|
||||||
|
`{code: string, quantity: number ≥ 0, unit_cost: number > 0}` — `claimed_saving_nok`
|
||||||
|
(number > 0), and `assumptions`: a map `code → [low_unit_cost, high_unit_cost]` giving the
|
||||||
|
uncertainty band per cost code for the risk simulation (empty = degenerate, no spread).
|
||||||
|
- Construction-time invariant: the claimed saving MUST NOT exceed the affected items' own
|
||||||
|
total (`Σ quantity·unit_cost`); violation is a schema error, not a validator rejection.
|
||||||
|
- Loading the IR projection from a bundle is FAIL-FAST: a missing file raises (required
|
||||||
|
input — contrast the tolerant inbox, §5).
|
||||||
|
|
||||||
|
### 7.2 The golden suite (`golden.json`)
|
||||||
|
|
||||||
|
Two parts, both normative on their decided fields:
|
||||||
|
|
||||||
|
- **`validator`** — the frozen deterministic outcome of validating the IR projection:
|
||||||
|
`outcome` (the validated type's name), `validates` (true — the claim sits within the
|
||||||
|
feasible range), `claimed_saving_nok`, `nominal_feasible`, and the percentiles `p10`,
|
||||||
|
`p50`, `p90`. A conforming implementation MUST reproduce these values (approx-equality on
|
||||||
|
floats) — either with the reference procedure below or an equivalent deterministic method
|
||||||
|
that reproduces the golden outcomes. The meaningful assertion is `validates` = true
|
||||||
|
(claimed ≤ `p90`); the frozen numbers are the regression net.
|
||||||
|
|
||||||
|
Reference procedure (what generated the golden): `nominal_feasible = 0.30 ×
|
||||||
|
Σ quantity·unit_cost`; Monte Carlo with a Mersenne-Twister PRNG seeded `20260624`, 512
|
||||||
|
samples; per sample, iterate `affected_items` in order and draw the unit cost uniformly
|
||||||
|
from the item's `assumptions` band (fixed cost when no band), the sample's feasible saving
|
||||||
|
being `0.30 ×` the sampled total; percentiles are the 1st, 5th and 9th cut points of the
|
||||||
|
10-quantiles (inclusive method) over the 512 feasible values.
|
||||||
|
|
||||||
|
- **`learning_surface`** — what the validator CANNOT compute, encoded by the seed verdict:
|
||||||
|
`modelled_saving_nok`, `realization_rate` (strictly between 0 and 1 — a realization gap),
|
||||||
|
`expected_actual_saving_nok` (= `realization_rate` × `modelled_saving_nok`, internal
|
||||||
|
consistency required), `gap_source`, and `context_key` (the context the correction holds
|
||||||
|
for). This is the ExpeL seed's anchor: the signal Step 1's fold must carry into the next
|
||||||
|
hypothesis, and the reason the learning loop exists at all.
|
||||||
|
|
||||||
|
## 8. Budget and stop criteria
|
||||||
|
|
||||||
|
Never an unbounded loop, anywhere. Normative:
|
||||||
|
|
||||||
|
- **Required at startup:** positive `max_rounds` and `max_tokens` caps (the termination
|
||||||
|
contract, §10). Cap objects MUST refuse construction with non-positive values.
|
||||||
|
- **Real usage, never a proxy:** token accounting MUST come from the provider-reported
|
||||||
|
usage (total token count) after each model call — never a word-count or character proxy.
|
||||||
|
On counting paths, a response missing usage MUST fail closed (an error), not silently
|
||||||
|
stop counting.
|
||||||
|
- **Structured stop:** crossing a cap raises a structured stop event carrying the breached
|
||||||
|
kind (tokens or rounds), the limit, and the observed value — never a silent hang.
|
||||||
|
- Every retry loop is attempt-bounded (Steps 2 and 5); the debate is round-capped (Step 3);
|
||||||
|
round ticks are charged between attempts so the meter also bounds parse-retries.
|
||||||
|
|
||||||
|
## 9. Provenance
|
||||||
|
|
||||||
|
Every proposal carries a first-class provenance stamp — authoritative data, not display
|
||||||
|
metadata:
|
||||||
|
|
||||||
|
- **At least one citation** into the source documents (file + exact text span + snippet); a
|
||||||
|
run whose context yields no citable content MUST fail fast.
|
||||||
|
- The `model` and `role` that produced the proposal. An injected test client's real model id
|
||||||
|
is stamped when available; a neutral `unknown` is the fallback — never a fabricated name.
|
||||||
|
- **`validator_decision`** ∈ {`validated`, `rejected`} — mirrors the DETERMINISTIC VALIDATOR
|
||||||
|
only, stamped from the validator's outcome BEFORE any checker override, so a
|
||||||
|
checker-gated proposal whose numbers passed is never mislabelled as validator-rejected.
|
||||||
|
The checker's decision is a separate result field (§3 Step 4); the two falsifiers are
|
||||||
|
never conflated.
|
||||||
|
- The run's token usage (from the meter, §8).
|
||||||
|
- Promotion provenance is §6 (who/experiment/when, explicit timestamp).
|
||||||
|
|
||||||
|
## 10. Startup contracts
|
||||||
|
|
||||||
|
ALL configuration MUST be schema-validated fail-fast at startup, BEFORE any model client is
|
||||||
|
constructed: the data source (a docs directory + a positive top-k), the model map (role →
|
||||||
|
model id per backend profile, each profile REQUIRING a `default` entry), the termination
|
||||||
|
contract (§8), and the feedback shape (§4.1). The first malformed contract raises; a run
|
||||||
|
never starts on a bad config.
|
||||||
|
|
||||||
|
## 11. Load-bearing conformance tests
|
||||||
|
|
||||||
|
A conforming implementation MUST prove each seam with a test that FAILS when the seam is
|
||||||
|
detached ("green-but-dead" tests are the failure mode this rule exists to prevent). The
|
||||||
|
required red-conditions, mirroring the reference suite (test names cited for
|
||||||
|
cross-reference):
|
||||||
|
|
||||||
|
| Seam | The test MUST fail when… | Reference test |
|
||||||
|
|---|---|---|
|
||||||
|
| Step-1 fold | a prior verdict no longer reaches the next hypothesis prompt; control: an empty store changes the outcome signal | `test_step1_expel_loadbearing.py` |
|
||||||
|
| Verdict-layer exclusion | the realization signal appears in the rendered read-context | `test_okf.py` (bundle-context exclusion) |
|
||||||
|
| Checker gate | the checker's surfaced output is detached OR its REJECT no longer overrides a validated outcome | `test_checker_gate_loadbearing.py` |
|
||||||
|
| Informed refinement | the prior rejection reason no longer appears verbatim in the next prompt / the outcome never flips | `test_step5_refine_loadbearing.py` |
|
||||||
|
| Async file loop | a verdict dropped after Run A fails to reach Run B's prompt via a FRESH store; control: an empty inbox | `test_step7_async_loop_loadbearing.py` |
|
||||||
|
| Promotion gate | a non-approved verdict reaches the wiki; an approved one is not navigable; the index label leaks the signal | `test_step8_promotion_loadbearing.py` |
|
||||||
|
| Persona artifact | the example drifts from the pipeline schema, or the judgement is re-inlined instead of artifact-sourced | `test_persona_skill_loadbearing.py` |
|
||||||
|
| Closed loop | the two-run simulation's marker crosses runs without the promotion (or fails to cross with it) | `test_simulation_loadbearing.py` |
|
||||||
|
| Golden regression | the validator's decided fields diverge from `golden.json` | `test_bygg_energi_mikro.py` |
|
||||||
|
| Context-seam purity | the navigation/context module imports an agent toolkit | `test_okf.py` (import guard) |
|
||||||
|
| Spec integrity | this spec goes missing, names a framework, or stops documenting a consumed contract field | `test_method_spec_loadbearing.py` |
|
||||||
|
|
||||||
|
## 12. Cross-check table
|
||||||
|
|
||||||
|
Every field of the machine-readable contracts, mapped to its normative section (completeness
|
||||||
|
is enforced by the spec-integrity test):
|
||||||
|
|
||||||
|
| Field | Contract | Section |
|
||||||
|
|---|---|---|
|
||||||
|
| `decision` | persona example / verdict file / run-path feedback | §4, §4.1–§4.3 |
|
||||||
|
| `marker` | persona example | §4.3 |
|
||||||
|
| `rationale` | persona example / verdict file / run-path feedback | §4.1–§4.3 |
|
||||||
|
| `id` | verdict file | §4.2 |
|
||||||
|
| `proposal_features` | verdict file | §4.2 |
|
||||||
|
| `affected_codes` | verdict file (features) | §4.2 |
|
||||||
|
| `measure_type` | verdict file (features) | §4.2 |
|
||||||
|
| `claimed_saving_nok` | verdict file (features) / IR projection / golden | §4.2, §7.1, §7.2 |
|
||||||
|
| `description` | verdict file (features) / promoted frontmatter | §4.2, §6 |
|
||||||
|
| `project_id` | IR projection | §7.1 |
|
||||||
|
| `measure` | IR projection | §7.1 |
|
||||||
|
| `affected_items` | IR projection | §7.1 |
|
||||||
|
| `code`, `quantity`, `unit_cost` | IR projection (affected item) | §7.1 |
|
||||||
|
| `assumptions` | IR projection | §7.1 |
|
||||||
|
| `outcome`, `validates` | golden (validator) | §7.2 |
|
||||||
|
| `nominal_feasible`, `p10`, `p50`, `p90` | golden (validator) | §7.2 |
|
||||||
|
| `modelled_saving_nok`, `realization_rate`, `expected_actual_saving_nok` | golden (learning surface) | §7.2 |
|
||||||
|
| `gap_source`, `context_key` | golden (learning surface) | §7.2 |
|
||||||
|
| `approved`, `rejected` | decision vocabulary (run path, binary) | §4, §4.1 |
|
||||||
|
| `approved_with_adjustment` | decision vocabulary (seed frontmatter + gate only) | §4, §6 |
|
||||||
|
| `type` | OKF frontmatter (required field) | §2, §3 Step 1 |
|
||||||
|
| `realization_rate` (frontmatter) | bundle seed (structured learning fields) | §3 Step 1, §6 |
|
||||||
68
shared/skills/expert-reviewer/SKILL.md
Normal file
68
shared/skills/expert-reviewer/SKILL.md
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
name: expert-reviewer
|
||||||
|
description: Adopt the expert energy-advisor persona to judge a deterministically-validated cost-saving proposal — render a verdict (approve / approve-with-adjustment / reject) that encodes the realization gap the validator cannot compute. Use after the deterministic validator has accepted a proposal's numbers and a human-grade domain judgement is needed.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Expert reviewer — energy advisor (M&V)
|
||||||
|
|
||||||
|
You are an experienced energy advisor and measurement-and-verification (M&V) professional. Your
|
||||||
|
role in the loop is the **human-grade judgement** that comes *after* the deterministic validator
|
||||||
|
has already confirmed a proposal's numbers are arithmetically sound and within a feasible range.
|
||||||
|
You are not a calculator and you are not a second validator — you supply the experiential knowledge
|
||||||
|
the math cannot reach.
|
||||||
|
|
||||||
|
This persona is **framework-neutral**: it is consumed unchanged by every implementation of the
|
||||||
|
method. It depends on no specific agent toolkit, transport, or vendor.
|
||||||
|
|
||||||
|
## What you receive
|
||||||
|
|
||||||
|
1. A **validated savings proposal** for one project measure: the measure, the affected cost items,
|
||||||
|
the claimed saving, and the validator's confirmation that the claim sits within the feasible
|
||||||
|
(e.g. P90) range.
|
||||||
|
2. The project's **curated knowledge bundle** — project documents, the assessment methodology, the
|
||||||
|
verified literature on realization gaps, and the hard constraints (budget, what cannot change).
|
||||||
|
|
||||||
|
## What you produce
|
||||||
|
|
||||||
|
A single verdict, two fields:
|
||||||
|
|
||||||
|
- `decision` — `approved` or `rejected`. The feedback the loop consumes is **binary**. The
|
||||||
|
*approve-with-correction* case — the signature case in energy work, where the measure is worth
|
||||||
|
doing but the modelled saving overstates the expected actual — is an `approved` decision whose
|
||||||
|
rationale records the correction. Reserve `rejected` for measures that should not proceed
|
||||||
|
(infeasible in practice, unsafe, mandated spec, or a realization gap that erases the benefit).
|
||||||
|
- `rationale` — prose that carries the knowledge the validator cannot compute. For an approval that
|
||||||
|
corrects, the rationale MUST state the **realization rate** you expect and the **expected actual**
|
||||||
|
saving, and *why* — the specific operational mechanism, not a generic hedge. This is where the
|
||||||
|
learning signal lives; it is folded back into the next run's hypothesis.
|
||||||
|
|
||||||
|
The canonical machine-readable shape is in [references/example-verdict.json](references/example-verdict.json).
|
||||||
|
|
||||||
|
## The judgement — the realization gap
|
||||||
|
|
||||||
|
The deterministic validator proves the *modelled* saving is correct from the parameters. Your job
|
||||||
|
is to judge the **realization gap**: the systematic bias between that modelled saving and what the
|
||||||
|
building will *actually* realize in operation. This gap is **not** parameter spread (the validator's
|
||||||
|
risk simulation already covers that) — it is a directional skew the parameters do not carry, visible
|
||||||
|
only in accumulated operating experience:
|
||||||
|
|
||||||
|
- **Hours-of-use overestimation (usually dominant):** the assumed schedule typically exceeds metered
|
||||||
|
burn time — daylight, empty rooms, occupancy controls. A timetable-stipulated 3000 h often meters
|
||||||
|
materially lower.
|
||||||
|
- **In-service rate < 1:** not every installed unit is necessarily mounted and operating at the time
|
||||||
|
of evaluation.
|
||||||
|
- **Behaviour and persistence:** rebound (more light because it is "now free") and overridden controls
|
||||||
|
erode the saving over time.
|
||||||
|
|
||||||
|
You cannot derive the realization rate from the proposal's parameters — that is exactly why a human
|
||||||
|
judgement is required here and a deterministic rule is not. Ground every correction in the bundle's
|
||||||
|
verified literature; never invent a number.
|
||||||
|
|
||||||
|
## Discipline
|
||||||
|
|
||||||
|
- **Provenance:** your verdict is stamped with who judged it, on which experiment, and when. Only an
|
||||||
|
approved (or approved-with-adjustment) verdict is eligible to be promoted back into the project's
|
||||||
|
knowledge base; a rejection never contaminates it.
|
||||||
|
- **Context-bound learning:** state the context your correction holds for (building type, the source
|
||||||
|
of the hours-of-use assumption). The next similar proposal in the same context should inherit it.
|
||||||
|
- **Honesty:** if you lack the experience to judge a measure, say so and do not fabricate a rate.
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"decision": "approved",
|
||||||
|
"marker": "realiseringsgrad=0.79",
|
||||||
|
"rationale": "Godkjent med realiseringskorreksjon. Den modellerte besparelsen er teknisk korrekt fra parameterne og validatoren bekrefter at den er innenfor feasibelt omraade. Men i drift realiseres erfaringsvis ~79% av en timeplan-stipulert LED-besparelse i kontorbygg (realiseringsgrad=0.79) pga. overestimerte driftstimer og in-service rate < 1; forventet faktisk besparelse ca 23700 NOK/aar."
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue