burn-down round 2: R-593 papra field copy, R-760 vikunja healthcheck reason, R-594 English allow-list, R-605 refusal exit 3, R-781 onboarding decoy clone, R-806 scheme; stale runner test fixed
gates / gates (push) Successful in 4s

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-05 19:15:02 +02:00
parent 29ac711d26
commit 4828dc754d
16 changed files with 536 additions and 50 deletions
+49 -5
View File
@@ -63,13 +63,19 @@ class CatalogGatesFastTest(unittest.TestCase):
# record's two halves; the slow pair stays out of --fast. STALE AGAIN until 2026-09-30: 10 since
# probe-measured joined; the test had been red on main (found by the more-night-apps session).
# 11 since 2026-10-01: onboarding (NEW-APP-CHECKLIST.md), fast and history-free, so it runs in CI too.
self.assertEqual(len(mod.GATES), 11)
# 12 since family-gate joined — STALE AGAIN until 2026-10-05 (found by the burn-down, round 2).
self.assertEqual(len(mod.GATES), 12)
self.assertIn("onboarding", [g[0] for g in mod.GATES if g[3] and not g[4]])
self.assertEqual([g[0] for g in mod.GATES if not g[3]], ["image-resolvable", "volume-persistence"])
self.assertIn("test-record", [g[0] for g in mod.GATES if g[3] and not g[4]]) # runs in CI too
# the gates that need git history are the ones the CI half cannot run (R-452's shallow gap)
self.assertEqual([g[0] for g in mod.GATES if g[4]], ["engine-major", "catalog-since", "test-record-move"])
def test_catalog_since_ran_under_fast(self):
"""R-452's gate is fast (git reads only) and must be IN --fast, like engine-major. (Until 2026-10-05 this
method sat after `if __name__ == "__main__":`, outside any class, so it never ran.)"""
self.assertIn("catalog-since gate", self.out)
def test_engine_major_ran_under_fast(self):
"""The 2026-09-13 gate is fast (git reads only) and must be IN --fast, or the hook that
exists to enforce its rule never runs it."""
@@ -98,9 +104,47 @@ class CatalogGatesFastTest(unittest.TestCase):
class SummaryTellsRefusedFromUndecided(unittest.TestCase):
"""R-605: a gate whose HARNESS refused (exit 3 — its canary failed, nothing was judged) and a gate that ran and
could not decide (exit 2) used to print the same word. Decoys each way, on the runner's summary."""
@classmethod
def setUpClass(cls):
import importlib.util
spec = importlib.util.spec_from_file_location("catalog_gates_summary", ENTRY)
cls.mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cls.mod)
def _run(self, results):
import contextlib
import io
buf = io.StringIO()
with contextlib.redirect_stdout(buf):
rc = self.mod.summarise(results)
return rc, buf.getvalue()
def test_a_refused_harness_does_not_read_as_undetermined(self):
rc, out = self._run([("image-pins", 0), ("volume-persistence", 3)])
self.assertEqual(rc, 2, "a refused harness is never a pass")
self.assertIn("DID-NOT-RUN", out)
self.assertIn("DID NOT RUN", out)
self.assertIn("volume-persistence", out.split("DID NOT RUN", 1)[1])
self.assertNotIn("UNDETERMINED", out)
self.assertNotIn("INCONCLUSIVE", out)
def test_an_undetermined_run_does_not_read_as_refused(self):
rc, out = self._run([("image-pins", 0), ("image-resolvable", 2)])
self.assertEqual(rc, 2)
self.assertIn("INCONCLUSIVE", out)
self.assertIn("UNDETERMINED", out)
self.assertNotIn("DID NOT RUN", out)
self.assertNotIn("DID-NOT-RUN", out)
def test_a_conviction_still_outranks_both(self):
rc, out = self._run([("image-pins", 1), ("image-resolvable", 2), ("volume-persistence", 3)])
self.assertEqual(rc, 1)
self.assertIn("CONVICTED: image-pins", out)
if __name__ == "__main__":
unittest.main(verbosity=2)
def test_catalog_since_ran_under_fast(self):
"""R-452's gate is fast (git reads only) and must be IN --fast, like engine-major."""
self.assertIn("catalog-since gate", self.out)