Home / All Skills / Workflow & Core Tools / adversarial-spec
Workflow & Core Tools · zscole/adversarial-spec

adversarial-spec

Iteratively refine a product spec by debating with multiple LLMs (GPT, Gemini, Grok, etc.) until all models agree. Use when user wants to write or refine a specification document using adversarial development.

L4 High-Privilege · Graded auth & full auditV1 Commit-PinnedExecute CommandNetwork AccessWrite FileDual-pass Audit
Author zscoleGitHub zscole/adversarial-spec ↗Stars 556License MIT(仓库根 LICENSE;GitHub API spdx=MIT;pyproject license = {text = "MIT"})Commit f90cf0c36c
Control levels describe skill capabilities and suggested control measures; they do not represent quality or safety certifications, nor do they dictate usability. Usage decisions rest entirely with users and administrators. Different agent hosts apply varying constraints; do not assume hosts provide automatic protection. Third-party skill copyrights belong to their original authors. Use at your own risk.

1How It Works & Mechanism

The core mechanism is not merely 'calling multiple models' but 'Claude actively participating in the ring': SKILL.md requires Claude to provide its own independent critique and synthesis adjudication alongside the opponent models' conclusions, clearly communicating this to the user.

skills/adversarial-spec/SKILL.md
**Important: Claude is an active participant in this debate, not just an orchestrator.** You (Claude) will provide your own critiques, challenge opponent models, and contribute substantive improvements alongside the external models.
Step 4 provides a fixed output template (--- Round N --- / Opponent Models / Claude's Critique / Synthesis), breaking down item-by-item which criticism came from whom, what Claude added on its own, and what it rejected, preventing multi-model review from devolving into a black box.

The actual execution layer is a built-in Python CLI (debate.py + 5 modules); the skill feeds documents to the script via stdin using fixed command lines, and the script uses litellm to call various providers in parallel, parsing `[AGREE]` / `[SPEC]` tags.

skills/adversarial-spec/SKILL.md
python3 "$(find ~/.claude -name debate.py -path '*adversarial-spec*' 2>/dev/null | head -1)" critique --models MODEL_LIST --doc-type TYPE <<'SPEC_EOF'
The script path is dynamically located under ~/.claude using find, indicating that the skill is installed into the user's home directory as a plugin; it is invoked via heredoc feeding stdin ('spec = sys.stdin.read().strip()' in debate.py).

Invocation channels fall into two categories: API key-based models use litellm as a unified egress; subscription-based models (ChatGPT/Google accounts) use local CLI child processes, passing documents via argv/stdin to codex / gemini.

skills/adversarial-spec/scripts/models.py
cmd = [ "codex", "exec", "--json", "--full-auto", "--skip-git-repo-check", "--model", actual_model, "-c", f'model_reasoning_effort="{reasoning_effort}"', ]
On the Gemini side, it executes 'gemini', '-m', actual_model, '-y' with the prompt passed via stdin (models.py call_gemini_cli_model). Availability checks reside in providers.py: CODEX_AVAILABLE = shutil.which("codex") is not None / GEMINI_CLI_AVAILABLE = shutil.which("gemini") is not None.

Convergence decisions rely on literal markers in model outputs rather than semantic evaluations: if any model fails to emit [AGREE], it proceeds to the next round; premature agreements in the first two rounds trigger an anti-laziness interrogation round via --press.

skills/adversarial-spec/SKILL.md
**Handling Early Agreement (Anti-Laziness Check):** If any model says `[AGREE]` within the first 2 rounds, be skeptical.
PRESS_PROMPT_TEMPLATE (prompts.py) requires the model to confirm it read the entire document, list at least 3 reviewed sections, explain why it agrees, and outline any residual concerns. The script side corresponds to the '--press' option; the maximum round limit is specified only in SKILL.md ('Maximum 10 rounds per cycle') and is not strictly enforced in code.

Long debates can be interrupted and rolled back: session states, per-round checkpoints, and common configurations are persisted separately to disk, isolating sessions from profiles.

skills/adversarial-spec/scripts/session.py
SESSIONS_DIR = Path.home() / ".config" / "adversarial-spec" / "sessions" CHECKPOINTS_DIR = Path.cwd() / ".adversarial-spec-checkpoints"
providers.py defines PROFILES_DIR = Path.home() / ".config" / "adversarial-spec" / "profiles" and GLOBAL_CONFIG_PATH = Path.home() / ".claude" / "adversarial-spec" / "config.json" (where the Bedrock toggle is stored). SKILL.md describes: 'Sessions are stored in `~/.config/adversarial-spec/sessions/`' and 'each round's spec is saved to `.adversarial-spec-checkpoints/`'.

An optional human-in-the-loop channel is available via a Telegram bot: it pushes a summary to the user after each round, polls for a reply within 60 seconds, and incorporates feedback into the next round; if no reply is received, it auto-continues.

skills/adversarial-spec/scripts/telegram_bot.py
TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"
Active when token != '' ('token = os.environ.get("TELEGRAM_BOT_TOKEN", "")'). SKILL.md states: 'After each round: Bot sends summary to Telegram / 60 seconds to reply with feedback (configurable via --poll-timeout) / Reply incorporated into next round / No reply = auto-continue'.

Enterprise alternative channel: switchable to AWS Bedrock to route all model invocations through the Bedrock prefix (for compliance/gateway scenarios), with configuration saved to config.json in the home directory.

skills/adversarial-spec/SKILL.md
**When Bedrock mode is enabled, ALL model calls route through Bedrock** - no direct API calls are made.
Code-side: models.py sets 'os.environ["AWS_REGION"] = bedrock_region' and 'if not model.startswith("bedrock/"): actual_model = f"bedrock/{model}"'; handle_bedrock_command in providers.py manages status/enable/disable/add-model/remove-model/alias, persisting settings in GLOBAL_CONFIG_PATH.

Final artifact delivery is performed by Claude (the host) rather than the script: the skill requires printing and writing the final document to spec-output.md in the current directory (or tech-spec-output.md if continuing from a PRD); the script itself does not produce this file.

skills/adversarial-spec/SKILL.md
1. Print the complete, polished document to terminal 2. Write it to `spec-output.md` in current directory
A grep for 'spec-output' across the entire scripts/ directory yields zero matches, corroborating that file writing is an action of the host Write tool (SKILL.md allowed-tools declares 'Bash, Read, Write, AskUserQuestion'), while the script only handles review, diffing, and export.

2Core Capabilities

01Multi-model parallel adversarial review (concurrently critiques across multiple providers in a single call, returning per-model critiques or [AGREE])
02Two document templates with corresponding critique criteria (structured checklists and 7-8 review criteria tailored for PRD and Technical Specification respectively)
03Interview mode: conducts a deep-dive requirement interview covering 8 major topics (AskUserQuestion) before entering the debate
04Focus mode (--focus): directs review focus toward security / scalability / performance / ux / reliability / cost
05Expert personas (--persona): security-engineer / oncall-engineer / junior-developer / qa-engineer / site-reliability / product-manager / data-engineer / mobile-developer / accessibility-specialist / legal-compliance, alongside support for custom strings
06Context injection (--context): passes existing API docs, DB schemas, or compliance requirements as attachments directly to review models
07Session persistence and resume capabilities (--session / --resume / sessions listing, plus rollback via per-round checkpoints)
08Round diff comparison and task export (diff --previous/--current; export-tasks with --json export for actionable items ready for issue trackers)
09Cost observability: tracks token usage and estimates costs based on model pricing schedules, outputting to terminal summaries, JSON, and Telegram notifications

3External Dependencies

KindDependency / Endpoint
packagelitellm
api多家 LLM 供应商 API(经 litellm 统一出口)
clicodex(OpenAI Codex CLI,走 ChatGPT 订阅)
cligemini(Google Gemini CLI,走 Google 账号)
apiAWS Bedrock(可选企业通道,全部调用可改走 bedrock/ 前缀)
networkTelegram Bot API(可选人工在环)
package开发依赖(pytest/pytest-cov/ruff/mypy/pre-commit)

4Recommended Governance & Evidence

Suggested Controls for Safe Operation
For Agent Runtime
Graded/per-use authorization, sandbox recommended
For Administrators
Approval workflow, rollback support, full audit
Evidence & Triggers (File Paths & Excerpts)
  • scripts/: Executes local scripts or commands: python3 <…>/debate.py critique|diff|export-tasks|send-final|providers|focus
  • 网络端点: Declares external network access: litellm → official vendor APIs (OpenAI / Anthropic / Google / xAI / Mistral / Groq / O
  • 本地工作目录: File I/O and artifact output: ~/.claude/adversarial-spec/config.json (bedrock enable/disable/add-model/ali
Audit Notes: Based on standard categorization: This skill explicitly accesses multiple environment variable credentials (LLM API keys, AWS credentials, Telegram tokens) and transmits full user documents externally to third-party models, falling under **'Involves credential/environment variable reading + third-party plugin/remote package dependencies'**; it also features a child-process execution surface (codex exec --full-auto, gemini -y, bundled debate.py/telegram_bot.py). Since outbound endpoints are expected (official APIs, official CLIs, Bedrock, Telegram Bot API) without TLS downgrades, bypasses, or obfuscated code, it is not flagged red. However, due to credential usage and human-in-the-loop channels, verify visible keys and document export boundaries prior to use (in enterprise environments, it is recommended to enable Bedrock mode directly or disable the Telegram path).

5Second-Pass Verification

  • [ok] 多模型调用确实存在(非纯提示词) — models.py import litellm + from litellm import completion,标准路径 'response = completion(**completion_kwargs)';providers.py CODEX_AVAILABLE/GEMINI_CLI_AVAILABLE 用 shutil.which 探测。
  • [ok] 订阅制模型走 CLI 子进程 — call_codex_model 构造 ['codex','exec','--json','--full-auto','--skip-git-repo-check','--model',…] 并 subprocess.run;call_gemini_cli_model 构造 ['gemini','-m',model,'-y'] 并把 prompt 经 input= 传入。
  • [ok] Telegram 端点与轮询 — telegram_bot.py 'TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"' + 'with urlopen(req, timeout=30)'(urllib,非 requests);poll_for_reply(timeout=60 默认) 与 cmd_notify 均存在。
  • [ok] Bedrock 模式确实可全量接管调用 — is_bedrock_enabled()/get_bedrock_config() 读 GLOBAL_CONFIG_PATH;models.py 在 bedrock 分支设置 AWS_REGION 并给 model 加 'bedrock/' 前缀;handle_bedrock_command 支持 status/enable/disable/add-model/remove-model/alias。
  • [discrepancy] 『Maximum 10 rounds』是否由代码强制 — SKILL.md 写 'Maximum 10 rounds per cycle (ask user to continue if reached)',但对 debate.py 全文检索无任何轮数上限常量/参数(--round 只是当前轮号,--rounds 只用于 send-final 汇报)。结论:轮数上限是提示词纪律,代码不设护栏,已在 how_it_works 第 4 条与 risks 中如实标注。
  • [discrepancy] 『Write it to spec-output.md』的归属 — 第一遍曾按『脚本写文件』记录;第二遍在 scripts/ 全目录检索 'spec-output' 零命中,确认该写入由宿主 Write 工具完成(SKILL.md allowed-tools: Bash, Read, Write, AskUserQuestion)。已改写为『成品交付由 Claude 完成』并据此调整 file_writes。
  • [discrepancy] Python 版本要求一致性 — SKILL.md Requirements 写 'Python 3.10+ with `litellm` package installed',而 pyproject.toml 写 requires-python = ">=3.9" 且 ruff target-version = "py39"、mypy python_version = "3.10"。属文档与打包元数据的轻微不一致(不影响功能判定)。
  • [ok] 成本追踪是否真有实现(非仅文档) — providers.py MODEL_COSTS 价目表 + DEFAULT_COST;debate.py 'Cost: ${cost_tracker.total_cost:.4f}' 与 JSON 输出 'cost': {total, input_tokens, output_tokens, by_model}。

6Verdict & Scenarios

  • Replaces 'single-model monologue' with structured adversarial review: parallel multi-model critique + host model's explicit verdict + per-round Synthesis accounting (who was accepted, what Claude added, what was rejected).
  • Convergence does not rely on superficial model consent: early agreements are strictly challenged via --press (requiring section citations, justification, and residual concerns), while --preserve-intent requires quoting original text and justifying hazards before deletion, resisting flattening consensus.
  • Engineering implementation far exceeds comparable solutions: 3300+ lines of script, 4300+ lines of tests (including mutation testing setup), ruff/mypy/pre-commit fully configured, and a CLI covering session recovery, diffing, task export, and cost metrics.
  • Three-channel provider abstraction turns debate model selection into a flexible choice: API keys, subscription CLIs, and enterprise Bedrock share a unified interface, probing channel availability before listing candidate models.
  • A practical human-in-the-loop channel: Telegram pushes round summaries and polls for 60s to incorporate feedback into subsequent rounds, freeing users from constantly watching the terminal during lengthy debates.
  • Best for: Best for: Engineering and product teams needing to author PRDs or technical specs and wanting rigorous, cross-model adversarial scrutiny from diverse vendors; individual developers with API keys or codex/gemini subscriptions willing to submit documents to respective providers; teams requiring structured spec reviews with an audit trail (per-round checkpoints, diffs, cost summaries); enterprise compliance contexts that can route through Bedrock.
    Not for: Not suitable for: Scenarios where documents contain sensitive/confidential information that cannot be transmitted externally and self-hosted/Bedrock channels cannot be used; users expecting the skill to automatically verify the factual correctness of a spec (it aggregates critiques, not factual validation); users unwilling to pay multi-model inference fees or manage multiple API keys; environments restricting agent execution of local codex/gemini CLIs (subprocess scope tied to subscription accounts); scenarios requiring quick drafts without adversarial review (the debate loop noticeably extends delivery time).
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload adversarial-spec.tar.gz
    sha256: 89a0a6e57cca0f6a…
    Option B · Copy Guide for Agent
    install.json
    Agents automatically download and verify mirrors from this JSON guide.
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit f90cf0c36c.