refactor(examples): replace sector-specific example material with generic, fictitious examples

The context sets, the packaged knowledge bases and the example bundles are
replaced by one fictitious example set about IT operations in an invented
organisation: three context sets (serverrom-2027, driftsavtale-2027 and the
two-base drift-og-avtale-2027), two synthetic knowledge bases under
src/portfolio_optimiser/data/kunnskapsbaser and two example bundles under
src/portfolio_optimiser/data/bundles. Numbers, codes and structural values in
tests and fixtures are kept; names, ids and wording change. Dated measurement
documents that only recorded runs on the replaced material are deleted.

Gate figures measured on the new set are not comparable with earlier ones.
The exclusion gate from the previous commit is green: 0 tracked files hit
outside the shared/ subtree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-23 15:04:21 +02:00
commit 37547fe292
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
1147 changed files with 24138 additions and 9503 deletions

View file

@ -40,7 +40,8 @@ from portfolio_optimiser import explore, okf, run as run_module
_EXAMPLES = Path(__file__).resolve().parents[1] / "shared" / "examples"
_BYGG = _EXAMPLES / "bygg-energi-mikro" # BYGG-KONTOR-NORD
_TUNNEL = _EXAMPLES / "tunnel-hauglia" # TUNNEL-HAUGLIA
_BUNDLES = Path(__file__).resolve().parents[1] / "src" / "portfolio_optimiser" / "data" / "bundles"
_KJOLING = _BUNDLES / "driftssenter-kjoling" # DRIFTSSENTER-KJOLING
_PROPOSAL = json.dumps(
{
@ -136,14 +137,14 @@ def test_each_base_writes_its_own_artefact_set_under_its_own_minted_run_id(tmp_p
DISTINCT: with one key the second base would overwrite the first and the outbox would hold one
base's answers under a name claiming to cover both.
"""
bases = _mount(tmp_path, _BYGG, _TUNNEL)
bases = _mount(tmp_path, _BYGG, _KJOLING)
outbox = tmp_path / "out"
rc = run_module.main(
_argv(
bases,
mandate=_mandate_file(
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "tunnel-hauglia")]
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "driftssenter-kjoling")]
),
run_id="X",
outbox=outbox,
@ -153,7 +154,7 @@ def test_each_base_writes_its_own_artefact_set_under_its_own_minted_run_id(tmp_p
)
assert rc == 0
for bundle_id, approach in (("bygg-energi-mikro", "a"), ("tunnel-hauglia", "b")):
for bundle_id, approach in (("bygg-energi-mikro", "a"), ("driftssenter-kjoling", "b")):
stem = f"X-{bundle_id}"
assert (outbox / f"{stem}-{approach}-proposal.json").is_file()
assert (outbox / f"{stem}-{approach}-outcome.json").is_file()
@ -165,11 +166,11 @@ def test_each_base_writes_its_own_artefact_set_under_its_own_minted_run_id(tmp_p
assert summary["run_id"] == "X"
assert [row["bundle_id"] for row in summary["runs"]] == [
"bygg-energi-mikro",
"tunnel-hauglia",
"driftssenter-kjoling",
]
assert [row["run_id"] for row in summary["runs"]] == [
"X-bygg-energi-mikro",
"X-tunnel-hauglia",
"X-driftssenter-kjoling",
]
assert summary["unreached"] == []
assert summary["collisions"] == []
@ -185,7 +186,7 @@ def test_the_summary_reports_the_stop_reason_each_base_recorded(tmp_path: Path)
An unparseable proposer burns the round cap, the FIRST approach to hit it re-raises by design
(``_evaluate_mandate`` only swallows mid-list), and the pass therefore ends rc 1 — which is
exactly what round 3 measured on ``kontrakt-sorasen-2027-04``. The summary must still be
exactly what round 3 measured on one context set's ``…-04`` run. The summary must still be
there, must say ``rounds`` rather than the empty string that means "the run finished", and
must say ``completed: false`` rather than leaving an empty ``unreached`` to be read as
"nothing was left unreached".
@ -293,7 +294,7 @@ def test_the_second_base_sees_the_verdict_the_first_base_minted(
EVENT: the set of verdict ids already in the store when base 2 began must contain the id base
1 minted, which a fresh-store-per-base implementation cannot produce.
"""
bases = _mount(tmp_path, _BYGG, _TUNNEL)
bases = _mount(tmp_path, _BYGG, _KJOLING)
seen: list[tuple[int, frozenset[str]]] = []
real = run_module.run_project
@ -308,7 +309,7 @@ def test_the_second_base_sees_the_verdict_the_first_base_minted(
_argv(
bases,
mandate=_mandate_file(
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "tunnel-hauglia")]
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "driftssenter-kjoling")]
),
run_id="X",
outbox=tmp_path / "out",
@ -337,7 +338,7 @@ def test_the_requirement_gate_reads_the_second_bases_own_opened_list(tmp_path: P
repo's own answer is to call each tool by name. Base 1 opens a document; declaring THAT path
against base 2 must refuse, because base 2's own sink never saw it.
"""
first, second = _mount(tmp_path, _BYGG, _TUNNEL)
first, second = _mount(tmp_path, _BYGG, _KJOLING)
opened_1: list[explore.ToolCall] = []
opened_2: list[explore.ToolCall] = []
@ -384,14 +385,14 @@ def test_each_bases_debate_artefact_lists_only_its_own_tool_calls(tmp_path: Path
base its own. With one shared sink base 2's artefact would carry base 1's call as well, so the
discriminator is the COUNT and not the presence.
"""
bases = _mount(tmp_path, _BYGG, _TUNNEL)
bases = _mount(tmp_path, _BYGG, _KJOLING)
outbox = tmp_path / "out"
rc = run_module.main(
_argv(
bases,
mandate=_mandate_file(
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "tunnel-hauglia")]
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "driftssenter-kjoling")]
),
run_id="X",
outbox=outbox,
@ -402,7 +403,7 @@ def test_each_bases_debate_artefact_lists_only_its_own_tool_calls(tmp_path: Path
assert rc == 0
counts = []
for bundle_id in ("bygg-energi-mikro", "tunnel-hauglia"):
for bundle_id in ("bygg-energi-mikro", "driftssenter-kjoling"):
payload = json.loads((outbox / f"X-{bundle_id}-debate.json").read_text(encoding="utf-8"))
counts.append([call["name"] for call in payload["tool_calls"]])
assert counts == [["list_bundles"], ["list_bundles"]], counts
@ -448,13 +449,15 @@ def test_a_dry_run_drills_every_base_and_stops_before_the_first_call(
Silently dropping the flag here is the F4 class — the dry run would fall through to the
single-project branch, which has no ``PROJECT_ID`` in this argv at all.
"""
bases = _mount(tmp_path, _BYGG, _TUNNEL)
bases = _mount(tmp_path, _BYGG, _KJOLING)
rc = run_module.main(
[
*sum([["--across-bundle", b] for b in bases], []),
"--mandate",
_mandate_file(tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "tunnel-hauglia")]),
_mandate_file(
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "driftssenter-kjoling")]
),
"--run-id",
"X",
"--outbox-dir",
@ -466,11 +469,11 @@ def test_a_dry_run_drills_every_base_and_stops_before_the_first_call(
out = capsys.readouterr().out
assert rc == 0
assert out.count("LIVE-DRY-RUN OK") == 2
assert "bygg-energi-mikro" in out and "tunnel-hauglia" in out
assert "bygg-energi-mikro" in out and "driftssenter-kjoling" in out
# The per-base notices are the discriminator against ONE drill that merely names two bases:
# ``bygg-energi-mikro`` ships no ``cost-baseline.json`` and ``tunnel-hauglia`` does, so exactly
# one unanchored notice and exactly one grounding offer must appear — and a drill of only the
# first, or only the second, produces a different count either way.
# ``bygg-energi-mikro`` ships no ``cost-baseline.json`` and ``driftssenter-kjoling`` does, so
# exactly one unanchored notice and exactly one grounding offer must appear — and a drill of
# only the first, or only the second, produces a different count either way.
assert out.count("Grounding offer") == 1
assert out.count("Cost baseline: NONE") == 1
@ -565,11 +568,13 @@ def test_the_anchoring_requirement_is_carried_to_every_base_not_dropped(
would be the F4 class on the one guarantee an operator asked for by name — so the arm asserts
the REFUSAL, and its control asserts that the same argv without the flag runs to rc 0.
``bygg-energi-mikro`` ships no ``cost-baseline.json`` and ``tunnel-hauglia`` does, so the
``bygg-energi-mikro`` ships no ``cost-baseline.json`` and ``driftssenter-kjoling`` does, so the
refusal must come from the first base rather than from "neither is anchored".
"""
bases = _mount(tmp_path, _BYGG, _TUNNEL)
mandate = _mandate_file(tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "tunnel-hauglia")])
bases = _mount(tmp_path, _BYGG, _KJOLING)
mandate = _mandate_file(
tmp_path, rows=[("a", "bygg-energi-mikro"), ("b", "driftssenter-kjoling")]
)
replies = _replies_file(tmp_path)
outbox = tmp_path / "out"