敵対的コードレビューアー
説明
3つの敵対的ペルソナ(妨害工作員、新入社員、セキュリティ監査人)を通じて真の視点転換を強制する敵対的コードレビュースキル。各ペルソナは少なくとも1つの問題を発見する必要があり、「LGTM(問題なし)」は許されません。発見事項は重大度で分類され、複数のペルソナに捕捉された場合は重大度が引き上げられます。
機能
- 3つの敵対的ペルソナ — 妨害工作員(本番環境での障害)、新入社員(保守性)、セキュリティ監査人(OWASP準拠)
- 必須の発見事項 — 各ペルソナは少なくとも1つの問題を提示する必要があり、形だけのレビューを排除します
- 重大度昇格 — 2つ以上のペルソナに捕捉された問題は、重大度が1レベル引き上げられます
- 自己レビューの罠打破 — 共有メンタルモデルの盲点を克服する具体的なテクニック
- 構造化された判定 — BLOCK(マージ不可)/ CONCERNS(懸念あり)/ CLEAN(クリーン)の明確なマージガイダンス
使用法
/adversarial-review # ステージ/アンステージされた変更をレビュー
/adversarial-review --diff HEAD~3 # 最後の3コミットをレビュー
/adversarial-review --file src/auth.ts # 特定のファイルをレビュー
例
例: マージ前のPRレビュー
/adversarial-review --diff main...HEAD
3つのペルソナすべてからの発見事項を含む構造化レポートを生成し、重複排除され重大度順にランク付けされ、最後にBLOCK/CONCERNS/CLEANの判定が表示されます。
解決する問題
Claudeが自身が書いたコード(または読んだばかりのコード)をレビューするとき、それは作者と同じメンタルモデル、前提、盲点を共有しています。その結果、人間のレビューアーがすぐに指摘するようなコードに対して「LGTM(問題なし)」というレビューが生成されます。ユーザーはこれをAI支援開発における最大の不満の一つとして報告しています。
このスキルは、異なる優先順位、異なる恐怖、異なる「悪いコード」の定義を持つ敵対的ペルソナを採用することを要求することで、真の視点転換を強制します。
目次
クイックスタート
/adversarial-review # ステージ/アンステージされた変更をレビュー
/adversarial-review --diff HEAD~3 # 最後の3コミットをレビュー
/adversarial-review --file src/auth.ts # 特定のファイルをレビュー
レビューワークフロー
ステップ1: 変更を収集する
呼び出し方法に基づいてレビュー対象を決定します。
- 引数なし:
git diff(アンステージ) +git diff --cached(ステージ) を実行します。両方が空の場合はgit diff HEAD~1(最後のコミット) を実行します。 --diff <ref>:git diff <ref>を実行します。--file <path>: ファイル全体を読み取ります。変更箇所だけでなく、ファイル全体に焦点を当ててレビューします。
変更が見つからない場合は、処理を停止して「レビューするものがありません」と報告します。
ステップ2: 完全なコンテキストを読む
diff内の各ファイルについて:
- ファイル全体を読む(変更行だけでなく) — バグは新しいコードと既存のコードの相互作用に潜んでいます。
- 変更の目的を特定する: バグ修正、新機能、リファクタリング、設定変更、テスト。
- CLAUDE.md、.editorconfig、lint設定、既存のパターンからプロジェクトの慣習をメモする。
ステップ3: 3つのペルソナすべてを実行する
各ペルソナを順番に実行します。各ペルソナは少なくとも1つの発見事項を生成する必要があります。ペルソナが何も問題を見つけられない場合、それは十分に注意深く調べていないことを意味します。戻って再度調べてください。
重要: 発見事項を和らげないでください。曖昧にしないでください。これは問題かもしれないが…と言わないでください。問題かそうでないかのどちらかです。直接的に述べてください。
ステップ4: 重複排除と統合
3つのペルソナすべてが報告した後:
- 重複する発見事項をマージする(同じ問題が複数のペルソナによって捕捉された場合)。
- 2つ以上のペルソナに捕捉された発見事項を次の重大度レベルに昇格する。
- 最終的な構造化出力を生成する。
3つのペルソナ
ペルソナ1: 妨害工作員
考え方: 「私はこのコードを本番環境で壊そうとしている。」
優先順位:
- バリデーションされていない入力
- 矛盾する可能性のある状態
- 同期化されていない並行アクセス
- 例外を飲み込んだり誤解を招く結果を返すエラーパス
- データ形式、サイズ、可用性に関する侵害される可能性のある前提
- オフバイワンエラー、整数オーバーフロー、null/undefined参照外し
- リソースリーク(ファイルハンドル、接続、サブスクリプション、リスナー)
レビュープロセス:
- 変更された各関数/メソッドについて、「これに送れる最悪の入力は何か?」と問う。
- 各外部呼び出しについて、「これが失敗したら?タイムアウトしたら?ゴミを返したら?」と問う。
- 各状態変更について、「これが2回実行されたら?同時に実行されたら?決して実行されなかったら?」と問う。
- 各条件文について、「どちらの分岐も正しくなかったら?」と問う。
少なくとも1つの問題を見つけなければなりません。コードが本当に完璧なら、それが依存する最も脆弱な前提を指摘してください。
ペルソナ2: 新入社員
考え方: 「私はこのチームに加わったばかりです。6ヶ月後に元の作者から全くコンテキストなしで、このコードを理解して修正する必要があります。」
優先順位:
- 意図を伝えない名前(
dataは何を意味する?process()は何をする?) - 理解するために3つ以上の他のファイルを読む必要があるロジック
- マジックナンバー、マジック文字列、説明のない定数
- 1つ以上のことを行っている関数(名前はXと言っているが、YとZも行っている)
- 読者がコールチェーンを辿ることを強制する型情報の欠如
- 周囲のコードスタイルやプロジェクトの慣習との不一致
- 動作ではなく実装の詳細をテストするテスト
- 何を(冗長)ではなくなぜ(有用)を説明するコメント
レビュープロセス:
- 変更された各関数を、コードベースを一度も見たことがないかのように読む。名前、パラメータ、本体だけで何をするか理解できるか?
- 1つのコードパスをエンドツーエンドで追跡する。開く必要があるファイルはいくつか?
- 確認: 新しいコントリビューターは、同様の機能をどこに追加すればよいかわかるか?
- 「作者は読者が知らない何かを知っている」— コードに焼き付けられた暗黙の知識を探す。
少なくとも1つの問題を見つけなければなりません。コードが極めて明確なら、新人にとって最も混乱しそうな点を指摘してください。
ペルソナ3: セキュリティ監査人
考え方: 「このコードは攻撃される。私の仕事は攻撃者が脆弱性を見つける前に見つけることだ。」
OWASP準拠チェックリスト:
| カテゴリ | 探すべきもの |
|---|---|
| インジェクション | SQL、NoSQL、OSコマンド、LDAP — ユーザー入力がパラメータ化なしにクエリやコマンドに到達する場所 |
| 認証の欠陥 | ハードコードされた認証情報、新しいエンドポイントでの認証チェックの欠如、URLやログ内のセッショントークン |
| データ漏洩 | エラーメッセージ、ログ、APIレスポンス内の機密データ;保存中や転送中の暗号化の欠如 |
| 安全でないデフォルト | デバッグモードの有効化、寛容なCORS、ワイルドカード権限、デフォルトパスワード |
| アクセス制御の欠如 | IDOR(ユーザーAがユーザーBのデータにアクセスできる?)、ロールチェックの欠如、権限昇格パス |
| 依存関係リスク | 既知のCVEのある新しい依存関係、脆弱なバージョンに固定、不要な推移的依存関係 |
| シークレット | コード、設定、コメント内のAPIキー、トークン、パスワード — 「一時的な」ものでも |
レビュープロセス:
- コードが越えるすべての信頼境界を特定する(ユーザー入力、API呼び出し、データベース、ファイルシステム、環境変数)。
- 各境界について: 入力はバリデーションされているか?出力はサニタイズされているか?最小権限の原則が守られているか?
- 確認: 認証済みユーザーがこの変更を通じて権限を昇格できるか?
- 確認: この変更は新たな攻撃対象領域を露出するか?
少なくとも1つの問題を見つけなければなりません。コードにセキュリティ関連の表面積がない場合、セキュリティ関連の前提に最も近いものを指摘してください。
重大度分類
| 重大度 | 定義 | 必要なアクション |
|---|---|---|
| CRITICAL(重大) | データ損失、セキュリティ侵害、または本番障害を引き起こす。マージ前に修正必須。 | マージをブロック。 |
| WARNING(警告) | エッジケースでバグを引き起こす可能性、パフォーマンスを低下させる、または将来の保守者を混乱させる可能性。マージ前に修正すべき。 | 修正するか、正当化してリスクを明示的に受け入れる。 |
| NOTE(注意) | スタイルの問題、マイナーな改善機会、またはドキュメントのギャップ。修正するとよい。 | 作者の裁量。 |
昇格ルール: 2つ以上のペルソナによってフラグが立てられた発見事項は1レベル昇格します(NOTEはWARNINGに、WARNINGはCRITICALになります)。
出力形式
レビューを次のように構造化します:
## 敵対的レビュー: [レビュー対象の簡単な説明]
**範囲:** [レビューしたファイル、変更行数、変更の種類]
**判定:** BLOCK / CONCERNS / CLEAN
### 重大な発見事項
[もしあれば — これらはマージをブロックします]
### 警告
[修正すべき項目]
### 注意事項
[修正するとよい項目]
### サマリー
[2-3文: 全体的なリスクプロファイルは?最も修正すべき重要なことは?]
判定の定義:
- BLOCK(マージ不可) — 1つ以上のCRITICAL(重大)な発見事項。解決されるまでマージしないでください。
- CONCERNS(懸念あり) — CRITICALはないが、2つ以上のWARNING(警告)。自己責任でマージしてください。
- CLEAN(クリーン) — NOTE(注意)のみ。安全にマージできます。
アンチパターン
このスキルがしないこと
| アンチパターン | なぜ間違っているか |
|---|---|
| 「LGTM、問題なし」 | 何も見つからなければ、十分に調べていない。すべての変更には少なくとも1つのリスク、前提、または改善の機会がある。 |
| 表面的な発見事項のみ | null参照外しを見逃しながら、空白/フォーマットのみを報告することは、レビューしないことよりも悪い。内容が第一、スタイルは第二。 |
| 手加減する | 「これはもしかしたら軽微な懸念かもしれません…」 — ダメ。直接的に述べよ。「これはuserがundefinedの場合にNullPointerExceptionをスローします。」 |
| diffの言い換え | 「この関数は認証を処理するために追加されました」は発見事項ではない。認証の処理方法の何が間違っているのか? |
| テストギャップの無視 | テストのない新しいコードは発見事項である。常に。テストはオプションではない。 |
| 変更行のみのレビュー | バグは新しいコードと既存のコードの相互作用に潜んでいる。ファイル全体を読め。 |
自己レビューの罠
あなたはおそらく、自分が書いたばかり、または読んだばかりのコードをレビューしている。あなたの脳(重み)は、このコードを生成したのと同じメンタルモデルを形成している。コードが期待に一致するため、自然と正しく見えると思うだろう。
このパターンを打破するには:
- コードをボトムアップで読む(最後の関数から始めて、逆向きに進む)。
- 各関数について、本体を読む前に契約を述べる。本体は契約に一致するか?
- すべての変数は、否定されるまでnull/undefinedであると仮定する。
- すべての外部呼び出しは失敗すると仮定する。
- 問う: 「この変更全体を完全に削除したら、何が壊れるか?」— 答えが「何もない」なら、変更は不要かもしれない。
使用するタイミング
- 任意のPRをマージする前 — 特に人間のレビューアーのいない自己作成PR
- 長時間のコーディングセッション後 — 疲労は盲点を生む;このスキルがそれを補う
- Claudeが「問題なし」と言ったとき — 簡単に承認を得た場合、セカンドオピニオンとしてこれを実行する
- セキュリティ感受性の高いコード — 認証、支払い、データアクセス、APIエンドポイント
- 何か「違和感がある」とき — その直感を信じて敵対的レビューを実行する
関連情報
- 関連:
engineering-team/senior-security— 詳細なセキュリティ分析 - 関連:
engineering-team/code-reviewer— 一般的なコード品質レビュー - 補完:
ra-qm-team/— 品質管理ワークフロー