"""Tests for the dedicated reconciliation controller-handoff schema (#303). Already-landed PR reconciliation runs must emit the reconciliation schema, not stale author/reviewer handoff fields; observed git ref mutations (fetch) must be reported, and legacy fields fail validation. """ import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from review_proofs import assess_reconciliation_handoff # noqa: E402 def _good_handoff(**overrides): fields = { "Task": "Reconcile already-landed open PRs", "Repo": "prgs/Scaled-Tech-Consulting/Gitea-Tools", "Role/profile": "prgs-reconciler", "Identity": "jcwalker3", "Selected PR": "278", "PR live state": "open", "Candidate head SHA": "2a544b7", "Target branch": "master", "Target branch SHA": "fa0cb12", "Ancestor proof": "candidate head is ancestor of target branch SHA", "Linked issue": "263", "Linked issue live status": "open (fetched live this session)", "Eligibility class": "ALREADY_LANDED_RECONCILE_REQUIRED", "Capabilities proven": "gitea.pr.comment", "Missing capabilities": "gitea.pr.close", "PR comments posted": "1 (PR #278 reconciliation notice)", "Issue comments posted": "none", "PRs closed": "none", "Issues closed": "none", "Git ref mutations": "git fetch prgs master", "Worktree mutations": "none", "MCP/Gitea mutations": "PR comment on #278", "External-state mutations": "none", "Read-only diagnostics": "gitea_view_pr 278, gitea_view_issue 263", "Blocker": "PR close capability missing", "Safe next action": "operator closes PR #278 or grants close capability", "No review/merge confirmation": "no review or merge mutations performed", } fields.update(overrides) lines = ["Controller Handoff"] lines += [f"- {k}: {v}" for k, v in fields.items() if v is not None] return "\n".join(lines) + "\n" class TestReconciliationSchemaPasses(unittest.TestCase): def test_blocked_reconciliation_passes(self): result = assess_reconciliation_handoff( _good_handoff(), observed_commands=["git fetch prgs master"], ) self.assertTrue(result["complete"]) self.assertEqual(result["reasons"], []) def test_successful_pr_close_passes(self): report = _good_handoff(**{ "Missing capabilities": "none", "PRs closed": "PR #278", "Blocker": "none", "Safe next action": "none; reconciliation complete", }) result = assess_reconciliation_handoff( report, observed_commands=["git fetch prgs master"] ) self.assertTrue(result["complete"]) def test_comment_only_reconciliation_passes(self): report = _good_handoff(**{ "Git ref mutations": "none", }) result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertTrue(result["complete"]) def test_noop_already_closed_passes(self): report = _good_handoff(**{ "PR live state": "closed", "PR comments posted": "none", "MCP/Gitea mutations": "none", "Git ref mutations": "none", "Blocker": "none", "Safe next action": "none; PR already closed", }) result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertTrue(result["complete"]) class TestSchemaViolationsFail(unittest.TestCase): def test_missing_linked_issue_proof_fails(self): report = _good_handoff(**{"Linked issue live status": None}) result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) self.assertTrue( any("linked issue live status" in r.lower() for r in result["reasons"]) ) def test_wrong_eligibility_class_fails(self): report = _good_handoff(**{"Eligibility class": "REVIEW_ELIGIBLE"}) result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) def test_missing_handoff_section_fails(self): result = assess_reconciliation_handoff( "no handoff here", observed_commands=[] ) self.assertFalse(result["complete"]) class TestStaleFieldsFail(unittest.TestCase): def test_pr_number_opened_fails(self): report = _good_handoff() + "- PR number opened: 278\n" result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) self.assertTrue( any("pr number opened" in r.lower() for r in result["reasons"]) ) def test_pinned_reviewed_head_fails(self): report = _good_handoff() + "- Pinned reviewed head: 2a544b7\n" result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) def test_scratch_worktree_used_fails(self): report = _good_handoff() + "- Scratch worktree used: False\n" result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) def test_workspace_mutations_fails(self): report = _good_handoff() + "- Workspace mutations: None\n" result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) def test_author_lock_fields_fail(self): report = ( _good_handoff() + "- Issue lock proof: locked before diff\n" + "- Claim/comment status: claimed\n" ) result = assess_reconciliation_handoff(report, observed_commands=[]) self.assertFalse(result["complete"]) class TestObservedFetchMustBeReported(unittest.TestCase): def test_fetch_with_ref_mutations_none_fails(self): report = _good_handoff(**{"Git ref mutations": "none"}) result = assess_reconciliation_handoff( report, observed_commands=["git fetch prgs master"] ) self.assertFalse(result["complete"]) self.assertTrue( any("git ref mutation" in r.lower() for r in result["reasons"]) ) if __name__ == "__main__": unittest.main()