feat(frozen-bundles): the measurements read a pinned copy, not another repo's build dir

Measured 2026-09-17 17:43: vegnormal-okf rebuilt build/ferdig/r761-2025 while this
repository's v1 gate, the stress judge and four corpus tests pointed straight at it.
Rows 6-7 went IKKE MAALT and five tests fell, for a change no one here made. The failure
mode was never falsehood - the gate says IKKE MAALT and exits non-zero, never green - it
was instability: two projects shared a directory neither owns, so what this repository
MEASURES could move without a commit here.

A copy alone would push that directory one move away, so the copy comes with a pin.
frozen_bundles.json (tracked) carries path + sha256 + file count per base; the bundles
themselves are NEVER committed here. Three states, separated by construction: match ->
resolves; gone -> FrozenBundleMissing (an OSError, so the gate's existing except OSError
gives IKKE MAALT + exit 1 unchanged and the corpus tests SKIP, MAJOR-3's ceiling); drift
-> FrozenBundleDrift (a ValueError), loud, named, and never a skip. The two classes are
deliberately unrelated: a caller that catches "missing" to skip must not swallow "drift".

The NAME is hashed alongside the bytes, and the directory name carries the first 12 chars
of the digest so a stale copy is visible in ls. Renewal is a decision: new copy + new pin
in the SAME commit (README). --bundle-root / PORTFOLIO_VEGNORMAL_ROOT stays as the
operator's explicit, UNPINNED live mount.

Iron Law: the tests were written and run RED first (collection error, then two arms of my
own making). Load-bearing MEASURED, eight mutations all red against the WHOLE suite with a
green control of 1984 passed / 5 skipped / 5 xfailed and a strict node-id superset
(1977 -> 1994, 0 removed): M1 the pin is never verified (7) - M2 drift collapsed into
missing (5) - M3 the name is not hashed (40) - M4 the gate seam reverted to root/name (1) -
M5 the corpus helpers skip on drift too (4, one per file) - M6a the slash spelling back in
src (1) - M6b the quoted path segment back in a test (1) - M7 the directory name drops the
short digest (1, and 45 skipped, which proves absence is a SKIP and not a false green) -
M8 the explicit override ignored (3, two of them in test_stress_judge_loadbearing.py,
independent witnesses older than this work).

M2 FALSIFIED THE TEST FIRST: the four parametrised arms did not go red, they went to SKIP
(5 -> 9 skipped) and stayed green - pytest.skip inside a pytest.raises is not a failure.
The arm now catches pytest.skip.Exception explicitly and turns it into an AssertionError.

grep -rnE 'vegnormal-okf/build|["'"'"']vegnormal-okf["'"'"']' src tests contexts -> 0
(3 + 4 hits before; the three remaining prose mentions document history and are allowed).
Gate re-run against the frozen copy: identical to the live mount (rows 0/3 - 0/3 - 3/8 -
no report - 3/8 - IKKE MAALT - 1/20, exit 1).

Order 20260917T223645Z-1296211942-from-.claude.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-18 03:22:22 +02:00
commit 50c9763706
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
12 changed files with 654 additions and 60 deletions

View file

@ -760,11 +760,11 @@ def _own_proposals(
def measure_stress(
evidence: Mapping[str, Any], repo_root: Path, stress_root: Path, bundle_root: Path
evidence: Mapping[str, Any], repo_root: Path, stress_root: Path, bundle_root: Path | None
) -> StressMeasure:
"""Re-judge every listed outbox with the current judge. Any run that cannot be judged makes the
whole measurement absent a partial one would carry the wrong denominator."""
from portfolio_optimiser import stress
from portfolio_optimiser import frozen_bundles, stress
from portfolio_optimiser.mandate import load_mandate
verdicts = []
@ -779,8 +779,11 @@ def measure_stress(
chosen = [d for d in declared if wanted in (None, d["name"], d["bundle_id"])]
if len(chosen) != 1:
return StressMeasure(where=str(stress_root), missing=f"{context}: base ikke entydig")
base = bundle_root / chosen[0]["name"]
try:
# The frozen copy this repository pins, unless the operator named a live mount.
# Drift is a ValueError and absence an OSError: both land in ``missing`` below, so a
# corpus that moved is IKKE MÅLT with the reason said, never a silently wrong number.
base = frozen_bundles.bundle_dir(chosen[0]["name"], override=bundle_root)
verdicts.append(
stress.score_context_set(
context,
@ -933,10 +936,7 @@ def evaluate(
evidence,
repo_root,
stress_root or repo_root / evidence["root"],
bundle_root
or Path(
os.environ.get("PORTFOLIO_VEGNORMAL_ROOT", "~/repos/vegnormal-okf/build/ferdig")
).expanduser(),
bundle_root,
)
return [
score_rounds(rounds_dir, required, ai),
@ -999,7 +999,10 @@ def main(argv: Sequence[str] | None = None) -> int:
"--stress-root", default=None, help="utboks-roten for stressrunden rad 6-7 dømmer"
)
parser.add_argument(
"--bundle-root", default=None, help="der stressrundens kunnskapsbaser er montert"
"--bundle-root",
default=None,
help="en EKSPLISITT, UPINNET levende montering; uten den svarer den frosne kopien og "
"sha256-pinnen verifiseres",
)
parser.add_argument("--json", action="store_true", help="maskinlesbar output")
args = parser.parse_args(argv)

View file

@ -0,0 +1,27 @@
{
"store": "~/corpora/po-frosne-bundles",
"source": "vegnormal-okf build/ferdig, READ-ONLY copy taken 2026-09-18",
"renewal": "Ny kopi + ny pin i SAMME commit - se README, 'Frosne kunnskapsbaser'.",
"bundles": {
"n100-2023": {
"directory": "n100-2023-69c62e5c5414",
"sha256": "69c62e5c541455fd4bfafbfde0a45b604ec3788532b61441e1445494c9e70bea",
"files": 450
},
"n200-2024": {
"directory": "n200-2024-9950f2f4cc8c",
"sha256": "9950f2f4cc8ccec8605c47035e8e9de3ba4028f4a4091c95a64953242a69137d",
"files": 1137
},
"n500-2024": {
"directory": "n500-2024-c68f18d6375f",
"sha256": "c68f18d6375f4461710c9cea54b2e8335d1b6461446364c9bfaf764fb88efdcb",
"files": 274
},
"r761-2025": {
"directory": "r761-2025-58e1ecca6007",
"sha256": "58e1ecca60075d77f3ca4776ee7e76466ef2631566099f37856eeef96620ab02",
"files": 5564
}
}
}

View file

@ -0,0 +1,134 @@
"""The frozen knowledge bases the measurements read — a copy this repository PINS, never another
repository's live build directory.
Measured 2026-09-17 17:43: ``vegnormal-okf`` rebuilt ``build/ferdig/r761-2025`` while this
repository's v1 gate and four corpus tests 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 *instability*: two projects shared a
directory neither owns, so what this repository MEASURES could move without a commit here.
A copy alone would only push that directory one move away, so the copy comes with a pin: the
sha256 of the bundle's files in deterministic order, tracked in ``frozen_bundles.json``. Three
states, separated by construction:
* the copy MATCHES the pin -> it resolves, and that is the only path that measures anything;
* the copy is GONE -> :class:`FrozenBundleMissing`, an ``OSError``, so the gate's existing
``except OSError`` says IKKE MÅLT and fails the exit code exactly as before, and the corpus
tests SKIP (MAJOR-3's ceiling: a hard error would break ``uv run pytest`` in the handover
archive, where no corpus is mounted);
* the copy DIFFERS -> :class:`FrozenBundleDrift`, a ``ValueError``, loud and named and
NEVER a skip. A drifted copy is not an unreadable measurement, it is a measurement of the wrong
corpus the one state that produces a silently wrong number.
The two classes are deliberately unrelated: a caller that catches "missing" in order to skip must
not swallow "drift".
The bundles themselves are NEVER committed here vegnormal corpora must not reach a public
remote. Only the pin is tracked. Renewing a copy is a DECISION, not maintenance: a new copy and a
new pin in the SAME commit (see README).
"""
from __future__ import annotations
import hashlib
import json
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Mapping
#: The pin this repository tracks: path fragment + sha256 + file count, one entry per base.
PIN_FILE = Path(__file__).with_name("frozen_bundles.json")
#: Where the frozen copies live, unless the environment says otherwise. OUTSIDE both repositories:
#: inside either one, the copy is a build artefact of a project that did not make it.
DEFAULT_STORE = "~/corpora/po-frosne-bundles"
#: Moves the store on a machine that keeps its corpora elsewhere. Read at CALL time.
STORE_ENV = "PORTFOLIO_FROZEN_BUNDLES"
#: The operator's explicit, UNPINNED escape hatch: a live mount, named on purpose. Kept because a
#: gate that cannot be pointed at a fresh corpus cannot be used to decide whether to refreeze.
OVERRIDE_ENV = "PORTFOLIO_VEGNORMAL_ROOT"
#: How much of the digest the directory name carries, so a stale copy is visible in ``ls``.
SHORT = 12
class FrozenBundleMissing(FileNotFoundError):
"""The pinned copy is not on this machine. Never green; never confused with drift."""
class FrozenBundleDrift(ValueError):
"""The copy on disk is not the copy that was pinned."""
@dataclass(frozen=True)
class Pin:
name: str
directory: str
sha256: str
files: int
def store_root(store: Path | str | None = None) -> Path:
return Path(store or os.environ.get(STORE_ENV) or DEFAULT_STORE).expanduser()
def load_pins(path: Path | None = None) -> dict[str, Pin]:
data = json.loads((path or PIN_FILE).read_text(encoding="utf-8"))
return {
name: Pin(name, spec["directory"], spec["sha256"], int(spec["files"]))
for name, spec in data["bundles"].items()
}
def digest_bundle(root: Path) -> tuple[str, int]:
"""(sha256 over every file, file count). Deterministic: sorted by the bundle-relative POSIX
path, and the NAME is hashed alongside the bytes without it a corpus reshuffled under the
same bytes would pin clean."""
entries = sorted((p.relative_to(root).as_posix(), p) for p in root.rglob("*") if p.is_file())
outer = hashlib.sha256()
for rel, path in entries:
outer.update(rel.encode("utf-8"))
outer.update(b"\0")
outer.update(hashlib.sha256(path.read_bytes()).hexdigest().encode("ascii"))
outer.update(b"\n")
return outer.hexdigest(), len(entries)
def bundle_dir(
name: str,
*,
override: Path | str | None = None,
store: Path | str | None = None,
pins: Mapping[str, Pin] | None = None,
) -> Path:
"""The directory a measurement reads for the base called ``name``.
``override`` (or ``PORTFOLIO_VEGNORMAL_ROOT``) is the operator's explicit live mount and is
NOT verified they named it. Without one, the frozen store answers and the pin is checked.
"""
named = override if override is not None else os.environ.get(OVERRIDE_ENV) or None
if named is not None:
base = Path(named).expanduser() / name
if not base.is_dir():
raise FrozenBundleMissing(f"knowledge base {name!r} is not mounted under {named}")
return base
pinned = dict(pins) if pins is not None else load_pins()
if name not in pinned:
raise FrozenBundleMissing(
f"{name!r} is not pinned in {PIN_FILE.name} (pinned: {', '.join(sorted(pinned))})"
)
pin = pinned[name]
base = store_root(store) / pin.directory
if not base.is_dir():
raise FrozenBundleMissing(
f"frozen knowledge base {name!r} is not at {base} "
f"(set {STORE_ENV}, or refreeze: new copy + new pin in the same commit)"
)
actual, files = digest_bundle(base)
if actual != pin.sha256:
raise FrozenBundleDrift(
f"frosset bundle {name!r} avviker fra pin: pinnet {pin.sha256[:SHORT]} "
f"({pin.files} filer), på disk {actual[:SHORT]} ({files} filer) i {base}. "
"En kopi fornyes BEVISST: ny kopi + ny pin i samme commit."
)
return base

View file

@ -67,20 +67,19 @@ from __future__ import annotations
import argparse
import json
import os
import sys
from collections.abc import Mapping, Sequence
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any
from portfolio_optimiser import okf
from portfolio_optimiser import frozen_bundles, okf
from portfolio_optimiser.mandate import Mandate, load_mandate
from portfolio_optimiser.validator import classify_codes, rejection_stage
#: Where the vegnormal bases are mounted, unless ``--bundle-root`` says otherwise. Read at CALL
#: time (the ``shared_root()`` idiom) so a test or an operator can move the mount without a reimport.
_DEFAULT_BUNDLE_ROOT = "~/repos/vegnormal-okf/build/ferdig"
#: Where a base is read from: the FROZEN store this repository pins, resolved at CALL time (the
#: ``shared_root()`` idiom). ``--bundle-root`` stays as the operator's explicit, unpinned live
#: mount. See ``frozen_bundles`` for why a shared build directory is not read directly any more.
class EmptyMeasurement(RuntimeError):
@ -604,8 +603,9 @@ def main(argv: list[str] | None = None) -> int:
parser.add_argument("--run-id", required=True)
parser.add_argument(
"--bundle-root",
default=os.environ.get("PORTFOLIO_VEGNORMAL_ROOT", _DEFAULT_BUNDLE_ROOT),
help="directory the set's bundle.txt name is mounted under",
default=None,
help="an explicit, UNPINNED live mount to read the set's bundle.txt name under; without "
"it the frozen store answers and its sha256 pin is verified",
)
parser.add_argument(
"--bundle",
@ -638,7 +638,11 @@ def main(argv: list[str] | None = None) -> int:
file=sys.stderr,
)
return 1
base = Path(args.bundle_root).expanduser() / chosen["name"]
try:
base = frozen_bundles.bundle_dir(chosen["name"], override=args.bundle_root)
except (frozen_bundles.FrozenBundleMissing, frozen_bundles.FrozenBundleDrift) as exc:
print(f"stress refused: {exc}", file=sys.stderr)
return 1
try:
verdict = score_context_set(