mcpField
D
debugging-patterns

debugging-patterns

github.com/romiluz13開発16636 回インストール1 週間前に更新
リポジトリ

debugging-patterns について

開発者向けの体系的なデバッグスキルで、修正案を出す前に根本原因を調査するよう求めます。調査、パターン分析、仮説検証、実装の段階に沿って、呼び出し経路の追跡と証拠の確認を支援します。

主な機能

  1. 01修正前に根本原因を調査
  2. 02障害の再現と切り分け
  3. 03LSPツールによる呼び出し経路の追跡
  4. 04検証可能な仮説と証拠の記録
  5. 05最小限の修正と検証
  6. 06一般的な障害向け手順書

活用シーン

  1. 01テストやビルドの失敗調査
  2. 02ランタイムクラッシュの原因追跡
  3. 03ブラウザーや統合エラーの診断
  4. 04断続的な不具合やリグレッションの分析

インストール

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

$npx skills add https://github.com/romiluz13/cc10x --skill debugging-patterns

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

同梱ファイルreferences/investigation-hygiene.mdreferences/root-cause-playbooks.md

詳細

系統的なデバッグ

概要

場当たり的な修正は時間を浪費し、新たなバグを生みます。応急処置は根本的な問題を覆い隠します。

基本原則: 修正を試みる前に、必ず根本原因を突き止めてください。症状だけを修正しても解決にはなりません。

このスキルは v10 では助言的なものです。調査の質を高めますが、ローカルだけのパッチ、推測、または「クラッシュした行を修正する」という考え方を認めるものではありません。

参考ファイル

現在の調査に必要な参考資料だけを読んでください。

  • references/root-cause-playbooks.md:ビルド/型の失敗、不安定なテスト、実行時クラッシュ、ブラウザーエラー、git bisect、境界の追跡について
  • references/investigation-hygiene.md:コンテキストの管理、証拠の記録、仮説の追跡、再開手順、アーキテクチャ上のエスカレーションについて

絶対原則

NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST

フェーズ 1 を完了していない場合、修正案を提示してはいけません。

5 ステップの簡易プロセス(参考パターン)

迅速なデバッグには、次の簡潔な流れを使用してください。

1. Capture error message and stack trace
2. Identify reproduction steps
3. Isolate the failure location
4. Implement minimal general fix
5. Verify solution works

デバッグ手法:

  • エラーメッセージとログを分析する
  • 最近のコード変更を確認する
  • 仮説を立てて検証する
  • 効果的な位置にデバッグログを追加する
  • 変数の状態を調べる

根本原因をたどる手法:

1. Observe symptom - Where does error manifest?
2. Find immediate cause - Which code produces the error?
3. Ask "What called this?" - Map call chain upward
4. Keep tracing up - Follow invalid data backward
5. Find original trigger - Where did problem actually start?

エラーが現れた箇所だけを修正してはいけません。元の引き金までさかのぼってください。 根本原因を特定したら、解決と判断する前に、近くに同じ兆候がないかを調べてください。

LSP を活用した根本原因の追跡

LSP を使って実行フローを体系的に追跡してください。

デバッグでの必要事項LSP ツール使用方法
「この関数はどこで定義されていますか?」lspGotoDefinition定義元へ移動する
「この関数を呼び出しているのはどこですか?」lspCallHierarchy(incoming)呼び出し元をさかのぼる
「この関数は何を呼び出していますか?」lspCallHierarchy(outgoing)呼び出し先をたどる
「この変数が使われている箇所はすべてどこですか?」lspFindReferencesすべての参照箇所を見つける

呼び出しチェーンを体系的に追跡する:

1. localSearchCode("errorFunction") → get file + lineHint
2. lspGotoDefinition(lineHint=N) → see implementation
3. lspCallHierarchy(incoming, lineHint=N) → who calls this?
4. For each caller: lspCallHierarchy(incoming) → trace up
5. Continue until you find the root cause

重要: まず localSearchCode から lineHint を必ず取得してください。行番号を推測してはいけません。

各問題について、次の内容を示してください:

  • 根本原因の説明
  • 診断を裏付ける証拠
  • 具体的なコード修正
  • テスト方法
  • 再発防止の提案

