mcpField
S
systematic-debugging

systematic-debugging

github.com/sickn33開発48.7k1.6k 回インストール今日更新
リポジトリ

systematic-debugging について

開発者やコーディングエージェント向けのデバッグスキルです。推測ではなく段階的に原因を調べ、仮説を一つずつ検証してから修正を実装し、確認します。

主な機能

  1. 014段階の根本原因調査
  2. 02障害の再現と証拠収集
  3. 03正常系と異常系の比較
  4. 04仮説を一つずつ検証
  5. 05回帰テストによる修正確認

活用シーン

  1. 01本番障害やテスト失敗の調査
  2. 02コンポーネント間の障害追跡
  3. 03ビルドや連携の問題診断

インストール

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

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill systematic-debugging

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

condition-based-waiting-example.ts
condition-based-waiting.md
CREATION-LOG.md
defense-in-depth.md
find-polluter.sh
root-cause-tracing.md
test-academic.md
test-pressure-1.md
test-pressure-2.md
test-pressure-3.md

詳細

体系的なデバッグ

概要

ランダムな修正は時間を無駄にし、新たなバグを生み出します。場当たり的なパッチは根本的な問題を覆い隠します。

中核原則: 推測する前に調査し、検証済みの修復と一時的な緩和策を区別してください。インシデント発生中は、根本原因の調査を続けながら、承認されたロールバックや封じ込め措置によってサービスを復旧させてもかまいません。

このプロセスの文言に違反することは、デバッグの精神に違反することです。

鉄の掟

NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST

まず観測可能な障害と、最小限で有用な証拠確認から始めてください。緊急緩和策には明示的にラベルを付け、後に行う根本原因調査のために証拠を保存してください。

使用すべき場面

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

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

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

  • 時間的プレッシャーがあるとき(緊急時は推測したくなります)
  • 「ちょっとした修正だけ」が明白に思えるとき
  • すでに複数の修正を試したとき
  • 以前の修正がうまくいかなかったとき
  • 問題を完全に理解していないとき

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

  • 問題が単純に見えるとき(単純なバグにも根本原因はあります)
  • 急いでいるとき(急ぐと必ず手戻りが発生します)
  • 上司が今すぐ修正を求めているとき(体系的な方が場当たり的な対応より速いです)

4 つのフェーズ

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

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

いかなる修正を試みる前にも:

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

    • エラーや警告を読み飛ばさない
    • そこには正確な解決策が含まれていることが多い
    • スタックトレースを完全に読む
    • 行番号、ファイルパス、エラーコードを書き留める
  2. 一貫して再現する

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

    • これを引き起こしうる変更は何か?
    • Git diff、最近のコミット
    • 新しい依存関係、設定の変更
    • 環境の違い
  4. 複数コンポーネントのシステムで証拠を集める

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

    修正を提案する前に、診断用の計装を追加してください:

    For EACH component boundary:
      - Record allowed field names, sizes, statuses and correlation IDs
      - Redact secrets and private payloads before logging
      - 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
    

    例(多層システム):

    # In each relevant process, report presence only; never dump secret values.
    if [ -n "${IDENTITY:-}" ]; then
      echo 'IDENTITY is set'
    else
      echo 'IDENTITY is absent or empty'
    fi
    
    # Read-only validation of an already-built artifact, when available.
    codesign --verify --verbose=2 "$APP"
    

    解釈: 実際のワークフロー/ビルドの境界で存在チェックを比較してください。成果物の検証だけでは、正しい署名 ID が伝播したことを証明するものではありません。

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

    エラーがコールスタックの深い位置にある場合:

    完全な逆方向追跡の手法については、このディレクトリの root-cause-tracing.md を参照してください。

    簡単なバージョン:

    • 不正な値はどこから発生したのか?
    • 何がこの不正な値でこれを呼び出したのか?
    • 発生源が見つかるまで追跡を続ける
    • 症状ではなく発生源で修正する
フェーズ 2: パターン分析

