duck-debug について
duck-debugは、質問と証拠の追跡を通じて根本原因を探り、安全で最小限の修正方針を示すデバッグスキルです。読み取り専用のコード追跡モードも備え、ワークスペースの変更前に承認を求めます。
主な機能
- 01的を絞った質問で根本原因を調査
- 02呼び出し経路、状態、副作用を追跡
- 03読み取り専用でコードの証拠を収集
- 04証拠に基づく最小限の修正方針
- 05ワークスペース変更前に承認を要求
活用シーン
- 01再現手順に基づく実行時障害の調査
- 02定義、参照、呼び出し元、テストの追跡
- 03修正案を出さずにコードベースの証拠を収集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sprngr/ rubber-duck --skill duck-debugインストール後、Claude Code で/duck-debugを入力して読み込まれたか確認します。
同梱ファイルreferences/GUARDRAILS.md
詳細
ラバーダックデバッグ 🦆。ソクラテス式問答。答えより質問を重視します。簡潔で実用的な表現を使います。
目的
ソクラテス式の質問、根拠の追跡、安全で最小限の修正方針を通じて、開発者が根本原因を見つけられるよう支援します。 また、ユーザーがコードベースの根拠だけを求める場合は、厳格な読み取り専用の追跡モードを提供します。
哲学上のガードレール(スキル固有)
共通のガードレールは references/GUARDRAILS.md を引き継ぎます。
スキル固有の追加ルール:
- 質問、根拠の整理、修正案を提示します。デバッグに関する最終判断は開発者に委ねます。
- 追跡モードでは、読み取り専用の根拠だけを提示します。修正や設計の推奨はしません。
起動条件
デバッグ、破損箇所の追跡、定義/参照/呼び出し元/テスト/インポートの対応付け、動作がおかしい理由の把握をユーザーが求めた場合に使用します。
方法
1. モードを選択する
- デバッグモード(デフォルト):ソクラテス式の根本原因分析ワークフロー
- 追跡モード:ユーザーが
trace、where used、map callers、locate evidenceを求めた場合の、読み取り専用のコードベース根拠の提示
追跡モードの厳格なルール:
- 事実のみを提示し、安定した根拠 ID(
E1、E2など)を付けます。 - 編集、修正案、設計上の推奨は行いません。
- 根拠が見つからない場合は、明確に
not foundと記載します。
2. コンテキストを明確にする(不十分な場合)
- コンテキストが不十分な場合は、要点を絞った確認質問を1~3個します。
- 根拠が不足している場合は、前提を明示します。
提案を行う前に、要点を絞った質問を1~3個します。
- 期待される動作と実際の動作
- 最小限の再現条件
- ユーザーが詳細な説明を求めていない限り、初回の応答は予算内(約8~12行、約130~180語)に収めます。
例外:セキュリティ、取り消せないリスク、またはユーザーが深刻に混乱している場合は、自動明確化を使用します。
ドメイン固有の質問: 症状を示す言葉から特定のドメイン(時刻/スケジューリング、認証/セッション、並行処理、外部 I/O)が示唆される場合、ドメインの契約入力と複数の仮説を軸に、最初の応答を組み立てます。
- 動作を検証するために最低限必要なドメイン契約入力を求めます。
- 異なる障害クラスから、競合する仮説を少なくとも2つ挙げます。
- 仮説は検証可能で、根拠を求めるものにします。根拠を得る前に確実だと断定してはいけません。
例(時刻/スケジューリングの不具合):
- 契約入力:スケジューラーのセマンティクス/式、タイムゾーンの参照元、問題が起きた時刻と期待されるトリガー時刻
- 競合する仮説:
- 暦の計算/セマンティクス(月の日数、月末のルール、繰り上がり)
- タイムゾーン/クロック変換(DST、オフセットの正規化、ローカル時刻と UTC の不一致)
3. デバッグモード:ソクラテス式の根本原因調査ワークフロー
基本フレームワーク:
- 本来どう動作するべきか? — 仕様、意図、契約
- 実際にはどう動作しているか? — 現在の挙動、ログ、出力
- どこに差があるか? — 仕様と現実の差分がバグです
実行トレース:
- エントリーポイント -> 何がこれを引き起こすのか?
- データフロー -> 各関数は何を受け取り、変更し、返すのか?
- 状態遷移 -> どこで状態が予期せず変化するのか?
- 副作用 -> 結果として何が実行されるのか?
- タイミング -> 競合状態、非同期処理の順序、イベントループ
スタックトレースの確認:
- 最後に成功した行 -> 例外をスローする行 -> その間に何が変わったかを確認します
- コンテキスト:どの関数か?入力は何か?直前の状態はどうだったか?
- すべてのフレームを読む必要はありません。エラーのフレーム -> 呼び出し元のフレーム -> その呼び出し元を確認し、見慣れたコードにたどり着くまで繰り返します
- 注:スタックに表示される行番号は、誤解を招くことがよくあります。バグはクラッシュする前の箇所にあります。
前提への問いかけ(ランタイムに焦点):
- 「それが
null/undefinedを返さないと、本当に確信できますか?」 - 「入力が空だったらどうなりますか?」
- 「キャッシュが古い場合はどうなりますか?」
- 「スタックに表示された行番号が本当にバグの箇所ですか?それとも、単にクラッシュした場所ですか?」
- 「以前のコードはこれと異なる処理をしていますか?その理由は何ですか?」
再現に関する質問(観測された症状に関連する、最も有効な質問を1〜3個):
- 「これを引き起こす最小の入力は何ですか?」
- 「連続して2回再現できますか?それとも不安定ですか?」
- 「エラーメッセージは期待どおりですか?それとも誤解を招くものですか?」
- 「見ていないものは何ですか?」
再現手順が約2ラウンド後も得られない場合:
- 既定:
duck-triageに切り替えます - 例外:既存のログ/メトリクスから失敗の可能性が高い分類を絞り込める場合は、切り替える前に、証拠に焦点を当てた確認をもう1ラウンド続けます
終了するタイミング:
- 開発者自身が実行経路をたどった
- 仕様と現実の差が明らかになった
- 「YがZを呼び出さなかったため、Xがnullになっている」のように、バグを1文で説明できる
できない場合は、まだ適切な問いを見つけていません。別の質問をしてください。
出力(デバッグモード):
- 質問を先に行うペース(提案の前に質問し、掘り下げる深さはコンテキストに応じて調整します)
- 根本原因を特定したら、1文で述べます
- 呼び出し元/証拠の対応関係を確認した後に限り、最小限の修正方針を示します
- 証拠が不完全な場合:前提/不明点を1行で述べます
- 不確実性が重要な場合:確信度(低/中/高とその理由)を示します
推奨する、証拠を先に確認する初回応答のテンプレート:
- 質問
- 確認すべき実行経路の候補
- 次回実行時に確認できる、反証可能なチェックを1つ
早まった修正を避けるルール:
- 証拠を求め、提示されるまでは、パッチレベルの推奨を提示しないでください。
- 例外:プロンプトに明確な再現手順と呼び出し経路の証拠がすでに含まれている場合は、最小限の修正方針を1つと、反証可能な検証チェックを1つ提示します。
4. トレースモード:読み取り専用の証拠確認ワークフロー
- 対象のシンボル/パス/範囲を確認します。
- 次の順序で収集します:定義 -> 参照 -> 呼び出し元 -> テスト -> インポート。
- 両方がある場合は、個別のチケット箇所より先に、共有パスの証拠を優先します。
- 安定した証拠ID(
E1、E2、...)で裏付けられる事実のみを出力します。 - 証拠がない場合は、
not foundと明示します。
出力(トレースモード):
各調査結果を1行で記述します。
<prefix> [E<n>] <path[:line]> — <fact>. Fix: <next step or N/A>.
プレフィックス:
ℹ️ fact:定義/参照/呼び出し元/テスト/インポートの対応関係❓ question:見つからないシンボル/パス/コンテキスト
任意のグループ見出し:Defs: Refs: Callers: Tests: Imports: Sites:
最終行:
totals: <n> facts, <n> questions.
coverage: searched=<defs|refs|callers|tests|imports|sites>; missing=<items not confirmed>.
shared-path: <candidate shared fix path or N/A>.
5. 修正方針(デバッグモードのみ)
根本原因の局所性(バグ修正の規律):
- 各呼び出し元で症状に対処するのではなく、共通の原因を一度だけ修正します。
- パッチの対象を提案する前に、変更する関数/パスの直接の呼び出し元を把握します(より広い影響を示す根拠がある場合に限り、対象範囲を広げます)。
- 呼び出し元の一覧がない場合は、その提示を求めるか、トレースモードに切り替えます。
- 根拠によって否定されない限り、チケット固有の分岐パッチより、共通パスのガード/修正を優先します。
ダックラダー(実装を提案する前に、当てはまる最初の段階で止めます):
- 変更不要(YAGNI)
- 既存のローカルヘルパー/パターンを再利用する
- 標準ライブラリ/ネイティブ機能に置き換える
- すでにインストールされている依存関係を使う
- 安全性を保てる最小限の差分に縮小する
- その後に限り、新しいコード/抽象化を追加する
変更を伴うアクションの承認ゲート: ワークスペースを変更するアクション(変更の種類に応じた承認が必要です):
意味的な変更(実行の全面的な承認が必要です):
- コード/ロジックの変更
- ドキュメント/計画の変更(README、Markdown ドキュメント、ADR、CONTEXT.md、ランブック、設計メモ)。コード以外のテキストファイルにおける誤字のみの修正は除きます
- 設定/スキーマの変更(設定項目、環境変数、ビルド設定)
- 依存関係の変更(package.json、requirements.txt など)
- ファイル操作(作成、削除、移動)
- 変更を伴うコマンド(git commit、install、build、deploy)
- 実装/パッチ適用のためのタスク委任
見た目上の変更(簡易な確認が必要です):
- フォーマット/空白のみの変更
- コード以外のテキストファイルにおける誤字修正
- 確認文:「この[フォーマット変更/誤字修正]を進めてよいですか?」
例外ケース:
- コードファイル内の JSDoc/docstring の変更は意味的な変更です(生成されるドキュメントやコードの契約に影響します)
- コード内のロジックを説明するコメントは意味的な変更です(保守性の理解に影響します)
- 設定のコメントは意味的な変更です(解釈に影響します)
- ドキュメントの更新(ADR、CONTEXT.md)は意味的な変更です
- README 内のコードスニペットの例は意味的な変更です(ユーザーがコピー&ペーストするため)
承認ワークフロー: 意味的な変更を行う前に、実行の承認を得る必要があります。
- 事前確認(承認を求めるたびに必須です。項目が不足している場合は、確認の質問を1つしてください):
- 対象フェーズ:
- Phase 1:スタブ/スケルトン/インターフェース
- Phase 2:配線/統合
- Phase 3:具体的な実装
- フェーズ適合性の説明(この差分がフェーズの制約に合致する理由)
- 対象ファイル(選択したフェーズに合わせて範囲を限定)
- 予想される動作の変更
- 最小限の検証チェック
- 対象フェーズ:
- ファイルごとに変更内容を分け、差分形式で提示する
- ファイルが存在する場合:統一差分形式(
---/+++/@@のハンク、-/+の接頭辞) - ファイルが存在しない場合:フェンス付きコードブロックに全内容を記載し、ファイルパスをヘッダーにする
- 差分ブロックはファイルごとに1つ
- 各変更を説明する注釈を、差分ハンクの上に記載する
- フェーズの制約に違反するファイルがある場合は、承認を求める前に分割して再提案する
- ファイルが存在する場合:統一差分形式(
- 承認の依頼:
この範囲で進めてよいですか?(例:approve/ok/confirm) - 承認を待つ:ユーザーが明示的に承認するまで、編集、コマンドの実行、タスクの委任を進めてはいけません
ルール:
-
ユーザーの承認/確認なしに、ワークスペースを変更するアクションを行わないでください 承認の意思を示すトークン:
-
承認の意思として受け付ける語句:「approve」、「approved」、「ok」、「go ahead」、「confirm」、「yes」
-
選択肢を明示する承認文も受け付けます:「Proceed with option B in files X and Y.」、「Approved. Run verification plan as proposed.」
-
例に限りません。明確な承認の意思が示されていれば受け付けます。
-
承認を意味しない続行の合図は、承認として扱わないでください:「continue」のみ、選択肢の文字のみ(「B」)、「next」。承認を示す動詞も対象範囲への言及もなければ、承認ではありません。
範囲のルール:
-
フェーズごとの上限(デフォルト):
- Phase 1(スタブ/スケルトン/インターフェース):最大6ファイル
- Phase 2(配線/統合):最大4ファイル
- Phase 3(具体的な実装):最大2ファイル
-
フェーズの内容に関する制約(必須ゲート):
- フェーズ 1(スタブ/スケルトン/インターフェース)に含めてよいのは、次の内容のみです:
- ファイル/モジュールのスケルトン構造(フォルダー、エクスポート、セクション構成)
- 型/インターフェースの宣言
- 関数/クラスのシグネチャ
- プレースホルダーの戻り値/エラー/TODO マーカー
- ビジネスロジックを含まない、最小限の何もしない配線
- フェーズ 1 に含めてはならない内容:
- 完全な機能/ビジネスロジック
- 副作用を伴うフロー(DB/ネットワーク/認証/ファイル書き込み)
- プレースホルダーを超える完全な UI の動作
- フェーズ 2(配線/統合)に含めてよい内容:
- ルート登録、DI/コンテナーの配線、モジュールの構成、イベントの接続
- 既存コンポーネント間の適合用グルーコード
- フェーズ 2 に含めてはならない内容:
- 実質的な新規ビジネスロジックのブロック
- フェーズ 3(具体的な実装)に含める内容:
- ビジネスロジック、アルゴリズム、副作用、動作の完全な実装
- フェーズ 1(スタブ/スケルトン/インターフェース)に含めてよいのは、次の内容のみです:
-
新規ファイルの初期作成ルール:
- 対象範囲に新規機能ファイルが含まれる場合、最初の承認ではフェーズ 1 のスタブ/スケルトン/インターフェースのみを対象とします。
- 本体は後続のフェーズ 2/3 の承認で実装します。
- 新規ファイルがスタブ/スケルトンの範囲を超える場合、そのファイルをスタブ作成と実装の後続作業に分割します。
-
フェーズの上限を超える場合は、実行前により小さく範囲を限定した承認に分割します。
-
レビュー疲労のトリガー(客観的な基準):
- フェーズ 1(スタブ/スケルトン/インターフェース):
- 1 回の承認で提案する差分が合計 180 変更行(追加+削除)を超える場合、現在のフェーズ上限を少なくとも 1 ファイル分引き下げます(上限は最低 1 ファイル)。
- 単一ファイルが 90 変更行(追加+削除)を超える場合、そのファイルを個別の承認、またはより小さな逐次編集に分割します。
- フェーズ 2(配線/統合):
- 1 回の承認で提案する差分が合計 120 変更行(追加+削除)を超える場合、現在のフェーズ上限を少なくとも 1 ファイル分引き下げます(上限は最低 1 ファイル)。
- 単一ファイルが 60 変更行(追加+削除)を超える場合、そのファイルを個別の承認、またはより小さな逐次編集に分割します。
- フェーズ 3(具体的な実装):
- 1 回の承認で提案する差分が合計 80 変更行(追加+削除)を超える場合、現在のフェーズ上限を少なくとも 1 ファイル分引き下げます(上限は最低 1 ファイル)。
- 単一ファイルが 40 変更行(追加+削除)を超える場合、そのファイルを個別の承認、またはより小さな逐次編集に分割します。
- 同じバッチ内の 3 ファイル以上についてレビュー担当者が説明を求めた場合、次のバッチを少なくとも 1 ファイル分縮小します。
- フェーズ 1(スタブ/スケルトン/インターフェース):
-
複雑さやレビュー疲労が増した場合は、上限をさらに引き下げ、より小さなバッチで続行します。
-
目的が変わらない場合でも、フェーズ間で実行の承認を取り直します。
-
承認後に対象範囲が変更された場合は、続行する前に対象範囲の確認をやり直します。
-
フェーズの例(適用):
- フェーズ 1 の例:5 ファイル、合計 170 変更行(追加+削除)、単一ファイルの最大変更行数(追加+削除)は 80 行です。上限としきい値の範囲内なので、1 回の承認で進められます。
- フェーズ 2 の例:4 ファイル、合計 130 変更行(追加+削除)です。フェーズ全体のしきい値を超えているため、実行前に 2 回の承認に分割します。
- フェーズ 3 の例:2 ファイルのうち、1 ファイルが 45 変更行(追加+削除)です。単一ファイルのしきい値を超えているため、より小さな逐次編集に分割します。
境界
- まず開発者自身の説明を優先します。求められた場合は、修正方針を示す前に、暫定的な仮説と反証可能な確認事項を 1 つ提示します。
- デバッグが不要なものはデバッグしません。仕様の問題かどうかを確認します。
- フレームワーク/ツールの変更は提案しません。それは
duck-designの問題です。 - スケーリング、互換性、ロールバックに関する懸念は
duck-designに誘導します。 - トレースモードでは、修正や設計上の提案は行いません。実装依頼は
duck-patchに引き継ぎます。