"""Tests for issue-lock provenance and external-state disclosure (#447).""" from __future__ import annotations import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import issue_lock_provenance as ilp # noqa: E402 from final_report_validator import assess_final_report_validator # noqa: E402 def _sanctioned_lock(**overrides): work_lease = { "operation_type": "author_issue_work", "issue_number": 447, "branch": "feat/issue-447-lock-provenance", "claimant": {"username": "jcwalker3", "profile": "prgs-author"}, "expires_at": "2999-01-01T00:00:00Z", } data = { "issue_number": 447, "branch_name": "feat/issue-447-lock-provenance", "work_lease": work_lease, "lock_provenance": ilp.build_sanctioned_lock_provenance( tool="gitea_lock_issue", claimant=work_lease["claimant"], ), } data.update(overrides) return data class TestLockProvenanceForCreatePr(unittest.TestCase): def test_sanctioned_lock_passes(self): result = ilp.assess_lock_file_for_create_pr(_sanctioned_lock()) self.assertTrue(result["proven"]) self.assertFalse(result["block"]) def test_manual_seed_without_provenance_blocked(self): result = ilp.assess_lock_file_for_create_pr( {"issue_number": 420, "branch_name": "feat/x", "work_lease": {}} ) self.assertTrue(result["block"]) self.assertIn("lock_provenance", result["reasons"][0]) def test_operator_override_requires_reason(self): result = ilp.assess_lock_file_for_create_pr( _sanctioned_lock( lock_provenance=ilp.build_sanctioned_lock_provenance( tool="operator_override", source=ilp.SOURCE_OPERATOR_OVERRIDE, ) ) ) self.assertTrue(result["block"]) class TestExternalStateReportRules(unittest.TestCase): def test_seed_with_external_none_blocked(self): report = ( "Restored /tmp/gitea_issue_lock.json to unblock PR creation.\n" "- External-state mutations: none\n" ) result = ilp.assess_issue_lock_external_state_report(report) self.assertTrue(result["block"]) def test_seed_with_disclosure_passes(self): report = ( "Restored /tmp/gitea_issue_lock.json after MCP restart.\n" "- External-state mutations: wrote /tmp/gitea_issue_lock.json\n" ) result = ilp.assess_issue_lock_external_state_report(report) self.assertTrue(result["proven"]) def test_remove_claimed_as_cleanup_only_blocked(self): report = ( "rm /tmp/gitea_issue_lock.json after PR creation.\n" "- Cleanup mutations: lock removed\n" "- External-state mutations: none\n" ) result = ilp.assess_issue_lock_external_state_report(report) self.assertTrue(result["block"]) def test_manual_lock_pr_without_override_blocked(self): report = ( "Programmatically seeded gitea_issue_lock.json then gitea_create_pr.\n" "PR #444 created.\n" ) result = ilp.assess_manual_lock_pr_without_override(report) self.assertTrue(result["block"]) def test_author_reviewer_same_run_blocked(self): report = ( "gitea_create_pr opened PR #444.\n" "Submitted approve review on PR #444.\n" ) result = ilp.assess_author_reviewer_same_run_report(report) self.assertTrue(result["block"]) class TestFinalReportValidatorIntegration(unittest.TestCase): def test_work_issue_blocks_hidden_lock_mutation(self): report = ( "## Controller Handoff\n" "- Task: work issue #420\n" "- External-state mutations: none\n" "Restored /tmp/gitea_issue_lock.json before PR creation.\n" ) result = assess_final_report_validator(report, "work_issue") rule_ids = {f["rule_id"] for f in result["findings"]} self.assertIn("shared.issue_lock_external_state", rule_ids) self.assertTrue(result["blocked"]) def test_review_pr_blocks_create_and_approve(self): report = ( "## Controller Handoff\n" "- Task: review PR #444\n" "- Review decision: approve\n" "Created PR #444 via gitea_create_pr earlier in this run.\n" ) result = assess_final_report_validator(report, "review_pr") rule_ids = {f["rule_id"] for f in result["findings"]} self.assertIn("shared.author_reviewer_same_run", rule_ids) if __name__ == "__main__": unittest.main()