Stress-test plans and proposals via systematic adversarial review. Assumption extraction, evidence check, failure scenarios, operational gotchas. Before implementation begins. Use when: 'devil's advocate', 'stress test', 'poke holes', 'what could go wrong', 'challenge this plan', 'find the holes in this', 'argue against this', new dependencies, infrastructure/CI/build changes, or any architecture decision with cross-module blast radius. An `incumbent` mode turns the same adversarial lens on t...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add melodic-software/claude-code-plugins --skill devils-advocate --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Devils Advocate?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/melodic-software-devils-advocate)More formats (shields.io, HTML) on the badges page.
---
description: "Stress-test plans and proposals via systematic adversarial review. Assumption extraction, evidence check, failure scenarios, operational gotchas. Before implementation begins. Use when: 'devil's advocate', 'stress test', 'poke holes', 'what could go wrong', 'challenge this plan', 'find the holes in this', 'argue against this', new dependencies, infrastructure/CI/build changes, or any architecture decision with cross-module blast radius. An `incumbent` mode turns the same adversarial lens on the status quo. 'is there a better way now', 'should we still use X', 'reconsider the current approach', 'is the incumbent still the right choice'. Surveying alternatives before a plan commits to keeping an existing tool or approach. Not for code correctness bugs or pre-PR verification."
argument-hint: "[incumbent [target]] or [plan text or file path]. An optional leading deep/shallow sets research depth; works from conversation context if no argument given"
user-invocable: true
disable-model-invocation: false
shell: bash
metadata:
workflow-stage: plan
summary: Stress-test a plan or the incumbent approach adversarially
---
## Pre-computed context
Current branch: !`git branch --show-current 2>/dev/null || echo "unknown"`
Recent commits: !`git log --oneline -5 2>/dev/null || echo "no commits"`
## Variables
Arguments: `$ARGUMENTS`
## Purpose
Plans fail for predictable reasons: unchecked assumptions, undiscovered bugs in dependencies, missing extensibility, no drift detection, no graceful degradation. This skill systematically finds these problems BEFORE implementation begins.
Not a rubber stamp. Find real issues that would cause rework, not generic warnings. Every finding must be backed by evidence. A specific bug number, doc reference, code path, or logical argument. "This might break" without evidence is not a finding.
The same discipline runs against the status quo. An incumbent tool, library, or approach already in place is a decision too, and "we already use it" is evidence of what is, never proof it still fits. The `incumbent` mode stress-tests that choice, naming the problem the incumbent actually solves, surveying alternatives, and asking whether a better fit exists now, before a plan commits to keeping or replacing it.
## Fresh-context requirement
This stress-test runs from a fresh pair of eyes, and dispatches to a fresh-context sub-agent in two cases:
- **Plan-review mode**. If the plan under review was produced in THIS context/session, the producing context shares the assumptions that created the plan's blind spots and drifts toward approving its own work; dispatch the stress-test to a fresh-context sub-agent. When you were invoked on an artifact this context did not author (a file, a plan from another session, a diff), you are already the fresh pair of eyes. Proceed directly.
- **`incumbent` mode**. Always dispatch. The incumbent lives in the current codebase, so any read of it you already hold is a digest; a first-hand exploration is what forms an independent view. The sub-agent invokes `/discovery:explore` via the Skill tool (if installed, else explores directly) on the incumbent itself (Alternatives Sweep, Step 1).
In both cases the dispatch prompt carries only WHAT to investigate: the plan artifact, or the incumbent's identity and where it lives, never your conclusions about it. "Here is the target; go look yourself," not "here is what I found; confirm it." A sub-agent handed the parent's verdict inherits the parent's blind spot. Where the verdict is high-stakes and correlated blind spots are the risk, prefer a cross-vendor advisor for that fresh pair of eyes **when one is installed and set up**, for example the OpenAI Codex plugin, when its documented surface can take this artifact, invoked per its own docs, with the fresh-context same-vendor sub-agent as the stated fallback, never a route to a command that may not resolve (per `docs/PLUGIN-PHILOSOPHY.md` "Fresh-eyes checkpoints" in the marketplace repository).
## When to Use
**Proactively (autonomous invocation):**
- Before exiting plan mode on plans involving infrastructure, hooks, CI/CD, build config, or cross-cutting changes
- Before presenting architecture decisions that affect multiple projects
- Before proposing new conventions or enforcement mechanisms
- When a plan has 3+ implementation steps and touches mechanisms with undocumented behavior
**On request (user invocation):**
- `/planning:devils-advocate`. Review the plan currently being discussed in conversation
- `/planning:devils-advocate <file-path>`. Review a plan from a specific file
- `/planning:devils-advocate <inline text>`. Review the provided text directly
- `/planning:devils-advocate incumbent <target>`. Stress-test the incumbent tool/approach against alternatives (target empty ⇒ take it from conversation context)
- `/planning:devils-advocate deep incumbent <target>`. Same, forcing the heaviest research tier; the depth token (`deep`/`shallow`) is recognized only as the leading token, so `incumbent deep <target>` would fold "deep" into the target text
## Input Resolution
Parse `$ARGUMENTS` in this order:
1. **Depth token (optional).** If the first token is `deep` or `shallow`, consume it as the research-depth override (see "Research depth" below) and continue with the rest.
2. **Mode.** If the next token is `incumbent`, enter **`incumbent` mode** (incumbent-target); the remainder identifies the incumbent. A tool, library, approach, or module. Or is empty to take the incumbent from the current conversation. The keyword selects the mode only as this leading token; a plan that merely contains the word elsewhere is not a mode switch.
3. **Plan-review mode (default).** Otherwise: if the remainder is a file path (ends in `.md`, `.txt`, or `.json`), read that file; if it is inline text, use it as the plan; if empty, work from the current conversation context. The most recent plan, proposal, or design being discussed.
To review an inline plan whose text legitimately *begins* with `incumbent`, `deep`, or `shallow`, pass it as a file path so the leading word is not consumed as a mode or depth token.
### Research depth
Both modes default to **risk-scaled** research (Round 2's high/medium/low scale). A leading `deep` token forces the heaviest tier. Route load-bearing evaluations to `/discovery:research-deep`, invoked via the Skill tool, if installed; `shallow` restricts to codebase read/grep with no external research. Depth is a per-invocation choice, not a stored setting.
## Analysis Process
**Mode branch.** In plan-review mode, run Rounds 1–4 below. In `incumbent` mode, run the **Alternatives Sweep** instead (it reuses Round 2's evidence discipline and Round 3's mitigation / residual-risk format); Rounds 1–4 do not apply.
Run the rounds below (up to 4). Stop early if a round produces no new critical or high findings. Except Round 4, which runs whenever its multi-layer / multi-context trigger matches, regardless of how quiet Rounds 1-3 were.
### Round 1: Assumption Identification
Extract every assumption in the plan. Explicit and implicit. Present as a table:
| # | Assumption | Explicit? | Category | Risk if wrong |
|---|-----------|-----------|----------|---------------|
| 1 | `transcript_path` is in all hook stdin | Yes | API contract | Hooks can't track state |
| 2 | Temp files survive session duration | Implicit | Platform | State lost mid-session |
**Categories**: API contract, platform behavior, performance, security, extensibility, dependency stability, cross-platform, convention compliance
### Round 2: Evidence Check
For each assumption, verify against evidence. This is the research-heavy round.
**Research depth. Match to risk:**
- **High risk**: deep multi-source research. Official docs, issue trackers, and web search (use the strongest research capability available: invoke `/discovery:research` via the Skill tool if installed, a research MCP server, or WebSearch/WebFetch)
- **Medium risk**: a targeted search or single authoritative doc fetch
- **Low risk**: codebase grep/read (no external research needed)
Check for:
- **Known bugs** affecting the plan's mechanisms (search the relevant issue trackers)
- **Undocumented behavior** that the plan relies on
- **Version-specific changes** that may have broken assumptions since training cutoff
- **Cross-platform issues** (Windows/Git Bash, macOS, Linux)
- **Conflicts with the consuming project's conventions** (check its `CLAUDE.md` and project rules)
Present findings:
| # | Assumption | Verified? | Evidence | Impact |
|---|-----------|-----------|----------|--------|
| 1 | `transcript_path` in stdin | YES | Official docs confirm base field | None. Assumption holds |
| 2 | `if` field fires under skip-perms | NO | silently no-ops (known issue) | CRITICAL. Use explicit guards |
**Incumbency-only support fails this check.** An assumption is unverified by definition when its *only* backing is that the status quo already relies on the thing, "We already use X", with no requirement, benchmark, or doc behind the original choice (per Purpose: incumbency is evidence of what is, never proof it still fits). It flows to a Round 3 finding whose **Mitigation names the follow-up**: `/planning:devils-advocate incumbent <target>`, the Alternatives Sweep on that incumbent. Suggest it; never auto-run it. Scope stays one mode per invocation. An assumption *also* backed by a requirement, benchmark, or doc is verified on that evidence and does not trigger this.
### Round 3: Failure Scenarios and Mitigations
For each unverified or partially verified assumption, propose:
1. **Failure scenario**: What specifically breaks and how
2. **Blast radius**: What else is affected
3. **Mitigation**: How to design around it
4. **Graceful degradation**: What happens if the mitigation itself fails
Also check for concerns the plan doesn't address:
- **Extensibility**: What happens when new tools/languages/ecosystems are added?
- **Drift detection**: How will we know when this goes stale?
- **Configuration**: Are there hardcoded values that should be externalizable?
- **Testability**: How do we verify this works? Smoke tests? Integration tests?
- **Maintenance**: Who updates this when the ecosystem changes?
- **Encapsulation**: Is this in the right place? Could it be better organized?
### Round 4: Operational Gotchas / Failure-Mode Pitfalls
Rounds 1-3 are assumption-driven. Round 4 sweeps for OPERATIONAL traps the assumption-driven rounds miss. Runtime failure modes, edge-case semantics, multi-source interactions, silent fallbacks, divergent contexts.
For each category, ask: *"What's the worst-case scenario? Does the plan handle it or admit it as a known limitation?"*
| Category | Probe questions |
|---|---|
| **Edge-case semantics** | Empty input → no-op or "set to empty"? Missing file → fallback or error? Partial state → graceful or corrupt? Default-of-default when nothing's defined? |
| **Multi-source interactions** | Composition order? Diamond inheritance (A→B and A→C, then merge)? Conflicting providers? Layer-skip semantics when one layer fully replaces? |
| **Silent failure modes** | Parse fail → silent fallback to default? Invalid input → coerced or rejected? Errors swallowed? Hooks silently no-op on platform mismatch? |
| **Divergent contexts** | CI vs local? Cloud (gitignored files invisible) vs interactive? Windows/Git Bash vs Unix? Per-user vs per-machine state? Worktree vs main? |
| **Mutable shared state** | Cache invalidation triggers? Race conditions on concurrent sessions? Mid-edit reload behavior? File-locking semantics? |
| **Lifecycle / migration** | Rename mechanism? Removal-deprecation pass? Stale references after partial upgrade? What happens if old + new coexist? |
| **Bypass / circumvent** | Can someone read past the contract? Skip the merger? Ignore the manifest? What if the contract isn't honored. Silent miscompute or visible error? |
| **Path / resource resolution** | Relative paths interpreted where? Glob ambiguity? Plugin-cache boundary? Worktree shared state? Cross-platform path-separator handling? |
| **Schema drift** | Type changes between versions/layers? Contract changes? Version mismatches across producer/consumer? Type-coercion vs error policy? |
| **Ordering / sequencing** | Multiple valid orderings. Which wins? Documented? Reproducible across runs? Stable under concurrent input? |
Findings use the same severity / failure-scenario / mitigation / residual-risk format as Round 3.
**When to run Round 4:** plans involving multi-layer composition (config layering, plugin extension points, hook chains, override mechanisms), or any plan whose blast radius spans multiple contexts (local + CI + cloud). Skip Round 4 for single-context single-mechanism plans where Round 3 already covers the failure surface.
### Alternatives Sweep (`incumbent` mode)
Runs in place of Rounds 1–4 when `incumbent` mode is selected. It inherits the evidence mandate. Every finding is backed by a specific bug number, doc reference, code path, or concrete logical argument, never training-data recall.
1. **Explore the incumbent first-hand.** Dispatch the fresh sub-agent (see Fresh-context requirement) to invoke `/discovery:explore` via the Skill tool on the incumbent. What it is, where it is used, what it is coupled to, and any recorded reason it was chosen. The sub-agent forms its own read; it receives the incumbent's identity, never a parent conclusion about it.
2. **Name the actual problem.** State what the incumbent solves, the real requirements, present and plausible-future, before any alternative is on the table. Do not let the incumbent's shape define the problem.
3. **Survey the field.** Judge candidate alternatives against those requirements, walking the preference ladder. **native** (what the platform / language / framework already provides) > **official / authoritative** > **vetted third-party** (well-maintained, known, safe, secure). Where an earlier rung wins when it covers the requirements. Price each dependency's coupling: abandonment, a pricing pivot, a license change, security posture, exit cost. The full selection discipline lives in `/discipline:pick-for-the-problem` (apply it if installed); this baseline is enough to run the sweep without it. The seam between the two: that corrector is the light in-session nudge when selection drift surfaces mid-conversation; this sweep is the formal, dispatched, verdict-producing review to run before a plan commits to the incumbent.
4. **"Is there a better way now?". Evidence, not memory.** The research-heavy step; scale to risk (Round 2) or the depth token. Route load-bearing evaluations to `/discovery:research` (or `/discovery:research-deep`), invoked via the Skill tool, if installed. A tool's maintenance, security, licensing, and native-alternative landscape drift constantly since the training cutoff. Look especially for what changed since the incumbent was chosen: a new native capability, a shifted dependency, a since-published better-fit option.
5. **Verdict per candidate.** One of:
- **KEEP**. Re-derived from the problem and still the best fit; the duty is to re-derive, not to switch for switching's sake. An incumbent that audits clean is a clean finding. Say so.
- **MIGRATE**. A better-fit alternative exists; state the coupling price and the migration cost, not just the upside.
- **RESEARCH**. The evaluation is load-bearing and unverified; route it (step 4), never a verdict from recall.
Findings use the same severity / failure-scenario / mitigation / residual-risk format as Round 3.
**Scope guard.** This is pre-implementation decision support. Should the plan adopt or keep X versus an alternative. Not a post-hoc audit of a running system's health or correctness.
## Output Format
**In `incumbent` mode**, the per-candidate **KEEP / MIGRATE / RESEARCH verdict** is the headline. The Risk Summary and finding bullets below still apply to the risks the sweep surfaces, with two field re-readings: **Assumption** becomes the claim under test (e.g. "the incumbent still fits" or "alternative X is better-maintained"), and **Failure scenario** becomes the cost of the wrong call (keeping a worse-fit incumbent, or paying an unpriced migration).
### Risk Summary
| Severity | Count | Action |
|----------|-------|--------|
| CRITICAL | N | Must fix before proceeding |
| HIGH | N | Should fix; plan is fragile without |
| MEDIUM | N | Consider fixing; acceptable risk if documented |
| LOW | N | Note for future; no action needed now |
### Findings (by severity)
For each finding:
**[SEVERITY] Finding title**
- **Assumption**: What was assumed
- **Evidence**: What was found (with source. Bug number, doc URL, code path)
- **Failure scenario**: What breaks
- **Mitigation**: How to fix
- **Residual risk**: What remains after mitigation
### Revised Plan Recommendations
If critical or high findings exist, present specific plan modifications:
- What to change and why
- What to add (new steps, new checks, new graceful degradation)
- What to remove (mechanisms that don't work)
In `incumbent` mode, this is the KEEP / MIGRATE / RESEARCH verdict with its coupling price and, for a MIGRATE, the migration cost. Not just the upside.
### Suggested Next Steps
Based on findings, suggest relevant follow-up actions:
- Verifying the changes end-to-end (`/verification:confirm` if installed) if code changes were involved
- Targeted research rounds (`/discovery:research` if installed, or the strongest research capability available) if critical assumptions remain unverified
- Running the Alternatives Sweep on any incumbent a Round 2 finding flagged as supported only by incumbency. The finding's Mitigation already names the invocation
- Filing deferred research or monitoring items in the project's work-item tracker (`/work-items:track` if installed)
## What This Skill Does NOT Do
- **Does not block execution**. It advises, the user decides
- **Does not replace code review**. It reviews plans, not code (use your code-review tooling for code)
- **Does not do exhaustive security analysis**. It finds design-level risks, not vulnerability scanning (use dedicated security tools for that)
- **Does not generate generic warnings**. Every finding must have specific evidence. "This might break" without a bug number, doc reference, or logical argument is not acceptable
- **Does not audit a running system's health**. `incumbent` mode is a pre-implementation keep-or-replace decision against alternatives, not a runtime performance / correctness audit of production
## Workflow position
Runs as the stress-test step between `/planning:plan`'s plan formulation and user approval: ... → `/planning:plan` → **stress-test (this skill)** → targeted research iteration if needed → user approval → execute.
For plans that don't warrant a full stress-test (single-file edits, simple config changes with well-understood behavior), prior research validation is sufficient. Use judgment. The trigger is complexity and blast radius, not every plan.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!