シナリオ別プレイブック

障害が次のいずれかに当てはまる場合は、references/root-cause-playbooks.md を読んでください。

  • ビルドまたは型の不具合
  • テストの失敗
  • 実行時クラッシュ
  • ブラウザーまたはコンソールのエラー
  • 非同期処理における断続的なバグ
  • 「以前は動いていた」機能のリグレッション
  • 複数コンポーネント間の受け渡しの失敗

この SKILL.md では、4 フェーズの調査ワークフローに焦点を当ててください。具体的なコマンド、境界を追跡するパターン、git bisect の手順については、参考資料を使用してください。

使用する場面

あらゆる技術的な問題に使用してください。

  • テストの失敗
  • 本番環境のバグ
  • 予期しない動作
  • パフォーマンスの問題
  • ビルドの失敗
  • 統合の問題

特に次のような場合に使用してください:

  • 時間に追われている(緊急時には推測に頼りたくなるため)
  • 「手早く一つ修正すればよい」と明らかに思える
  • すでに複数の修正を試した
  • 前回の修正が効果を発揮しなかった
  • 問題を十分に理解できていない

次の場合も省略しないでください:

  • 問題が単純に見える(単純なバグにも根本原因はあります)
  • 急いでいる(急ぐと必ずやり直しが発生します)
  • マネージャーから今すぐ直すよう求められている(場当たり的に試すより、体系的に進める方が速く解決できます)

4 つのフェーズ

次のフェーズに進む前に、各フェーズを必ず完了してください。

フェーズ 1:根本原因の調査

修正を試みる前に、必ず以下を行ってください。

  1. エラーメッセージを注意深く読む

    • エラーや警告を読み飛ばさないでください
    • 解決策そのものが記載されていることもよくあります
    • スタックトレースを最後まで読みます
    • 行番号、ファイルパス、エラーコードを記録します
  2. 一貫して再現する

    • 安定して発生させられますか?
    • 正確な手順は何ですか?
    • 毎回発生しますか?
    • 再現できない場合 → 推測せず、さらにデータを集めてください
  3. 最近の変更を確認する

    • 原因となり得る変更は何ですか?
    • Git の差分、最近のコミット
    • 新しい依存関係、設定の変更
    • 環境の違い
  4. 複数コンポーネントからなるシステムで証拠を集める

    システムに複数のコンポーネント(CI → ビルド → 署名、API → サービス → データベースなど)がある場合:

    修正を提案する前に、診断用の計測機能を追加してください。

    For EACH component boundary:
      - Log what data enters component
      - Log what data exits component
      - Verify environment/config propagation
      - Check state at each layer
    
    Run once to gather evidence showing WHERE it breaks
    THEN analyze evidence to identify failing component
    THEN investigate that specific component
    

    境界を追跡する具体的な手順については、 references/root-cause-playbooks.mdをお読みください。

  5. データフローを追跡する

    呼び出しスタックの深い場所でエラーが発生している場合:

    • 不正な値はどこから来ていますか?
    • 不正な値を渡した呼び出し元は何ですか?
    • 発生源が見つかるまでさかのぼって追跡してください
    • 症状ではなく、発生源を修正してください
  6. 設定がどこで使用されるかを追跡する(サードパーティ SDK、環境変数、インポート時)

    置き換え、移行、大規模なリファクタリングを提案する前に:

    • 選択肢ゼロ: 設定または環境の変更だけで修正できますか? コードを書き換える案を提案する前に、その仮説を明示し、テストしてください。多くの連携バグは、アーキテクチャではなく配線の問題です。
    • 環境変数がアプリケーションの設定で検証されているのに、ライブラリのコンストラクターに渡されていない場合は、誰がその値を読み取るのかを確認してください。サードパーティ SDK は、アプリの DI や設定オブジェクト経由ではなく、モジュールのインポート時/読み込み時にprocess.env(または各言語の同等のもの)を読み取ることがよくあります。アプリケーションコードを変更するのではなく、環境変数を設定または修正することで解決する場合があります。
    • サードパーティ SDK の置き換えを提案する前に、設定方法を少し調べてください。パッケージの README、公式ドキュメント、またはnode_modules(またはベンダーパス)にあるインストール済みのソースを確認します。別のライブラリが必要なのではなく、エンドポイントやフラグが間違っている可能性があります。
    • コードのコメントにインポート時の動作や環境変数への依存が記載されている場合、それらを単なる装飾ではなく、調査の手がかりとして扱い、実際に読み取る箇所を追跡してください。
