#!/usr/bin/env python3 """Deterministic verdict gate for the review gauntlet. Parses each configured lane's verdict SENTINEL with a regex — no LLM re-reads, no judgment. The gate's hard rules: - a missing sentinel is a LANE FAILURE and blocks — never a pass; - any 🔴 finding in the code-review report blocks regardless of the lane's own verdict line; - NEEDS-HUMAN without 🔴 passes but is surfaced as attention required; - probe INCONCLUSIVE blocks with an ENVIRONMENT note — it is never treated as PASS or FAIL (fix the environment per the plan's local-run recipe, then re-run); - the gate itself must never crash into a silent pass: any internal error emits GAUNTLET: BLOCKED naming the error. """ import json import os import re def load_state(): if path := os.environ.get("GRAPH_STATE_FILE"): with open(path) as f: return json.load(f) return json.loads(os.environ.get("GRAPH_STATE", "{}")) def main(): state = load_state() blockers, attention, lane_lines, reports = [], [], [], [] def lane_report(key): arr = state.get(key) or [] if not arr: return None item = arr[0] return item if isinstance(item, str) else json.dumps(item) def record(lane, status, detail=""): lane_lines.append(f"| {lane} | {status} | {detail} |") # --- code-review ------------------------------------------------------ cr = lane_report("code_review_results") if cr is None: record("code-review", "SKIPPED", "not selected") else: reports.append(("code-review", cr)) m = re.search(r"Verdict:\**\s*\**\s*(MERGE-READY|NEEDS-HUMAN)", cr) reds = cr.count("🔴") if reds: blockers.append( f"code-review: {reds} 🔴 CRITICAL finding(s) — fix before claiming done" ) record("code-review", "BLOCKED", f"{reds} 🔴 finding(s)") elif m and m.group(1) == "MERGE-READY": record("code-review", "GREEN", "MERGE-READY") elif m: attention.append( "code-review: NEEDS-HUMAN — see the lane report's " "'Human attention required' section" ) record("code-review", "GREEN (attention)", "NEEDS-HUMAN, no 🔴") else: blockers.append( "code-review: no Review Verdict sentinel found — the lane failed; " "a missing verdict is never a pass" ) record("code-review", "BLOCKED", "missing verdict sentinel") # --- adversary -------------------------------------------------------- adv = lane_report("adversary_results") if adv is None: record("adversary", "SKIPPED", "not selected") else: reports.append(("adversary", adv)) m = re.search(r"ADVERSARIAL_REVIEW:\s*(CONFORMS|DIVERGES)", adv) if m and m.group(1) == "CONFORMS": record("adversary", "GREEN", "CONFORMS") elif m: blockers.append( "adversary: DIVERGES — the implementation does not conform to the plan" ) record("adversary", "BLOCKED", "DIVERGES") else: blockers.append( "adversary: no ADVERSARIAL_REVIEW sentinel found — lane failed; never a pass" ) record("adversary", "BLOCKED", "missing verdict sentinel") # --- security --------------------------------------------------------- sec = lane_report("security_results") if sec is None: record("security", "SKIPPED", "not selected") else: reports.append(("security", sec)) m = re.search(r"SECURITY_REVIEW:\s*(PASS|FAIL)", sec) if m and m.group(1) == "PASS": record("security", "GREEN", "PASS") elif m: blockers.append("security: SECURITY_REVIEW: FAIL — exploitable finding(s)") record("security", "BLOCKED", "FAIL") else: blockers.append( "security: no SECURITY_REVIEW sentinel found — lane failed; never a pass" ) record("security", "BLOCKED", "missing verdict sentinel") # --- probe ------------------------------------------------------------ pb = lane_report("probe_results") if pb is None: record("probe", "SKIPPED", "not selected") else: reports.append(("probe", pb)) m = re.search(r"USAGE_PROBE:\s*(PASS|FAIL|INCONCLUSIVE)", pb) if m and m.group(1) == "PASS": record("probe", "GREEN", "PASS") elif m and m.group(1) == "FAIL": blockers.append("probe: USAGE_PROBE: FAIL — observed behavior contradicts the contract") record("probe", "BLOCKED", "FAIL") elif m: blockers.append( "probe: INCONCLUSIVE — the ENVIRONMENT could not be established; this is " "not a code verdict. Follow the plan's local-run recipe to fix the " "environment and re-run. INCONCLUSIVE is never treated as PASS or FAIL." ) record("probe", "BLOCKED", "INCONCLUSIVE (environment)") else: blockers.append( "probe: no USAGE_PROBE sentinel found — lane failed; never a pass" ) record("probe", "BLOCKED", "missing verdict sentinel") verdict = "BLOCKED" if blockers else "PASS" md = "\n".join( ["| lane | status | detail |", "|------|--------|--------|"] + lane_lines ) md += "\n\n## Lane selection\n" + (state.get("lanes_summary") or "(none recorded)") if blockers: md += "\n\n## Blockers\n" + "\n".join(f"- {b}" for b in blockers) if attention: md += "\n\n## Human attention required\n" + "\n".join(f"- {a}" for a in attention) if state.get("signals_error"): md += f"\n\n> {state['signals_error']}" md += "\n\n## Full lane reports\n" for lane, rep in reports: md += f"\n
{lane}\n\n{rep}\n\n
\n" print(json.dumps({"gauntlet_verdict": verdict, "gauntlet_report": md})) try: main() except Exception as e: # noqa: BLE001 — the gate must never crash into a silent pass print( json.dumps( { "gauntlet_verdict": "BLOCKED", "gauntlet_report": f"verdict gate error: {e} — treat as a failed gate, not a pass.", } ) )