{"slug": "adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary", "title": "Adversarial multi-agent code review — the pipeline + the actual reviewer/adversary prompts (disprove-first verification, hostile second round, author never approves its own work)", "summary": "A developer built an adversarial multi-agent code review pipeline that uses a squad of AI agents with independent lenses, a disprove-first verification step, and a second hostile pass over fixed code to reduce false positives. The pipeline runs in Claude Code with parallel sub-agents and enforces that the author never reviews or approves their own code. The verification step, which tries to disprove each finding by reading source context, is key to filtering out confident-but-wrong findings before fixes are applied.", "body_md": "How I review code -- including AI-written code -- with a squad of AI agents, without drowning in confident-but-wrong findings. Product-agnostic. I run it in Claude Code with parallel sub-agents, but the shape ports to any setup where you can run more than one agent.\n\nThe agent (or person) that wrote the code never reviews or approves it. Reviewers and the verifier are separate from the author. Everything below exists to enforce that.\n\nA single pass gives you a wall of findings and half are wrong -- plausible, well-argued, and wrong. Fix those blindly and you add bugs chasing bugs that were never there. The value isn't more reviewers. It's three things: independent lenses, a disprove-first verification step, and a second hostile pass over the *fixed* code.\n\n``` php\n1. Team review     -> N reviewers, parallel, different lenses. They only FILE findings.\n2. Verify (VCA)    -> you read the source and try to DISPROVE each finding. Score it.\n3. Fix             -> fix what survived. Commit.\n4. Adversarial     -> a hostile crew reviews the FIXED code. AFTER the commit.\n5. Verify again    -> same disproval pass, dedup against round 1.\n6. Fix again       -> fix survivors. Commit.\n7. Report          -> merged summary + false-positive rate + cross-reviewer agreement.\n```\n\nWhy two separate rounds instead of one big one: the adversarial reviewers see different code (round-1 bugs already gone), so they don't re-find them, they catch bugs the fixes *introduced*, and \"how does this break?\" is a different question than \"does this work?\" -- it finds different bugs. Running them together just finds the same things twice.\n\nFor each finding, try to prove it WRONG:\n\n- Open the actual source file (not just the diff). Read ~50 lines around the flag.\n- Trace the path: is the \"missing\" guard actually in the caller? Does the function really return what the reviewer claims? Is the nil handled upstream? Is the \"missing\" auth check done at the router instead?\n- Score confidence 0-100:\n- 90-100: verified the path fails, no upstream guard -> real bug\n- 70-89: probably real, edge case may be rare\n- 50-69: uncertain, depends on context\n- 0-49: verified handled, or it's a style opinion -> drop it\n\n- Verdict: CONFIRMED / DISPROVED / UNCERTAIN, with the specific code evidence.\n- Dedup (same file:line within ~5 lines, or same root cause -> merge). Recalibrate severity by confidence. Anything under 50 gets filtered out.\n\nThis step is the whole game. It's where the confident-but-wrong findings die, and it's why the fix phase isn't chasing ghosts.\n\nFour reviewers, each a different axe, run in parallel. Short version of each prompt:\n\n**Requirements skeptic:** what user scenarios and edge cases aren't handled? Where does this meet the letter of the requirement but miss the point?**Architect:** what patterns does this violate? Hidden coupling? Missing error handling that cascades? Behavior at 10x/100x?**Engineer (correctness):** return-type tracing, nil paths, auth flows, data-flow correctness, cross-file reasoning. (Leave lint/types/tests to your quality gate -- this lens is for logic.)**Convention drift:** does this drift from your team's*documented*decisions/ADRs? (The architect only sees this repo's code; this lens checks it against what you've written down.)\n\nSame four seats, but now they hate your code. Real prompts I use:\n\n**Skeptical Business Analyst**\n\n```\nYou are a Business Analyst burned too many times by \"that edge case will never happen\"\nright before it happened in production. Review the diff with EXTREME skepticism:\n- What user scenarios are NOT handled?\n- What edge cases will definitely happen that the dev didn't consider?\n- What acceptance criteria are technically met but miss the spirit of the requirement?\n- How does this break when real-world data doesn't match the happy path?\nBe harsh. Write findings to review/adversarial-ba.md.\n```\n\n**Paranoid Systems Architect**\n\n```\nYou are a Systems Architect who has been paged at 3 AM too many times. You trust nothing.\nFind EVERYTHING that will break:\n- How does this violate existing patterns?\n- Where are the hidden coupling points that make this unmaintainable?\n- What happens at 10x scale? 100x?\n- Where's the missing error handling that cascades into system-wide failure?\n- What race conditions are lurking?\nWrite findings to review/adversarial-arch.md.\n```\n\n**Cynical Senior Engineer** -- return types, nil, resource leaks, the \"clever\" line that will page someone.\n\n**Security & Resilience Adversary** -- walk ten areas explicitly: auth boundaries, data loss, idempotency, race conditions, degraded dependencies, schema drift, observability gaps, resource exhaustion, tenant leakage, information disclosure.\n\n- Dispatch all reviewers of a round in ONE message, foreground (not background), so the run waits for all of them.\n- Each writes findings to its own file (e.g.\n`review/<role>.md`\n\n) -- your shared findings store. - The orchestrator (you) does the disproval pass, fixes, commits, THEN dispatches round 2 against the committed code.\n\nBias hard toward fixing now. Before deferring anything, answer: can I describe the fix? (then do it) how many files/lines? (< 3 files, < 50 lines isn't a \"refactor\") is it actually by-design? (then drop the finding, don't defer). Only a concrete, named blocker justifies a deferral.\n\n```\nAdapt these lenses to my stack: <stack>. Add a <domain> reviewer lens.\nThen make verification a vote: for each finding, spawn 3 skeptics that each try to\nrefute it by reading the actual source; drop any finding 2 of 3 can refute.\nReport only survivors, each with a confidence score and the code evidence.\n```\n\n", "url": "https://wpnews.pro/news/adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary", "canonical_source": "https://gist.github.com/mkreyman/e440e27f1e2292c038b497ad9d6c95df", "published_at": "2026-07-02 02:45:38+00:00", "updated_at": "2026-07-13 02:09:42.974224+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools", "ai-safety"], "entities": ["Claude Code"], "alternates": {"html": "https://wpnews.pro/news/adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary", "markdown": "https://wpnews.pro/news/adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary.md", "text": "https://wpnews.pro/news/adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary.txt", "jsonld": "https://wpnews.pro/news/adversarial-multi-agent-code-review-the-pipeline-the-actual-reviewer-adversary.jsonld"}}