フェーズ 2:パターン分析

修正する前に、パターンを見つけてください。

  1. 動作する例を見つける

    • 同じコードベース内から、類似する動作中のコードを探します
    • 壊れている箇所と似ていて、正常に動作しているものは何ですか?
  2. 参考資料と照らし合わせる

    • パターンを実装する場合は、参考実装をすべて読みます
    • ざっと読むのではなく、一行ずつ確認してください
    • 適用する前に、パターンを完全に理解してください
  3. 違いを特定する

    • 動作するものと壊れているものの違いは何ですか?
    • どんなに小さくても、すべての違いを書き出します
    • 「影響するはずがない」と決めつけないでください
  4. 依存関係を理解する

    • これには他にどのコンポーネントが必要ですか?
    • どの設定、構成、環境が必要ですか?
    • どのような前提がありますか?
フェーズ 3:仮説とテスト

科学的な手順に従ってください。

  1. 単一の仮説を立てる

    • 「Y が理由で、X が根本原因だと思います」と明確に述べます
    • 書き留めます
    • 曖昧にせず、具体的にします
  2. 最小限のテストを行う

    • 仮説を検証するために、可能な限り最小限の変更を行います
    • 一度に一つの変数だけを変更します
    • 複数のことを一度に修正しないでください
  3. 先に進む前に検証する

    • 動作しましたか? はい → フェーズ 4 へ
    • 動作しませんでしたか? 新しい仮説を立てます
    • 修正を次々と重ねないでください
  4. わからない場合

    • 「X が理解できません」と伝えます
    • わかったふりをしないでください
    • 助けを求めます
    • さらに調査します
仮説の品質基準

反証可能性の要件: 優れた仮説は、誤りであることを証明できます。それを否定する実験を考案できないなら、その仮説は役に立ちません。

悪い例(反証不可能):

  • 「状態のどこかがおかしい」
  • 「タイミングがずれている」
  • 「どこかに競合状態がある」

良い例(反証可能):

  • 「ルート変更時にコンポーネントが再マウントされるため、ユーザーの状態がリセットされる」
  • 「アンマウント後に API 呼び出しが完了し、アンマウントされたコンポーネントで状態が更新される」
  • 「2 つの非同期処理がロックせずに同じ配列を変更するため、データが失われる」

違い: 具体性です。優れた仮説は、具体的で検証可能な主張を示します。

仮説の確信度スコア

確信度を付けて複数の仮説を追跡します:

H1: [hypothesis] — Confidence: [0-100]
    Evidence for: [what supports this]
    Evidence against: [what contradicts this]
    Next test: [what would raise or lower confidence]

H2: [hypothesis] — Confidence: [0-100]
    Evidence for: [...]
    Evidence against: [...]
    Next test: [...]

H3: [hypothesis] — Confidence: [0-100]
    Evidence for: [...]
    Evidence against: [...]
    Next test: [...]

スコアの目安:

範囲意味対応
80-100強い証拠があり、確実性が高い修正に進む
50-79間接的な証拠があり、さらなるデータが必要「次のテスト」を実行する
0-49推測であり、根拠が弱い優先度を下げるか、破棄する

ルール:

  • いずれかの仮説が 80 以上になるまで、常に 2~3 個の仮説を維持します
  • 新しい証拠が得られるたびに、必ず確信度を更新します
  • 最も確信度の高い仮説が 50 未満の状態で、修正に進んではいけません
