mcpField
D
diagnose

diagnose

github.com/leandrocfe開発4141 回インストール11 週間前に更新
リポジトリ

diagnose について

diagnose は、コーディングエージェント向けの難しいバグのデバッグスキルです。調査に先立って確実なフィードバックループを作り、再現、仮説の検証、計測、回帰テスト、後片付けへと進めます。

主な機能

  1. 01決定的な不具合フィードバックループの構築
  2. 02障害の再現と正確な記録
  3. 03反証可能な仮説の順位付け
  4. 04要所に絞った計測
  5. 05回帰テストの追加と後片付け

活用シーン

  1. 01断続的な障害のデバッグ
  2. 02報告された本番環境の問題調査
  3. 03コミットやバージョン間の回帰追跡

インストール

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

$npx skills add https://github.com/leandrocfe/skills --skill diagnose

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

同梱ファイルscripts/hitl-loop.template.sh

詳細

診断

難しいバグに取り組むための手順です。明確な根拠がない限り、フェーズを飛ばさないでください。

コードベースを調べる際は、プロジェクトのドメイン用語集を使って関連モジュールの明確なメンタルモデルを構築し、対象領域の ADR も確認してください。

フェーズ 1 — フィードバックループを構築する

これがこのスキルの本質です。 それ以外はすべて機械的な作業です。バグに対して高速かつ決定論的で、エージェントが実行できる合否判定のシグナルがあれば、原因を見つけられます。二分探索、仮説検証、計測はいずれもそのシグナルを利用するだけです。シグナルがなければ、どれだけコードを眺めても解決にはつながりません。

ここに、通常よりはるかに多くの労力をかけてください。積極的に取り組んでください。創意工夫してください。諦めないでください。

構築方法 — おおむね次の順に試してください
  1. バグに到達できる seam での失敗するテスト — unit、integration、e2e。
  2. 起動中の dev server に対する curl / HTTP スクリプト。
  3. fixture input を使った CLI の実行。stdout を既知の正常な状態のスナップショットと比較します。
  4. ヘッドレスブラウザーのスクリプト(Playwright / Puppeteer)— UI を操作し、DOM/console/network をアサートします。
  5. キャプチャした trace の再生。 実際の network request/payload/event log をディスクに保存し、該当する code path を分離して再生します。
  6. 使い捨ての harness。 システムの最小限のサブセット(1 つの service、モック化した依存関係)を起動し、1 回の function call でバグの code path を実行します。
  7. property/fuzz のループ。 バグが「出力がときどき間違う」なら、ランダムな入力を 1000 件実行して failure mode を探します。
  8. 二分探索用 harness。 バグが 2 つの既知の状態(commit、dataset、バージョン)の間で発生した場合は、「状態 X で起動して確認し、繰り返す」を自動化し、git bisect run を使えるようにします。
  9. 差分ループ。 同じ入力を旧バージョンと新バージョン(または 2 つの設定)で実行し、出力を比較します。
  10. bash による HITL。 最後の手段です。人間がクリックする必要がある場合は、scripts/hitl-loop.template.sh で 人間を 操作し、ループを構造化します。キャプチャした出力を次の調査に使います。

適切なフィードバックループを構築すれば、バグは 90% 解決したも同然です。

ループ自体を改善する

ループを 1 つのプロダクトとして扱ってください。1 つ ループを構築したら、次の点を確認します。

  • もっと速くできるか?(セットアップをキャッシュする、無関係な初期化を省く、テスト範囲を絞る。)
  • シグナルをもっと明確にできるか?(「クラッシュしなかった」ではなく、特定の症状をアサートする。)
  • もっと決定論的にできるか?(時刻を固定する、乱数生成器にシードを設定する、ファイルシステムを分離する、ネットワークを固定する。)

不安定で 30 秒かかるループは、ループがない状態と大差ありません。決定論的で 2 秒のループは、デバッグの強力な武器です。

非決定論的なバグ

目標はクリーンな再現ではなく、再現率を上げることです。トリガーを 100 回実行し、並列化し、ストレスを加え、タイミングの間隔を狭め、sleep を挿入します。再現率 50% のバグならデバッグできますが、1% ではできません。デバッグできるまで再現率を上げてください。

どうしてもループを構築できない場合

作業を止め、明確にその旨を伝えてください。試したことを列挙します。ユーザーに次のいずれかを依頼してください。(a)再現できる環境へのアクセス、(b)キャプチャした成果物(HAR file、ログダンプ、core dump、タイムスタンプ付きの画面録画)、または(c)本番環境に一時的な計測を追加する許可。ループがない状態で、仮説の検討に進まないでください。

