R-426: decoy-coverage names stale exemptions; dead offbox-rename entry removed

controller/offbox-rename kept its EXEMPT entry after R-425 gave it decoys, so
the debt list read longer than the debt. The gate now prints a STALE EXEMPTION
line for any exempt gate that has a decoy (named, not convicted: the decoy lands
in a sibling repo, and failing this repo's push for it would couple the two).
A check in test_gate_decoys.py plants a stale entry and asserts it is named;
seen to fail with the notice removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 01:14:18 +02:00
parent b4e4b1b3c6
commit 1ed0eba41d
2 changed files with 29 additions and 3 deletions
+17
View File
@@ -414,6 +414,23 @@ elif "decoy-red-proof" not in _out:
else:
print(" ok %-20s a new gate with no decoy is convicted BY NAME" % "decoy-coverage")
# ...and its STALE-EXEMPTION notice (R-426, 2026-10-06): an EXEMPT entry for a gate that has a decoy must be
# NAMED, or the debt list reads longer than the debt (controller/offbox-rename sat there after R-425).
ran += 1
_DCG = os.path.join(ROOT, "scripts", "decoy_coverage_gate.py")
_dcg = io.open(_DCG, encoding="utf-8").read()
try:
assert "EXEMPT = {\n" in _dcg, "the EXEMPT literal's shape changed — this check can no longer be built"
io.open(_DCG, "w", encoding="utf-8").write(_dcg.replace(
"EXEMPT = {\n", 'EXEMPT = {\n ("felhom.eu", "site"): "decoy: a stale entry for a covered gate",\n', 1))
_rc, _out = gate("decoy_coverage_gate.py", (ROOT,))
finally:
io.open(_DCG, "w", encoding="utf-8").write(_dcg)
if "STALE EXEMPTION: felhom.eu / site" not in _out:
fails.append("decoy-coverage: an EXEMPT entry for a COVERED gate was not named as stale\n%s" % _out[-400:])
else:
print(" ok %-20s a stale exemption is NAMED" % "decoy-coverage")
# ── guide-quote (R-596) ──────────────────────────────────────────────────────────────────────────
#
# Its decoys build whole fake workspaces (a guide plus a sibling controller clone), which does not