デバッグモード
このスキルは、ユーザーが明示的に debug-mode、$debug-mode、debug mode、またはインストルメント化されたデバッグを呼び出した場合にのみ使用してください。
ユーザーが明示的にオプトインしていない場合は、通常通りデバッグしてください。このスキルについて言及するのは、一時的なランタイム計装が実質的に役立つ場合のみにしてください。
コアループ
仮説駆動型デバッグループを実行します:
- 関連するコード、再現の詳細、既存のログを読みます。
H1、H2、H3などのIDを付けて、2〜5個の優先順位付き仮説をリストアップします。各仮説は、ランタイムプローブが何を示すかを予測する必要があります。- ループバックコレクター(コレクター契約)を起動するか再利用します。
- 仮説を区別するための3〜8個のターゲットプローブを追加します。
stdout/stderrではなく、DEBUG_URL + "/log"に送信される構造化イベントを使用します。以下のイベント形状、リージョンマーカー、ヘルパーに従ってください。 - 手動チェックポイントで停止します。チェックポイントテンプレートを送信します。ユーザーが
A、B、またはCで応答するまで、分析、修正、プローブの削除を行わないでください。 Aが返された後、印刷されたLOG_FILEを検査し、各仮説をCONFIRMED(確認済み)、REJECTED(却下)、またはINCONCLUSIVE(結論不可)に分類し、ログが根本原因を説明している場合にのみ最小限の修正を行います。以下の証拠サマリーに従ってください。- 事後修正の実行には、
runId: "post-fix"がタグ付けされたプローブを1回の実行のためにアクティブに保ちます。 - ユーザーが事後修正チェックポイントに
Bと応答した後、すべての計装を削除し、関連するチェックを実行します。以下のクリーンアップチェックリストに従ってください。
ハードルール
- プローブを追加した後、手動再現チェックポイントをスキップしないでください。
- このスキルがアクティブな間は、推測による修正を行わないでください。
- ユーザーが事後修正チェックを確認する前にプローブを削除しないでください。
- デバッグログや一時的な計装をコミットしないでください。
- 機密情報、トークン、クッキー、認証ヘッダー、APIキー、プライベートデータを含む可能性のある生のリクエストボディやレスポンス、不要な個人データをログに記録しないでください。
コレクター契約
バンドルされたコレクターは意図的に小規模です:
GET /healthは、既存のコレクターが再利用可能かどうかを確認します。POST /logは1つのJSONオブジェクトを受け入れ、非同期的に1つのNDJSON行を追加します。検証後に200を返します。行はバックグラウンドで書き込まれます。- 異なるセッションは独立したキューを持つ別々のファイルに書き込まれるため、セッション間で並行して書き込みを進めることができます。
- ログはデフォルトでOS一時ディレクトリの下、ワークスペースの外側に保存されます。
--ensureは、DEBUG_URL、SESSION_ID、LOG_DIR、LOG_FILE、およびHEALTH_URLを出力します。- コレクターは最初のイベントで
LOG_FILEを作成します。再現後にtouch、事前作成、切り詰め、クリアを行わないでください。 - コレクターはループバック専用です。
0.0.0.0や公開インターフェースにバインドしないでください。
以下のように起動または再利用します:
node <skill-dir>/scripts/log-server.mjs --ensure --session <session_id> --host 127.0.0.1 --port 0
ローカルポートリスナーをブロックする管理されたサンドボックスでは、最初の試行でエージェントの通常の承認を要求してください。理由を、このループバック専用デバッグコレクターの起動または再利用に限定してください。
チェックポイントテンプレート
プローブを追加した後、実際のセッション詳細を含めてこの形式で停止して送信します:
デバッグモードプローブを追加しました。コレクターが書き込み中です:
- セッション: <session_id>
- ログファイル: <LOG_FILE>
- デバッグエンドポイント: <DEBUG_URL>/log
バグを手動で再現してください。その後、以下を返信してください:
A - 再現しました
B - 修正済み
C - その他(状況を説明してください)
事後修正確認の場合は、最初の文のみを変更します:
デバッグモードプローブを事後修正確認のためにアクティブに保ちました。コレクターが書き込み中です:
- セッション: <session_id>
- ログファイル: <LOG_FILE>
- デバッグエンドポイント: <DEBUG_URL>/log
元のバグを手動で確認してください。その後、以下を返信してください:
A - 再現しました
B - 修正済み
C - その他(状況を説明してください)
チェックポイントの応答を小さな状態機械として解釈します:
A(修正前):NDJSONログを読み、仮説の証拠を分類し、確認された原因のみを修正するか、より狭いプローブを追加します。A(修正後):バグがまだ再現しています。事後修正ログを読み、より狭い仮説またはプローブで続行します。B(修正前):終了状態ではありません。計装下ではバグが再現しなかった証拠として扱い、明確化またはより狭い再現手順を求めます。B(修正後):プローブを削除し、最終チェックを実行します。C(いつでも):ユーザーのテキストを証拠として扱います。再現手順、仮説、またはプローブを調整します。
イベント形状
構造化された低量のイベントを使用します。典型的なイベントは次のようになります:
{
"session": "<session_id>",
"runId": "pre-fix",
"probe": "settings.beforePersist",
"hypothesis": "H1",
"file": "src/settings/save.ts",
"fn": "saveSettings",
"vars": {
"enabled": true,
"userId": "redacted"
}
}
修正前は runId: "pre-fix" を、確認用には runId: "post-fix" を使用します。高頻度パスでは、状態変更時のみログを記録するか、積極的にサンプリングします。
リージョンマーカー
すべての一時的な計装をリージョンマーカーで囲み、機械的なクリーンアップを可能にします:
// #region DEBUG_MODE_PROBE <session_id> settings-before-persist
debugModeLog({
probe: "settings.beforePersist",
hypothesis: "H1",
file: "src/settings/save.ts",
fn: "saveSettings",
vars: { enabled, userId: "redacted" },
});
// #endregion DEBUG_MODE_PROBE <session_id>
一般的なコメント形式:
// #region DEBUG_MODE_PROBE <session_id> ... JavaScript, TypeScript, Java, C#, Go, Rust, C, C++
# #region DEBUG_MODE_PROBE <session_id> ... Python, Ruby, Shell, YAML
<!-- #region DEBUG_MODE_PROBE <session_id> --> HTML, Vue, Svelte
/* #region DEBUG_MODE_PROBE <session_id> */ CSS and C-style block contexts
-- #region DEBUG_MODE_PROBE <session_id> ... SQL, Lua
ヘルパー
ブラウザまたはフロントエンドJavaScriptの場合、assets/browser-log-helper.js を正規のヘルパーテンプレートとして使用します。これを計装するモジュールまたはスクリプトにコピーし、<session_id> と <DEBUG_URL> を置き換え、関数名 debugModeLog を維持します。
Node.jsまたはサーバーサイドJavaScriptの場合、assets/node-log-helper.js を正規のヘルパーテンプレートとして使用します。これを計装するモジュールまたはスクリプトにコピーし、<session_id> と <DEBUG_URL> を置き換え、関数名 debugModeLog を維持します。
サードパーティ依存関係のないPythonの場合:
# #region DEBUG_MODE_PROBE <session_id> debug-log-helper
import json
import urllib.request
DEBUG_MODE_URL = "<DEBUG_URL>/log"
def debug_mode_log(event):
try:
payload = {"session": "<session_id>", **event}
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(
DEBUG_MODE_URL,
data=data,
headers={"content-type": "application/json"},
method="POST",
)
urllib.request.urlopen(req, timeout=0.5).close()
except Exception:
pass
# #endregion DEBUG_MODE_PROBE <session_id>
証拠サマリー
A の応答後、コードを編集する前に証拠を要約します:
H1 設定状態がAPI呼び出し前に失われる
ステータス: CONFIRMED
証拠: settings.beforePersist が enabled=false を記録したが、UIイベントは enabled=true を記録した。
H2 APIが値を拒否する
ステータス: REJECTED
証拠: この再現ではAPI呼び出しは発生しなかった。
次のアクション: onToggle と saveSettings の間のローカル状態の受け渡しを修正する。
すべての仮説が REJECTED または INCONCLUSIVE の場合、異なるサブシステムから新しい仮説を生成し、より狭いプローブを追加します。雰囲気でパッチを当てないでください。
トラブルシューティング
- 空のログ:アプリケーションが計装されたパスを実行したこと、セッションIDが一致していること、エンドポイントに
/logが含まれていることを確認してください。 - ブラウザでリクエストがブロックされる:混合コンテンツ、CSPの
connect-src、拡張機能の分離、コンテンツスクリプトのコンテキストを確認してください。 - CORS/プリフライトの問題:コレクターは
OPTIONSを処理します。それでも失敗する場合は、navigator.sendBeacon、同一オリジンの開発サーバープロキシ、またはサーバーサイド計装を試してください。 - ホストが拒否される:
127.0.0.1、localhost、または::1を使用してください。LANや公開インターフェースには絶対にバインドしないでください。 - サンドボックスがリスナーをブロックする:このループバックコレクターに必要な承認を得て、一度再試行してください。承認が拒否された場合は、ローカルコレクションがブロックされていることを説明し、安全なファイルベースのプローブパスが存在する場合にのみフォールバックします。
- ログが多すぎる:ノイズの多いプローブを、より狭い状態変更プローブに置き換えてください。
- 再現できない:正確な手順、環境、入力データ、または画面録画を要求してください。修正をでっち上げないでください。
クリーンアップチェックリスト
タスクが完了したと宣言する前に:
- 元の再現手順または最も近い利用可能な自動チェックを再実行します。
DEBUG_MODE_PROBE <session_id>とマークされたすべてのペアのリージョンを削除します。- セッションID、
DEBUG_MODE_PROBE、#region DEBUG_MODE_PROBE、#endregion DEBUG_MODE_PROBEを検索します。 - 表示された
LOG_FILEにあるセッションのNDJSONログを削除するか、ローカル証拠として保持すべきかを確認します。 - 製品の修正と有用な回帰テストのみを残します。