mcpField
S
skeptical-triage

skeptical-triage

github.com/avelikiyテスト・品質10867 回インストール今日更新
リポジトリ

skeptical-triage について

Skeptical Triageは、レビューやセキュリティ監査、QA回帰、アーキテクチャ判断における重大な指摘を再検証するスキルです。証拠を重視した3回のレビューと中立的な裁定者が、最終判断と信頼度を示します。

主な機能

  1. 01順次行う3回のレビュー
  2. 02引用された防御策の証拠確認
  3. 03中立的な最終裁定者
  4. 04投票に基づく信頼度スコア
  5. 05追記専用のトリアージログ

活用シーン

  1. 01セキュリティレビューの誤検知候補を選別
  2. 02テスト失敗が不安定か回帰かを判定
  3. 03アーキテクチャ上の選択肢の対立を整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/avelikiy/great_cto --skill skeptical-triage

インストール後、Claude Code で/skeptical-triageを入力して読み込まれたか確認します。

詳細

Skeptical Triage

多角的なレビュー、セキュリティ監査、QA のリグレッション判定、または重大な判断がブロッカーになる前に、誤検知を除外します。

懐疑的なセルフレビューを3ラウンド実施し、公平な裁定者が投票から信頼度スコアを算出します。

呼び出すタイミング

呼び出し元指摘の種類トリアージを適用するか?
/review角度2/4/7/9のP0/P1(セキュリティ、SQL、プライバシー、並行性)はい
/review --deepすべての角度のP0/P1はい
security-officerCSO 監査のP0/P1はい
security-officerソース/git内のシークレット、確認済みのCVEいいえ — 確定した指摘
qa-engineer不安定なテストの判定(リグレッションか、不安定なテストか?)はい
architectADR のトレードオフに関する論争(両方妥当に見える場合の選択肢A対B)はい
すべてP2/助言的な指摘いいえ

4ステップのパターン

順番に実行します。各ラウンドでは、それまでの推論を確認します。裁定者はすべてのラウンドを確認します。

ラウンド1 — 到達可能性/前提

質問:前提は正しいですか?

  • セキュリティ/信頼性の場合:信頼できない入力を使って、外部の攻撃者がこのコードパスに到達できますか?バグの箇所から入力元まで、入力フローを逆方向にたどってください。信頼できる内部呼び出し元しかない場合は、INVALID 寄りと判断します。
  • リグレッションの場合:対象ブランチで、クリーンな状態から問題の挙動を再現できますか?
  • ADR のトレードオフの場合:選択を迫る制約は、実際に選択を拘束していますか?(例:「p99 を10ms未満にする必要がある」—これは実際の要件ですか、それとも単なる目標ですか?)

出力:{round: 1, verdict: VALID|INVALID|UNCERTAIN, reasoning: "...", crux: "単一の重要な事実"}

ラウンド2 — 引用された防御策/反証を検証

質問:主張されている防御策は実在し、十分ですか?

  • 引用された防御策はすべて、Grep を使って実際の実装箇所を探します。
  • 定数名を数値に解決します。MAX_BUF_SIZE は検証済みの上限ではありません。#define MAX_BUF_SIZE 64 なら検証済みです。
  • リグレッションの場合:「テストでカバーされている」という主張は、実際に適切な不変条件を検証していますか?
  • ADR の場合:引用されたベンチマーク/先例は実在しますか(grep で検索し、内容を確認してください)。それとも単なる噂ですか?

防御策を適用する行を示せない場合、その防御策は存在しません。

出力:同じ JSON 形式で、grep_used: true/false を追加します。

ラウンド3 — 見落とした観点

質問:ラウンド1〜2で考慮されなかった点は何ですか?

  • エラーパス、整数オーバーフロー、競合が起きるタイミング、異なる呼び出し元、プラットフォーム間の違い
  • 以前のラウンドの内容を繰り返さないでください。新たな証拠を追加するか、認めてください。
  • QA の場合:リトライロジックが失敗を隠していませんか?別のテストによるテスト汚染はありませんか?
  • ADR の場合:どちらのレビュアーも挙げなかった選択肢Cはありませんか?

出力:同じ JSON 形式です。

裁定者

入力:3ラウンドすべての内容+元の指摘/質問+ソースコード。

質問:最終判断 — どちらの側の証拠がより強いですか?

  • 単一の verdict: VALID|INVALID を出します(UNCERTAIN は不可。必ず判断してください)。
  • 1文の crux を出します。これは判断を左右する重要な事実です。
  • それまでの3ラウンドがすべて同じ結論の場合、圧倒的な新証拠があるときに限り結論を覆し、その理由を説明してください。

出力:

{
  "verdict": "VALID",
  "crux": "memcpy at auth.c:142 copies network-controlled len bytes into 64-byte stack buffer with no bound check",
  "reasoning": "Rounds 1 and 3 verified attacker reach; Round 2 found no size check in 50 LOC radius; arbiter confirms no caller clamps len."
}

厳守事項