修正する前にパターンを見つける:

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

    • 同じコードベース内で類似の動作するコードを探す
    • 壊れているものに似ていて、動作しているものは何か?
  2. 参照実装と比較する

    • パターンを実装する場合、参照実装を完全に読む
    • 斜め読みしない - すべての行を読む
    • 適用する前にパターンを完全に理解する
  3. 相違点を特定する

    • 動作するものと壊れているものの違いは何か?
    • どんなに小さくても、すべての違いを列挙する
    • 「それは関係ないはず」と決めつけない
  4. 依存関係を理解する

    • これには他にどのコンポーネントが必要か?
    • どの設定、構成、環境が必要か?
    • どのような前提を置いているか?
フェーズ 3: 仮説と検証

科学的手法:

  1. 単一の仮説を立てる

    • 明確に述べる: 「X が根本原因だと思う。なぜなら Y だからだ」
    • 書き留める
    • 曖昧にせず、具体的にする
  2. 最小限の検証を行う

    • 仮説を検証するために可能な限り最小の変更を加える
    • 一度に 1 つの変数のみ
    • 複数のことを一度に修正しない
  3. 続行する前に検証する

    • うまくいったか? はい → フェーズ 4
    • うまくいかなかったか? 新しい仮説を立てる
    • さらなる修正を上乗せしないこと
  4. わからないとき

    • 「X が理解できない」と伝える
    • 知っているふりをしない
    • 助けを求める
    • さらに調査する
フェーズ 4: 実装

症状ではなく根本原因を修正する:

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

    • 可能な限り最も単純な再現
    • 可能であれば自動テスト
    • フレームワークがなければ単発のテストスクリプト
    • 修正する前に必ず用意すること
    • 適切な場合は、焦点を絞った振る舞いのリグレッションに test-driven-development を使用する
  2. 単一の修正を実装する

    • 特定した根本原因に対処する
    • 一度に 1 つの変更のみ
    • 「ついでに」改善は行わない
    • リファクタリングを同梱しない
  3. 修正を検証する

    • テストが通ったか?
    • 他のテストが壊れていないか?
    • 問題は実際に解決したか?
  4. 修正がうまくいかない場合

    • 停止する
    • 数える: これまでにいくつの修正を試したか?
    • 3 未満の場合: フェーズ 1 に戻り、新しい情報で再分析する
    • 3 以上の場合: 停止し、アーキテクチャを疑う (以下のステップ 5)
    • アーキテクチャについての議論なしに修正 #4 を試みないこと
  5. 3 つ以上の修正が失敗した場合: アーキテクチャを疑う

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

    • 各修正が、別の場所で新たな共有状態/結合/問題を明らかにする
    • 修正の実装に「大規模なリファクタリング」が必要になる
    • 各修正が、他の場所で新たな症状を生み出す

    停止し、根本を疑う:

    • このパターンは根本的に健全か?
    • 「単なる惰性でそれに固執して」いないか?
    • 症状の修正を続けるのではなく、アーキテクチャをリファクタリングすべきか?

    さらなる修正を試みる前に、人間のパートナーと話し合う

    繰り返しの失敗は、前提と結合を見直すための証拠であり、アーキテクチャが間違っていることを証明するものではありません。

危険信号 - 停止してプロセスに従う

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

  • 「今は応急処置をして、後で調査しよう」
  • 「とりあえず X を変えてみて、うまくいくか見てみよう」
  • 「複数の変更を加えて、テストを実行しよう」
  • 「テストを飛ばして、手動で検証しよう」
  • 「おそらく X だろう、それを修正しよう」
  • 「完全には理解していないが、これでうまくいくかもしれない」
  • 「パターンは X と言っているが、違うやり方で適応させよう」
  • 「主な問題はこれらだ: [調査せずに修正を列挙]」
  • データフローを追跡する前に解決策を提案する
  • 「もう一度だけ修正を試す」(すでに 2 回以上試した場合)
  • 各修正が別の場所で新たな問題を明らかにする

これらすべては次のことを意味します: 停止する。フェーズ 1 に戻る。

3 つ以上の修正が失敗した場合: アーキテクチャを疑う (フェーズ 4.5 を参照)

あなたが間違っているときの人間のパートナーのシグナル

これらの軌道修正に注意する:

  • 「そんなことは起きていないのでは?」 - 検証せずに思い込んだ
  • 「それは私たちに…を示してくれるか?」 - 証拠収集を追加すべきだった
  • 「推測をやめろ」 - 理解せずに修正を提案している
  • 「これを徹底的に考えろ」 - 症状だけでなく根本を疑え
  • 「行き詰まっている?」(いらだち) - あなたのアプローチは機能していない

