fix(review): harden #211 decision lock and CLI gate per review blockers

- Bind review decision state to in-process session (pid + profile lock); drop /tmp file path.
- Fail closed on review_pr.py CLI; route live reviews through gated MCP tools only.
- Require operator_authorized on review correction; allow re-mark after correction.
- Validate remote/org/repo on mark and submit; wire review mutation proof into build_final_report.
- Add security regression tests for spoofed locks, correction flow, and CLI bypass.

Refs #211
This commit is contained in:
2026-07-05 20:16:04 -04:00
parent 7489107768
commit 16f977fde0
9 changed files with 272 additions and 172 deletions
+35 -5
View File
@@ -168,12 +168,16 @@ def _good_live_state(**overrides):
def _good_review_mutation():
return {
"complete": True,
"downgraded": False,
"missing_fields": [],
"reasons": [],
report = (
"Review complete on PR #203.\n"
"Review mutations: one request_changes on #203.\n"
"Review decision: request_changes."
)
lock = {
"live_mutations": [{"pr_number": 203, "action": "request_changes"}],
"correction_authorized": False,
}
return assess_review_mutation_final_report(report, lock)
def _good_role_boundary_179(**overrides):
@@ -920,6 +924,32 @@ class TestReviewMutationFinalReport(unittest.TestCase):
)
self.assertTrue(complete["complete"])
def test_build_final_report_wires_review_mutation_from_report_text(self):
report_text = (
"Review complete on PR #203.\n"
"Review mutations: one request_changes on #203."
)
lock = {
"live_mutations": [{"pr_number": 203, "action": "request_changes"}],
"correction_authorized": False,
}
final = build_final_report(
checkout_proof=_good_checkout(),
inventory=_good_inventory(),
validation=_good_validation(),
contamination=_good_contamination(),
identity_eligible=True,
merge_performed=False,
issue_status_verified=True,
capability_evidence=_good_capability_evidence(),
sweep=_good_sweep(),
live_state=_good_live_state(),
role_boundary=_good_role_boundary(),
report_text=report_text,
review_decision_lock=lock,
)
self.assertTrue(final["review_mutation_complete"])
class TestPRInventoryTrustGate(unittest.TestCase):
"""Issue #194: unit tests for the PR inventory trust gate."""