test(b-gate): 31 arms against the gate's own denominators, 30 red on an assert about behaviour

The PM checkpoint on 207337c judged the gate DELVIS: row 1's M=13 is a curated list in the
gate's OWN b_gate.json (the run path has 41 po-calls, 7 of 10 outbox writers), rows 4, 5 and 6
have denominators with no source at all, 6 of 10 cheat-attacks got through, and the
never-Claude guard sees 433 of 512 published files.

This commit is the red half. Every arm fails on an ASSERT about behaviour, never at collection:
the four names that do not exist yet (ENTRY_KINDS, run_path_calls, registered_entry,
published_files) are stubbed here with DELIBERATELY wrong values — everything is a door, the
run path calls nothing, the surface is empty — so each arm measures the defect rather than the
absence of a symbol.

30 av 31 red on assert. The one that is green is the rc-0 control
(test_a_valid_attestation_is_the_only_thing_that_turns_row6_green): a valid attestation must
turn row 6 green both before and after, or the row refuses everything, which proves as little
as refusing nothing. All 34 pre-existing arms stay green — measured, not assumed.

The planted claude-invocations are base64 in the test file for the same reason the contract's
patterns are: tests/ is itself part of the surface row 3 scans, and a cleartext variant here
would register as its own finding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-19 19:14:17 +02:00
commit 332eb5965b
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 576 additions and 7 deletions

View file

@ -123,6 +123,37 @@ finnes er RØD, aldri grønn og aldri hoppet over.
"""
# ---------------------------------------------------------------------------------------------
# STUBBER (rød-først). Navnene finnes her for at armene under skal felle på en ASSERT om ATFERD
# og ikke ved innsamling; verdiene er MED VILJE gale og erstattes i reparasjons-commiten.
# ---------------------------------------------------------------------------------------------
#: Inngangsartene gaten kan VERIFISERE. Tom her med vilje: stubben kjenner ingen.
ENTRY_KINDS: tuple[str, ...] = ()
def run_path_calls(src: Path, spec: Mapping[str, Any]) -> dict[str, str]:
"""STUB: skal lese kjørestiens faktiske kall av KILDEN. Returnerer ingenting ennå."""
return {}
def console_scripts(repo_root: Path) -> dict[str, str]:
"""STUB: skal lese [project.scripts] fra pyproject.toml."""
return {}
def registered_entry(
src: Path, repo_root: Path, package: str, entry: Mapping[str, Any]
) -> tuple[bool, str]:
"""STUB: godtar ALT som dør — nøyaktig feilen reparasjonen skal fjerne."""
return True, ""
def published_files(root: Path, manifest: Mapping[str, Any]) -> tuple[list[Path], str]:
"""STUB: skal utlede den publiserte flaten av repo-manifestet."""
return [], "stub"
def load_config(path: Path = _DATA) -> dict[str, Any]:
data: dict[str, Any] = json.loads(path.read_text(encoding="utf-8"))
return data
@ -274,12 +305,26 @@ def measure_steps(steps: Sequence[Mapping[str, Any]], src: Path) -> list[Step]:
return measured
def score_toolbox(steps: Sequence[Mapping[str, Any]], src: Path) -> Row:
def score_toolbox(
steps: Sequence[Mapping[str, Any]],
src: Path,
run_path: Mapping[str, Any] | None = None,
outcomes: Mapping[str, str] | None = None,
repo_root: Path = _REPO_ROOT,
) -> Row:
measured = measure_steps(steps, src)
in_path = [s for s in measured if s.resolved and s.called]
n = len(in_path)
undeclared = sorted(
name
for name in (run_path_calls(src, run_path) if run_path else {})
if name not in {str(s["symbol"]) for s in steps}
and name not in {str(h["symbol"]) for h in (run_path or {}).get("held_out", ())}
)
n = len(in_path) + len(undeclared)
k = sum(1 for s in in_path if s.external)
exceptions = tuple(f"{s.id}: {s.why}" for s in measured if not s.external)
exceptions = tuple(f"{s.id}: {s.why}" for s in measured if not s.external) + tuple(
f"udeklarert: {name} kalles i kjørestien uten å være et steg" for name in undeclared
)
return Row(
"verktøykasse",
"1 steg i kjørestien kallbare utenfra",
@ -408,7 +453,12 @@ class Pattern:
def measure_patterns(config: Mapping[str, Any], root: Path) -> list[Pattern]:
scanned: list[tuple[Path, list[tuple[int, str]]]] = []
for path in surface_files(root, list(config["roots"])):
surface = (
surface_files(root, list(config["roots"]))
if "roots" in config
else published_files(root, config.get("manifest", {}))[0]
)
for path in surface:
try:
text = path.read_text(encoding="utf-8")
except (UnicodeDecodeError, OSError):
@ -439,7 +489,11 @@ def score_no_claude_path(config: Mapping[str, Any], root: Path) -> Row:
measured = measure_patterns(config, root)
n = len(measured)
k = sum(1 for p in measured if p.valid and not p.hits)
files = len(surface_files(root, list(config["roots"])))
files = (
len(surface_files(root, list(config["roots"])))
if "roots" in config
else len(published_files(root, config.get("manifest", {}))[0])
)
exceptions: list[str] = []
for pattern in measured:
if not pattern.valid:
@ -463,7 +517,9 @@ def score_no_claude_path(config: Mapping[str, Any], root: Path) -> Row:
# ---------------------------------------------------------------------------------------------
def score_no_model_calls(config: Mapping[str, Any], outcomes: Mapping[str, str]) -> Row:
def score_no_model_calls(
config: Mapping[str, Any], outcomes: Mapping[str, str], src: Path | None = None
) -> Row:
checks = config["checks"]
verdicts = {name: _probe_verdict(list(ids), outcomes) for name, ids in checks.items()}
k = sum(1 for why in verdicts.values() if not why)
@ -585,7 +641,12 @@ def read_runbook_attestation(path: Path, keys: Sequence[str]) -> RunbookAttestat
return RunbookAttestation(True, True, "")
def score_runbook(config: Mapping[str, Any], repo_root: Path, attest: Path | None = None) -> Row:
def score_runbook(
config: Mapping[str, Any],
repo_root: Path,
attest: Path | None = None,
now: Any | None = None,
) -> Row:
runbook = repo_root / str(config["path"])
has_runbook = runbook.is_file() and bool(runbook.read_text(encoding="utf-8").strip())
attest_path = attest if attest is not None else repo_root / str(config["attestation"])