デバッグにおける認知バイアス
バイアス落とし穴対策
確証バイアス仮説を裏付ける証拠だけを探す「何があれば、自分の考えが間違いだと証明できるか?」
アンカリング最初の説明にとらわれる調査を始める前に、3 つ以上の仮説を立てる
利用可能性ヒューリスティック最近のバグから、同じ原因だと思い込む証拠が示すまでは、各バグを新しい事象として扱う
サンクコストその方針に 2 時間費やしたため、証拠に反して続ける30 分ごとに、「今初めて取り組むとしても、この方針を選ぶか?」と自問する
メタデバッグ:自分のコード

自分が書いたコードをデバッグするときは、自分自身のメンタルモデルと向き合うことになります。

難しい理由:

  • 自分で設計上の判断を下したため、それが明らかに正しいと感じます
  • 実際に実装した内容ではなく、意図したことを覚えています
  • 慣れによって、バグが見えなくなります

心構え:

  1. 自分のコードを他人のコードとして扱う - 誰か別の人が書いたかのように読みます
  2. 設計上の判断を疑う - 実装上の選択は事実ではなく、仮説です
  3. 自分のメンタルモデルが間違っている可能性を認める - コードの動作が真実であり、自分のモデルは推測です
  4. 自分が変更したコードを優先的に調べる - 100 行を変更して何かが壊れたなら、その行が有力な容疑箇所です

最も認めにくいこと: 「自分の実装が間違っていた」。「要件が明確でなかった」ではありません。間違えたのは、あなたです。

調査をやり直すタイミング

次の場合は、最初からやり直すことを検討します:

  1. 2 時間以上進展がない - 視野が狭くなっている可能性があります
  2. 修正を 3 回以上試しても効果がない - メンタルモデルが間違っています
  3. 現在の動作を説明できない - 混乱した状態に変更を重ねてはいけません
  4. デバッガー自体をデバッグしている - 根本的な問題があります
  5. 修正は機能するが、理由がわからない - これは修正ではなく、運です

やり直しの手順:

  1. すべてのファイルとターミナルを閉じます
  2. 確実にわかっていることを書き出します
  3. 原因ではないと判断したことを書き出します
  4. 以前とは異なる新しい仮説を列挙します
  5. フェーズ 1 から再開します
フェーズ 4:実装

症状ではなく、根本原因を修正します。

  1. 失敗するテストケースを作成する

    • 可能な限り簡単に再現します
    • 可能であれば自動テストを作成します
    • テストフレームワークがない場合は、単発のテストスクリプトを作成します
    • 修正前に必ず作成してください
  2. 修正を1つだけ実装する

    • 特定した根本原因に対処します
    • 一度に変更するのは1つだけです
    • 「ついでに」改善することはありません
    • リファクタリングをまとめて行うことはありません
  3. 修正を検証する

    • テストは通るようになりましたか?
    • ほかのテストに影響はありませんか?
    • 問題は実際に解決しましたか?
  4. 修正が機能しない場合

    • 停止します
    • 試した修正の数を数えます
    • 3回未満の場合:フェーズ 1 に戻り、新たな情報をもとに再分析します
    • 3回以上の場合:停止してアーキテクチャを疑います(下記のステップ 5)
    • アーキテクチャについて話し合わずに、修正 #4 を試してはいけません
  5. 修正が3回以上失敗した場合:アーキテクチャを疑う

    アーキテクチャ上の問題を示すパターン:

    • 修正するたびに、別の箇所で新たな共有状態/結合/問題が見つかる
    • 修正の実装に「大規模なリファクタリング」が必要になる
    • 修正するたびに、別の箇所で新たな症状が発生する

    停止して、根本を問い直します。

    • このパターンは根本的に妥当ですか?
    • 「ただ惰性で続けている」状態ではありませんか?
    • 症状の修正を続けるのではなく、アーキテクチャをリファクタリングすべきではありませんか?

    さらに修正を試みる前に、人間のパートナーと話し合ってください。

    これは仮説の失敗ではありません。アーキテクチャが間違っています。

危険信号 — 停止して手順に従う

