run_project KREVDE verdict_input og kjorte capture_verdict ubetinget; CLI-en
defaultet det til {"approved", "reviewed by expert"} og hosting listet det som
PAAKREVD. Netto: hver flaggloes kjoering myntet en ekspertgodkjenning ingen ga,
den gikk inn i den delte storen, og run_portfolio bar den inn i neste prosjekts
hypotese-prompt som en prior expert verdict -- paa flaten som ble overlevert
14.08. Non-goal 3, brutt i en soem.
RunResult.verdict er naa Verdict | None, og None er hva stillhet produserer:
ingenting myntes, ingenting lagres, ingenting varsles. Prinsippet sto allerede i
repoet -- RunFailure sin docstring: aa fylle et felt med en dummy legger
FABRIKKERT proveniens inn i aggregatet.
Traceability koster ingenting: RunResult.verdict_key (property, derivert fra
kandidaten) er verdicts.verdict_key sitt alt dokumenterte formaal -- identisk
med verdict.id naar en dom BLE gitt, og fortsatt meningsfull naar ingen ble det.
Det er den outboxen og den hostede responsen stempler.
Halv dom NEKTES paa begge doerer (FeedbackContract er eneste sted formen
valideres; CLI-en nekter ved navn FOER enhver mode-dispatch). Validering, aldri
reparasjon. De to mode-partisjonene fikk --decision/--rationale inn: kommentarene
sa ordrett at en aerlig nekt var uimplementerbar fordi de non-None
argparse-defaultene gjorde en eksplisitt verdi uskillbar fra defaulten -- med
defaultene borte er den implementerbar.
Hosting er WIDENING, ikke bryting: verdict_input flyttet fra _REQUIRED_FIELDS
til _OPTIONAL_FIELDS. Ingen ekstern kaller brekker.
AERLIGHETS-GRENSE: referanse-fixturens SYNTETISKE verdict_input-rader staar
uroert -- de er merket SYNTETISK paa fire steder og er reviewens F5 (maaling av
misjonspaastanden), ikke F2. Project.verdict_input er naa valgfri.
Load-bearing MAALT (tests/test_ungiven_verdict_loadbearing.py, 15 armer), aatte
mutasjoner alle roede mot HELE suiten + gronn kontroll 1080/5 og golden
demo-transcript.stdout BYTE-UENDRET (ea8c534773acdbe41ae68f2c55724d69aaf8be4f).
En mutasjon falsifiserte testen foerst (vakuoes-gate-klassen, ellevte gang):
--report-armen brukte et bart --report, som nekter rc 1 uansett fordi --ledger
mangler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
Limbare ekspert-svar
Dette dokumentet er for deg som skal avgi dommen i loopen — fageksperten som får et validert forslag i fanget og skal si ja, ja-med-forbehold eller nei. Det gir deg ferdige svar du kan lime rett inn, og forklarer hvor de skal limes.
Ærlighetsmerking. Svarteksten under er AI-forfattet og er ikke verifisert fagdom. Den er laget for å vise formen et ekspertsvar har og for å gjøre gjennomkjøringen mulig uten en levende ekspert. Tallene og resonnementene er forankret i kildene som ligger i kunnskapsbasen (
shared/examples/bygg-energi-mikro/kilder-realiseringsgap.md), men ingen fagperson har godkjent dem. Skal en dom telle som fagdom, må en fagperson skrive den selv.
De to formene, og når du bruker hvilken
Systemet tar imot en ekspertdom på to steder, og de gjør forskjellige ting:
| Form A — begrunnelses-streng | Form B — dom-fil i innboksen | |
|---|---|---|
| Hvor | --decision / --rationale på kommandolinjen |
en JSON-fil i mappa --verdict-dir peker på |
| Når | du er til stede mens kjøringen skjer | du dømmer etterpå, kanskje dager senere |
| Rekkevidde | denne ene kjøringen | alle senere kjøringer som leser innboksen |
| Hva du skriver | bare begrunnelsen (én streng) | hele dommen som JSON-dokument |
Form B er den som lærer systemet noe. Form A er en synkron snarvei.
Ingen av dem er default, og det er poenget. Utelater du begge flaggene, blir det ikke registrert
noen dom i det hele tatt — kjøringen sier det høyt (no expert verdict given; verdict key=…), og
ingenting går inn i læringsstoren. Fram til 1.1.0 defaultet --decision til approved, slik at
hver flaggløs kjøring produserte en ekspertgodkjenning ingen ekspert hadde gitt, og bar den videre
inn i neste prosjekts hypotese. Nøkkelen linja skriver ut er den du fører inn i id-feltet i Form
B, og det er slik en dom avgitt dager senere finner tilbake til kandidaten den gjelder.
Halv dom nektes: --decision og --rationale må gis sammen. Den manglende halvdelen er
ekspertens å skrive, aldri systemets å fylle inn.
decision er binær på kjørestien: approved eller rejected. Det finnes ikke et tredje
«godkjent med justering» her — en realiseringskorreksjon er en godkjenning der forbeholdet står
i begrunnelsen. Det er med vilje: forbeholdet er fagkunnskap som skal leses, ikke en enum-verdi som
kan telles.
Form A — begrunnelses-streng på kommandolinjen
uv run python -m portfolio_optimiser.run BYGG-KONTOR-NORD \
--docs-dir shared/examples/bygg-energi-mikro \
--bundle-dir shared/examples/bygg-energi-mikro \
--scripted-replies replies.json \
--decision approved \
--rationale "Godkjent med realiseringskorreksjon. Besparelsen er teknisk korrekt utledet, men i drift realiseres erfaringsvis ~79 % av en timeplan-stipulert LED-besparelse i kontorbygg; forventet faktisk besparelse ca 23 700 NOK/aar."
Form B — dom-fil i innboksen
Slik finner du feltene du må fylle ut
Kjør med --outbox-dir (som krever --run-id), så legger kjøringen igjen artefaktene sine:
uv run python -m portfolio_optimiser.run BYGG-KONTOR-NORD \
--docs-dir shared/examples/bygg-energi-mikro \
--bundle-dir shared/examples/bygg-energi-mikro \
--scripted-replies replies.json \
--outbox-dir utboks --run-id run-001
uv run python -m portfolio_optimiser.hitl pending --outbox-dir utboks --verdict-dir innboks
pending skriver én linje per forslag som fortsatt venter på en dom:
run-001 c91cb2fe1aa139a9 validated
Midterste kolonne er id-en dommen din må bære. Den er en innholds-hash av forslagets
egenskaper, ikke et løpenummer — den er nøkkelen en senere kjøring bruker for å finne igjen dommen
din, så den må gjengis ordrett. Resten av feltene ligger i utboks/run-001-proposal.json:
measure → measure_type, hver affected_items[].code → affected_codes, og
claimed_saving_nok uendret.
Har du bestilt flere tilnærminger?
Da får hver vurderte tilnærming sin egen artefakt — ellers kunne du bare dømt den ene kjøringen
valgte, og de andre du bestilte ville ikke lært systemet noe. Filene heter
utboks/run-001-<tilnærming>-proposal.json, og pending lister dem hver for seg med
tilnærmingen i klammer:
run-001 c91cb2fe1aa139a9 validated [behovsstyrt-lys]
run-001 4f0a1d77b2e5c318 rejected [aggregat-bytte]
run-001 9b31e0c4a7d6f025 validated [own-proposal]
own-proposal er systemets eget forslag, ikke et av dine. Hver linje dømmes for seg, med sin egen
id — akkurat som over. To tilnærminger som endte på nøyaktig samme forslag deler id (den er en
innholds-hash), og da gjør én dom opp for begge; det er ikke en feil, det er at de var samme forslag.
Merk hva artefaktene ikke sier: en tilnærming som står som rejected, er avvist av den
deterministiske validatoren — altså på tallene. Det er ikke en fagdom over ideen. Det er nettopp
derfor den fortsatt havner i pending og venter på deg.
Utboks og innboks skal være to forskjellige mapper. De har motsatt eierskap: systemet skriver
utboksen, du skriver innboksen. (Målt: å peke dem på samme mappe ødelegger ingenting i dag —
utboksens filer heter run-001-*.json og mangler dom-feltene, så innboks-lasteren hopper over dem.
Men den dagen noe skriver en dom-formet fil i utboksen, blir rå agent-output lest inn som om en
ekspert hadde godkjent den. Hold dem adskilt.)
Fila legges i innboksen som <id>.json, altså innboks/c91cb2fe1aa139a9.json.
Svar 1 — godkjent med realiseringskorreksjon
Det vanligste ekte svaret på et energitiltak: regnestykket stemmer, men drift leverer mindre enn modellen lovte. Dette er dommen som bærer mest læring, fordi den forteller systemet noe det ikke kunne lest ut av tallene selv.
{
"id": "c91cb2fe1aa139a9",
"decision": "approved",
"rationale": "Godkjent med realiseringskorreksjon. Den modellerte besparelsen er teknisk korrekt utledet fra parameterne, og validatoren bekrefter at den ligger innenfor feasibelt omraade. Men i drift realiseres erfaringsvis ~79 % av en timeplan-stipulert LED-besparelse i kontorbygg (realiseringsgrad=0.79), fordi driftstimene er overestimerte og in-service rate er under 1. Forventet faktisk besparelse er ca 23 700 NOK/aar. Tiltaket gjennomfoeres, men gevinsten foeres opp med det korrigerte tallet.",
"proposal_features": {
"affected_codes": ["ENERGI-TOTAL-EL"],
"measure_type": "LED-retrofit av kontorbelysning",
"claimed_saving_nok": 30000.0,
"description": ""
}
}
Svar 2 — godkjent uten forbehold
Når du faktisk mener tallet står seg som det er. Kort er riktig her; en lang begrunnelse for et enkelt ja gir systemet støy å lære av.
{
"id": "c91cb2fe1aa139a9",
"decision": "approved",
"rationale": "Godkjent. Effekt foer/etter og antall armaturer er verifisert mot anleggets egen dokumentasjon, og driftstimene er metret, ikke stipulert. Det vanlige realiseringsavviket gjelder derfor ikke her, og besparelsen foeres opp uendret.",
"proposal_features": {
"affected_codes": ["ENERGI-TOTAL-EL"],
"measure_type": "LED-retrofit av kontorbelysning",
"claimed_saving_nok": 30000.0,
"description": ""
}
}
Svar 3 — avvist: tiltaket er ikke gjennomførbart her
Den viktigste dommen å ha et eksempel på, fordi den er den eneste som stopper noe. Validatoren har allerede sagt at tallene holder — du sier at virkeligheten rundt tallene ikke gjør det. Det er en dom bare et menneske kan avgi.
{
"id": "c91cb2fe1aa139a9",
"decision": "rejected",
"rationale": "Avvist. Regnestykket er internt konsistent, men forutsetningen om 3 000 driftstimer holder ikke for dette bygget: belysningen staar paa naermest kontinuerlig i fellesarealene og er allerede dagslysstyrt i kontorsonene, saa faktisk brenntid ligger langt fra timeplanen tiltaket er regnet paa. I tillegg ble armaturene skiftet i 2023 og er ikke avskrevet. Et nytt bytte naa gir en gevinst som ikke forsvarer kostnaden, uavhengig av at den modellerte besparelsen er feasibel.",
"proposal_features": {
"affected_codes": ["ENERGI-TOTAL-EL"],
"measure_type": "LED-retrofit av kontorbelysning",
"claimed_saving_nok": 30000.0,
"description": ""
}
}
Svar 4 — avvist: feil kostnadsgrunnlag
Bruk denne når tiltaket i seg selv er fornuftig, men det er regnet mot feil tall. Her sier du noe om grunnlaget, ikke om tiltaket — og det er en annen lærdom for systemet.
{
"id": "c91cb2fe1aa139a9",
"decision": "rejected",
"rationale": "Avvist paa grunnlaget, ikke paa tiltaket. Besparelsen er regnet mot byggets totale elforbruk, men belysning utgjoer bare ~18 % av det forbruket. Den paastaatte besparelsen tilsvarer over halvparten av hele belysningsposten, noe som ikke er oppnaaelig med et rent armaturbytte. Send tiltaket inn paa nytt regnet mot belysningsposten alene, saa er det sannsynligvis godkjennbart i redusert form.",
"proposal_features": {
"affected_codes": ["ENERGI-TOTAL-EL"],
"measure_type": "LED-retrofit av kontorbelysning",
"claimed_saving_nok": 30000.0,
"description": ""
}
}
Hva systemet gjør med dommen din
Legg fila i innboksen og kjør på nytt med --verdict-dir:
uv run python -m portfolio_optimiser.run BYGG-KONTOR-NORD \
--docs-dir shared/examples/bygg-energi-mikro \
--bundle-dir shared/examples/bygg-energi-mikro \
--scripted-replies replies.json \
--verdict-dir innboks
Dommen slås sammen inn i minnet før hypotesen lages, så neste forslag ser hva du sa forrige
gang. hitl pending er tom etterpå — forslaget er dømt.
Dommen din blir liggende i råt-laget: den er lest, men den er ikke skrevet inn i
kunnskapsbasen. Det siste skrittet er bevisst atskilt og krever en godkjenning
(verdicts.promote_verdict), slik at bare kunnskap et menneske har stått inne for havner i wikien.
En avvist dom kan ikke promoteres i det hele tatt — porten er lukket den veien, så rå agent-output
aldri kan skrive seg selv inn som lærdom.
Om du skriver dine egne
idgjengis ordrett frahitl pending. Endrer du den, blir dommen din hengende på et forslag som ikke finnes.decisionerapprovedellerrejected. Ingen tredje verdi på denne stien.proposal_featuresskal beskrive forslaget du dømte, ikke det du mener det burde vært. Feltene kopieres frarun-001-proposal.json.- Begrunnelsen er det eneste som bærer fagkunnskap videre. Skriv hvorfor, ikke hva — «avvist, ikke feasibelt» lærer systemet ingenting det ikke allerede visste.
- En ufullstendig eller halvskrevet fil hoppes stille over, ikke feiler. Sjekk med
hitl pendingat forslaget faktisk forsvant fra lista.