各ラウンドのプロンプトに、以下を必ず含めてください。

  1. 防御策が存在しない場合 → UNCERTAIN ではなく VALID。 防御策を検索して見つからなかったなら、それが答えです。「おそらく別のコードが処理している」は有効な防御策ではありません。
  2. 定数名は検証済みの上限ではありません。解決された値だけが検証済みです。 #define/const の宣言を grep してください。
  3. 行を示せないものは存在しません。 「このコードベースの前提」などの曖昧な参照は認められません。
  4. 同じ回答内で、自分の結論と矛盾しないでください。 防御策が不十分だと検証できたなら、それが判定です。結論を覆す理由を探すのはやめてください。
  5. コード品質の問題 ≠ セキュリティ脆弱性。 診断状態のデータ競合、内部専用 API の NULL チェック、デバッグビルドでのみ発生する UB → INVALID。
  6. 自分の推論を信頼してください。 最初に読んだ時点で要点が分かったなら、反論を無理に作り出さないでください。

確信度スコア

confidence = valid_rounds_before_arbiter / 3
  • 100%(VVV)— 3/3 ラウンドで VALID です。新たな情報が見つからない限り、裁定者はそのまま承認します。
  • 67%(VVI または VIV または IVV)— VALID が多数です。裁定者は新たな根拠に基づいて判断します。
  • 33%(IIV または IVI または VII)— INVALID が多数です。裁定者は通常、INVALID を確認します。
  • 0%(III)— 3/3 ラウンドで INVALID です。裁定者が覆すことはほとんどありません。

裁定者は最終判定を覆すことがあります。確信度は、透明性を確保するためラウンドの投票を反映します。裁定者が異なる判断を下した箇所を人が確認できるよう、出力には両方を記録してください。

トリアージ結果を重大度に反映する

裁定者が判定を返したら、次のように処理します。

裁定者の判定確信度重大度への対応
VALID≥ 50%元の重大度を維持
VALID< 50%引き下げる:P0→P1、P1→P2
INVALID任意ゲートの集計から除外し、監査用レポートに [FILTERED] として記録
UNCERTAIN(裁定者が判断できなかった場合のみ)n/a元の重大度を維持し、CTO による手動レビューのためフラグを設定

出力スキーマ

すべての呼び出し元は、トリアージ結果を .great_cto/triage-log.jsonl に記録します(追記のみ、1 行につき JSON 1 件)。

{
  "timestamp": "2026-04-19T12:34:56Z",
  "caller": "review|security-officer|qa-engineer|architect",
  "finding_id": "SEC-042",
  "file": "src/auth.c:142",
  "original_severity": "P0",
  "rounds": [
    {"round": 1, "verdict": "VALID",   "crux": "..."},
    {"round": 2, "verdict": "VALID",   "crux": "...", "grep_used": true},
    {"round": 3, "verdict": "INVALID", "crux": "..."}
  ],
  "arbiter": {"verdict": "VALID", "crux": "..."},
  "confidence": 0.67,
  "final_severity": "P0"
}

このログを使って、トリアージが効果を上げているかどうかを測定します。毎週確認してください。

# False-positive rate: how many findings the arbiter flipped to INVALID
jq 'select(.arbiter.verdict=="INVALID")' .great_cto/triage-log.jsonl | wc -l

# Average rounds-to-consensus (did we need all 3 or did R1+R2 agree?)
jq '[.rounds[].verdict] | unique | length' .great_cto/triage-log.jsonl

FP 率が 50 回のトリアージ後に 10% 未満なら、トリアージによって、そもそも存在しなかったノイズを除去しています。しきい値を下げるか、その観点ではトリアージを省略してください。FP 率が 40% を超える場合は、元のレビュー用プロンプトが過剰に検出しています。観点のルールを厳しくしてください。

トークン予算

トリアージ対象の指摘 1 件あたり、約 4 回の LLM ターン(3 ラウンド+裁定者)です。一般的なレビュー規模(PR あたりトリアージ対象が約 5~10 件)では、合計予算は /review あたり 20~40 ターンの追加です。可能な場合はまとめて処理してください。論点が互いに独立していれば、1 回の呼び出しで 1 人の裁定者が複数の指摘を処理できます。

コストを重視する実行(巨大な PR で approval-level: auto を指定する場合)では、P0 のみをトリアージし、P1 はトリアージしないことを検討してください。.great_cto/triage-log.jsonl のデータに基づいて再調整してください。

アンチパターン

  • P2/参考情報の指摘をトリアージしないでください。 目的はゲートの判断です。P2 は参考情報なので、作成者に提示して次に進んでください。
  • 各ラウンドで同じ議論を繰り返させないでください。 ラウンド 3 のプロンプトには「新たな根拠を追加するか、認めること」と明記してください。3 ラウンドで同じ推論が繰り返されたなら、2 ターン分を無駄にしています。
  • UNCERTAIN の場合に裁定者を省略しないでください。 3 ラウンドすべてが UNCERTAIN なら、裁定者の役割は霧の中に加わることではなく、判断を下すことです。
  • 裁定者による覆しを隠さないでください。 裁定者が多数決を覆した場合は、投票を示す confidence と裁定者の判定を示す final_verdict の両方を記録してください。人が意見の相違を確認できるようにしてください。

コメント