次のように考えていることに気づいたら:

  • 「とりあえず応急処置をして、調査は後で」
  • 「X を変えて、うまくいくか試そう」
  • 「変更をいくつか加えて、テストを実行しよう」
  • 「テストは省略して、手動で確認しよう」
  • 「おそらく X だろう。修正しよう」
  • 「完全には理解していないけれど、これでうまくいくかもしれない」
  • 「パターンでは X となっているけれど、違うやり方にしよう」
  • 「主な問題はこちらです:[調査せずに修正を列挙する]」
  • データの流れを追跡する前に解決策を提案する
  • 設定だけの修正(オプションゼロ)と、インポート時に環境変数/設定を誰が読み取るのかの追跡を行う前に、SDK の置き換えや大規模な移行を提案する
  • 「もう一度だけ修正を試す」(すでに2回以上試している場合)
  • 修正するたびに、別の箇所で新たな問題が見つかる

これらはすべて、停止してフェーズ 1 に戻る必要があることを示しています。

**修正が3回以上失敗した場合:**アーキテクチャを疑います(フェーズ 4.5 を参照)。

ユーザーが、対応を誤っていると示すサイン

次のような指摘に注意してください。

  • 「それは起きていないのでは?」— 検証せずに思い込んでいます
  • 「それで……が分かりますか?」— 証拠を集めるべきでした
  • 「推測をやめて」— 理解する前に修正を提案しています
  • 「徹底的に考えて」— 症状だけでなく、根本を問い直してください
  • 「行き詰まっているの?」(苛立った様子)— そのアプローチはうまくいっていません

**このような指摘があったら:**停止してフェーズ 1 に戻ります。

正当化を防ぐ

言い訳実際のところ
「単純な問題だから、手順は必要ない」単純な問題にも根本原因があります。単純なバグなら、手順にかかる時間も短くて済みます。
「緊急だから、手順を踏む時間がない」体系的なデバッグのほうが、推測と確認を繰り返すより速く解決できます。
「まずこれを試してから、調査しよう」最初の修正がその後の進め方を決めます。最初から正しく行いましょう。
「修正がうまくいくと確認してから、テストを書こう」テストしていない修正は定着しません。先にテストを書けば、修正が有効か確認できます。
「複数の修正を一度に行えば、時間を節約できる」何がうまくいったのか特定できず、新たなバグの原因になります。
「参照資料が長すぎるから、パターンを応用しよう」理解が不完全なままでは、必ずバグにつながります。最後まで読んでください。
「問題が分かった。修正しよう」症状が見えていることと、根本原因を理解していることは別です。
「もう一度だけ修正を試す」(2回以上失敗した後)3回以上の失敗は、アーキテクチャ上の問題を示します。パターンを疑い、再度修正を試してはいけません。

クイックリファレンス

フェーズ主な活動成功基準
1. 根本原因エラーを読み、再現し、変更を確認し、証拠を集めます何が起きたのか、なぜ起きたのかを理解する
2. パターン動作する例を見つけ、比較します違いを特定する
3. 仮説仮説を立て、最小限のテストを行います仮説が確認されるか、新たな仮説が立つ
4. 実装テストを作成し、修正して、検証しますバグが解決し、テストが通る

プロセスを経ても「根本原因がない」と判明した場合

体系的な調査の結果、問題が本当に環境依存、タイミング依存、または外部要因によるものだと判明した場合:

  1. プロセスを完了しています
  2. 調査した内容を記録します
  3. 適切な対処(再試行、タイムアウト、エラーメッセージ)を実装します
  4. 今後の調査に備えて、監視やログ記録を追加します

ただし:「根本原因がない」ケースの95%は、調査が不十分です。

出力形式

## Bug Investigation

### Phase 1: Evidence Gathered
- **Error**: [exact error message]
- **Stack trace**: [relevant lines]
- **Reproduction**: [steps to reproduce]
- **Recent changes**: [commits/changes]

### Phase 2: Pattern Analysis
- **Working example**: [similar working code]
- **Key differences**: [what's different]

### Phase 3: Hypothesis
- **Theory**: [I think X because Y]
- **Test**: [minimal change made]
- **Result**: [confirmed/refuted]

### Phase 4: Fix
- **Root cause**: [actual cause with evidence]
- **Change**: [summary of fix]
- **File**: [path:line]
- **Regression test**: [test added]

### Verification
- Test command: [command] → exit 0
- All tests: PASS
- Functionality: Restored

コメント