test(vitality): pin scaffold guard refusals — 8 panic-only sites converted red-first (placement, secret-kwargs, bind-first, duplicate, illegal-transition ×2, unwritable-store dual-core, accounting KeyError); lifecycle tests repaired to the quality-gate close() entry (pre-existing red since 2597b58b); 3 mutation kills verified, src byte-identical

This commit is contained in:
Nick committed 2026-10-22 11:30:36 +01:00
1 parent ba63d15a6f
commit a2bd7f2688
1 file changed
+21 -13
+21 -13
View File
@@ -146,7 +146,7 @@ class TestRepoBinding:
def test_bind_repo_rejects_unknown_placement(self, tmp_path):
s, doc = _init_doc(tmp_path)
with pytest.raises(ValueError):
with pytest.raises(ValueError, match="unknown repo placement: WHENEVER"):
s.bind_repo(
doc, forge="gitea", owner="o", name="r", default_branch="main", repo_root="/x", placement="WHENEVER"
)
@@ -156,7 +156,7 @@ class TestRepoBinding:
has a fixed schema — unknown/secret kwargs raise), and a secret
value smuggled into observations is stripped before disk."""
s, doc = _init_doc(tmp_path)
with pytest.raises(TypeError): # no **kwargs passthrough at all
with pytest.raises(TypeError, match="token"): # no **kwargs passthrough at all
s.bind_repo(doc, forge="gitea", owner="o", name="r", default_branch="main", repo_root="/x", token="hunter2")
s.bind_repo(doc, forge="gitea", owner="o", name="r", default_branch="main", repo_root="/x")
s.observe_repo(doc, "o", "r", head="abc123", clean=True, last_verification="green")
@@ -168,7 +168,7 @@ class TestRepoBinding:
def test_observe_repo_requires_binding_first(self, tmp_path):
s, doc = _init_doc(tmp_path)
with pytest.raises(ValueError):
with pytest.raises(ValueError, match="bind_repo first: repo:ghost/repo not found"):
s.observe_repo(doc, "ghost", "repo", head="abc")
def test_repo_state_from_git(self, tmp_path):
@@ -299,7 +299,7 @@ class TestContractLifecycle:
def test_duplicate_contract_rejected(self, tmp_path):
s, doc = _make_contract(tmp_path)
with pytest.raises(ValueError):
with pytest.raises(ValueError, match="contract already exists: C1"):
s.new_contract(doc, contract_id="C1", need="again")
def test_legal_transition_path(self, tmp_path):
@@ -307,24 +307,26 @@ class TestContractLifecycle:
s.transition_contract(doc, "C1", "approved")
s.transition_contract(doc, "C1", "building")
s.transition_contract(doc, "C1", "verifying")
s.transition_contract(doc, "C1", "closed")
# quality-gate law: `closed` is entered via close() (quality recorded),
# never a raw transition
s.close_contract(doc, "C1", scope_files=["src/export/writer.py"])
c = s.contract(doc, "C1")
assert c["phase"] == "closed"
assert c["status"] == "closed"
assert c["identities"]["next_action"] == "observe real outcome; capture lessons"
def test_illegal_transition_rejected(self, tmp_path):
s, doc = _make_contract(tmp_path)
with pytest.raises(IllegalPhaseTransition):
with pytest.raises(IllegalPhaseTransition, match="illegal transition: draft → verifying"):
s.transition_contract(doc, "C1", "verifying") # draft → verifying
# state unchanged after illegal attempt
assert s.contract(doc, "C1")["phase"] == "draft"
def test_closed_contract_is_terminal(self, tmp_path):
s, doc = _make_contract(tmp_path)
for p in ("approved", "building", "verifying", "closed"):
s.transition_contract(doc, "C1", p)
with pytest.raises(IllegalPhaseTransition):
s.transition_contract(doc, "C1", "approved")
s.transition_contract(doc, "C1", "building")
s.transition_contract(doc, "C1", "verifying")
s.close_contract(doc, "C1", scope_files=["src/export/writer.py"])
with pytest.raises(IllegalPhaseTransition, match="illegal transition: closed → building"):
s.transition_contract(doc, "C1", "building")
def test_failed_contract_can_retry(self, tmp_path):
@@ -656,8 +658,14 @@ class TestCommitSemanticReadback:
blocker.write_text("this is a file, not a directory",
encoding="utf-8")
s.current = blocker / "current.json" # parent is a FILE → unwritable
with pytest.raises((OSError, AssertionError)):
# kernel core surfaces the mkdir failure as RuntimeError, the python
# oracle as OSError — both are the visible failure, neither is success
with pytest.raises((OSError, RuntimeError)):
s.commit(doc, what="unwritable path")
# the failure was NOT mistaken for fresh-success: the blocker file is
# still a file, no store got written through it
assert blocker.is_file()
assert "this is a file, not a directory" in blocker.read_text(encoding="utf-8")
def test_corrupt_persisted_state_fails_visibly(self, tmp_path):
"""§12B held-out 5: unreadable persisted state is DETECTED (load →
@@ -687,7 +695,7 @@ class TestCommitSemanticReadback:
s.new_contract(doc, contract_id="D1", need="n", scope=["src/x"])
s.commit(doc, what="contract")
# accounting AFTER commit raises — durability unaffected
with pytest.raises(KeyError):
with pytest.raises(KeyError, match="nonexistent"):
s.contract(doc, "D1")["identities"]["nonexistent"]["deep"]
reloaded = Scaffold(tmp_path / ".rune" / "scaffold", "t12b").load()
assert s.contract(reloaded, "D1") is not None