| name | backend-debug-session |
| description | バグ調査を場当たり的でなく体系的に進める。再現→仮説→検証→修正→回帰テストの順序を守り、仮説と事実を分けて記録する。「バグ調査して」「なぜか動かない」「デバッグ手伝って」などで起動。 |
Debug Session
バグ調査を 場当たり的に修正しない。仮説駆動で進める。
いつ使うか
- バグ報告があり原因が不明
- 「動かない」という報告から原因を絞り込みたい
- 本番で起きた障害の事後分析(post-mortem)
基本原則
- まず再現。再現しないバグは修正してはいけない
- 事実と仮説を分ける。口調で区別する(「〜である」vs「〜かもしれない」)
- 修正前にテストを書く。テストなしに直すと再発する
- 根本原因まで遡る。症状を消すだけでは解決ではない
実行手順
1. 症状の言語化
ユーザーに以下を確認:
- 何が起きた: エラー / 無応答 / 不正な値 / パフォーマンス
- 期待する振る舞い: どうなるべきか
- 発生条件: 再現手順、環境、ユーザー操作
- いつから: 直近の変更、リリースとの関係
- 影響範囲: 1 ユーザー / 全員 / 特定条件
2. 再現
再現手順を 機械的に実行可能な形 で書き出す:
1. <setup>
2. <action>
3. 期待: ...
4. 実際: ...
再現しない場合:
- 環境差(OS / バージョン / データ)
- タイミング差(並行処理 / キャッシュ / クロック)
- データ差(本番データ vs サンプル)
を疑う。再現しないまま先に進まない。
3. 仮説リストアップ
少なくとも 3 つ の仮説を出す(1 つだけだと確証バイアスに陥る):
仮説 A: <原因候補>
- 根拠: <コード / ログ / 挙動の事実>
- 検証方法: <どうすれば真偽が分かるか>
- 優先度: 高(根拠が強い)/ 中 / 低
仮説 B: ...
仮説 C: ...
4. 検証
優先度の高い仮説から 最小コストで検証:
- ログ追加 / 既存ログの確認
- デバッガで状態観察
- 単体テストで疑いのある関数に入力を与える
git log / git blame で最近の変更を確認
git bisect で退行コミット特定
検証結果を 事実 として記録。仮説欄と混ぜない。
5. 仮説の更新
- 仮説が正しければ → 根本原因特定 → ステップ 6
- 仮説が間違いなら → 他の仮説に戻る。無理に仮説 A を修正しない
- 全仮説が外れたら → ステップ 3 に戻って新しい仮説を出す
6. 再発防止テストを先に書く
修正前に 失敗するテスト を書く。これが再発防止の要。
- バグを再現する最小のテストケース
backend-test-writer の原則に従ってプロジェクト既存パターンで書く
- テストを走らせて 確実にレッド になることを確認
7. 修正
- 仮説で特定した根本原因を直す
- 症状だけ消す対症療法(try-catch で握りつぶす等)は 避ける
- 修正範囲は最小に(「ついでに直す」は別 PR)
8. 検証
- 先ほど書いたテストが グリーン になる
- 既存テストが壊れていないことを確認
- 再現手順で実際に動作確認
9. 記録
docs/work/YYYYMMDD_<bug>_postmortem.md に残す(重大な障害の場合):
# バグ調査記録: <概要>
## 症状
<ユーザーから見た症状>
## 再現手順
1. ...
## 原因
<根本原因。コード引用可>
## なぜ起きたか(5 Why)
1. なぜ X が起きた? → Y
2. なぜ Y が起きた? → Z
...
## 修正
- <変更内容の要点>
- 再発防止テスト: <path>
## 類似箇所の点検
- <同じパターンの疑いがあるコードを grep で列挙>
## 参考
- 関連 commit: <hash>
- 関連 issue / PR: <url>
アンチパターン
- ❌ ログを見て勘で直す
- ❌ テストなしで本番に入れる
- ❌
catch (e) {} で握りつぶす
- ❌ 「たぶんこれで直ったはず」で終える
- ❌ 再現できないまま「直した」と言う
関連