test(fase2a): repo-lokal mini-bundle-fixture for kryssprosjekt-læring (S2.0)

This commit is contained in:
Kjell Tore Guttormsen 2026-07-15 07:01:06 +02:00
commit 3497e64bdc
4 changed files with 92 additions and 0 deletions

View file

@ -0,0 +1,27 @@
---
type: index
okf_version: 0.1
title: "Bygg-energi mikro-A — repo-lokal fixture (kryssprosjekt-læring)"
description: "Minimal repo-lokal OKF-bundle under data/ for S2.0 kryssprosjekt-lærings-tester. Backer prosjekt k+1 i road-k + bundle-k+1-topologien, så dens bundle_dir-gatede Step-1 ExpeL-fold fyrer."
tags: [fixture, S2.0, kryssprosjekt-laering]
timestamp: 2026-07-15
---
# Bygg-energi mikro-A (repo-lokal test-fixture)
En **repo-lokal mini OKF-bundle** under pakkens `data/` (ALDRI `shared/` — subtree er PULL-ONLY).
Den er liten med vilje: eneste formål er å **back prosjekt *k+1*** i S2.0-kryssprosjekt-lærings-
testene (`test_portfolio_learning_loadbearing.py`), slik at dens `bundle_dir`-gatede Step-1 ExpeL-
fold fyrer på portefølje-stien og en dom fanget på prosjekt *k* materielt når *k+1*s hypotese-prompt.
> Framework-nøytral artefakt (null kode-avhengighet), speiler `shared/examples/bygg-energi-mikro/`-
> formen, men bor bevisst under `data/` (ikke i den PULL-ONLY `shared/`-subtreet).
## Innhold (progressiv disclosure)
- [verdict-seed.md](verdict-seed.md) — `type: verdict` — frøsatt realiseringskorreksjon. Ekskludert
fra lese-konteksten (`bundle_context`); prior dommer når hypotesen KUN via den gatede ExpeL-folden.
`validator-input.json` er IR-projeksjonen den eksisterende deterministiske validatoren konsumerer
(kandidatens kost-IR: `measure`, `affected_items`, `claimed_saving_nok`) — kilden for ExpeL-query-
nøkkelen (`bundle_candidate_features`).

View file

@ -0,0 +1,16 @@
{
"_note": "SYNTHETIC repo-local mini-bundle IR-projeksjon (Fase 2a S2.0-fixture) — ikke ekte data. Backer prosjekt k+1 i road-k + bundle-k+1-topologien; project_id matcher det bundle-backede prosjektets id (run._project_from_bundle fail-faster ved mismatch).",
"project_id": "BYGG-ENERGI-MIKRO-A",
"measure": "LED-retrofit av 120 lysrorarmaturer i kontorflA (90 W -> 40 W)",
"affected_items": [
{
"code": "ENERGI-TOTAL-EL",
"quantity": 180000,
"unit_cost": 1.0
}
],
"claimed_saving_nok": 18000,
"assumptions": {
"ENERGI-TOTAL-EL": [0.70, 1.40]
}
}

View file

@ -0,0 +1,27 @@
---
type: verdict
title: "Ekspert-dom (frø): LED-retrofit kontorfløy A — godkjent med realiseringskorreksjon"
description: "Frøsatt realiseringskorreksjon for den repo-lokale mini-A-bundelen (S2.0-fixture). Gjør bundelen til en fullstendig bygg-energi-mikro-formet OKF-bundle; når IKKE lese-konteksten (verdict-lag ekskludert)."
resource: BYGG-ENERGI-MIKRO-A
measure_id: LED-RETROFIT-A
decision: approved
realization_rate: 0.80
modelled_saving_nok: 18000
expected_actual_saving_nok: 14400
gap_source: hours-of-use-overestimation
context_key: "kontorbygg; HOU-kilde=timeplan-stipulert"
provenance: "frø — AI-forfattet test-fixture, forankret i National Grid SBS 2010 (RR ~0,81); erstattes av ekte HITL i produksjon"
tags: [verdict, realization-rate, fixture]
timestamp: 2026-07-15
---
# Ekspert-dom (frø): LED-retrofit kontorfløy A
> **Frø, ikke en ekte dom.** Brukes kun til å gjøre den repo-lokale S2.0-fixturen til en fullstendig
> `bygg-energi-mikro`-formet OKF-bundle. Verdict-laget er ekskludert fra `bundle_context`; en prior
> dom når neste hypotese KUN via den gatede ExpeL-folden (målbilde §2/§4).
Den modellerte besparelsen (**18 000 NOK/år**) er teknisk korrekt fra parameterne. I drift realiseres
erfaringsvis **~80 %** av en timeplan-stipulert LED-besparelse i kontorbygg → forventet faktisk
besparelse **≈ 14 400 NOK/år**. Korreksjonen er kontekstbetinget
(`context_key = "kontorbygg; HOU-kilde=timeplan-stipulert"`).

View file

@ -38,6 +38,28 @@ def test_every_project_has_docs_dir_and_verdict_input(projects: tuple[Project, .
assert p.verdict_input["decision"] and p.verdict_input["rationale"]
def test_repo_local_mini_bundle_loads_as_ir_projection() -> None:
"""Step 1 (S2.0 fixture): the repo-local mini OKF-bundle under the package ``data/`` root loads
as a valid IR projection via ``okf.load_ir_projection`` (fail-fast), exposing its ``project_id``,
and lives under ``data/`` NEVER under ``shared/`` (the subtree is PULL-ONLY). It is also a
navigable OKF bundle (readable ``index.md``), so the Step-3 bundle-context navigation works."""
import os
from importlib.resources import files
from portfolio_optimiser import okf
bundle_dir = str(files("portfolio_optimiser").joinpath("data/bundles/bygg-energi-mikro-a"))
assert os.path.isdir(bundle_dir)
assert f"{os.sep}data{os.sep}bundles{os.sep}" in bundle_dir
assert f"{os.sep}shared{os.sep}" not in bundle_dir
ir = okf.load_ir_projection(bundle_dir)
assert ir["project_id"] == "BYGG-ENERGI-MIKRO-A"
bundle = okf.navigate_bundle(bundle_dir)
assert bundle.index_summary.strip()
def test_cost_item_total_is_quantity_times_unit_cost() -> None:
item = CostItem(code="X", description="d", quantity=4.0, unit="m2", unit_cost=215.0)
assert item.total_cost == pytest.approx(860.0)