debug について
修正に着手する前に、再現可能な失敗シグナルを用意し、根本原因を調査するデバッグスキルです。再現範囲の縮小、仮説の検証、回帰テストの追加、修正の確認を順に進めます。
主な機能
- 01失敗を再現するコマンドの構築
- 02障害の再現範囲の縮小
- 03反証可能な仮説の順位付けと検証
- 04修正前の回帰テスト追加
- 05修正の確認と計測コードの削除
活用シーン
- 01再現可能なソフトウェア障害の調査
- 02システム境界をまたぐエラーの追跡
- 03根本原因の修正後の再発防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jayden-dang/ skills --skill debugインストール後、Claude Code で/debugを入力して読み込まれたか確認します。
詳細
デバッグ
鉄則
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
推測してパッチを当てると、何時間も無駄にするうえ、新たなバグを生みます。このプロセスはあらゆる技術的な問題に適用できます。特に、緊急時、「明らか」なワンライナー、前回の修正が効かなかった直後など、省略したくなる場面でこそ徹底してください。
フェーズ 1 — フィードバックループを作る(ゲート)
理論を組み立てる前に、失敗を検知できるシグナルを作成して実行してください。テストの実行、スクリプト、curl などのコマンドを 1 つ用意します。これは今、まさにこのバグが原因で失敗し、修正後に成功するものでなければなりません。適切なフィードバックループを作れば、バグは 90% 解決したも同然です。以降のフェーズは、そのループを利用するだけです。
このコマンドを用意する前に、理論を立てるためにコードを読んでいることに気づいたら、そこで止めてください。失敗を検知できるコマンドがなければ、フェーズ 2 に進んではいけません。
作成方法の例を、概ね推奨順に示します。
- バグに到達できる任意の境界で失敗するテスト(単体、統合、E2E)
- 起動中の開発サーバーに対する curl/HTTP スクリプト
- フィクスチャ入力に対する CLI の実行と、既知の正常な出力との差分比較
- DOM/コンソール/ネットワークを検証するヘッドレスブラウザースクリプト
- 保存済みのリクエスト、ペイロード、イベントログなど、記録したトレースをコードパスに再生
- 使い捨てハーネス:バグの発生経路を実行するシステムの最小スライス
- 出力が「ときどき間違う」場合、ランダムな入力を使ったプロパティ/ファズループ
- 既知の 2 つの状態の間でバグが発生した場合の二分探索ハーネス(
git bisect run) - 差分比較ループ:同じ入力を旧バージョンと新バージョンに通し、出力を比較
- 人間が介在するスクリプト — 最終手段。人間が物理的な操作を行う必要がある場合に限り、ループの構造を保てるよう操作手順をスクリプト化します
次に、ループを改善してください。より高速に(セットアップをキャッシュし、範囲を絞り、数分ではなく数秒で実行)、より的確に(「クラッシュしなかった」ではなく、ユーザーの具体的な症状を検証)、より決定論的に(時間を固定し、乱数のシードを指定し、ファイルシステムを分離)します。バグが非決定的な場合、確実に再現できる状態を追い求めないでください。トリガーを 100 回ループさせたり、負荷を加えたり、タイミングの幅を狭めたりして、デバッグに十分な再現率まで引き上げます。
本当に作成できない場合は、その旨を明確に述べ、試したことを列挙し、再現環境、記録した成果物、または一時的な計測を追加する許可をユーザーに求めてください。勘に頼って先に進んではいけません。
ゲートの確認: コマンドを示し、失敗時の出力を 1 回分貼り付けてください。
フェーズ 2 — 再現して最小化する
ループを実行し、ユーザーが説明した障害で失敗することを確認します(近いものの別の障害なら、対象のバグも修正も間違っています)。エラーを全文確認してください。完全なメッセージ、完全なスタックトレース、行番号を確認します。エラーに答えが含まれていることはよくあります。最近の変更も確認してください。git diff、新しい依存関係、設定、環境などです。
入力、設定、呼び出し元、手順を一度に 1 つずつ削り、削るたびに再実行して、残ったすべての要素が不可欠になるまで再現を小さくします。要素を 1 つでも取り除くと成功する状態が目安です。最小の再現例は仮説の範囲を絞り、回帰テストにもなります。
複数のコンポーネントからなるシステム(CI → ビルド → デプロイ、API → サービス → DB)では、各境界に計測を追加します。すべての層への入力と出力をログに記録し、修正に触れる前に一度実行して、どこで壊れるかを確認してください。呼び出しチェーンの深い場所でエラーが発生する場合は、呼び出し元をたどって不正な値を逆方向に追い、根本的なトリガーを突き止めます。エラーが表面化した箇所だけを直してはいけません。それでは症状を治療しているにすぎません。
フェーズ 3 — 仮説を立てる
検証する前に、優先順位を付けた仮説を3〜5個書き出します(仮説が1つだけだと、最初に思いついたもっともらしい案に固執してしまいます)。それぞれに、明確な予測が伴う反証可能な仮説を立てます。「Xが原因なら、Yを変えるとバグが消える」という形です。予測を示せないものは単なる思い込みです。具体化するか、候補から外してください。優先順位付きのリストをユーザーに見せます(すぐに順位を付け直すこともよくあります)。ユーザーが不在でも作業を止める必要はありません。
もっとも小さな仮説から検証します。変数は一度に1つだけ変更し、変更を重ねてはいけません。利用できる場合はデバッガー/REPLで計測します(ブレークポイント1つはログ10個に勝ります)。利用できない場合は、各プローブに固有のプレフィックス(例:[DBG-x7q2])を付けて、対象を絞ったログを出します。後で1回のgrepで削除できるようにするためです。すべてをログに出してからgrepするやり方は避けてください。パフォーマンスのバグでは、まずベースラインを測定し(プロファイラー、計測用ハーネス)、その後に二分探索します。ログはこの場合、誤解を招きます。理解できないことがあれば、「Xが理解できません」と伝えて調査します。理解したふりをして推測してはいけません。
仮説が反証されたら、取り下げて次の仮説に進みます。失敗した仮説の上に新たな修正を積み重ねてはいけません。
フェーズ 4 — 修正する
- まず失敗する回帰テストを作成します。 必須のサブスキル:
tddを使用してください。テストは正しい接点に置きます。つまり、実際に発生したバグのパターンを再現できる接点です。適切な接点がない場合、それ自体が調査結果です。内容を記録し、事後検証で取り上げるよう明記してください。その場所に浅いテストを置くと、誤った安心感を生みます。 - 根本原因に対処する修正は1つだけにします。「ついでに」行う改善や、修正と一緒に行うリファクタリングは避けてください。
- 回帰テストが成功することを確認し、テストスイート全体を再実行し、フェーズ1のループを最初の縮小していないシナリオに対して再実行します。
修正の試行が3回失敗したら、必ず停止します。 問題なのは最新の仮説ではなく、アーキテクチャです。特に、修正のたびに別の場所で新たな結合が見つかる場合はそうです。4回目を試す前にユーザーと相談してください。
終了 — ミニ仕様、クリーンアップ、事後検証
- Tier-1ミニ仕様:修正要件と、処理を続行するためのガード要件
SHALL CONTINUE TOを、担当する機能のrequirements.mdに追加します(担当する機能がない場合はdocs/specs/fixes.mdに追加します)。回帰テストに新しいIDを付けます。 - 計測コードをすべて削除します。自分の
[DBG-...]プレフィックスをgrepし、一時的なハーネスを削除してください。 - コミットメッセージに、確認済みの根本原因を記載します。
- 「このバグを防ぐには何が必要だったか?」と問いかけます。答えがアーキテクチャ上の問題(適切な接点がない、隠れた結合がある、呼び出し元が複雑に絡み合っている)なら、具体的な内容を書き留め、ユーザーに
/improve-architectureを実行するよう伝えます。修正を反映した後、もっとも詳しい情報が得られた時点で実行してください。 - 必須のサブスキル:バグが修正されたと主張する前に、
verifyを使用してください。
合理化
| 考え | 実態 |
|---|---|
| 「緊急で、手順を踏む時間がない」 | 根本原因のデバッグは、推測と試行錯誤を繰り返すより速いです |
| 「原因は明らかにXだから、すぐ修正しよう」 | 症状を見ただけでは、原因を理解したことにはなりません |
| 「とりあえず素早くパッチを当てて、後で調査しよう」 | パッチは恒久化し、原因は再び問題を引き起こします |
| 「時間を節約するため、変更をいくつかまとめて試そう」 | どれが効いたか分からなくなり、そのうちの1つが何かを壊す可能性もあります |
| 「単純すぎて再現手順は不要」 | 単純なバグにも根本原因があります。このループにかかるのは数分です |
| 「修正後に回帰テストを追加しよう」 | テストされていない修正は再発します。テストが失敗する状態は、修正が本当に直すことの証明です |
| (2回以上失敗した後に)「もう一度だけ試そう」 | アーキテクチャについて議論せずに4回目を試すのは、堂々巡りです |
ユーザーのシグナル — フェーズ1に戻る
| ユーザーの発言 | 意味 |
|---|---|
| 「推測をやめて」 | 根本原因を特定せずに修正案を提示しました。フェーズ1に戻ります |
| 「本当にそうなっているの?」 | 検証せずに決めつけました。証拠を集めます |
| 「それで何が分かるの?」 | プローブが予測に結び付いていません。仮説を言い直します |
| 「堂々巡りになっている」 | 失敗した修正の回数を数えてください。おそらくアーキテクチャの判断が必要な段階です |