| name | adversarial |
| description | GAN-inspired adversarial quality loop: write code, gate with hard fitness, attack with LLM adversary, iterate until it survives |
| level | 4 |
| triggers | ["adversarial","quality loop","adversarial harness","verify hard"] |
Run an adversarial quality loop on your coding task. You write code, hard fitness checks
(tests/types/lint) gate it, then an independent LLM adversary tries to break it.
If the adversary finds real issues, you fix them and repeat. Ship what survives.
Inspired by Anthropic's GAN-style harness design and Karpathy's fitness-driven iteration.
<Use_When>
- User invokes
/adversarial or /adversarial --profile <name>
- User asks for "adversarial review", "quality loop", "verify hard"
- User wants higher confidence in code correctness before shipping
</Use_When>
<Do_Not_Use_When>
- Trivial changes (typos, comments, formatting) — just do them directly
- User explicitly says they don't want adversarial review
- No code changes are involved (pure research/planning tasks)
</Do_Not_Use_When>
<Execution_Policy>
- Maximum iterations: 5 (override with
--max-iter N)
- Hard fitness MUST pass before LLM adversary runs — never waste evaluator tokens on code that can't pass basic checks
- Generator and Evaluator are ALWAYS separate contexts — you write code, the adversary reviews it in a fresh subagent with no sunk-cost bias
- Only CRITICAL and HIGH severity issues from the adversary count as blockers
- If max iterations reached without PASS: output best version + full adversarial report, let user decide
</Execution_Policy>
Phase 1: CLASSIFY & CONFIGURE
Parse arguments from the /adversarial invocation:
--profile <name>: force a specific adversary profile (strict|pedantic|chaos|mentor)
--max-iter N: override max iterations (default 5)
--fitness-only: skip LLM adversary, only run fitness gates
If no explicit profile, auto-select based on task keywords:
- auth/security/payment/token/session/permission → strict
- refactor/library/api/interface/public/naming → pedantic
- infra/distributed/concurrent/network/scale/deploy → chaos
- everything else → mentor (balanced, educational, safest default)
Detect project stack by checking for marker files in the working directory:
pyproject.toml or setup.py → Python stack
package.json → JavaScript/TypeScript stack
Cargo.toml → Rust stack
go.mod → Go stack
- If
.adversarial-harness.toml exists, read explicit fitness commands from it
Announce the configuration:
Adversarial loop armed:
Profile: <selected> | Max iterations: <N> | Stack: <detected>
Phase 2: GENERATE
Write the code for the user's task. Use standard tools: Edit, Write, Bash, Read, Grep, Glob.
You ARE the generator. Do not spawn a separate agent for code generation.
Write the best code you can on the first attempt — the adversary will catch what you miss.
Phase 3: HARD FITNESS GATE
Run fitness checks via Bash tool. All gates must pass (exit code 0).
Python stack:
python -m pytest -x --tb=short 2>&1 | tail -20
python -m mypy . --ignore-missing-imports 2>&1 | tail -20
python -m ruff check . 2>&1 | tail -20
JavaScript/TypeScript stack:
npx vitest run 2>&1 | tail -30
npx tsc --noEmit 2>&1 | tail -20
npx eslint . 2>&1 | tail -20
Rust stack:
cargo test 2>&1 | tail -30
cargo check 2>&1 | tail -20
cargo clippy -- -D warnings 2>&1 | tail -20
Go stack:
go test ./... 2>&1 | tail -30
go vet ./... 2>&1 | tail -20
Gate rules:
- If a tool is not installed, skip that gate and note it
- If no test framework is detected, skip tests gate
- If ALL available gates pass → proceed to Phase 4
- If ANY gate fails → fix the issue directly, re-run ONLY the failing gate
- Repeat fitness fix cycle up to 3 times per iteration
- If still failing after 3 fitness attempts → report to user, ask how to proceed
Key principle: Hard fitness is CHEAP (no LLM tokens). Never send code to the LLM adversary
that can't pass basic tests/types/lint. This saves significant cost.
Phase 4: LLM ADVERSARY
Only reached when all fitness gates pass.
Step 4a: Read the adversary profile
Read the selected profile file from the plugin's profiles/ directory.
The profile contains the adversary's specific evaluation lens and focus areas.
Step 4b: Construct the adversary prompt
Build the full prompt for the evaluator subagent by combining:
- The profile content (read in 4a)
- The original task description
- A summary of changes made (files modified, key decisions)
- The fitness check results (all passed)
Step 4c: Spawn the adversary
Task(
subagent_type="adversarial-harness:adversary",
model="sonnet",
prompt="<constructed prompt from 4b>"
)
For complex tier tasks (multi-file refactors, auth/security, infrastructure):
use model="opus" instead of model="sonnet".
Step 4d: Parse the verdict
The adversary returns a structured verdict:
- PASS: All checks passed. Proceed to Phase 6.
- FAIL: Issues found. Read the feedback, proceed to Phase 5.
Phase 5: ITERATE
On FAIL verdict from the adversary:
- Read the adversary's specific feedback (file:line citations, severity ratings)
- Fix ONLY the CRITICAL and HIGH issues identified
- Do NOT fix MEDIUM/LOW issues unless trivial (they are non-blocking)
- Return to Phase 3 (fitness gate) with the fixes
Track iteration count. If this is iteration N of max:
- Iterations 1-4: normal fix cycle
- Iteration 5 (max): output the current best version + full report of all issues
found across all iterations. Let the user decide whether to ship.
Phase 6: SHIP & REPORT
On PASS verdict (or user accepts after max iterations):
Print the session telemetry report:
╭─────────────── adversarial-harness ───────────────────────╮
│ Task: "<task summary>" │
│ Profile: <name> │ Iterations: <N>/<max> │
│ │
│ Fitness: ✓ tests ✓ types ✓ lint │
│ Adversary: <verdict history, e.g. FAIL → FAIL → PASS> │
│ │
│ Issues caught & fixed: │
│ R1: [severity] description │
│ R2: [severity] description │
│ ... │
╰───────────────────────────────────────────────────────────╯
The SubagentStop hook automatically logs the adversary's verdict to
~/.adversarial-harness/verdicts.jsonl for calibration tracking.
<Escalation_And_Stop_Conditions>
- Stop immediately if user says "skip", "enough", "ship it", or "cancel"
- Stop if max iterations reached — output best attempt + full report
- Stop if fitness gates fail 3 times in a row on the same issue — ask user for help
- If the adversary returns NO_VERDICT (unparseable output) — treat as PASS with low confidence, note in report
</Escalation_And_Stop_Conditions>
<Final_Checklist>