信頼できるループを構築するまでは、フェーズ 2 に進まないでください。

フェーズ 2 — 再現する

ループを実行し、バグが発生することを確認します。

次の点を確認してください。

  • ループが、ユーザーの説明した failure mode を発生させること。近くで発生する別の failure ではありません。違うバグを対象にすれば、修正も間違います。
  • 複数回の実行で failure を再現できること(非決定論的なバグの場合は、デバッグに十分な再現率であること)。
  • 正確な症状(エラーメッセージ、誤った出力、遅いタイミング)を記録し、後続フェーズで修正が実際に対処できているか確認できること。

バグを再現するまでは先に進まないでください。

フェーズ 3 — 仮説を立てる

どれかを検証する前に、優先順位を付けた仮説を3〜5個挙げてください。仮説を1つだけ立てると、最初に思いついたもっともらしい案に固執してしまいます。

各仮説は反証可能である必要があります。仮説が予測することを明記してください。

形式:「が原因なら、<Yを変更>するとバグが消える/<Zを変更>すると悪化する。」

予測を明記できないなら、それは勘にすぎません。破棄するか、具体化してください。

検証を始める前に、優先順位付きのリストをユーザーに提示してください。 ユーザーは多くの場合、優先順位をすぐに見直せるドメイン知識を持っています(「#3の変更をたった今デプロイしました」など)。すでに除外した仮説を知っていることもあります。確認の手間はわずかですが、大幅な時間の節約になります。確認待ちで作業を止めないでください。ユーザーが離席中なら、提示した優先順位に従って進めてください。

フェーズ 4 — 計測手段を仕込む

各プローブは、フェーズ 3 の特定の予測に対応させてください。一度に変更する変数は1つだけです。

ツールの優先順位:

  1. デバッガー/REPLによる検査。環境が対応しているならこちらを優先します。ブレークポイント1つは、ログ10個に勝ります。
  2. 仮説を見分けられる境界に対象を絞ったログを追加します。
  3. 「すべてをログに出してgrepする」方法は使わないでください。

各デバッグログに、例:[DEBUG-a4f2]のような一意のプレフィックスを付けてください。最後のクリーンアップはgrep 1回で済みます。タグのないログは残り、タグ付きのログは削除できます。

パフォーマンスの分岐。 パフォーマンスのリグレッションでは、ログが誤解を招くことがよくあります。代わりに、まずベースラインを計測してください(タイミング用ハーネス、performance.now()、プロファイラー、クエリプランなど)。その後、二分探索します。先に計測し、修正はその後です。

フェーズ 5 — 修正とリグレッションテスト

適切なテストシームがある場合に限り、修正の前にリグレッションテストを書いてください。

適切なテストシームとは、呼び出し元で発生するのと同じバグのパターンをテストで再現できる箇所です。利用可能なテストシームが浅すぎる場合(バグの再現には複数の呼び出し元が必要なのに、単一の呼び出し元しかテストできない場合や、バグを引き起こした呼び出しチェーンを再現できないユニットテストなど)、そこでリグレッションテストを書いても誤った安心感を与えます。

適切なテストシームが存在しないこと自体が、発見事項です。 記録してください。コードベースのアーキテクチャが、バグを確実に防ぐ妨げになっています。次のフェーズに申し送ってください。

適切なテストシームがある場合:

  1. 最小化した再現ケースを、そのテストシームで失敗するテストにします。
  2. テストが失敗することを確認します。
  3. 修正を適用します。
  4. テストが成功することを確認します。
  5. フェーズ 1 のフィードバックループを、元の(最小化していない)シナリオに対して再実行します。

フェーズ 6 — クリーンアップと事後検証

完了を宣言する前に、必ず実施してください。

  • 元の再現ケースで再現しなくなった(フェーズ 1 のループを再実行)
  • リグレッションテストが成功する(または、テストシームがないことを記録済み)
  • [DEBUG-...]の計測コードをすべて削除した(プレフィックスをgrepで検索)
  • 使い捨てのプロトタイプを削除した(または、デバッグ用と明示した場所に移動した)
  • 正しいと判明した仮説をコミット/PRのメッセージに記載した(次のデバッガーが学べるようにするため)

そのうえで、このバグを防ぐには何が必要だったかを考えてください。 回答にアーキテクチャの変更(適切なテストシームがない、呼び出し元が複雑に絡み合っている、隠れた結合など)が含まれる場合は、詳細を添えてスキル/improve-codebase-architectureに引き継いでください。提案は修正が入った後に行ってください。作業を始めた時点より、今のほうが多くの情報を得られています。

コメント