systematic-debugging について
技術的な問題に取り組む開発者やエンジニア向けのデバッグスキルです。根本原因の調査、パターン分析、仮説検証、修正と確認の4段階で、推測による修正を避けます。
主な機能
- 014 段階の根本原因デバッグ手順
- 02問題の再現と証拠の収集
- 03動作例と失敗例の比較
- 04仮説を一つずつ検証
- 05修正失敗が続く場合にアーキテクチャを再検討
活用シーン
- 01テスト失敗やビルドエラーの調査
- 02本番環境の予期しない動作の診断
- 03性能問題や統合障害の追跡
- 04修正が続けて失敗した際の構成再評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ osmontero/ opencode-skills --skill systematic-debuggingインストール後、Claude Code で/systematic-debuggingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
condition-based-waiting-example.tscondition-based-waiting.mddefense-in-depth.mdfind-polluter.shLICENSE.txtroot-cause-tracing.md詳細
系統的なデバッグ
概要
手当たり次第に修正すると時間を無駄にし、新たなバグを生みます。応急処置では根本的な問題が隠れてしまいます。
基本原則: 修正を試みる前に、必ず根本原因を突き止めてください。症状だけを修正するのは失敗です。
このプロセスを字面どおりに守らないことは、デバッグの精神に反することです。
絶対の原則
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
フェーズ 1 を完了していない場合、修正を提案することはできません。
使用する場面
あらゆる技術的な問題に使用してください。
- テストの失敗
- 本番環境のバグ
- 予期しない動作
- パフォーマンスの問題
- ビルドの失敗
- 統合の問題
特に次のような場合に使用してください:
- 時間に追われている(緊急時には推測に頼りたくなります)
- 「すぐにできる簡単な修正」が明らかに思える
- すでに複数の修正を試している
- 以前の修正がうまくいかなかった
- 問題を十分に理解できていない
次のような場合でも省略しないでください:
- 問題が単純に見える(単純なバグにも根本原因があります)
- 急いでいる(焦るとやり直しが確実に増えます)
- マネージャーが「今すぐ」直すよう求めている(体系的に進めるほうが、試行錯誤を繰り返すより速く済みます)
4 つのフェーズ
次のフェーズに進む前に、各フェーズを必ず完了してください。
フェーズ 1:根本原因の調査
修正を試みる前に:
-
エラーメッセージを注意深く読む
- エラーや警告を読み飛ばさない
- 多くの場合、正確な解決方法が記載されています
- スタックトレースを最後まで読む
- 行番号、ファイルパス、エラーコードを記録する
-
一貫して再現できるようにする
- 確実に発生させられますか?
- 正確な手順は何ですか?
- 毎回発生しますか?
- 再現できない場合 → 推測せず、さらにデータを集める
-
最近の変更を確認する
- 原因となりそうな変更は何ですか?
- Git の差分、最近のコミット
- 新しい依存関係、設定の変更
- 環境の違い
-
複数のコンポーネントで構成されたシステムの証拠を集める
システムに複数のコンポーネント(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例(複数レイヤーのシステム):
# Layer 1: Workflow echo "=== Secrets available in workflow: ===" echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}" # Layer 2: Build script echo "=== Env vars in build script: ===" env | grep IDENTITY || echo "IDENTITY not in environment" # Layer 3: Signing script echo "=== Keychain state: ===" security list-keychains security find-identity -v # Layer 4: Actual signing codesign --sign "$IDENTITY" --verbose=4 "$APP"これにより、どのレイヤーで失敗しているかが明らかになります(シークレット → ワークフロー OK、ワークフロー → ビルド FAIL)
-
データフローを追跡する
呼び出しスタックの深いところでエラーが発生している場合:
完全な逆方向トレース手法については、このディレクトリの
root-cause-tracing.mdを参照してください。簡易版:
- 不正な値はどこで発生していますか?
- 何が不正な値を使ってこれを呼び出しましたか?
- 発生源が見つかるまで、上流へたどり続ける
- 症状ではなく、発生源を修正する
フェーズ 2:パターン分析
修正する前にパターンを見つけてください:
-
正常に動作する例を見つける
- 同じコードベース内で、類似した正常動作するコードを探す
- 壊れているものと似ていて、正常に動作するものは何ですか?
-
参照実装と比較する
- パターンを実装する場合は、参照実装を最初から最後まで読む
- 斜め読みせず、すべての行を読む
- 適用する前に、パターンを完全に理解する
-
違いを特定する
- 正常に動作するものと壊れているものの違いは何ですか?
- どんなに小さくても、すべての違いを列挙する
- 「これは関係ない」と決めつけない
-
依存関係を理解する
- これが必要とする他のコンポーネントは何ですか?
- 必要な設定、構成、環境は何ですか?
- どのような前提を置いていますか?
フェーズ 3:仮説とテスト
科学的手法:
-
単一の仮説を立てる
- 「Y であるため、根本原因は X だと考えます」と明確に述べる
- 書き留める
- 曖昧にせず、具体的にする
-
最小限のテストを行う
- 仮説を検証するために、可能な限り小さな変更を加える
- 一度に変更する変数は 1 つだけにする
- 複数の問題を一度に修正しない
-
続行する前に検証する
- 動作しましたか? はい → フェーズ 4
- 動作しませんでしたか? 新しい仮説を立てる
- 修正をさらに重ねない
-
わからないとき
- 「X が理解できません」と伝える
- わかったふりをしない
- 助けを求める
- さらに調査する
フェーズ 4:実装
症状ではなく、根本原因を修正します:
-
失敗するテストケースを作成する
- 可能な限りシンプルに再現する
- 可能であれば自動テストを作成する
- テストフレームワークがない場合は、単発のテストスクリプトを作成する
- 修正前に必ず作成する
- 適切な失敗テストを書くには、
test-driven-developmentスキルを使用する
-
修正を 1 つだけ実装する
- 特定した根本原因に対処する
- 一度に変更するのは 1 つだけ
- 「ついでの」改善はしない
- リファクタリングをまとめて行わない
-
修正を検証する
- テストは通るようになったか?
- ほかのテストは壊れていないか?
- 問題は実際に解決したか?
-
修正がうまくいかない場合
- 停止する
- 試した修正の回数を数える
- 3 回未満の場合:フェーズ 1 に戻り、新しい情報をもとに再分析する
- 3 回以上の場合:停止し、アーキテクチャを検討する(下記のステップ 5)
- アーキテクチャについて話し合わずに、修正 #4 を試してはいけません
-
修正が 3 回以上失敗した場合:アーキテクチャを検討する
アーキテクチャ上の問題を示すパターン:
- 修正のたびに、別の場所で新たな共有状態、結合、問題が明らかになる
- 修正の実装に「大規模なリファクタリング」が必要になる
- 修正のたびに、別の場所で新たな症状が発生する
停止して、根本から検討する:
- このパターンは根本的に妥当か?
- 「ただ惰性で続けている」だけではないか?
- 症状の修正を続けるのではなく、アーキテクチャをリファクタリングすべきか?
さらに修正を試す前に、人間のパートナーと話し合ってください
これは仮説が間違っていたのではありません。アーキテクチャが間違っています。
注意すべき兆候 — 停止して手順に従う
次のように考えていることに気づいたら:
- 「とりあえず応急処置をして、調査は後で」
- 「X を変更して、うまくいくか試してみよう」
- 「いくつか変更を加えて、テストを実行しよう」
- 「テストは省略して、手動で確認しよう」
- 「おそらく X だろう。修正してみよう」
- 「完全には理解していないけれど、うまくいくかもしれない」
- 「パターンでは X となっているけれど、別のやり方にしよう」
- 「主な問題はこちらです:[調査せずに修正を列挙する]」
- データの流れを追跡する前に解決策を提案する
- 「もう一度だけ修正を試す」(すでに 2 回以上試している場合)
- 修正のたびに別の場所で新たな問題が見つかる
これらはすべて、停止してフェーズ 1 に戻るべきサインです。
修正が 3 回以上失敗した場合: アーキテクチャを検討してください(フェーズ 4、ステップ 5 を参照)
人間のパートナーが示す、誤った進め方のサイン
次のような指摘に注意してください:
- 「それは本当に起きていますか?」 — 確認せずに決めつけています
- 「それで分かるようになりますか……?」 — 証拠を集めるべきでした
- 「推測はやめてください」 — 理解せずに修正を提案しています
- 「これを徹底的に考えてください」 — 症状だけでなく、根本から検討する必要があります
- 「行き詰まっていませんか?」(不満げに) — 進め方がうまくいっていません
このような指摘を受けたら: 停止してフェーズ 1 に戻ります。
よくある正当化
| 言い訳 | 実際のところ |
|---|---|
| 「問題は簡単だから、手順は不要」 | 簡単な問題にも根本原因があります。簡単なバグなら、手順を踏んでもすぐに解決できます。 |
| 「緊急なので、手順を踏む時間がない」 | 系統的なデバッグは、推測と試行錯誤を繰り返すよりも速く進みます。 |
| 「先にこれだけ試して、それから調査しよう」 | 最初の修正が進め方の基準になります。最初から正しく進めてください。 |
| 「修正がうまくいったと確認してからテストを書こう」 | テストされていない修正は定着しません。先にテストを書けば、修正が正しいと証明できます。 |
| 「修正を一度に複数行えば時間を節約できる」 | 何が有効だったのか切り分けられず、新たなバグの原因になります。 |
| 「参考資料が長すぎるので、パターンを応用しよう」 | 理解が不完全だと、必ずバグにつながります。最後まで読んでください。 |
| 「問題は分かった。修正しよう」 | 症状が見えていることと、根本原因を理解していることは別です。 |
| 「もう一度だけ修正を試す」(2 回以上失敗した後) | 3 回以上失敗した場合は、アーキテクチャに問題があります。パターンを見直し、修正を繰り返さないでください。 |
クイックリファレンス
| フェーズ | 主な作業 | 成功基準 |
|---|---|---|
| 1. 根本原因 | エラーを読む、再現する、変更を確認する、証拠を集める | 何が起きているか、なぜ起きているかを理解する |
| 2. パターン | 動作する例を探して比較する | 相違点を特定する |
| 3. 仮説 | 理論を立て、最小限のテストを行う | 確認できた、または新たな仮説を立てた |
| 4. 実装 | テストを作成し、修正して、検証する | バグが解決し、テストが通る |
プロセスを尽くしても「根本原因」が見つからない場合
体系的に調査した結果、問題が実際に環境、タイミング、または外部要因に依存していると判明した場合:
- プロセスを最後まで完了しています
- 調査した内容を記録します
- 適切な処理を実装します(再試行、タイムアウト、エラーメッセージ)
- 今後の調査に備えて、監視とログ記録を追加します
ただし:「根本原因が見つからない」ケースの95%は、調査が不十分です。
関連するテクニック
これらのテクニックは体系的なデバッグの一環であり、このディレクトリで利用できます。
root-cause-tracing.md- コールスタックを逆方向にたどり、バグの最初の引き金を見つけますdefense-in-depth.md- 根本原因を見つけた後、複数の層に検証を追加しますcondition-based-waiting.md- 任意のタイムアウトを、条件をポーリングする方法に置き換えます
関連するスキル:
- test-driven-development - 失敗するテストケースの作成(フェーズ4、ステップ1)
- verifying-before-completion - 成功を宣言する前に、修正が機能したことを検証します
実環境での効果
デバッグセッションでの実績:
- 体系的なアプローチ:修正に15~30分
- 手当たり次第に修正するアプローチ:試行錯誤に2~3時間
- 初回で修正できる割合:95% 対 40%
- 新たなバグの発生:ほぼゼロ 対 頻発