motel-debug について
Motelが収集する実行時トレースとログを使い、仮説の検証から修正、再確認まで進めるデバッグスキルです。計測、再現、証拠の分析、後片付けを一連の手順として定めています。
主な機能
- 01Motelを使ったトレースとログの検索
- 02検証可能な不具合仮説の作成
- 03タグと属性を付けたデバッグ計測
- 04実行時の証拠に基づく修正確認
- 05確認後の一時計測の削除
活用シーン
- 01コード確認だけでは特定しにくい不具合の調査
- 02トレースによるリクエスト経路の追跡
- 03再現可能な問題に対する修正の検証
- 04修正前後の実行時データの比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kitlangton/ motel --skill motel-debugインストール後、Claude Code で/motel-debugを入力して読み込まれたか確認します。
同梱ファイルreferences/effect.mdscripts/clear-motel-debug.ts
詳細
Motel Debug
デバッグモードです。推測ではなく、ランタイムの証拠に基づいてデバッグしてください。
エージェントはコードだけを見て推測します。必要なのは実際のランタイムデータです。Motel はトレースとログを収集するローカルの OpenTelemetry サーバーです。証拠を得るためのループとして活用してください。
ローカルサーバーのデフォルト設定:
- ベース URL:
http://127.0.0.1:27686 - OTLP トレース:
POST /v1/traces - OTLP ログ:
POST /v1/logs - クエリ API:
GET /api/* - OpenAPI:
GET /openapi.json - ヘッダー:
Content-Type: application/json - 認証:デフォルトでは不要
ユーザーが別の motel URL を指定した場合は、デフォルトではなくその URL を使用してください。
ワークフロー
1. motel が実行中か確認し、実行されていなければ起動する
GET /api/health を確認します。200 が返された場合は続行してください。
失敗した場合(接続拒否、タイムアウト、200 以外)、motel は実行されていません。 バックグラウンドデーモンとして起動してください。対話型でシェルをブロックする TUI は 起動しないでください。
motel start
motel start は、マシン全体で管理されるデーモンが実行中であることを保証し、
${XDG_STATE_HOME:-~/.local/state}/motel/ の下にランタイムファイルを書き込み、
JSON のステータス情報を返します。冪等であり、ローカルプロジェクト間で共有されます。motel が PATH にない場合は、
bunx @kitlangton/motel start にフォールバックしてください。
起動後、GET /api/health を再確認してください(準備完了まで 1〜2 秒かかる場合があります)。
それでも失敗する場合は、${XDG_STATE_HOME:-~/.local/state}/motel/daemon.log を読み込んでエラーを確認し、
ユーザーに伝えてください。
参考として、その他のライフサイクルコマンドを示します。
motel status # JSON status (running? pid? originating workdir?)
motel stop # stop the shared managed daemon for all local projects
必要に応じて、GET /api/services を使ってレポートサービスを検出してください。
2. 仮説を立てる
コードに手を加える前に、バグが発生する理由について、具体的な仮説を3〜5 個立ててください。正確に記述してください。「キャッシュキーにユーザー ID が含まれていない」は、「キャッシュに問題がある」より適切です。
3. タグ付きデバッグブロックで計測する
すべての仮説を並行して確認または棄却するために必要な、最小限の計測を追加してください。各デバッグブロックは、次の要件を満たす必要があります。
#region motel debug/#endregion motel debugマーカーで囲む- 特定の仮説に関連付ける
debug.hypothesis属性を含める - コードベースですでに使用されているトレース/ログ機構(スパン、構造化ログ、アノテーションなど)を使う(生の
fetch呼び出しは使用しない)
後でクエリできるように、デバッグ計測のすべての項目に構造化属性でタグを付けてください。次のキーを再利用してください。
| キー | 用途 |
|---|---|
debug.session | このデバッグセッションの計測をまとめます |
debug.hypothesis | 特定の仮説に関連付けます(例:"cache-miss"、"A") |
debug.step | フロー内の位置を示します(例:"entry"、"before-write"、"after-read") |
debug.label | この計測ポイントで記録する内容を人が読みやすく説明します |
仮説に基づいてログの配置場所を選んでください。
- 関数の開始時(パラメーターを記録)
- 関数の終了時(戻り値を記録)
- 重要な操作の前後の値
- 分岐の実行経路(どの if/else が実行されたか)
- 状態の変更と中間値
- 疑わしいエラー値や境界ケースの値
ガイドライン:
- 計測ポイントを最低 1 つ追加してください。計測を省略しないでください
- 10 個を超えないでください。さらに必要だと思う場合は、仮説を絞り込んでください
- 通常は 2〜6 個です
4. 問題を再現する
- 失敗するテストがある場合は、直接実行してください
- 再現が簡単な場合(CLI コマンド、curl、簡単なスクリプト)は、自分で作成して実行してください
- それ以外の場合は、明確な番号付きの手順を示し、必要に応じて再起動するよう伝えて、ユーザーに再現を依頼してください
- 再現手順が確立したら、その後のすべての反復で同じ手順を再利用してください
5. 証拠を分析する
Motel にクエリを実行して、デバッグ計測を確認してください。
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attr.debug.hypothesis=<id>"
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attr.debug.session=<session>"
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&attr.debug.hypothesis=<id>"
各仮説について、証拠として具体的なスパン、ログ、または属性値を挙げ、CONFIRMED、REJECTED、INCONCLUSIVE のいずれかで評価してください。
6. 証拠に基づいてのみ修正する
ランタイムの証拠なしに修正してはいけません。修正する際は、次の点に従ってください。
- すべてのデバッグ計測を残し、まだ削除しないでください
- 修正はできる限り小さく、対象を絞ってください
- 既存のアーキテクチャとパターンを再利用し、過剰に設計しないでください
7. 修正を検証する
計測を有効にしたまま、もう一度問題を再現します。修正前後の証拠を比較します。
- 修正が機能していることを証明する、具体的なログ行またはスパン属性を示します
- 修正に失敗した場合:却下した仮説に基づくコード変更を元に戻し(推測に基づく修正を蓄積しないでください)、別のサブシステムから新たな仮説を立て、計測を追加して、反復します
- 反復は想定されています。より多くのデータを集めて時間をかけるほど、より適切な修正につながります
8. クリーンアップ
修正を検証し、かつユーザーが残っている問題はないと確認した後に限り、次の操作を行います。
- クリーンアップスクリプトを実行するか、ブロックを手動で削除します(以下の「クリーンアップ」セクションを参照)
git diffを実行し、意図した修正だけが残っていることを確認します
計測のルール
一時的なデバッグブロックはすべて、次の正確なマーカーで囲みます。
// #region motel debug
// temporary debug instrumentation
// #endregion motel debug
トレースとログには、コードベースですでに用意されているものを使います。マーカーは言語コメントのラッパーです。JS/TS 以外のファイルでは、コメント構文を適宜調整してください(例:Python では # #region motel debug)。
禁止事項:
- シークレット、トークン、パスワード、生の PII をログに記録しないでください
- 修正後の検証が成功する前に、計測を削除しないでください
- 修正として
setTimeout、sleep、人為的な遅延を使わないでください - 却下した仮説に基づくコード変更を蓄積しないでください。元に戻してください
クエリパターン
属性検索で使うフィルタープレフィックスは次の 2 つです。
| プレフィックス | マッチタイプ | 例 |
|---|---|---|
attr.<key>=<value> | 完全一致 | attr.debug.hypothesis=cache-miss |
attrContains.<key>=<substring> | 大文字小文字を区別しない部分一致 | attrContains.ai.prompt.messages=hello world |
curl http://127.0.0.1:27686/api/health
curl http://127.0.0.1:27686/api/services
# Trace search
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&operation=<text>&attr.debug.session=<session>"
# Span search (supports traceId to scope to one trace)
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&traceId=<trace-id>&attr.debug.hypothesis=<id>"
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attrContains.ai.prompt.messages=<phrase>"
# Log search (supports severity filter, case-insensitive body search)
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&severity=ERROR&body=<text>"
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attrContains.debug.label=<substring>"
# AI call search (compact summaries with previews)
curl "http://127.0.0.1:27686/api/ai/calls?model=gpt-5.4&sessionId=<session>"
curl "http://127.0.0.1:27686/api/ai/calls?text=<phrase>&status=error"
# AI call detail (full prompt/response payloads)
curl "http://127.0.0.1:27686/api/ai/calls/<span-id>"
# AI stats
curl "http://127.0.0.1:27686/api/ai/stats?groupBy=model&agg=total_input_tokens"
curl http://127.0.0.1:27686/openapi.json
一覧および検索の応答には、さらにデータがある場合に meta.nextCursor が含まれます。
Motel はトレースと相関付けられたデータを提供します。デバッグログがどのスパンに属するか、親オペレーション、タイミング、トレースツリー全体を確認できます。相関関係をたどるには、GET /api/traces/<trace-id>/spans と GET /api/spans/<span-id>/logs を使います。
AI/LLM の呼び出しには、検索可能な簡潔な概要(プロンプトと応答のプレビュー、トークン使用量を含む)を取得できる /api/ai/calls と、ペイロード全体を取得できる /api/ai/calls/<span-id> を使います。
Effect
対象のリポジトリで Effect を使用している場合、ランタイムの配線を変更したり計測を追加したりする前に、references/effect.md を読んでください。
クリーンアップ
確実にクリーンアップするには、同梱のスクリプト scripts/clear-motel-debug.ts を使います。このスクリプトは JS/TS ファイル内の #region motel debug と #endregion motel debug の間にあるブロックをすべて削除し、マーカーの対応が取れていない場合は失敗します。
スクリプトを実行できない場合は、マークされたブロックをすべて手動で削除し、その後 #region motel debug を grep して、残っていないことを確認してください。