adverse-review
Multi-agent adversarial code review. Spawns three reviewer subagents (Auditor, Adversary, Pragmatist) on a single model, runs a cross-examination round, then deterministically synthesizes a single ranked report. Use this for non-trivial PRs, security-sensitive changes, refactors that touch many files, or any change where one perspective has obvious blind spots. Trigger phrases include "adverse review", "adversarial review", "multi-perspective review", "review my changes from multiple angles", "panel review". NOT suitable for trivial diffs (typos, dependency bumps, formatting).
How do I install this agent skill?
npx skills add https://github.com/addyosmani/adverse --skill adverse-reviewIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill implements a multi-agent adversarial code review workflow. It uses local Node.js scripts for data management and includes specific prompt-based mitigations to handle untrusted code inputs safely.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Adverse — Multi-Agent Adversarial Code Review
This skill is the Claude Code-native side of the
adverse project. The same logic is
also available as a standalone CLI (adverse review …). When you run inside
Claude Code, prefer this skill — it uses Claude Code's native Agent tool to
spawn reviewers (no subprocess auth issues, faster) and calls Node helpers
only for the deterministic source-collection and synthesis steps.
When to use this skill
The user explicitly asked for an adversarial / multi-perspective / panel review of their code, OR they're about to merge / land / ship a non-trivial change and asked for one more pass. If the diff is trivially mechanical (formatting, dependency bumps, typos), do NOT invoke this — say so and stop.
Prerequisites
node (>= 20) on PATH. Verify with node --version. The skill scripts live
under ${SKILL_DIR}/scripts/ and are stdlib-only (no npm install needed).
If node is missing, tell the user: install Node 20+ from nodejs.org (or
their package manager) and re-invoke. Do not fall back to a different
implementation; the deterministic synthesizer is the contract.
Phase 0 — decide what to review
Pick scope before spending tokens:
- If the user named a path, that's the scope.
- Else if
git status --porcelainreports uncommitted changes, review those (diff mode againstHEAD). - Else if the current branch is ahead of
main(ormaster/ the configured upstream), review the diff since the merge base. - Else review the whole working directory.
State the scope you picked in one sentence so the user can redirect.
Phase 1 — collect source
Run the Node helper that walks the target and produces a single prompt-ready text block:
node ${SKILL_DIR}/scripts/collect.mjs --target <path> [--diff [base]] --out /tmp/adverse-source.txt --files-out /tmp/adverse-files.json
/tmp/adverse-source.txt is what you'll embed in the reviewer prompts.
/tmp/adverse-files.json is the file list (use it to confirm scope to the
user). The helper enforces the same source-size caps as the CLI.
If collect fails, surface the error to the user — it's almost always "target not found" or "diff is empty".
Phase 2 — round 1: independent reviews
Spawn three reviewers in parallel using Claude Code's Agent tool, one per persona. Each one gets:
- System prompt: read from
${SKILL_DIR}/scripts/prompts/<persona>.txt(auditor / adversary / pragmatist). - User message: the contents of
/tmp/adverse-source.txtprefixed by${SKILL_DIR}/scripts/prompts/round1.txt. - Model:
opusunless the user asked for a different one. If the user picks a smaller model, pass it to all three personas — different models across personas defeats the single-model design.
Each subagent must respond with a single JSON object matching this schema:
{
"persona": "<auditor|adversary|pragmatist>",
"verdict": "approve|conditional|reject",
"summary": "<one sentence>",
"findings": [
{
"severity": "critical|warning|info",
"file": "<path or null>",
"line": <int or null>,
"title": "<short noun phrase>",
"detail": "<2-6 sentences>",
"fix": "<concrete remediation or null>"
}
]
}
Save each parsed JSON object to disk:
/tmp/adverse-round1-auditor.json/tmp/adverse-round1-adversary.json/tmp/adverse-round1-pragmatist.json
If a subagent returns malformed JSON, retry that one persona once with the parser/validator error appended to the original prompt. If the retry also fails, drop that persona. If fewer than 2 personas survive, abort the run and report the failure — synthesis requires at least 2 voices.
When all three are done, combine them into one file for the next phase:
node ${SKILL_DIR}/scripts/combine.mjs \
--round1 /tmp/adverse-round1-auditor.json /tmp/adverse-round1-adversary.json /tmp/adverse-round1-pragmatist.json \
--out /tmp/adverse-round1.json
Phase 3 — round 2: cross-review
For each persona that produced a valid round-1 review, spawn a subagent that:
- Sees ALL round-1 reviews (the combined
/tmp/adverse-round1.json). - Validates findings it agrees with (cross-lane validation is the signal).
- Challenges findings it thinks are wrong / overstated (with a concrete reason).
- Optionally adds new findings the other angles surfaced.
System prompt: same persona file as round 1. User prompt: the contents of
${SKILL_DIR}/scripts/prompts/round2.txt, then the round-1 combined JSON,
then the source block.
Output schema:
{
"persona": "<auditor|adversary|pragmatist>",
"validate": [{ "from": "<reporter>", "title": "<title>", "reason": "<…>" }],
"challenge": [{ "from": "<reporter>", "title": "<title>", "reason": "<…>" }],
"added": [<finding object>]
}
Save each to /tmp/adverse-round2-<persona>.json and combine:
node ${SKILL_DIR}/scripts/combine.mjs \
--round2 /tmp/adverse-round2-*.json \
--out /tmp/adverse-round2.json
If the user asked for a faster review or --single-round, skip phase 3
entirely. The synthesizer treats missing round 2 as an empty cross-review.
Phase 4 — synthesize
Run the deterministic synthesizer. This produces the canonical report — never LLM-render the findings yourself, the synthesizer's groupings (cross-validated / consensus / disputed / solo) carry the signal.
node ${SKILL_DIR}/scripts/synthesize.mjs \
--round1 /tmp/adverse-round1.json \
--round2 /tmp/adverse-round2.json \
--out /tmp/adverse-report.md \
--json-out /tmp/adverse-report.json \
--html-out /tmp/adverse-report.html
Read /tmp/adverse-report.md and present a summary to the user, not the
full report:
- The verdict line (e.g.,
SHIP-WITH-CAVEATS (2/3 ship, 1/3 block)). - Counts by severity and confidence.
- The top 3 findings (cross-validated first, then consensus, then disputed) with one-line previews.
- A pointer to the full report on disk and the HTML dashboard.
Then ask the user how they want to proceed:
- Apply fixes for cross-validated findings only? (highest confidence)
- Apply fixes for everything except disputed? (most common)
- Show me a specific finding's full reasoning?
- Just save the report; I'll review it myself.
Do not start editing files until the user picks one.
Phase 5 — clean up
After the user is done with the report, delete /tmp/adverse-* and tell the
user the run is complete. Do not commit those files.
Failure handling
| Failure | What to do |
|---|---|
collect.mjs exits non-zero | Surface the error. Common causes: target doesn't exist, --diff on non-git dir, empty diff. |
| One reviewer returns garbage twice | Continue with 2 reviewers, mark the run "degraded" in your summary. |
| ≥2 reviewers fail | Abort. Tell the user the model is misbehaving and suggest re-running with a different model or with --single-round. |
node not on PATH | Tell the user to install Node 20+. Do not improvise a fallback. |
| User interrupts | Stop spawning new subagents. Tell the user where the partial artifacts are. |
Notes for the orchestrator
- This skill spends ~6 model calls (3 × round-1 + 3 × round-2). Skip round 2 on user request to halve it.
- Persona prompts are deliberately written to "stay in your lane" — do NOT override them with general-purpose review instructions, doing so collapses the orthogonality the design relies on.
- The synthesizer is deterministic Python-free Node code (
synthesize.mjs). Counting validate/challenge edges is the consensus signal; do not run a fourth LLM "judge" pass. - The standalone CLI (
adverse review) is an alternative path that subprocesses any coding agent (claude -p,codex exec, …). Mention it to the user only if they ask how to run this without Claude Code.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/addyosmani/adverse/adverse-review">View adverse-review on skillZs</a>