From 6c50c60c2243b03db44b48b1dec41913d0e4b77e Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Tue, 15 Sep 2026 15:14:25 -0600 Subject: [PATCH] feat: improve the code review suite to support larger PRs --- assets/agents/adversary/scripts/diff_facts.py | 7 ++++++- assets/agents/code-reviewer/scripts/facts.py | 5 +++++ assets/agents/code-reviewer/scripts/verdict.py | 17 ++++++++++++++++- assets/agents/finding-verifier/graph.yaml | 2 +- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/assets/agents/adversary/scripts/diff_facts.py b/assets/agents/adversary/scripts/diff_facts.py index 85efdb5..8019707 100644 --- a/assets/agents/adversary/scripts/diff_facts.py +++ b/assets/agents/adversary/scripts/diff_facts.py @@ -56,8 +56,13 @@ try: if line.startswith("+++ b/") }) out["changed_files"] = files[:300] + if len(files) > 300: + out["diff_note"] += ( + f" (file list capped at 300 of {len(files)} changed files — use the fs " + "tools for the rest)" + ) if len(text) > MAX_DIFF_CHARS: - out["diff_note"] = ( + out["diff_note"] += ( f" (truncated to {MAX_DIFF_CHARS} chars of {len(text)} — use the fs tools " "to inspect files beyond the cut)" ) diff --git a/assets/agents/code-reviewer/scripts/facts.py b/assets/agents/code-reviewer/scripts/facts.py index 3c51aba..1b1fed1 100644 --- a/assets/agents/code-reviewer/scripts/facts.py +++ b/assets/agents/code-reviewer/scripts/facts.py @@ -80,6 +80,11 @@ except Exception as e: # noqa: BLE001 out["resolved_diff_spec"] = resolved out["changed_files"] = files[:300] out["file_count"] = len(files) +if len(files) > 300: + notes.append( + f"file list truncated: {len(files)} changed files, only the first 300 are " + "grouped and reviewed" + ) def diff_text(): diff --git a/assets/agents/code-reviewer/scripts/verdict.py b/assets/agents/code-reviewer/scripts/verdict.py index 1718400..283d4c3 100644 --- a/assets/agents/code-reviewer/scripts/verdict.py +++ b/assets/agents/code-reviewer/scripts/verdict.py @@ -192,6 +192,19 @@ def main(): f"branch fault: {_fv_detail(soft_fv)}) — they stand above UNVERIFIED; " "verify them manually" ) + # Files beyond facts.py's 300-file cap were never grouped or reviewed — + # disclose the gap and force NEEDS-HUMAN with wording that does NOT match + # the gauntlet's degraded-run anchors (a lane re-run cannot fix a cap). + coverage_notes = [] + try: + total_files = int(state.get("file_count") or 0) + except (TypeError, ValueError): + total_files = 0 + if total_files > len(changed): + coverage_notes.append( + f"Coverage gap: {total_files - len(changed)} of {total_files} changed files " + "were NOT reviewed (file-list cap) — review them manually or split the PR" + ) # Keyed off synth_failure + a non-empty diff, NEVER off findings == [] — # a clean review legitimately has zero findings and stays MERGE-READY. synth_failure = state.get("synth_failure") @@ -208,7 +221,7 @@ def main(): # faults go FIRST and uncapped so the display cap can never hide one; # the trigger reason keys off the human-facing triggers alone has_triggers = bool(attention) - attention = faults + soft_notes + attention[:5] + attention = faults + soft_notes + coverage_notes + attention[:5] reasons = [] if counts["🔴"]: @@ -223,6 +236,8 @@ def main(): # unverified findings are a human-attention item, not a re-runnable # lane fault. reasons.append(f"{len(soft_fv)} finding(s) unverified (verifier branch fault)") + if coverage_notes: + reasons.append(f"{total_files - len(changed)} changed file(s) not reviewed (file cap)") if has_triggers: reasons.append("always-human trigger(s) fired") verdict = "NEEDS-HUMAN" if reasons else "MERGE-READY" diff --git a/assets/agents/finding-verifier/graph.yaml b/assets/agents/finding-verifier/graph.yaml index 2e03f57..4782e87 100644 --- a/assets/agents/finding-verifier/graph.yaml +++ b/assets/agents/finding-verifier/graph.yaml @@ -25,7 +25,7 @@ variables: settings: max_loop_iterations: 8 log_state_snapshots: true - timeout: 900 + timeout: 3000 initial_state: findings_list: []