double-check について
GitHub のプルリクエストを準備、独立したレビュー、修正、結果の投稿の順に再確認するスキルです。先行レビューを検証して差分を確認し、レビュー対象のコミットと一致する場合にコメントやラベルを反映します。
主な機能
- 014段階の逐次レビュー
- 02独立した批判的レビュー
- 03patch-id による判定の引き継ぎ
- 04新規コミットの差分レビュー
- 05完全一致するコミットへの投稿制御
活用シーン
- 01先行する PR レビューの再確認
- 02修正後の変更のレビュー
- 03差分が変わらない場合の判定引き継ぎ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fellowship-dev/ dogfooded-skills --skill double-checkインストール後、Claude Code で/double-checkを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CONTEXT.mdreferences/follow-up-issue-template.mdshared/exact-head-receipt.shreport-template.mdreview-comment-template.mdstages/01-setup/CONTEXT.mdstages/02-review/CONTEXT.mdstages/03-fix/CONTEXT.mdstages/04-post/CONTEXT.mdtests/base-merge-no-push.test.shexact-head-receipt.test.shpatch-id-carry.test.shspeed-contract.test.shtest_installed_resources.pytests/fixtures/pr-3179-stage03-to-stage04.json詳細
double-check
目的
スタンドアロンの2回目のPRレビューを、ステージごとに分割したICM手順で実施します。PR、最初のレビュー、差分を取得してチェックアウトし(setup)、クリーンなコンテキストで一貫した批判的判断に基づくレビューを1回実施します(最初のレビューの指摘を検証し、見落とされたエッジケースを探し、テストとドキュメントを併せて確認して、単一の統合された判定を出します)。次に、必要に応じて修正を適用してテストを再実行し(fix)、最後に精査したコメントを投稿し、double-checked ラベルを適用して、レポートを作成します(post)。動作は元の double-check スキルと同等ですが、判断ステップにオーケストレーターの履歴が影響しないよう、切り離されています。
引数
| パラメーター | 必須 | デフォルト | 備考 |
|---|---|---|---|
pr | はい | — | PR番号。例:742 |
repo | はい | — | org/repo。例:fellowship-dev/booster-pack |
$ARGUMENTS から解析します。最初のトークンが pr、2つ目が repo です。
GitHub 認証情報は環境に設定されているため、トークン用の環境変数は不要です。Pod の git-credential-pylot ヘルパーと gh シムは、操作ごとに有効期間の短い App インストールトークンを発行するため、git URL はプレーンな形式(https://github.com/<org>/<repo>.git)のままにしてください。認証情報を URL に埋め込むとヘルパーを迂回し、実行中に期限切れになります。
実行内容
4ステージの順次実行ICM手順です(並列ステージはありません)。
| ステージ | モード | 説明 |
|---|---|---|
| 01-setup | サブエージェント | 現在の HEAD を含むPRメタデータを取得し、最初のレビューの記録(Head reviewed の行)を現行/古い/なしに分類し、コメントと差分全体を取得して、PRブランチとマージベースをチェックアウトします |
| 02-review | サブエージェント | クリーンなコンテキストで一貫した批判的レビューを1回実施します。最初のレビューの指摘を検証し、見落とされたエッジケースを探し、テスト/ドキュメントを確認して、統合された判定(未解決の MUST-FIX コード項目がゼロの場合に限り ready)と精査した指摘をまとめます |
| 03-fix | サブエージェント | MUST-FIX(および価値のある NICE-TO-HAVE)の修正を適用し、テストを再実行してプッシュします。修正が必要な場合に限ります |
| 04-post | インライン | 最新の HEAD を再取得し、それがステージ02でレビューした正確な40桁の16進数の HEAD と一致するか、同じ patch-id を持つ場合に昇格します。それ以外の場合は1回再起動します。その後、精査したレビューコメントを投稿し、一致する HEAD に対してのみラベルを適用します |
Patch-id の引き継ぎと差分レビュー(pylot#3738)
すべての判定記録には、HEAD と PR の patch-id(git diff base...head | git patch-id --verbatim)を記録します。HEAD の変更だけでレビューが無駄になることはありません。
- 同じ patch-id(リベース、ベースからのマージ):判定と
double-checkedは新しい HEAD に引き継がれ、「判定を引き継ぎました:patch-id に変更なし」という1行の注記を添えます。Setup ではreview_scope: carryを報告し、ステージ02と03はスキップされ、ステージ04では引き継ぎ用の分岐が実行されます。 - 新しいコミット(手直し、ステージ03の修正):ステージ02では、前回の判定以降にハンクが変更されたファイルと、それらの修正を目的とする指摘のみをレビューします(
review_scope: delta)。PR のファイルの30%を超えて変更されている場合、または到達可能な以前の判定がない場合は、全体をレビューします。 - コンフリクト解決で差分が変更された場合は新しい patch-id になるため、必ず再レビューします。
引き継ぎ先
すべての引き継ぎファイルは、リポジトリの作業ディレクトリにあります。
.procedure-output/double-check/{stage}/handoff.md
Setup ステージでは、ローカルのチェックアウトディレクトリ(REPO_DIR)を引き継ぎファイルに記録するため、Fix ステージは同じ作業ツリーで作業します。各サブエージェントステージには必要な引き継ぎファイルのみを渡し、オーケストレーターのコンテキスト全体は渡しません。
実行方法
作業ディレクトリを変更する前に、読み込まれた SKILL.md を含む絶対ディレクトリを、渡されたリソースパスを使って DC_SKILL_DIR として解決します。ステージの指示、テンプレート、ヘルパーには同じルートを使用し、レビュー対象リポジトリの cwd から推測したり、別のインストール済みバージョンを優先したりしないでください。このパスを各ステージに明示的に渡し、そのステージのシェルでエクスポートしてください。読み込まれたリソースパスを利用できない場合は、ステージを実行する前に停止して解決してください。
正確な HEAD でのサイクル(逐次サブエージェント)
各ステージで Task を 1 つ実行し、順番に進めます。ステージを並列で起動してはいけません。現在のステージが完了するまで、次のステージを開始しないでください。restart_count=0 から開始します。ステージ 04 で、異なる patch-id を持つ別の完全なリモート SHA が確認された場合は、判定を投稿したりラベルに触れたりせずに停止します。その後、オーケストレーターは、確認された SHA で 01 → 02 → 03 → 04 の条件付きサイクルを最初から最後まで実行し、restart_count=1 を設定します。delta_base_head(前のサイクルでレビューした HEAD)をステージ 01 に渡し、まず前のステージ 02 の引き継ぎファイルを .procedure-output/double-check/prior-review.md に移動して、新しいサイクルでは差分と、それによって修正される指摘のみをレビューします。ステージ 02 に渡すのは、新しいセットアップの引き継ぎ情報と成果物だけです。オーケストレーションの履歴は絶対に渡さないでください。2 回目の遷移が発生した場合、またはライブ HEAD を読み取れない場合は、ブロックされた状態で停止します。同じ patch-id を持つ HEAD の移動は遷移ではありません。ステージ 04 は判定を引き継ぎます。
各 Task のプロンプトは自己完結している必要があります。
- そのステージの入力引き継ぎパスのみを含めます
- そのステージの CONTEXT.md へのパスを含めます
prとrepoの値を渡します- オーケストレーションの履歴や過去の推論は渡さないでください
Task プロンプトのテンプレート:
You are running stage {NN}-{name} of the double-check procedure.
PR: {pr} REPO: {repo}
DC_SKILL_DIR: {absolute skill directory}
Export DC_SKILL_DIR to this absolute path before executing shell snippets.
Read your stage instructions:
{DC_SKILL_DIR}/stages/{NN}-{name}/CONTEXT.md
Your inputs:
{list only the input handoff paths from that stage's CONTEXT.md}
Write your output to:
.procedure-output/double-check/{NN}-{name}/handoff.md
Execute all steps in CONTEXT.md. Write handoff.md before exiting.
ステージの実行条件:
- ステージ 02 は、独立して重要な判断を行うステップです。そのプロンプトにはセットアップの引き継ぎ情報(PR + 最初のレビュー + diff)のみを含めなければなりません。それ以外は何も含めないでください。これが、このプロシージャ全体の目的であるクリーンなコンテキストウィンドウです。
- ステージ 01 の後、引き継ぎファイルを読みます。
review_scope: carryの場合は、ステージ 02 と 03 をスキップし、ステージ 04 の引き継ぎ分岐を実行します(ready判定以降、PR 自体の diff に変更がないため)。 - ステージ 02 の後、引き継ぎファイルを読みます。
fixes_needed: falseの場合は、修正を適用する必要がないためステージ 03 をスキップし、ステージ 04 に進みます。それ以外の場合はステージ 03 を実行します。
ステージ 04(インライン)
オーケストレーターのコンテキストでステージ 04 を自分で実行してください。Task を起動してはいけません。CONTEXT.md を読みます。
{DC_SKILL_DIR}/stages/04-post/CONTEXT.md
ライブの正確な HEAD ゲート(gh pr view)を実行し、HEAD が一致する場合に限り、コメントを投稿してラベルを適用します。ラベルとコメントが実際に反映されたことを確認し、レポートファイルを書き込み、オーケストレーターから [pylot] outcome=... マーカーを出力します(サブエージェントから出力してはいけません)。
ステージ 04 が 3 で終了した場合は、RESTART_COUNT=1 を設定し、現在のライブ HEAD で条件付きのステージ 01 → 02 → 03 → 04 サイクルを最初から最後まで新たに実行します。古いステージ 02 またはステージ 03 の引き継ぎ情報は渡さないでください。2 で終了した場合は、ブロックされた状態で終了です。昇格パスを実行してはいけません。
ステージ引き継ぎチェーン
01-setup ─► 02-review ─► 03-fix ─► 04-post (inline, reads 01+02+03)
│ ▲
└── fixes_needed:false ┘ (skip 03)
終了パス
- 初回チェックで fail closed(未解決の MUST-FIX コード項目が 1 件以上ある場合):ステージ 04 は
`` コメントを投稿し、
double-checkedを削除または付与せず、needs-workを追加または 維持し、肯定的な後続処理は作成しません。次を出力します:[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-check {repo}#{pr} — verdict {verdict}, double-checked withheld, needs-work retained" status=success - 再チェック PASS(PR に
needs-workがあり、verdict=ready の場合):ステージ 04 はneeds-workを削除し、double-checkedを再度切り替え (削除してから再追加)、次を出力します:[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-checked re-check PASS {repo}#{pr} — loop closed, cto-review re-fired" status=success - 再チェック FAIL(PR に
needs-workがあり、未解決の MUST-FIX コード項目が 1 件以上ある場合):ステージ 04 はneeds-workを維持し、double-checkedを再度切り替えず、`` マーカーを含む構造化された判定コメントを投稿し (冪等。マーカーがすでに存在する場合はスキップ)、次を出力します:[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-checked re-check FAIL {repo}#{pr} — needs-work retained" status=success - 初回チェック成功:正確に一致するライブの 40 桁の 16 進数ヘッドで、明示的に
readyと判定された場合に限り、double-checkedを適用できます。次を出力します:[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-checked {repo}#{pr} — verdict ready, {N} findings curated, {N} fixes pushed" status=success - 判定を引き継ぎ(
review_scope: carry):ステージ 04 は 1 行の引き継ぎメモを投稿し、ラベルを維持して、 次を出力します:[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-check {repo}#{pr} — verdict carried: patch-id unchanged, no re-review" status=success - 失敗:失敗したステージは
[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-check failed at stage NN: {reason}" status=failedを出力します。 - ブロック:セットアップで PR を取得/チェックアウトできない場合(マージコンフリクト、PR が存在しない場合など)、ライブ
ヘッドを読み取れない場合、または 2 回目のヘッド遷移が発生した場合 →
[pylot:$PYLOT_OUTCOME_NONCE] outcome="double-check blocked: {reason}" status=blocked(意図的な停止です。blockedは独自の終端状態であり、失敗ではありません)
再作業フォローアップモード
「修正を行う」フォローアップのディスパッチが存在するかどうか、またどのように存在するかは、プロトコルではなくリポジトリのポリシーです。このスキルの上に CTO の再作業自動化を組み込んでいる組織もあれば、そうでない組織もあります。リポジトリのプレイブック(GET /admin/playbooks/<org>/<repo>)で再作業ディスパッチのセクションを確認してください。契約が定められている場合、次のような内容です。
以前のレビューで
needs-workとなった場合、ゲートルールがこのスキルに再ディスパッチします。タスク文字列で PRODUCE フォローアップ(再判定ではない)と識別されます。プレイブックには、一致させる正確なトリガー文字列/ラベルと自動化の ID が記載されています。以下では、それらをハードコードする文字列ではなく、確定済みの値として扱ってください。
この契約に基づいてディスパッチされた場合、上記のステージを実行する前に、次の手順を実施してください(トリガーとルール名の正本はプレイブックです。このプロトコルとの同期を保ち、両者に食い違いが生じないようにしてください)。
- まず PR のコメントを確認します。以前の試行ですでに
⚠️ NEEDS HUMANマーカーが投稿されている場合、または以前の再作業で同じゲートへの対応を試みて失敗している場合は、ループさせず、人間に委ねて停止してください。何も実施せずにneeds-workを再確認して再適用することは決してしないでください。 - 最新の CTO レビューコメントを読み、具体的なアクション項目を確認します。
- 実際に対応します。コード/テスト/ドキュメントの修正は、変更を加えてプッシュします。PR 本文の編集やステージングの証跡を求める依頼は再作業項目ではありません。ステージングはリリーストレインの手順(pylot#3389)であり、本文によって判定が決まることはありません。コードに関する項目が残っていない場合は、以下のステージを実行します。MUST-FIX 項目が 0 件なら合格です。依頼内容が本当にこのスキルの範囲を超えている場合(専用ランナーや人間の判断、または保有していない認証情報が必要な場合)は、
needs-workを黙って再適用しないでください。妨げとなっていることと、解決に必要なことを明記したコメントを⚠️ NEEDS HUMANで始めて投稿し、その後停止してください。 - 項目に実際に対応した後に限り、
gh pr edit <number> --repo <repo> --remove-label "double-checked,needs-work"を実行し、その後、上記のステージを実行してラベルの連鎖を再発火させます。セットアップでは、再作業後の差分を直近の判定の patch-id と比較するため、レビュー対象は再作業による差分と、それが対応する指摘のみになります(差分がファイルの 30% を超える場合は全体レビュー)。
プレイブックに再作業ディスパッチのセクションがない場合は? このモードは適用されません。通常のレビュー/修正/投稿パスとして、上記のステージを実行してください。
厳守事項
- 順次実行のみ — 各ステージで実行する Task は 1 つだけとし、順番に実行します。並列で Task を起動することは、いかなる場合も禁止です。
- レビューは一体的な 1 つのステージです — ステージ 02 をファイル別または観点別のサブエージェントに分割しないでください。正確性、エッジケース、テスト、ドキュメント、依存関係、セキュリティをまとめて、1 つの判定を下します。
- ステージ 02 にはクリーンなコンテキストを渡します — セットアップの引き継ぎ情報とその成果物ファイル(PR 本文、最初のレビュー、変更ファイル、差分)のみを渡してください。オーケストレーターの履歴は渡さないでください。
- ステージ 04 はインラインで実行します —
[pylot] outcome=...マーカーは、必ずオーケストレーターが出力します。 - オーケストレーターのコンテキスト全体をサブエージェントの Task プロンプトに渡さないでください — 入力のみを渡してください。
- 次のステージが読み込む前に、各ステージが
handoff.mdを書き込みます。 - ステージ 03 は
fixes_needed: falseの場合に限り(明示的に許可されたスキップ)、ステージをスキップしてはいけません。 - Quest は使用しません。 報告先はローカルのレポートファイルのみです。Quest POST、
127.0.0.1:4242、quest.fellowship.dev、QUEST_TOKENは使用しないでください。 - ラベルを適用するのは、コメントの投稿が成功した後(ステージ 04)のみです。 再チェックが PASS の場合、
double-checkedを再追加する前にneeds-workを削除してください。これが構造上のループを断ち切ります。再チェックが FAIL の場合は、ラベルに触れたり、double-checkedを再度切り替えたりしないでください。 - 判定を決めるのはコードです。MUST-FIX が 0 件なら合格です。 初回チェックでも再チェックでも、オープン中の MUST-FIX コード項目がない場合、判定は
readyです。ステージ 04 はmust_fix_open: 0のneeds-workをreadyに正規化します。PR 本文が示すのは意図だけです。主張との照合ステップはなく、古くなった本文については 1 行程度の注記を付けるにとどめます。(これは pylot#2649 の主張ゲートに代わるものです。30 日間の調査では、needs-workフラグの大半がクリーンな差分に対する古い本文によるもので、それぞれ手戻りを招いていました。) - ステージ 04 は自身の副作用を検証します — ラベル付け後に
gh pr viewで PR を確認し、想定したラベルとコメントが実際に存在することを確かめます。副作用を検証せずに成功を報告することこそ、このスキルが防ごうとしている失敗です。 - 最初のレビューは精査して引き継ぎ、内容を確かめずに再作成しないでください — セットアップでは、最初のレビューのコメントと
Head reviewedのレシート行をそのまま記録します。ステージ 02 では、階層に応じた深さで調査結果を精査します(エスカレーションのみ)。最初のレビューが見つからない場合は、深度を下げずに新規レビューを行います。 - 古い最初のレビューは過去の証拠であり、ブロッカーでも現在のカバレッジでもありません — その
head_shaをリベース後の PR HEAD と比較します。現在の完全な差分を対象に一体的なレビューを続行し、以前の指摘を再確認して、現在の HEAD に対する新しいレシートを投稿してください。受け取ったレシートが古いという理由だけで、パイプライン全体を最初からやり直してはいけません。 - プロモーションは最終的な完全 SHA に紐づけます — 判定コメントの投稿またはラベル変更の直前に、毎回
headRefOidを取得します。ライブの 40 文字の SHA がステージ 02 のreviewed_head_shaと一致するか、レビュー済み差分と同じ完全な patch-id を持つ必要があります。一致する場合は処理を続行します(その際、ライブ HEAD をプロモートされた HEAD とします)。それ以外の場合は安全側に倒して中止します。patch-id が初めて変わった場合は差分レビューに切り替えて再開し、2 回目の変更または取得失敗の場合はブロックして停止します。ファイルリスト、差分統計、短縮 SHA、ローカル HEAD を、SHA または patch-id の一致の代わりにしてはいけません。古い実行またはブロックされた実行ではdouble-checkedを変更せず、後続の自動処理も起動しません。 - 初回チェックからのプロモーションは、明示的な肯定の場合のみです — レビュアーの判定が正確に
readyで、ライブ HEAD と完全に紐づいている場合に限りdouble-checkedを適用します。否定、欠落、不正形式、古い情報、または矛盾するシグナルがあれば、安全側に倒してdouble-checkedを削除するか適用せず、needs-workを追加または維持し、CTO、FlowChad、ステージング、マージの後続処理を作成しないでください。 - 成功マーカーは、ステージ 04 のテンプレートからのみ出力します(pylot#3392)。 ステージ 04 の「Emit outcome marker」セクションに記載された 5 つの
status=successマーカー(4 つの判定分岐と carry 分岐)が、出力できるマーカーの全てです。オーケストレーターが自由形式の成功マーカーを作成してはいけません。また、ステージ 04 が完了し(レシートコメントが投稿され、実行後の検証に合格する)、それ以前にstatus=successを出力してはいけません。2026-09-05 に、オーケストレーターがステージ 04 を実行せずに「queued-worker result ok」を出力した結果、レシートがないままミッションがdoneで終了し、完了した作業が約 6 時間見えなくなりました。ステージ 04 を実行できない場合は、理由とともにstatus=failedまたはstatus=blockedを出力してください。成功を捏造することは、最悪の終了方法です。 - 逐語的な成果物はシェルで書き込み、手入力しないでください。 ステージ 01 では PR 本文、最初のレビュー、マニフェスト、差分を
handoffと同じ場所にあるファイルへリダイレクトします。Write ツールを使ってコピーするとセットアップで最も時間がかかり、内容が元の情報から気づかないうちにずれる可能性があります。 - 時計ではなく、プロセスを待ってください。 長時間かかるコマンド(テスト、フック付きの
git push)は、ツールの最長タイムアウトを使ってフォアグラウンドで実行するか、PID を記録してバックグラウンドで実行し、終了時にすぐ戻るブロッキング待機を行います(ステージ 03 の「Waiting on a long command」を参照)。30 秒以上の固定時間sleep Nでポーリングしてはいけません。実測では、完了後も最大 10 分間スリープしていました。 - 検証は対象リポジトリの規約に従います。 ステージ 03 では修正差分と影響を受けるコンシューマーに対して有意義なチェックを選び、必須の広範囲/全体チェック、依存関係、変換、統合、リリースのゲートを維持します。現在のリポジトリポリシーと設定済みワークフローによって定められている場合に限り、CI がゲートを担います。ポリシー上の再利用が許可され、スコープと環境が一致する場合に限り、同じリビジョンに対する重複実行を避けてください。変更後、失敗後、または懸念が解消されていない場合は再実行します。フックのバイパスには、リポジトリでの明示的な許可と、バイパスによって省略されるすべてのチェックに合格した証拠が必要です。ステージ 02 の独立したレビューとステージ 04 の完全一致する HEAD の受け入れ確認は、引き続き必須です。対象を絞ったテストを行っても、どちらも省略できません。
参照ファイル
CONTEXT.md— アーキテクチャの概要stages/NN-name/CONTEXT.md— 各ステージの入力、タスク、出力仕様shared/review-comment-template.md— 厳選された PR コメントのテンプレート(ステージ 04)shared/report-template.md— ローカルレポートファイルのテンプレート(ステージ 04)