adversarial-review
対抗的AIによるコード・プラン審査。Codex がレビューを行い、Claude が修正を実施し、承認されるまでの反復ループを自動で実行します。プラン・コード・コード対プランの各モードを自動判定します。
description の原文を見る
Adversarial AI code/plan review. Codex reviews, Claude fixes, iterative loop until approved. Auto-detects plan/code/code-vs-plan mode.
SKILL.md 本文
敵対的コードレビュー
プラットフォーム: Claude Code のみ。このスキルは Claude ↔ Codex インタラクションを調整します。Claude が実行者、Codex が外部レビュアーです。Codex CLI 自体からこのスキルを実行すると、再帰ループが発生します — Codex が自分自身を起動しようとします。あなたが Codex の場合 — このスキルを実行しないでください。直接レビューを実施してください。
現在の作業を敵対的レビューのため外部 AI モデル(デフォルトは OpenAI Codex)に送信します。レビュー対象を自動検出します:プラン または コード。Claude はレビュアーのフィードバックに基づいて問題を修正し、承認されるまで再提出します。最大 5 ラウンド。
実行時機
/adversarial-review— レビュー対象を自動検出/adversarial-review plan— プランレビューを強制実行/adversarial-review code— コードレビューを強制実行/adversarial-review <file-path>— 特定ファイルをレビュー(引数に/または.を含む)- 推論をオーバーライド:
/adversarial-review xhighまたは/adversarial-review medium(オプション:medium,high,xhigh) - モデルをオーバーライド:
/adversarial-review model:gpt-5.3-codex(引数にmodel:プレフィックス付き)
手順
プレースホルダ: 以下の手順内の
${REVIEW_ID}、${ATTEMPT_ID}、${CODEX_SESSION_ID}、${REPO_ROOT}、${BASE_BRANCH}はテンプレートプレースホルダであり、シェル変数ではありません。実際の値を各ツール呼び出しに直接代入してください。特に:
${REPO_ROOT}は常に Step 2 でキャプチャされた絶対パスであり、$(pwd)で置換しないでください。${REVIEW_ID}はレビュー全体を通じて安定しており、ファイルパスに使用されます。${ATTEMPT_ID}は 起動ごと に生成された 6 桁のランダム整数です — 初期実行用、その実行の再試行用、Step 7 のすべての再開用、および新規実行フォールバック用に新しい値が生成されます。結合マーカ${REVIEW_ID}-${ATTEMPT_ID}はプロンプト(HTML コメント)に埋め込まれるため、ファイルシステムセッション ID フォールバックはこの起動のロールアウトを正確に識別できます。前の起動の ATTEMPT_ID を再利用しないでください — 複数のロールアウトがマッチして、サイレントセッションドリフトが再導入されます。
Step 1: レビューモードを決定する
何をレビューするかを決定します。優先順位順でチェック:
1. 明示的な引数 (plan、code、ファイルパス) → それを使用します。
planの場合 → すべての git チェックをスキップして Step 2 に進みます (REVIEW_ID のみ)。
2. Claude Code プランモード — コンテキストにシステムメッセージ「Plan mode is active」が含まれている場合 → モード = plan、git をスキップします。プランモードではコードが編集されないため、コード/コード対プランは不可能です。
3. 自動検出 (明示的な引数がない、プランモードにない):
- コード変更をチェック (空でない出力はエラーが存在することを意味します):
git diff --name-only— ステージングされていないgit diff --cached --name-only— ステージングされているgit diff --name-only ${BASE_BRANCH}...HEAD— ブランチコミット
- 現在の会話コンテキストにプランが存在するかチェック (プランモード、タスク、またはディスカッション)。
| コード変更あり? | コンテキストにプランあり? | モード |
|---|---|---|
| いいえ | はい | plan — プランをレビュー |
| はい | はい | code-vs-plan — プランに対する実装をレビュー |
| はい | いいえ | code — コード変更をレビュー |
| いいえ | いいえ | ユーザーに何をレビューするか尋ねる |
Step 2: セッション ID を生成、REPO_ROOT をキャプチャ、ベースブランチを決定
REVIEW_ID: 自分で生成、形式 {unix_timestamp}-{random_8digit_number}。
例: 1711872000-48217593。bash を使用しないでください — 値を以下の手順のコマンドに直接代入してください。8 桁のランダム数値は衝突をほぼ無視できる程度にします (同一秒での呼び出しあたり 10^8 分の 1)。
REPO_ROOT をキャプチャ:
git rev-parse --show-toplevel
- 終了 0、空でない出力 → 絶対パス。リテラルとして
REPO_ROOTとして保存(テンプレートプレースホルダ — codex コマンドにそのまま代入;どこでも$(pwd)を使用しないでください)。 - 終了 128 (ベアリポジトリ、またはワークツリー内ではない) → ユーザーに告げる:
Cannot run adversarial review — current directory is not inside a git working tree.スキルを中止します。 - パスに単一引用符、二重引用符、
$、バックティック、改行を含む → ユーザーに告げる:REPO_ROOT path contains shell-special characters; cannot safely construct codex commands.中止。
サブモジュール警告: REPO_ROOT をキャプチャした後、実行:
git rev-parse --show-superproject-working-tree
空でない場合、ユーザーは git サブモジュール内にいます。ユーザーに告げる: You are inside a submodule. The review will be scoped to this submodule (${REPO_ROOT}), not the parent repo. If you meant to review the parent, invoke from there. 続行 — これは警告であり、中止ではありません。
ベースブランチを決定 (コード と コード対プラン モードのみ):
plan モード — ベースブランチ検出をスキップ、Step 3 に進みます。
他のモード、リポジトリのベースブランチを決定:
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'
コマンドが空を返す場合 (リモートHEADが設定されていない)、フォールバックを使用:
git rev-parse --verify main 2>/dev/null && echo main || echo master
結果を BASE_BRANCH として保存 — 以下の git diff ${BASE_BRANCH}...HEAD で使用します。
Step 3: レビュー資料を準備
プランレビュー:
- プランが既にファイルとして存在する場合 (プロジェクト内、プランモードのプランファイル、メモリ、またはリポジトリ内のどこか) — パスを直接使用します。コピーしないでください。Claude Code プランモードではプランは常にファイルです。
- プランが会話コンテキストにのみ存在する場合 (プランモード外) — Write ツール を使用して
/tmp/codex-plan-${REVIEW_ID}.mdに書き込みます。 - 常にプランファイルパスをユーザーに表示 して IDE で開けるようにしてください:
Plan for review: <file-path>
コードレビュー:
変更されたファイルのリストを収集:
git diff --name-only— ステージングされていない変更git diff --cached --name-only— ステージングされた変更
ステージングされていない + ステージングされた (一意のパス) をマージ。両方が空の場合:
git diff --name-only ${BASE_BRANCH}...HEAD— ブランチコミット (フォールバック)
ブランチ差分は、ローカル変更がない場合にのみ使用されます — そうでなければコンテキストが肥大化します。
ブランチ差分では、コマンド git diff ${BASE_BRANCH}...HEAD (完全な diff) をプロンプトに含めます。
レビュアーはリポジトリにアクセスでき、完全な diff とファイルを自分で読み込みます。 プロンプト (Step 4) では、ファイルリストとどの git diff コマンドを実行するかを渡します。
多くのファイル (> 50): 結合リストが 50 パスを超える場合、 ファイルリストなしで git コマンドのみを渡します — レビュアーがそれを判断します。
すべてのソースが空の場合 — レビューするコード変更がない場合、ユーザーに通知します。
コード対プランレビュー: プランパスを準備して、変更されたファイルのリストを収集 (上記の通り)。
Step 4: プロンプト本文を構築、ランナーサブエージェントをディスパッチ
メインスレッドはプロンプト本文を構成します (セッションマーカーなし — サブエージェントが追加)。レビューモードに基づいて以下から正しいテンプレートを選択します。
プランレビューのプロンプト本文:
<role>
あなたは実装計画の上級敵対的レビュアーです。
あなたの仕事は計画への信頼を破壊することです。検証ではありません。
</role>
<operating_stance>
懐疑的がデフォルト。証拠がそれ以外を示すまで、計画にはギャップがあると仮定します。
良い意図や可能性のあるフォローアップ作業に対してクレジットを与えないでください。
何かが幸せなパスでのみ機能する場合、それを実際の弱点として扱います。
</operating_stance>
<task>
<plan-path> の実装計画をレビューしてください。
</task>
<attack_surface>
各エリアをチェック。該当しない場合はスキップ:
- 実現可能性 — このアプローチはコードベースと制約を考慮して実際に機能するでしょうか?
- 欠落ステップ — 何が忘れられているか、仮定されているが記載されていないか?
- リスク領域 — 実装中に何が起こる可能性がありますか? データ損失? ダウンタイム?
- シーケンス — ステップは正しい順序ですか? 隠れた依存関係はありますか?
- 代替案 — より単純またはより堅牢なアプローチはありますか?
- ロールバック — 失敗した場合、これを安全に復旧できますか?
- セキュリティ — 認証、データ露出、インジェクション、安全でない操作
</attack_surface>
<finding_bar>
各検出結果は以下に答える必要があります:
1. 何が起こる可能性がありますか? (具体的なシナリオ、仮説ではなく)
2. なぜこの計画は脆弱ですか? (特定のセクションを引用)
3. 影響 — 何が壊れて、どの程度深刻ですか?
4. 推奨 — 計画への特定の変更
</finding_bar>
<scope_exclusions>
以下についてはコメントしないでください:フォーマット、言葉遣いのスタイル、具体的なトリガーシナリオのない投機的な問題。
</scope_exclusions>
<calibration>
複数の弱い検出結果より 1 つの強い検出結果を優先します。
計画が堅実な場合、はっきりと述べてください — 誤検知は信頼を損ないます。
</calibration>
<output_format>
セクションに markdown ヘッダーを使用:概要、検出結果、判定。
概要:1 段落 — この計画が何をするか、および全体的な評価。
検出結果:検出結果ごとに、[severity: critical|high|medium] とタイトルのサブヘッダーを使用。
検出結果ごとにこれらのフィールドを含めます:
- **セクション:** 計画のどの部分
- **何が起こる可能性がありますか:** ...
- **なぜ脆弱か:** ...
- **影響:** ...
- **推奨:** ...
検出結果がない場合:「操作可能な検出結果なし」。
判定ルール:検出結果がない場合、または低度の場合は承認;高度/重大な場合は修正。
正確に 1 つを選択します。応答の最後の行は以下のいずれかです:
VERDICT: APPROVED
VERDICT: REVISE
</output_format>
コードレビューのプロンプト本文 (≤ 50 ファイル):
<role>
あなたは上級敵対的コードレビュアーです。
あなたの仕事はコード変更への信頼を破壊することです。検証ではありません。
</role>
<operating_stance>
懐疑的がデフォルト。証拠がそれ以外を示すまで、コード変更は微妙な、高コストの、
またはユーザーに見える方法で失敗する可能性があると仮定します。
良い意図、部分的な修正、または可能性のあるフォローアップ作業に対してクレジットを与えないでください。
何かが幸せなパスでのみ機能する場合、それを実際の弱点として扱います。
</operating_stance>
<task>
このリポジトリ内のコード変更をレビューします。変更されたファイル:
<file list from --name-only>
変更は以下を含みます:<unstaged changes / staged changes / unstaged + staged changes / branch changes vs ${BASE_BRANCH}>。
<git diff commands> を実行して完全な diff を確認します。
</task>
<attack_surface>
各エリアをチェック。このコード変更に適用されない場合はスキップ:
- 認証と権限:バイパス、権限昇格、欠落チェック
- データ整合性:喪失、破損、部分的な書き込み、制約違反
- レース条件:TOCTOU、同時アクセス、デッドロック
- ロールバック安全性:このコード変更を安全に復旧できますか?
- スキーマドリフト:マイグレーション、下位互換性、データフォーマット変更
- エラーハンドリング:無視されたエラー、欠落再試行、カスケード障害
- 観測可能性:オペレータはこれが壊れた時に知ることができますか?
</attack_surface>
<finding_bar>
各検出結果は以下に答える必要があります:
1. 何が起こる可能性がありますか? (具体的なシナリオ、仮説ではなく)
2. なぜこのコードは脆弱ですか? (特定のファイルと行を引用)
3. 影響 — 何が壊れて、どの程度深刻ですか? (データ損失 > ダウンタイム > 低下した UX)
4. 推奨 — コード参照を含む具体的な修正
</finding_bar>
<scope_exclusions>
以下についてはコメントしないでください:コードスタイル、フォーマット、命名規則、
具体的なトリガーシナリオのない投機的な問題、
正確性または安全性に無関係な「あると良い」改善。
</scope_exclusions>
<calibration>
複数の弱い検出結果より 1 つの強い検出結果を優先します。
重度:critical (データ損失/セキュリティ) > high (本番環境のバグ) > medium (エッジケース)。
コード変更が堅実な場合、はっきりと述べてください — 誤検知は信頼を損ないます。
</calibration>
<output_format>
セクションに markdown ヘッダーを使用:概要、検出結果、判定。
概要:1 段落 — このコード変更が何をするか、および全体的な評価。
検出結果:検出結果ごとに、[severity: critical|high|medium] とタイトルのサブヘッダーを使用。
検出結果ごとにこれらのフィールドを含めます:
- **ファイル:** path/to/file.ext lines N-M
- **何が起こる可能性がありますか:** ...
- **なぜ脆弱か:** ...
- **影響:** ...
- **推奨:** ...
検出結果がない場合:「操作可能な検出結果なし」。
判定ルール:検出結果がない場合、または低度の場合は承認;高度/重大な場合は修正。
正確に 1 つを選択します。応答の最後の行は以下のいずれかです:
VERDICT: APPROVED
VERDICT: REVISE
</output_format>
コードレビューのプロンプト本文 (> 50 ファイル):
≤ 50 ファイルと同じですが、<task> セクションを以下に置き換えます:
<task>
このリポジトリ内のコード変更をレビューします。
変更は以下を含みます:<unstaged changes / staged changes / ...>。
<git diff commands> を実行して、変更されたファイルと完全な diff を確認します。
</task>
コード対プランレビューのプロンプト本文:
コードレビュー (≤ 50 またはファイル数に応じた > 50 バージョント) と同じですが、以下の通り:
<task>はプランファイルを参照するように拡張:Review the code changes in this repo against the implementation plan in <plan-path>.<attack_surface>はこれら 3 項目を追加:- 完全性:実装はすべてのプランステップをカバーしていますか? - 偏差:コードがプランとどのように異なるか? 偏差は正当化されますか? - 欠落:計画から実装されていないことは何ですか?
テンプレートプレースホルダをディスク書き込み前に置換:
上記のインラインプロンプト本文にはテンプレートプレースホルダが含まれており、メインが Write する前に実際のキャプチャされた値で解決する必要があります。プレースホルダはモードごと:
| プレースホルダ | 値の出所 | 適用対象 |
|---|---|---|
${BASE_BRANCH} | Step 2 でキャプチャ (コード & コード対プランのみ) | コード、コード対プラン |
<plan-path> | Step 3 でキャプチャ | プラン、コード対プラン |
<file list from --name-only> | git diff --name-only + git diff --cached --name-only の結果(または Step 3 のブランチ差分) | コード、コード対プラン (≤50 ファイルのみ) |
<unstaged changes / staged changes / ...> | Step 3 でどの diff コマンドにコンテンツがあったかから導出された人間が読める説明 | コード、コード対プラン |
<git diff commands> | Step 3 でメインが決定した正確なコマンド (例:git diff、git diff --cached、git diff ${BASE_BRANCH}...HEAD) | コード、コード対プラン |
${BASE_BRANCH} を最初に置換 (それは <unstaged changes / staged changes / ...> 内にネストしている)、次に、どの diff にコンテンツがあるかに基づいて外側の人間が読める説明を計算します。メインは置換された文字列を Write ツールに書き込みます — テンプレートプレースホルダは本文ファイルに残ってはいけません。
Step 1 で CODEX_MODEL / CODEX_REASONING のユーザーオーバーライドをキャプチャ:
スキルは /adversarial-review xhigh、/adversarial-review medium、/adversarial-review model:gpt-5.3-codex のようなオーバーライドをサポート。Step 1 でキャプチャ:
CODEX_MODEL— デフォルトgpt-5.4。^model:(.+)$にマッチする引数によってオーバーライド;キャプチャグループを使用。CODEX_REASONING— デフォルトhigh。low、medium、high、またはxhighと正確にマッチする引数によってオーバーライド。
これらはランナー YAML 入力ブロックで渡されます。
Write ツール経由でプロンプト本文をディスクに書き込み:
置換された本文テキスト(セッションマーカーなし — ランナーが追加)を含む /tmp/codex-body-${REVIEW_ID}.md に書き込みます。
プランモード注記: Write ツール経由で
/tmpに書き込むと、権限プロンプトが発生したり、プランモードを終了したりする可能性があります。これは既知の Claude Code の制限です。さらに、プランモード下でサブエージェントをディスパッチすると、制限を継承する可能性があります — 経験的な動作は DESIGN.md §12.7 に記載されています。
ランナー仕様パスを解決:
ランナー仕様は、スキルのインストールディレクトリ内の references/runner.md にあります。メインは Claude Code のスキル呼び出しヘッダーを独自のコンテキスト内から確実に内省することができません (独自のシステムプロンプトを読むツールはありません — 任何の試みは幻覚リスクです)。したがって、発見は具体的なファイルシステムチェックのみを使用し、この優先順位で:
- ユーザー スコープ インストール (主要):
~/.claude/skills/adversarial-review/references/runner.mdをチェック:
ls ~/.claude/skills/adversarial-review/references/runner.md 2>/dev/null
終了 0 の場合、拡張された絶対パスに RUNNER_SPEC_PATH を設定して続行します。
- プラグイン マーケットプレース インストール (二次): Claude Code のプラグインシステムは
~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills/adversarial-review/のようなパスでスキルをインストールします。Glob で検索:
ls ~/.claude/plugins/cache/*/*/*/skills/adversarial-review/references/runner.md 2>/dev/null | head -1
Glob が 1 つ以上のパスを返す場合、最初のものを取り、RUNNER_SPEC_PATH を設定します。
- 開発チェックアウト (三次): 上記のいずれでもない場合、
$(git rev-parse --show-toplevel)/references/runner.mdを試します:
REPO=$(git rev-parse --show-toplevel 2>/dev/null) && ls "$REPO/references/runner.md" 2>/dev/null
- 中止: どのパスも読み取り可能なファイルを生成しない場合、ユーザーに告げる:
Could not locate references/runner.md. Expected locations: (1) ~/.claude/skills/adversarial-review/references/runner.md, (2) ~/.claude/plugins/cache/*/*/*/skills/adversarial-review/references/runner.md, (3) $(git rev-parse --show-toplevel)/references/runner.md. Re-install the skill.スキルを中止。
解決された絶対パスを RUNNER_SPEC_PATH として保存。会話内の「この スキルの基本ディレクトリ:」行からパスを抽出しようとしないでください — その行はシステム インジェクション Claude で確実に読むことができません。
Agent ツール経由でランナーサブエージェントをディスパッチ:
メインで ${RUNNER_SPEC_PATH} を Read しないでください。 パスをサブエージェントに渡します;それが仕様自体を読みます。これにより runner.md (~12K) をメインのコンテキストから除外します — Read 結果 AND Agent プロンプトの重複。ラウンドあたり ~12K × レビューあたり最大 5 ラウンドを節約。
Agent ツール呼び出し:
subagent_type: "general-purpose"model: "sonnet"description: "Adversarial-review runner, round N"(N は現在のラウンド番号)prompt:短いブートストラップ指示 + YAML 入力ブロック (インラインランナー.md なし):
${RUNNER_SPEC_PATH} で完全な指示仕様を読み、この入力を使用してそこの手順に従ってください:
---
REVIEW_ID: 1711872000-48217593
REPO_ROOT: /home/dementev/sources/myproject
OPERATION: initial
CODEX_MODEL: gpt-5.4
CODEX_REASONING: high
PROMPT_BODY_PATH: /tmp/codex-body-1711872000-48217593.md
RESULT_PATH: /tmp/codex-runner-result-1711872000-48217593.json
---
実際に解決された ${RUNNER_SPEC_PATH} (絶対パス) と他のすべてのプレースホルダの実際の値を置換。RESULT_PATH は常にパターン /tmp/codex-runner-result-${REVIEW_ID}.json に従います。
Agent ツール呼び出しをバックグラウンドで実行しないでください。 サブエージェントが戻るまで待機します。(ランナー独自の codex exec も Step R3 に従い同期的です。)
サブエージェントの応答を解析 — 2 チャネルプロトコル:
正規表現 RUNNER_RESULT_AT:\s+(\S+) を適用 (アンカーなし — Agent ツール結果テキスト内のどこでもマッチし、markdown フェンスと前置きに寛容)。最初のマッチのキャプチャグループを結果ファイルパスとして取得します。
サブエージェントの応答で正規表現がマッチしない場合、決定論的パス /tmp/codex-runner-result-${REVIEW_ID}.json の Glob にフォールバック — REVIEW_ID は既にメインに既知です。Glob も何も返さない場合、infra_error と errors: "runner did not write result file at deterministic path and did not emit RUNNER_RESULT_AT line" として扱い、中止します。
解決されたパスのファイルを読みます。JSON として解析。result、verdict、review_file、codex_session_id、errors、user_warning、archived_stdout、archived_stderr を抽出。
user_warning が非 null の場合、Step 5 の冗長レビューメッセージ BEFORE に個別の短いユーザー表示メッセージとしてサーフェスします。 フォーマット:
⚠ <user_warning contents>
これを独自のターンで発行 — Step 5 ## Adversarial Review — Round N ヘッダーメッセージと結合しないでください (そのメッセージの本文はレビューの冗長なコンテンツのままである必要があり、他は何もありません)。警告を最初に発行してから Step 5 メッセージを発行します。これにより、pre-refactor §2.4.4「no-op refresh」診断と Step 5 冗長表示契約の両方が保持されます。
result に基づいてディスパッチ:
result 値 | メインスレッドアクション |
|---|---|
success | codex_session_id を保存 (§2.4.4 に従い null の場合は前の値を保持)。user_warning が設定されている場合はサーフェス。Step 5 に進みます。 |
timeout | 終了 — 再ディスパッチしないでください。 ランナーは既に内部で 2 回試行 (R4.1 + R5 再試行 = 2 × 10 分)。ユーザーに告げる:「レビュアーが 2 回の試行後にタイムアウト (合計 20 分)。」スキルを中止。ユーザーは /adversarial-review を再実行して新しいレビューを開始できます。 |
launch_failure | 終了 — 再ディスパッチしないでください。 ランナーは既に内部で 1 回再試行 (Step R5)。errors をユーザーに表示、スキルを中止。これにより、ラウンドあたりの総試行数不変量を 2 に保ちます (マッチ pre-refactor: 1 初期 + 1 再試行)。 |
infra_error | ユーザーに errors を表示 (インフラ:/tmp 書き込み不可、stderr ファイル欠落、RUNNER_RESULT_AT ライン欠落)。中止。 |
input_error | オーケストレーション内のバグ。ユーザーに errors を表示。中止。 |
ラウンド レベル試行不変量: ランナーディスパッチあたり正確に 1 つ。すべての失敗結果はメインで終了。ランナーは完全な再試行予算を所有 (ディスパッチあたり ≤2 回の試行、内部)、失敗タイプに関係なく。ラウンドあたりの総 codex 実行 ≤ 2。
重大 — メインスレッドは stdout/stderr/JSONL/ロールアウトファイルを内容で読む はしません。 それらはサブエージェント内に存在して消えます。メインが読みます:
RESULT_PATHのランナー結果 JSON、review_fileのレビューファイル、他は/tmp/codex-*から何もありません。アーカイブmv(再開失敗時) はランナーによって実施され、メインではありません — メインは/tmp/codex-stdout-*または/tmp/codex-stderr-*を任意の Bash argv で参照しません。
Step 5: レビューを読み、表示、判定をチェック
1. レビューファイルを読む。 /tmp/codex-review-${REVIEW_ID}.md を読みます。
2. セマンティック衛生チェック。 ファイルはすべてを渡す必要があります:
- 存在して空でない。
^VERDICT: (APPROVED|REVISE)$に正確にマッチするライン を含む。- 判定が
REVISEの場合 → ファイルは\[severity:\s*(critical|high|medium)にマッチするライン を最低 1 つ含む必要があります (つまり、少なくとも 1 つの構造化検出結果)。
いずれかのチェックが失敗する → これは起動失敗 (モデルが実行可能なレビューを生成しなかった):
- ユーザーに
/tmp/codex-stderr-${REVIEW_ID}.txtコンテンツ (存在する場合) AND 生のレビューファイルを表示します。 - Step 4 の 1 回の再試行を提供 (同じラウンドを再起動)。再試行はラウンドカウンターを消費しません — ラウンドカウンターは有効なレビューが生成されたときのみ進みます。
- 現在のラウンド の理由付けのみで再試行カウンターを追跡。カウンターはすべての新しいラウンドの開始時にリセット。
- 失敗した再試行後 → ハード中止スキル。Step 7 新規実行フォールバック (そのパスは再開失敗のラウンド 2+ 用で、前ラウンドコンテンツに依存) にルートしないでください。
3. レビューをユーザーに表示。これは必須でブロッキング。
1 行の
⚠ <warning>診断ではない次のユーザー表示メッセージは、以下のヘッダーで始まる必要があり、その後にファイルコンテンツが 冗長 に続きます。「レビューを受け取りました」、「レビュアーが述べた」という表現、要約ではなく — リテラルなファイルコンテンツ。レビューをコードフェンス内にラップしないでください (レビューは既に markdown であり、外側のフェンスは内側のフェンスで壊れます)。
レビューと同じメッセージで Edit、Write、または修正適用ツールを呼び出さないでください。レビュー出力はスタンドアロンのユーザー表示メッセージです。
メッセージ形式:
## Adversarial Review — Round N (mode: <plan|code|code-vs-plan>, model: gpt-5.4)
<verbatim contents of /tmp/codex-review-${REVIEW_ID}.md>
4. レビューメッセージが送信された後のみ — VERDICT ラインを解析してディスパッチ:
VERDICT: APPROVED→ Step 8 (完了)。VERDICT: REVISE→ Step 6 (修正)。- 最大ラウンド到達 (5 ラウンド) → Step 8 にマックスラウンドメモ付き。
Step 6: 修正を適用
前提条件ゲート (最初にチェック)。 Edit、Write、または他の修正適用ツールを呼び出す前に:THIS ラウンド で冗長レビューテキストを含むユーザー表示メッセージを既に送信したことを確認。短い
⚠ <user_warning>診断メッセージは カウント しません。していない場合 — 停止。Step 5 に戻ってレビューメッセージを今すぐ送信します。これは「ユーザーがレビューを見る」契約を保護する同じルール;リテラル読者はそれ以外の方法でそれをスリップ可能です。
レビュアーの検出結果に基づいて:
プランレビュー用: プランを修正 — 各検出結果に対処。プランファイル (または temp ファイル) を更新。ユーザーに表示:
### Fixes (Round N)
- [何が変更され、なぜか、検出結果あたり 1 つの項目]
コードレビュー用: コードを直接修正 — ファイルを編集、該当する場合はテストを実行。ユーザーに表示:
### Fixes (Round N)
- [何が修正され、なぜか、検出結果あたり 1 つの項目]
ユーザーの明示的な要件と矛盾する修正を スキップ — ユーザーに注記します。
Step 7: Codex に再提出 (ラウンド 2-5)
再開が主要パス。 トークンを節約し、セッションコンテキストを保持。再開自体が失敗した場合のみ、再開なしの新規 codex exec は 緊急フォールバック。
Step 7.1: 再開プロンプト本文をディスクに書き込み。
以下を含む /tmp/codex-resume-body-${REVIEW_ID}.md に書き込み:
フィードバックに基づいて修正しました。
変更内容:
[Step 6 からの修正リスト]
同じ敵対的スタンスで再レビュー。焦点:
1. 修正が報告された問題を実際に解決したかどうか
2. 修正によって導入された新しい問題
VERDICT: APPROVED または VERDICT: REVISE で終了
Step 6 からの修正リストを置換 (検出結果あたり 1 つの箇条書き)。セッションマーカーを含めないでください — サブエージェントが追加。
Step 7.2: 再開用ランナーサブエージェントをディスパッチ。
Step 4 と同じ Agent ツール呼び出し (bootstrap 指示と ${RUNNER_SPEC_PATH} + YAML 入力ブロック;サブエージェントが仕様自体を読む)。Step 4 で解決された RUNNER_SPEC_PATH を再利用 (再解決しない)。入力ブロック:
---
REVIEW_ID: <初期ラウンドと同じ>
REPO_ROOT: <同じ>
OPERATION: resume
CODEX_MODEL: <同じ>
CODEX_REASONING: <同じ>
PROMPT_BODY_PATH: /tmp/codex-resume-body-<REVIEW_ID>.md
RESULT_PATH: /tmp/codex-runner-result-<REVIEW_ID>.json
CODEX_SESSION_ID: <前のラウンドのランナー結果からの uuid>
---
Step 7.3: 2 チャネル結果を解析。
RUNNER_RESULT_AT: ラインを抽出 (Step 4 と同じ寛容正規表現 + Glob フォールバック)、JSON ファイルを読む、フィールドを抽出。user_warning が非 null の場合、その独自の ⚠ <user_warning> メッセージとして発行 BEFORE 他のアクション (冗長レビューを含む前) — Step 4 の user_warning ルールを参照。
result 値 | メインスレッドアクション |
|---|---|
success、判定 APPROVED | review_file を読む、Step 5 に進む (APPROVED で Step 8 にディスパッチ)。 |
success、判定 REVISE | 新しい codex_session_id を保存。サブエージェントが null を返した場合 (ゼロ検出再開) §2.4.4 に従い、前の id を保持 — user_warning は既にサーフェスされます。Step 5 に進む。 |
timeout | このラウンドで終了 — ランナーは既に 2 回試行。以下のフォールバックにルート。(新規実行は 5 ラウンドカウンターから新規ラウンド — 独自の ≤2 試行/ラウンド予算を適用。) ユーザー提供の再試行なし;それは複雑です。 |
launch_failure | このラウンドで終了 — ランナーは既に内部で 1 回再試行。フォールバックにルート (ランナーは既に stdout/stderr を -failed-resume.* にアーカイブ — archived_stdout / archived_stderr のパス)。 |
infra_error | ユーザーに errors を表示、中止。 |
ラウンド レベル試行不変量: 再開ラウンドあたりランナーディスパッチ正確に 1 つ。すべての失敗結果はフォールバックにルート (同じラウンド内での再ディスパッチなし)。フォールバックの新規実行ディスパッチは 5 ラウンドカウンターから新規ラウンドを消費し、独自の独立した 2 試行/ラウンド予算を持ちます。失敗タイプに関係なく、ラウンドあたりの総 codex 実行 ≤ 2 — pre-refactor マッチ;Round-2 検出 #1 クローズ。
Step 7.4: フォールバック チェーン — ランナーからの launch_failure または反復 timeout によってトリガー。
重度分類: 前のラウンドのレビューを解析 (Step 5.3 の冗長表示から会話履歴に保持) 最高 [severity: レベル。マッチ ゼロの場合は critical がデフォルト (形式ドリフト)。
インタラクティブモード (このセッション内でのユーザーメッセージが前にある):ユーザーに尋ねる:
再開失敗 — レビュアーの再レビューは使用可能な結果を生成しなかったし。
最後のラウンドの最高重度:<レベル>。
オプション:
(a) 完全な前ラウンド コンテキスト付きで新規 `codex exec` を実行 (高トークンコスト、新規セッション)
(b) レビュー終了 — 現在の検出結果を未検証として表示
非インタラクティブモード:
- 最大重度
criticalまたはhigh→ 新規実行自動。 - 最大重度
mediumのみ → Step 8 の未検証終了状態で。
新規実行ディスパッチ: 現在のモード用の元の Step 4 プロンプトに続く新規 PROMPT_BODY を構築し、セクション ## Previous review rounds (冗長ラウンド 1..N レビュー + 会話履歴からの修正) と ## Current state of the artifact。/tmp/codex-body-${REVIEW_ID}.md に書き込み (元の上書き)。
アーカイブ注記: フォールバックが launch_failure によってトリガーされた場合、ランナーは既に失敗再開 stdout/stderr を Step R5 中に -failed-resume.* パスにアーカイブ — メインは何も mv する必要がありません。反復 timeout によってトリガーされた場合、アーカイブは発生しなかった (2 つ目の codex 実行は有用な診断を生成しなかった);メインは直接続行できます。いずれにせよ、メインは /tmp/codex-stdout-* または /tmp/codex-stderr-* に決してタッチしません。
OPERATION=fresh-exec でランナーサブエージェントをディスパッチ (同じ入力スキーマ、再構築されたプロンプトを指す新規 PROMPT_BODY_PATH)。新規実行は 5 ラウンドカウンターから 1 ラウンドを消費。新しいレビューで Step 5 に戻ります。
Step 8: 最終結果
承認:
## Adversarial Review — Summary (mode: <mode>, model: gpt-5.4)
**Status:** Approved after N round(s)
[最終レビュー]
---
**レビュアーによってレビューおよび承認されました。決定を待っています。**
最大ラウンド到達:
## Adversarial Review — Summary (mode: <mode>, model: gpt-5.4)
**Status:** Maximum reached (5 rounds) — not fully approved
**Remaining findings:**
[未解決の問題]
---
**レビュアーはまだ検出結果があります。確認して続行方法を決定してください。**
未検証 (再開が失敗してオペレータが結論を選択した、または ヘッドレスで中度重度のみ):
## Adversarial Review — Summary (mode: <mode>, model: gpt-5.4)
**Status:** NOT VERIFIED — fixes applied, reviewer did not re-verify
**Last round's findings:**
[最後に成功したラウンドからの冗長検出結果]
**Applied fixes:**
[検出結果あたりの修正リスト]
---
**警告:これは承認ではありません。修正が適用されましたが、レビュアーによって検証されたことはありません。マージ前に手動レビューが必要です。**
Step 9: クリーンアップ
終了状態に条件付き:
| 終了状態 | クリーンアップ動作 |
|---|---|
| 承認 | すべての temp ファイルを削除 |
| 最大ラウンド到達 | すべての temp ファイルを削除 |
| 未検証 (フォールバック結論) | すべての temp ファイルを削除 |
| 中止 (起動失敗、リダイレクト失敗、インフラエラー) | 診断用にファイルを IN PLACE に残す |
Claude Code プランモード内: すべてのクリーンアップ (遅延を含む) をスキップ。rm は権限プロンプトをトリガーします。ファイルは次のプランモード外での呼び出しでクリーンアップされます。
プランモード外、クリーンアップ可能な終了状態:
rm -f /tmp/codex-plan-${REVIEW_ID}.md \
/tmp/codex-prompt-${REVIEW_ID}.md \
/tmp/codex-resume-prompt-${REVIEW_ID}.md \
/tmp/codex-review-${REVIEW_ID}.md \
/tmp/codex-stdout-${REVIEW_ID}.jsonl \
/tmp/codex-stderr-${REVIEW_ID}.txt \
/tmp/codex-stdout-${REVIEW_ID}-failed-resume.jsonl \
/tmp/codex-stderr-${REVIEW_ID}-failed-resume.txt \
/tmp/codex-body-${REVIEW_ID}.md \
/tmp/codex-runner-result-${REVIEW_ID}.json
ユーザーが rm を拒否 — エラーなしで続行。
レビュー前に存在していたプランファイルを削除しないでください (このスキルが作成した temp ファイルのみ)。中止パスで、古い temp ファイルが診断用に残り、再起動時に OS によってクリーンアップされるか、同じ REVIEW_ID を使用する次の呼び出しで上書きされます (衝突確率は ~10⁻⁸ 同一秒実行あたり)。
ルール
- Claude は 積極的に レビュアーのフィードバックに基づいて問題を修正します — これはメッセージ転送ではありません。
- レビュアー検出結果は 冗長に 表示されます — 言い換えない、短縮しない。Step 5「次のメッセージ」指示はブロッキング。
- コンテキストからレビューモードを自動検出;ユーザーの引数が優先。
- 明示的な
plan引数またはClaude Code プランモード:git チェックとベースブランチ検出をスキップ。 REPO_ROOTは Step 2 でキャプチャ され、すべてのランナーディスパッチに絶対リテラルとして渡されます。RUNNER_SPEC_PATHは Step 4 で解決 (レビューあたり 1 回) 優先順位:(1)~/.claude/skills/adversarial-review/references/runner.md(ユーザースコープインストール)、(2) Glob~/.claude/plugins/cache/**/skills/adversarial-review/references/runner.md最初のヒットを取得 (プラグインマーケットプレースインストール)、(3)$(git rev-parse --show-toplevel)/references/runner.md(開発チェックアウト)、(4) インストレーションエラーで中止。メインはClaude 独自のシステムプロンプト / スキル呼び出しヘッダー を読もうとしません — そのパスは幻覚プローンであり、明示的に禁止されています。- Codex-exec メカニクスはランナーサブエージェント (
references/runner.md) に住んでいます:ATTEMPT_ID 生成、プロンプト マーカー付きライティング (mtime 新鮮さ用に反復 Write 呼び出し — Bashtouchではなく、継承プランモードでゲートできます)、同期起動、厳密チェック、2 層セッション ID キャプチャ正のコンテンツバインド付き、ANY 失敗タイプ (launch_failure、timeout、stderr-infra) の 1 つの内部再試行、再開失敗時のアーカイブ mv。メインスレッドは codex stdout/stderr/ロールアウトファイルコンテンツを読むことはなく、独自の Bash argv でそれらのパスを参照しません。 - 2 チャネル結果プロトコル。 ランナーは構造化 JSON を
/tmp/codex-runner-result-${REVIEW_ID}.json(権限) と、その最終メッセージとして単一のRUNNER_RESULT_AT: <path>ラインに書き込みます。メインはパスを正規表現経由で抽出 (markdown フェンス / マイナーラッピングに寛容)、JSON を読み、生の JSON-in-message パーシング に依存しません。 - メインスレッドが読むのは:
RESULT_PATHのランナー結果 JSON とreview_fileのレビューファイル。メインはreferences/runner.mdを読む ではありません — ランナー仕様をサブエージェントにパス で渡されるため、それが自体を読みます。他の/tmp/codex-*読み取りはありません。 - ランナーは Agent ツール で
subagent_type: general-purpose, model: sonnetでディスパッチされます。Agent ツール呼び出しは同期的です (バックグラウンドで実行 ではなく)。 - すべてのランナー失敗結果はメインで終了 (
launch_failure,timeout,infra_error,input_error)。ランナーは ANY 失敗で 1 回内部で再試行。メインは再ディスパッチ しません また、ユーザーに再試行を提供しません — それらのパスは層を越えて再試行を複雑化。ラウンドあたりの総 codex 実行 ≤ 2 (pre-refactor 不変量マッチ: 1 初期 + 1 再試行)。新規実行フォールバックは 5 ラウンドカウンターから新規ラウンド、独自の独立した 2 試行予算。 - ランナーからの
user_warningはユーザーにサーフェスされる必要があります」。これにより pre-refactor §2.4.4「両層空、前の ID で継続」診断が保持されます。 CODEX_MODEL/CODEX_REASONINGランナー入力スキーマでは、codex CLI が起動するモデルを参照します (例:gpt-5.4)。ランナー独自のモデルは Sonnet、Agent ツールのmodel: "sonnet"経由で設定。混同しないでください。- 再開がラウンド 2-5 の主要パス。 新規実行フォールバックは 5 ラウンドカウンターから 1 ラウンドを消費。
- Step 9 クリーンアップ
rmglob は pre-refactor から変更なし。 それでも/tmp/codex-plan-${REVIEW_ID}.md、/tmp/codex-prompt-${REVIEW_ID}.md、/tmp/codex-resume-prompt-${REVIEW_ID}.md、/tmp/codex-review-${REVIEW_ID}.md、/tmp/codex-stdout-${REVIEW_ID}.jsonl、/tmp/codex-stderr-${REVIEW_ID}.txt、/tmp/codex-stdout-${REVIEW_ID}-failed-resume.jsonl、/tmp/codex-stderr-${REVIEW_ID}-failed-resume.txtをカバーします。リファクタリングで導入された 2 つの新しいパスを追加:/tmp/codex-body-${REVIEW_ID}.mdと/tmp/codex-runner-result-${REVIEW_ID}.json。 - クリーンアップは 終了状態に条件付き:承認/最大到達/未検証で temp ファイルを削除;中止で IN PLACE に残す (診断価値)。プランモードですべてのクリーンアップをスキップ。
- 常に読み取り専用サンドボックス — レビュアーはファイルを書き込みません。
- 無限ループから保護するため最大 5 ラウンド。
- 各ラウンドでレビューと修正をユーザーに表示。
- Codex CLI がイン
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- dementev-dev
- ライセンス
- Apache-2.0
- 最終更新
- 2026/4/25
Source: https://github.com/dementev-dev/adversarial-review / ライセンス: Apache-2.0
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。