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

@ -1,11 +1,11 @@
"""The measurements read a FROZEN copy of the vegnormal bases, pinned by sha256 — never another
"""The measurements read a FROZEN copy of the knowledge bases, pinned by sha256 — never another
repository's live build directory.
Measured 2026-09-17 17:43: ``vegnormal-okf`` rebuilt ``build/ferdig/r761-2025`` while this
repository's gate pointed straight at it. Rows 6-7 went "IKKE MÅLT" and five tests fell, for a
change no one here made. The failure mode was never falsehood — the gate says IKKE MÅLT and exits
non-zero, never green — it was that two projects shared a directory neither owns, so what this
repository MEASURES could change without a commit here.
Measured 2026-09-17: another project rebuilt the corpus directory this repository's gate pointed
straight at. Rows 6-7 went "IKKE MÅLT" and five tests fell, for a change no one here made. The
failure mode was never falsehood — the gate says IKKE MÅLT and exits non-zero, never green — it was
that two projects shared a directory neither owns, so what this repository MEASURES could change
without a commit here.
The fix is a copy outside both repositories plus a pin this repository tracks. The pin is the whole
point: a copy with no pin is the same shared directory one move further away. So the three states
@ -13,9 +13,10 @@ are separated by construction, and each has its own arm below:
* the copy matches the pin -> it resolves, and that is the only green path;
* the copy is GONE -> ``FrozenBundleMissing`` (an ``OSError``): the gate says
IKKE MÅLT and fails the exit code exactly as it did before this change; the delivered-corpus
tests SKIP, which is MAJOR-3's ceiling rule (a hard error would break ``uv run pytest`` in the
handover archive, where no corpus is mounted);
IKKE MÅLT and fails the exit code exactly as it did before this change; the corpus tests SKIP.
Since the bases became the package's own fictional examples (``data/kunnskapsbaser/``) the
default store is always present, so this state is reached only through a user's own store
(``PORTFOLIO_FROZEN_BUNDLES``) — and it is still pinned below, because that door stays open;
* the copy DIFFERS from the pin -> ``FrozenBundleDrift`` (a ``ValueError``): loud, named, and
NEVER a skip. A drifted copy is not an unreadable measurement, it is a measurement of the wrong
corpus, which is the one thing that produces a silently wrong number.
@ -42,18 +43,20 @@ _REPO = Path(__file__).resolve().parent.parent
#: Joined at run time on purpose: this file NAMES the forbidden path spellings, and a literal
#: would make the gate below red against its own source. (Implicit concatenation is not enough —
#: ``ruff format`` folds ``"a" "b"`` back into one literal, measured here.)
_OTHER_REPO = "-".join(("vegnormal", "okf"))
#: The two spellings a path to that repository's build directory takes in this codebase. Both were
#: present before this change (3 + 4 hits, the known positives recorded in the order's evidence).
#: Each is paired with the line that PROVES it can match: a pattern that matches nothing makes a
#: gate that can only be green, and the two spellings do not match each other's sample.
_OTHER_REPO = "-".join(("another", "project"))
#: The two spellings a path into ANOTHER repository's build directory takes. Both were present
#: before this change (3 + 4 hits against the corpus project's build directory, the known
#: positives recorded in the order's evidence); the patterns are now written for ANY sibling
#: repository rather than for that one name, which is the rule the order stated. Each is paired
#: with the line that PROVES it can match: a pattern that matches nothing makes a gate that can
#: only be green, and the two spellings do not match each other's sample.
_FORBIDDEN = (
(
re.compile(re.escape(_OTHER_REPO + "/build")),
re.compile(r"~/repos/[\w.-]+/build"),
f'ROOT = Path("~/repos/{_OTHER_REPO}/build/ferdig")',
),
(
re.compile("[\"']" + re.escape(_OTHER_REPO) + "[\"']"),
re.compile(r'home\(\) / "repos" / "[\w.-]+" / "build"'),
'ROOT = Path.home() / "repos" / "' + _OTHER_REPO + '" / "build" / "ferdig"',
),
)
@ -76,7 +79,7 @@ def _bundle(root: Path, body: str = "one") -> Path:
return root
def _store(tmp_path: Path, name: str = "n500-2024", body: str = "one") -> tuple[Path, Path]:
def _store(tmp_path: Path, name: str = "driftskrav-2027", body: str = "one") -> tuple[Path, Path]:
"""A frozen store holding ONE pinned bundle, and the pin file that names it."""
store = tmp_path / "store"
digest, files = fb.digest_bundle(_bundle(tmp_path / "src-of-truth", body))
@ -134,18 +137,18 @@ def test_an_added_or_removed_file_is_drift_even_when_no_kept_byte_changes(
only the SET of files moved, and the set is what a copy is."""
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
base = fb.bundle_dir("n500-2024") # control: green before either edit
base = fb.bundle_dir("driftskrav-2027") # control: green before either edit
extra = base / "krav" / "b.md"
extra.write_text("---\ntype: Krav\ntitle: B\n---\n", encoding="utf-8")
with pytest.raises(fb.FrozenBundleDrift):
fb.bundle_dir("n500-2024")
fb.bundle_dir("driftskrav-2027")
extra.unlink()
assert fb.bundle_dir("n500-2024") == base # the edit, not the fixture, was the cause
assert fb.bundle_dir("driftskrav-2027") == base # the edit, not the fixture, was the cause
(base / "krav" / "a.md").unlink()
with pytest.raises(fb.FrozenBundleDrift) as exc:
fb.bundle_dir("n500-2024")
fb.bundle_dir("driftskrav-2027")
assert "1 filer" in str(exc.value) # what disk holds now: one file of the pinned two
@ -173,7 +176,7 @@ def test_a_matching_copy_resolves_to_the_pinned_directory(
) -> None:
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
resolved = fb.bundle_dir("n500-2024")
resolved = fb.bundle_dir("driftskrav-2027")
assert resolved.parent == store
assert (resolved / "index.md").is_file()
@ -188,15 +191,15 @@ def test_one_changed_byte_is_drift_named_with_both_digests(
) -> None:
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
base = fb.bundle_dir("n500-2024") # green before the edit — the control
expected = json.loads(pin.read_text(encoding="utf-8"))["bundles"]["n500-2024"]["sha256"]
base = fb.bundle_dir("driftskrav-2027") # green before the edit — the control
expected = json.loads(pin.read_text(encoding="utf-8"))["bundles"]["driftskrav-2027"]["sha256"]
_touch_one_byte(base)
with pytest.raises(fb.FrozenBundleDrift) as exc:
fb.bundle_dir("n500-2024")
fb.bundle_dir("driftskrav-2027")
message = str(exc.value)
assert "avviker fra pin" in message
assert "n500-2024" in message
assert "driftskrav-2027" in message
assert expected[: fb.SHORT] in message # what was pinned
assert fb.digest_bundle(base)[0][: fb.SHORT] in message # what is on disk
@ -207,12 +210,12 @@ def test_a_missing_copy_is_missing_and_stays_an_oserror(
"""``measure_stress`` already catches ``OSError`` -> IKKE MÅLT + exit 1; that path is unchanged."""
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
shutil.rmtree(store / fb.load_pins()["n500-2024"].directory)
shutil.rmtree(store / fb.load_pins()["driftskrav-2027"].directory)
with pytest.raises(fb.FrozenBundleMissing) as exc:
fb.bundle_dir("n500-2024")
fb.bundle_dir("driftskrav-2027")
assert isinstance(exc.value, OSError)
assert "n500-2024" in str(exc.value)
assert "driftskrav-2027" in str(exc.value)
def test_drift_is_not_a_missing_copy(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
@ -224,10 +227,10 @@ def test_drift_is_not_a_missing_copy(tmp_path: Path, monkeypatch: pytest.MonkeyP
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
_touch_one_byte(fb.bundle_dir("n500-2024"))
_touch_one_byte(fb.bundle_dir("driftskrav-2027"))
with pytest.raises(fb.FrozenBundleDrift):
try:
fb.bundle_dir("n500-2024")
fb.bundle_dir("driftskrav-2027")
except fb.FrozenBundleMissing: # pragma: no cover - the defect this arm forbids
pytest.fail("drift was answered as a missing copy")
@ -238,22 +241,22 @@ def test_an_unknown_name_is_refused_by_name(
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
with pytest.raises(fb.FrozenBundleMissing) as exc:
fb.bundle_dir("n100-2023")
assert "n100-2023" in str(exc.value) and "n500-2024" in str(exc.value)
fb.bundle_dir("prosesskatalog-2027")
assert "prosesskatalog-2027" in str(exc.value) and "driftskrav-2027" in str(exc.value)
def test_an_explicit_override_is_unpinned_and_the_operator_named_it(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""``--bundle-root`` / ``PORTFOLIO_VEGNORMAL_ROOT`` stays an escape hatch: the operator who
"""``--bundle-root`` / ``PORTFOLIO_BUNDLE_ROOT`` stays an escape hatch: the operator who
names a live mount gets it, pin or no pin. Absent it, the frozen store answers."""
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
live = tmp_path / "live"
_bundle(live / "n500-2024", body="something else entirely")
assert fb.bundle_dir("n500-2024", override=live) == live / "n500-2024"
_bundle(live / "driftskrav-2027", body="something else entirely")
assert fb.bundle_dir("driftskrav-2027", override=live) == live / "driftskrav-2027"
monkeypatch.setenv(fb.OVERRIDE_ENV, str(live))
assert fb.bundle_dir("n500-2024") == live / "n500-2024"
assert fb.bundle_dir("driftskrav-2027") == live / "driftskrav-2027"
# ---------------------------------------------------------------------------------------------
@ -287,8 +290,31 @@ def test_the_pin_file_carries_no_key_nobody_reads() -> None:
assert keys == {"source", "renewal", "bundles"}
def test_the_bundle_itself_is_never_tracked_here() -> None:
"""Vegnormal corpora must not reach a public remote: only the pin is tracked."""
def test_the_default_store_is_the_packaged_example_bases(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""The pinned bases are the package's OWN fictional examples, so the default store sits next
to the module — a wheel finds it without a checkout — and every pin resolves there, matched,
with nothing in the environment helping.
Three halves, each a defect of its own: a default pointing at a machine-local path (the old
``~/corpora`` store) makes every corpus arm skip on every other machine; a pin that does not
resolve from the default is a pin nothing checks; and a copy left in the store with no pin is
a stale base that ``ls`` shows and nothing measures. The pin file itself still carries only
the pin, never bundle bytes.
"""
monkeypatch.delenv(fb.STORE_ENV, raising=False)
monkeypatch.delenv(fb.OVERRIDE_ENV, raising=False)
packaged = Path(fb.__file__).resolve().parent / "data" / "kunnskapsbaser"
assert Path(fb.DEFAULT_STORE).resolve() == packaged
pins = fb.load_pins()
assert set(pins) == {"driftskrav-2027", "prosesskatalog-2027"}
for name, pin in pins.items():
base = fb.bundle_dir(name)
assert base == Path(fb.DEFAULT_STORE) / pin.directory
assert fb.digest_bundle(base)[1] == pin.files
on_disk = sorted(p.name for p in packaged.iterdir() if p.is_dir())
assert on_disk == sorted(pin.directory for pin in pins.values()), on_disk
tracked = (_REPO / "src" / "portfolio_optimiser" / "frozen_bundles.json").read_text("utf-8")
assert "index.md" not in tracked
@ -357,7 +383,7 @@ def _evidence(tmp_path: Path) -> tuple[dict[str, Any], Path]:
"root": "scratchpad",
"runs": [
{
"context": "contexts/tunnel-hauglia-2027",
"context": "contexts/serverrom-2027",
"outbox": "o",
"run_id": "r",
"bundle": None,
@ -371,7 +397,7 @@ def test_a_drifted_copy_fails_the_gate_with_the_reason_said(
) -> None:
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
_touch_one_byte(fb.bundle_dir("n500-2024"))
_touch_one_byte(fb.bundle_dir("driftskrav-2027"))
evidence, stress_root = _evidence(tmp_path)
m = gate.measure_stress(evidence, _REPO, stress_root, None)
@ -422,14 +448,14 @@ def test_the_corpus_tests_skip_when_absent_but_fail_on_drift(
store, pin = _store(tmp_path)
_use(monkeypatch, store, pin)
assert resolve("n500-2024").is_dir() # control: the matching copy resolves
_touch_one_byte(fb.bundle_dir("n500-2024"))
assert resolve("driftskrav-2027").is_dir() # control: the matching copy resolves
_touch_one_byte(fb.bundle_dir("driftskrav-2027"))
# A skip is caught EXPLICITLY, never left to ``pytest.raises``: measured against the mutation
# that makes drift a subclass of missing, these four arms SKIPPED instead of failing (5 -> 9
# skipped over the whole suite) and stayed green — a gate that cannot see the one defect it
# exists for.
try:
resolve("n500-2024")
resolve("driftskrav-2027")
except fb.FrozenBundleDrift:
pass
except pytest.skip.Exception as exc:
@ -439,4 +465,4 @@ def test_the_corpus_tests_skip_when_absent_but_fail_on_drift(
monkeypatch.setenv(fb.STORE_ENV, str(tmp_path / "gone"))
with pytest.raises(pytest.skip.Exception):
resolve("n500-2024")
resolve("driftskrav-2027")