Portable release gate

Run it on any agent.
Exclude the one that
wrote the code.

Adversarial-review is a folder of zero-dependency Python that any coding agent can operate. The pipeline is identical everywhere — deterministic gates, an independent multi-model panel, and a PASS / FAIL / BLOCKED verdict computed by a script, never narrated by a model. Only two things change per platform: how you point the agent at it, and which model family you exclude.

PASS · exit 0 FAIL · exit 1 BLOCKED · exit 2
Many coding agents feeding one identical review pipeline that outputs a single computed verdict one pipeline · every platform
4–6independent families
0third-party deps
reviewer tokens / run
Py 3.9+anywhere it runs
The one idea

One pipeline. Two dials.

A model that reviews its own work is the fox auditing the henhouse. So correctness comes from deterministic tools with exit codes and from reviewer models whose provider families did not write the change — and the decision is computed from the recorded artifacts by aggregate.py, which you cannot argue with.

01
Agent writes
Claude · Codex · Cursor · Devin · Gemini …
02
Deterministic gates
build · unit · sast · secrets · deps · ai-defects
03
Independent panel
author's family excluded
04
Validate & fix
reproduce · regress · rerun gates
05
aggregate.py
the only verdict author
06
Verdict
PASS · FAIL · BLOCKED
The thing people get wrong

Exclude the family that wrote it.

Match --dev-providers to whoever authored the change on your platform. Get this wrong and the author quietly grades its own work — the single mistake that turns the whole thing into theatre.

Claude Code / CoworkAnthropic wrote it
--dev-providersanthropic
OpenAI CodexGPT wrote it
--dev-providersopenai
Gemini CLI / JulesGoogle wrote it
--dev-providersgoogle
Cursor · Windsurf / Devin · Copilotwhichever model you selected
--dev-providersthe family you picked
Two authors touched it? List every family: --dev-providers anthropic,openai. When in doubt, over-exclude — too few independent families comes back BLOCKED on purpose, never a soft pass. The panel is then drawn only from the families that did not write it.
Four ways to wire it in

Pick one per platform.

If your agent reads AGENTS.md, you are already 90% set up. Everything below drives the exact same pipeline.

A · Native skill — Claude Code, Cowork

Skills are first-class. Drop the one folder into your skills directory and invoke it; the agent reads SKILL.md and runs the pipeline for you.

# clone into your skills dir
git clone https://github.com/SathiaAI/adversarial-review \
  ~/.claude/skills/adversarial-review
B · AGENTS.md pointer

Codex, Cursor, Windsurf/Devin, Copilot, Gemini CLI, Aider, Zed, Warp, goose — and 60k+ repos' agents. Add a short release-gate block that tells the agent to run the review before it calls a change "done."

## Release gate
Run adversarial-review per its SKILL.md before
any change is "done": init (--dev-providers =
this agent's family), gates, panel, aggregate.
Relay the verdict verbatim.
C · MCP server

Any MCP host. Run ar-mcp with the repo under review as the working directory; the host drives the review through MCP tools. Stdlib-only, and deliberately not an arbitrary-command surface.

ar-mcp # or: python scripts/mcp_server.py
# ar_init → ar_gate_record → ar_panel_* → ar_aggregate
D · GitHub Action — no agent at all

Wire the verdict's exit code into CI so it gates the merge, not a human's optimism.

- uses: SathiaAI/adversarial-review@main
  with:
    fail-on: fail
    openrouter-api-key: ${{ secrets.OPENROUTER_API_KEY }}
Per-platform playbook

Where you code, and what to expect.

Same verdict everywhere; the wiring and the excluded family change. Each card: when to reach for it, and the one thing to watch.

Claude Code & Claude (Cowork)

exclude anthropic

The reference experience. Gate a branch you and Claude just built before the PR — Cowork additionally hands a stakeholder a readable verdict.md + attested run directory, not just a green check.

# the author is also the operator —
# independence comes from the panel,
# and the verdict is computed, not narrated.
wire · A native skillwatch · keep --dev-providers anthropic

OpenAI Codex

exclude openai

AGENTS.md-native. Gate a Codex-built change before merge; the most common miss is forgetting to exclude openai — then GPT reviews GPT.

wire · B / skills dirwatch · give it the diff, not the repo

Windsurf / Devin

the family used

Now Devin Desktop; the Cascade agent reads AGENTS.md and runs commands, so it can gate its own autonomous work before opening a PR. The highest-leverage case.

wire · B AGENTS.mdwatch · pin the exclusion so it can't self-review

Cursor

the family picked

Model-agnostic IDE. Exclude whatever model you selected — easy to get wrong because you can switch models mid-session.

wire · B (.cursorrules ok)watch · switched models? exclude all of them

GitHub Copilot

the family used

PR-native. Let the Action compute the verdict in CI rather than trusting the agent's prose summary of its own change.

wire · B + D Actionwatch · required check = aggregator exit code

Gemini CLI / Jules

exclude google

AGENTS.md-native. Exclude Gemini, keep the panel diverse, gate on the exit code.

wire · B AGENTS.mdwatch · same pattern, boring on purpose

Any other agent

that model's family

Aider, Zed, Warp, goose, or open-weight (Hermes/Nous, Llama, Qwen). Reads AGENTS.md → path B; otherwise paste SKILL.md as instructions. Open models are also useful on the panel for provider diversity.

wire · B or SKILL.mdwatch · anything with Python 3.9+ and a shell works
Honest expectations

What you get, and what to watch.

A computed verdict, not a vibe. PASS / FAIL / BLOCKED from recorded artifacts, relayed verbatim.

Real findings from models that didn't write the code — and, when high/critical findings exist, a rebuttal round where reviewers confront each other with evidence.

BLOCKED when review is incomplete. Unknown is treated as unshippable, so a half-run never reads as confidence.

A tamper-evident audit trail. Coverage + attestation in every verdict.json, verifiable with --check-digest.

A few cents of reviewer tokens per run — it reports usage. Not a replacement for your scanners; the layer that makes their results and an independent review converge into one honest verdict.

01

Never let the authoring family review itself. Setting --dev-providers correctly is 90% of the value.

02

The operator is a conflicted party. Safe only because the verdict is computed by aggregate.py, not narrated by the model. Don't let an agent interpret a FAIL into a pass.

03

Transport privacy. An MCP transport routes your code through that provider — fine for NORMAL, confirm before SENSITIVE/CRITICAL. Never put secrets or .env in context.md.

04

Feed it the diff, not the repo. main...HEAD plus the surrounding code that matters — not a 200-file dump.

05

Don't move the goalposts. Weakening a gate to get a pass defeats the point — and the aggregator resists it; waivers must be on the record with a named authorizer.

Point it at one moment

The instant an agent says "done."

That claim is precisely what this exists to verify. Wire the verdict into a pre-push hook or a required check — a verdict nobody enforces is a comment.