これらを見たら: 停止する。フェーズ 1 に戻る。

よくある正当化

言い訳現実
「問題は単純だから、プロセスは必要ない」単純な問題にも根本原因はあります。単純なバグならプロセスは高速です。
「緊急事態だから、プロセスを踏む時間がない」体系的なデバッグは、当てずっぽうの試行錯誤よりも速いです。
「まずこれを試してから、調査する」最初の修正がパターンを決めます。最初から正しく行いましょう。
「修正が機能することを確認してからテストを書く」テストされていない修正は定着しません。まずテストで証明しましょう。
「複数の修正を一度に行えば時間の節約になる」何が効いたのかを切り分けられません。新たなバグを生みます。
「リファレンスが長すぎるので、パターンをアレンジする」部分的な理解はバグを保証します。完全に読みましょう。
「問題はわかった、修正させて」症状が見えること ≠ 根本原因を理解すること。
「もう一度だけ修正を試す」(2回以上失敗した後)3回以上の失敗 = アーキテクチャ上の問題。パターンを疑い、再び修正しないこと。

クイックリファレンス

フェーズ主な活動成功基準
1. 根本原因エラーを読む、再現する、変更を確認する、証拠を集めるWHAT と WHY を理解する
2. パターン動作する例を探す、比較する差異を特定する
3. 仮説理論を立てる、最小限にテストする確認される、または新たな仮説
4. 実装テストを作成する、修正する、検証するバグが解決し、テストが通る

プロセスが「根本原因なし」を明らかにしたとき

体系的な調査により、問題が真に環境依存、タイミング依存、または外部要因であることが明らかになった場合:

  1. プロセスを完了しています
  2. 調査した内容を文書化します
  3. 適切な処理(リトライ、タイムアウト、エラーメッセージ)を実装します
  4. 今後の調査のためにモニタリング/ログを追加します

残っている不確実性と、環境的な障害と実装上の欠陥を区別するであろう証拠を明記します。

補助テクニック

これらのテクニックは体系的なデバッグの一部であり、このディレクトリで利用できます:

  • root-cause-tracing.md - コールスタックを遡ってバグを追跡し、元のトリガーを見つける
  • defense-in-depth.md - 根本原因を特定した後、複数のレイヤーに検証を追加する
  • condition-based-waiting.md - 恣意的なタイムアウトを条件ポーリングに置き換える

関連スキル:

  • test-driven-development - 焦点を絞った振る舞いのリグレッション
  • 成功を主張する前に、現在のリポジトリの検証コマンドを使用する

実例と期待される結果

入力: ビルドがローカルでは成功するが、CI では失敗する。理由は、ビルドのサブプロセスに必要な識別情報が存在しないため。各境界でそれが設定されているかどうかのみを記録し、環境変数がどのように転送されるかを調べ、その伝播を一度だけ変更します。失敗したビルドを再実行し、成果物を別途検証します。期待される結果: サブプロセスが必要な設定を受け取り、元の失敗が消えること。ログに認証情報の値が含まれないこと。

入力と前提条件

再現可能なコマンドまたは観察された失敗、正確なリビジョン/ランタイム、最近の変更、および承認されたテスト環境へのアクセス。同梱の過去のケースノートはテクニックを説明するものです。そこに報告されている件数は、新鮮な測定値でも、このプロジェクトに対する保証でもありません。

制限事項

  • 一時的な緩和と根本原因の修理は異なる結果です。インシデントが即時の封じ込めを必要とする場合は、両方を記録してください。
  • ログはシークレットや個人のパスを露出する可能性があります。許可リストに登録されたサマリーを使用し、共有する前にキャプチャした成果物を検査してください。
  • polluter ヘルパーはプロジェクトのテストコマンドを実行し、プロジェクトのコードを実行する可能性があります。隔離されたフィクスチャ/チェックアウトを使用し、ランナーがファイル引数を受け入れることを確認してください。
  • waiting の例はドメインアダプターを必要とし、すべての競合を不可能にすることはできません。実際のタイムアウト/エラーのパスを再現してください。

コメント