-
Notifications
You must be signed in to change notification settings - Fork 544
Add adversarial-verification plugin #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wizardengineer
wants to merge
4
commits into
main
Choose a base branch
from
adversarial-verification-plugin
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
833dbef
Add adversarial-verification plugin
wizardengineer 593b27a
Merge branch 'main' into adversarial-verification-plugin
dguido a664194
docs: address adversarial-verification review feedback
wizardengineer b5718d6
Merge branch 'main' into adversarial-verification-plugin
dguido File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../plugins/adversarial-verification/skills/adversarial-verification | ||
|
Check failure on line 1 in .codex/skills/adversarial-verification
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
plugins/adversarial-verification/.claude-plugin/plugin.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "name": "adversarial-verification", | ||
| "version": "1.0.0", | ||
| "description": "Verify claims, designs, and bug findings by dispatching isolated advocate/skeptic sub-agents and synthesizing their arguments into a structured verdict. Counters sycophancy and single-agent agreement bias.", | ||
| "author": { | ||
| "name": "Julius Alexandre", | ||
| "email": "opensource@trailofbits.com", | ||
| "url": "https://github.com/trailofbits" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # adversarial-verification | ||
|
|
||
| Stress-test claims, designs, and bug findings by dispatching two isolated sub-agents — one advocate, one skeptic — and synthesizing their arguments into a structured verdict. | ||
|
|
||
| ## When to Use | ||
|
|
||
| - Choosing between competing technical approaches | ||
| - Verifying a bug finding is real (not a false positive) | ||
| - Reviewing a design decision before commit | ||
| - Any claim you're inclined to agree with by default | ||
| - Stress-testing your own reasoning when you suspect it may be one-sided | ||
|
|
||
| ## What It Does | ||
|
|
||
| Counters sycophancy and single-agent agreement bias by forcing maximal disagreement before committing. Each sub-agent runs in isolated context — the advocate never sees the skeptic's arguments and vice versa. After both return, the caller synthesizes a verdict table that picks winners per dimension and produces a concrete recommendation. | ||
|
|
||
| ### Two modes | ||
|
|
||
| | Mode | Claim type | Structure | | ||
| |------|-----------|-----------| | ||
| | **Decision mode** | "X is the best approach" | Free-form arguments organized by evaluation dimensions | | ||
| | **Proof mode** | "X is a real bug/finding" | N null hypotheses — skeptic proves, advocate refutes | | ||
|
|
||
| ## Installation | ||
|
|
||
| ``` | ||
| /plugin marketplace add trailofbits/skills | ||
| /plugin install adversarial-verification | ||
| ``` |
133 changes: 133 additions & 0 deletions
133
plugins/adversarial-verification/skills/adversarial-verification/SKILL.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| --- | ||
| name: adversarial-verification | ||
| description: Verify a claim, idea, approach, design, or finding by dispatching two isolated sub-agents — an advocate (argues the claim is correct/best) and a skeptic (argues it is wrong/inferior) — then synthesize their arguments into a structured verdict. Counters sycophancy and agreement bias by forcing maximal disagreement before the caller commits. Use when making technical decisions ("should we use X or Y?"), verifying bug findings ("is this a real bug?"), reviewing system designs ("is this architecture sound?"), evaluating strategic claims, or whenever the caller suspects their own reasoning may be one-sided. Triggers on phrases like "verify this claim", "adversarial verification", "is this right?", "prove this is a real bug", "which approach is best", "stress-test this idea", "get a second opinion on", "argue against this", "devil's advocate", or whenever pattern-breaking from agreement is needed. | ||
| --- | ||
|
|
||
| # Adversarial Verification | ||
|
|
||
| ## Overview | ||
|
|
||
| Dispatch two sub-agents with isolated context — one **advocate**, one **skeptic** — to argue opposite sides of a claim as strongly as possible. Then synthesize their arguments into a structured verdict table. This breaks the pattern of single-agent reasoning converging toward agreement and surfaces the strongest objections and the strongest supports in one pass. | ||
|
|
||
| **Core principle:** Independent isolated context is non-negotiable. An agent that has read the other side's arguments will soften to accommodate them. The adversarial value comes from each agent arguing without knowledge of the counter-argument. | ||
|
|
||
| **Announce at start:** "I'm using the adversarial-verification skill to stress-test this claim." | ||
|
|
||
| ## When to Use | ||
|
|
||
| - Choosing between 2+ technical approaches | ||
| - Verifying a bug finding is real (not a false positive) | ||
| - Reviewing a design decision before commit | ||
| - User asks "is this correct?" about a non-trivial claim | ||
| - Any claim you're inclined to agree with by default — that's the tell | ||
|
|
||
| ## When NOT to Use | ||
|
|
||
| - Simple factual lookup ("what version is X?") | ||
| - Obvious syntax error fix | ||
| - User has already made the decision and is executing | ||
|
|
||
| ## The Process | ||
|
|
||
| ### Step 1: State the claim precisely | ||
|
|
||
| Before dispatching agents, state the claim in a single sentence. Ambiguous claims produce worthless verifications. | ||
|
|
||
| **Bad:** "Should we use yarpgen?" | ||
| **Good:** "YARPGen program-level differential testing is the best strategy for finding semantic translation bugs in Rosetta 2, better than grammar-aware x86 mutation or a Cascade-style oracle." | ||
|
|
||
| The claim must be **falsifiable** — something the skeptic could in principle prove wrong. | ||
|
|
||
| ### Step 2: Select the mode | ||
|
|
||
| Two modes, chosen by the claim type: | ||
|
|
||
| | Claim type | Mode | Details | | ||
| |-----------|------|---------| | ||
| | Bug finding / security claim | **Proof mode** | Structured N-proof hypotheses (e.g., P1-P5). See [references/proof-mode.md](references/proof-mode.md) | | ||
| | Approach / design decision | **Decision mode** | Free-form arguments with evidence. See [references/decision-mode.md](references/decision-mode.md) | | ||
|
|
||
| If unsure, default to decision mode. | ||
|
|
||
| ### Step 3: Dispatch both agents in parallel | ||
|
|
||
| Use the Agent tool with TWO tool calls in a SINGLE message (parallel dispatch). Each agent is a fresh context with no knowledge of the other. | ||
|
|
||
| Load prompt templates from [references/prompt-templates.md](references/prompt-templates.md). The templates enforce: | ||
| - Each agent argues ONE side maximally, not balanced | ||
| - Each agent is told explicitly "do not be balanced" and "argue as hard as possible" | ||
| - Each agent cites specific evidence (files, line numbers, facts) | ||
| - Each agent anticipates and pre-refutes the obvious counter-arguments | ||
|
|
||
| Give each agent the **same claim**, the **same background context**, but **opposite instructions**. Never mention the other agent's existence or arguments in either prompt. | ||
|
|
||
| ### Step 4: Synthesize with a verdict table | ||
|
|
||
| After both agents return, produce a verdict table. For each significant point raised by either side: | ||
|
|
||
| | Point | Advocate position | Skeptic position | Verdict | | ||
| |-------|-------------------|------------------|---------| | ||
|
|
||
| Verdict values: | ||
| - **Survives** — one side's position held up; the other failed to counter it | ||
| - **Weakens** — partially rebutted; position should be qualified | ||
| - **Falls** — cleanly refuted by the other side | ||
|
|
||
| Then write a one-paragraph **recommendation**: which overall position won, which specific claims survived, and what the caller should actually do. | ||
|
|
||
| See [references/synthesis.md](references/synthesis.md) for the full synthesis template. | ||
|
|
||
| ### Step 5: Report to the caller | ||
|
|
||
| Present three things: | ||
| 1. The claim (one sentence, as stated in Step 1) | ||
| 2. The verdict table | ||
| 3. The recommendation (what action follows from the verdict) | ||
|
|
||
| Do NOT dump the raw agent outputs unless the user asks. The verdict is the product. | ||
|
|
||
| ## Reference Guide | ||
|
|
||
| - Mode selection quick reference: [references/decision-mode.md](references/decision-mode.md) and [references/proof-mode.md](references/proof-mode.md) | ||
| - Prompt templates for advocate and skeptic dispatch: [references/prompt-templates.md](references/prompt-templates.md) | ||
| - Verdict table and recommendation shape: [references/synthesis.md](references/synthesis.md) | ||
| - Failure modes and recovery patterns: [references/anti-patterns.md](references/anti-patterns.md) | ||
|
|
||
| ## Anti-patterns | ||
|
|
||
| See [references/anti-patterns.md](references/anti-patterns.md) for full failure modes. The three most important: | ||
|
|
||
| 1. **False symmetry** — treating both sides as equally valid when one is clearly stronger. The verdict must pick a winner, not split the difference. | ||
| 2. **Hedged agents** — agents that softened their argument. If an agent returns a balanced view, re-dispatch with a stronger prompt. Real adversarial value requires real adversarial arguments. | ||
| 3. **Shared context leakage** — mentioning the other agent's arguments in either prompt. This collapses independence. Each prompt must be written as if that agent is the only one you've asked. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Example A — approach decision (decision mode) | ||
|
|
||
| Claim: *"Using YARPGen to generate C programs is the fastest path to finding semantic translation bugs in Rosetta 2."* | ||
|
|
||
| Dispatch: | ||
| - Advocate prompt: "Make the strongest case FOR this claim. Cite known bugs YARPGen would catch, expected exec/s, why compiler-emitted code is the right attack surface. Do not be balanced." | ||
| - Skeptic prompt: "Make the strongest case AGAINST. YARPGen has no FP support, known Rosetta bugs are in FP/SIMD/implicit registers, oracle problem without Intel hardware. Do not be balanced." | ||
|
|
||
| Result: verdict table shows skeptic's "no FP support" and "oracle problem" survive; advocate's "fastest to set up" survives. Recommendation: use YARPGen as complement, not primary strategy. | ||
|
|
||
| ### Example B — bug verification (proof mode) | ||
|
|
||
| Claim: *"FINDING-001 (pcmpestrm register allocator abort) is a real translation bug, not a false positive."* | ||
|
|
||
| Dispatch with 5 proofs, each tests one null hypothesis: | ||
| - P1: "This is just normal input rejection (exit -302)." | ||
| - P2: "This is a harness artifact (doesn't reproduce in clean env)." | ||
| - P3: "This is a benign assertion (SIGABRT in validation code)." | ||
| - P4: "The input is unreachable in practice (no compiler emits it)." | ||
| - P5: "Already fixed in a newer macOS." | ||
|
|
||
| Skeptic tries to prove each null; advocate tries to refute each. If all 5 fail to prove = CONFIRMED bug. | ||
|
|
||
| ## Integration | ||
|
|
||
| **Called by:** | ||
| - User directly via explicit request | ||
| - Any skill that needs to verify a claim before acting on it — e.g., when brainstorming an approach choice, when evaluating a code review suggestion that seems technically questionable, or when verifying a proposed root cause before applying a fix |
81 changes: 81 additions & 0 deletions
81
...sarial-verification/skills/adversarial-verification/references/anti-patterns.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Anti-patterns | ||
|
|
||
| Common failure modes that destroy the adversarial value of this skill. Each has a diagnosis and a fix. | ||
|
|
||
| ## 1. False symmetry | ||
|
|
||
| **Symptom:** The verdict says "both sides have merit" and splits the difference. No clear winner. Vague recommendation like "consider both approaches." | ||
|
|
||
| **Why it happens:** Reluctance to pick a side. Treating the adversarial structure as performative rather than decisional. | ||
|
|
||
| **Fix:** Pick a winner. The dimensions in the verdict table each have one winner, not a tie. If truly 3/3 split across dimensions, the winner is whichever dimensions matter most for the caller's actual decision — name those dimensions explicitly in the recommendation. | ||
|
|
||
| ## 2. Hedged agents | ||
|
|
||
| **Symptom:** Agent returns things like "I see merits on both sides," "this is a nuanced question," "both approaches have tradeoffs." No strong adversarial position. | ||
|
|
||
| **Why it happens:** Weak prompt. The agent defaulted to balanced reasoning because nothing stopped it. | ||
|
|
||
| **Fix:** Re-dispatch with a stronger prompt. The key phrase: "Do not acknowledge merit in the opposing position. Do not hedge." Do not accept a hedged response as valid output. If you need the full templates, return to [SKILL.md](../SKILL.md) Step 3. | ||
|
|
||
| ## 3. Shared context leakage | ||
|
|
||
| **Symptom:** Advocate mentions the skeptic's arguments (or vice versa), softening the tone to accommodate. Arguments collapse toward agreement. | ||
|
|
||
| **Why it happens:** Prompt mentioned the other agent's existence or previewed their arguments. | ||
|
|
||
| **Fix:** Each prompt must be written as if that agent is the ONLY agent you've asked. Do not mention the other side. Do not say "another agent will argue X." Do not give hints about counter-arguments. The synthesis happens separately after both return. | ||
|
|
||
| ## 4. Unfalsifiable claim | ||
|
|
||
| **Symptom:** The skeptic can't argue against the claim because it's too vague or too broad. | ||
|
|
||
| **Why it happens:** Claim wasn't stated precisely in Step 1. | ||
|
|
||
| **Fix:** Return to Step 1. Rewrite the claim as a specific, falsifiable sentence. "YARPGen is good" is unfalsifiable. "YARPGen will catch more Rosetta 2 semantic bugs than grammar-aware mutation in 7 days of fuzzing" is falsifiable. | ||
|
|
||
| ## 5. Missing evidence | ||
|
|
||
| **Symptom:** Agents make claims but don't cite specific files, line numbers, CVEs, benchmarks. Arguments are plausible but unverifiable. | ||
|
|
||
| **Why it happens:** Prompt didn't require citations. | ||
|
|
||
| **Fix:** Every prompt includes: "Cite specific files, line numbers, facts, CVEs, benchmarks where possible." Reject outputs that make unsupported claims on critical dimensions. | ||
|
|
||
| ## 6. Wrong mode | ||
|
|
||
| **Symptom:** Trying to prove a bug is real with "what do you think is best" prompts, or trying to pick between approaches with proof-style null hypotheses. | ||
|
|
||
| **Fix:** Reread [SKILL.md](../SKILL.md) Step 2. Decision mode = approach/design choice. Proof mode = bug/finding/security claim verification. Pick the right one. | ||
|
|
||
| ## 7. Synthesis dump | ||
|
|
||
| **Symptom:** Presenting both agents' full outputs as the result. No verdict table. No recommendation. | ||
|
|
||
| **Why it happens:** Skipping the synthesis step. | ||
|
|
||
| **Fix:** The verdict table is the product, not the raw arguments. Always produce the table + recommendation. Only dump raw agent outputs if the user explicitly asks for them. | ||
|
|
||
| ## 8. Confirmation bias in prompt | ||
|
|
||
| **Symptom:** Advocate wins trivially because the prompt was stacked in its favor. The skeptic has nothing to work with. | ||
|
|
||
| **Why it happens:** Caller's preferred answer leaks into the prompt framing. | ||
|
|
||
| **Fix:** Both prompts should frame the claim neutrally. "Make the case FOR/AGAINST {CLAIM}" not "Make the case FOR the obviously correct {CLAIM}". Both agents get the SAME background. If the advocate gets more context than the skeptic, the test is rigged. | ||
|
|
||
| ## 9. Too many dimensions | ||
|
|
||
| **Symptom:** Verdict table has 15 rows. Each row is shallow. Recommendation is unclear because so many points survived/fell. | ||
|
|
||
| **Fix:** Pick 3-5 dimensions. The dimensions should be the ones that actually determine the decision. Cut dimensions that don't move the verdict either way. | ||
|
|
||
| ## 10. Ignoring UNCERTAIN | ||
|
|
||
| **Symptom:** Proof-mode verdict marks every null as REFUTED/PROVED when some were actually UNCERTAIN. Finding is reported as CONFIRMED when one null is still plausible. | ||
|
|
||
| **Fix:** UNCERTAIN is a valid outcome. If P4 ("input unreachable") has evidence on both sides, the finding is NOT confirmed. Either: | ||
| - Gather more evidence on that specific P before concluding, OR | ||
| - Report the finding WITH the caveat that P4 is uncertain | ||
|
|
||
| Do not round UNCERTAIN up to CONFIRMED. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 This PR adds a
.codex/skills/adversarial-verificationsymlink, but AGENTS.md:41 explicitly prohibits.codex/sidecar directories — Codex already supports the canonical.claude-plugin/marketplace.jsondirectly (AGENTS.md:35-37). The README.md update in this same PR even states "Codex supports Claude plugin marketplaces directly, so this repository does not need Codex-specific sidecar metadata," directly contradicting the new symlink. Fix: delete the.codex/directory entirely; the marketplace entry already added to.claude-plugin/marketplace.jsonhandles Codex discovery.Extended reasoning...
What the bug is
The PR creates a new top-level
.codex/directory containing a symlink:AGENTS.md:41 (which is
@-included by CLAUDE.md and is therefore the binding contributor guide) explicitly states:AGENTS.md:35-37 explains the rationale: "This repository uses Claude plugin marketplace metadata as the canonical source for both Claude Code and Codex. Codex supports
.claude-plugin/marketplace.jsonandplugins/<name>/.claude-plugin/plugin.jsondirectly, so do not add duplicate Codex-only sidecar metadata."Why existing code does not prevent it
There is no CI check that fails on
.codex/paths —validate_plugin_metadata.pyandcheck_codex_loadability.pyvalidate plugin contents, not the absence of forbidden sidecar directories. The rule lives only in the contributor guide, and the PR's test plan even lists "Codex symlink created at.codex/skills/adversarial-verification" as a deliberate step, indicating the author was working from outdated knowledge of the repo conventions. (Relatedly, the test plan referencesvalidate_codex_skills.py, which does not exist —.github/scripts/only containscheck_claude_loadability.py,check_codex_loadability.py, andvalidate_plugin_metadata.py.)Step-by-step proof
.codex/.find . -maxdepth 5 -name '.codex*'on the PR branch returns exactly one hit: the new.codex/skills/adversarial-verificationfrom this PR. No other plugin in the marketplace uses this pattern..claude-plugin/marketplace.json(lines 395-406 of the diff), which is the canonical discovery mechanism Codex consumes via marketplace compatibility. The symlink adds nothing functional.Impact
Sets a bad precedent. If merged, future plugin contributors will see
.codex/in the tree and replicate the pattern, drifting the repo away from the single-source-of-truth Claude marketplace metadata that AGENTS.md establishes. There is no functional benefit — Codex already discovers the plugin through.claude-plugin/marketplace.json.How to fix
Delete the
.codex/directory entirely:The plugin remains discoverable for both Claude Code and Codex through the marketplace entry already added in this PR. Also remove the "Codex symlink created at
.codex/skills/adversarial-verification" line from the PR description's test plan.