mcpField
R
root-cause-tracing

root-cause-tracing

github.com/neolabhq開発1.8k1.3k 回インストール9 週間前に更新
リポジトリ

root-cause-tracing について

コールスタックの深部で起きるエラーを調査する開発者向けスキルです。呼び出し元と入力をたどって元の原因を特定し、関連する層に検証を加える手順を示します。

主な機能

  1. 01コールチェーンをさかのぼる
  2. 02無効な値の発生源を特定
  3. 03スタックトレースと状況を記録
  4. 04テストを二分して汚染源を特定
  5. 05複数の層に検証を追加

活用シーン

  1. 01誤ったファイルパスの発生源を特定
  2. 02テスト汚染の原因を調査
  3. 03実行の深部で起きる障害を診断

インストール

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

$npx skills add https://github.com/neolabhq/context-engineering-kit --skill root-cause-tracing

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

詳細

根本原因の追跡

概要

バグは、コールスタックの深い場所で表面化することがよくあります(間違ったディレクトリでの git init、間違った場所へのファイル作成、間違ったパスでのデータベースのオープンなど)。エラーが現れた場所を修正したくなりますが、それでは症状に対処しているにすぎません。

基本原則: 呼び出しチェーンをさかのぼり、最初のトリガーを見つけてから、発生源で修正します。

使用するタイミング

digraph when_to_use {
    "Bug appears deep in stack?" [shape=diamond];
    "Can trace backwards?" [shape=diamond];
    "Fix at symptom point" [shape=box];
    "Trace to original trigger" [shape=box];
    "BETTER: Also add defense-in-depth" [shape=box];

    "Bug appears deep in stack?" -> "Can trace backwards?" [label="yes"];
    "Can trace backwards?" -> "Trace to original trigger" [label="yes"];
    "Can trace backwards?" -> "Fix at symptom point" [label="no - dead end"];
    "Trace to original trigger" -> "BETTER: Also add defense-in-depth";
}

次の場合に使用します:

  • 実行の深い場所でエラーが発生する(エントリーポイントではない)
  • スタックトレースに長い呼び出しチェーンが表示される
  • 無効なデータがどこで発生したのかが不明
  • 問題を引き起こすテストやコードを特定する必要がある

追跡の手順

1. 症状を確認する
Error: git init failed in /Users/jesse/project/packages/core
2. 直接の原因を見つける

この原因となっているコードは何ですか?

await execFileAsync('git', ['init'], { cwd: projectDir });
3. 何がこれを呼び出したのかを確認する
WorktreeManager.createSessionWorktree(projectDir, sessionId)
  → called by Session.initializeWorkspace()
  → called by Session.create()
  → called by test at Project.create()
4. さらにさかのぼって追跡する

どの値が渡されましたか?

  • projectDir = ''(空文字列!)
  • cwd に空文字列を指定すると、process.cwd() に解決される
  • それがソースコードのディレクトリです!
5. 最初のトリガーを見つける

空文字列はどこから来ましたか?

const context = setupCoreTest(); // Returns { tempDir: '' }
Project.create('name', context.tempDir); // Accessed before beforeEach!

スタックトレースの追加

手動で追跡できない場合は、計測コードを追加します:

// Before the problematic operation
async function gitInit(directory: string) {
  const stack = new Error().stack;
  console.error('DEBUG git init:', {
    directory,
    cwd: process.cwd(),
    nodeEnv: process.env.NODE_ENV,
    stack,
  });

  await execFileAsync('git', ['init'], { cwd: directory });
}

重要: テストでは console.error() を使用してください(logger は表示されない場合があります)

実行して記録します:

npm test 2>&1 | grep 'DEBUG git init'

スタックトレースを分析します:

  • テストファイル名を探す
  • 呼び出しを引き起こした行番号を見つける
  • パターンを特定する(同じテストか?同じパラメーターか?)

汚染を引き起こすテストを見つける

テスト中に何かが現れたものの、どのテストが原因かわからない場合:

二分探索スクリプトを使用します:@find-polluter.sh

./find-polluter.sh '.git' 'src/**/*.test.ts'

テストを1つずつ実行し、最初に汚染を引き起こした時点で停止します。使用方法はスクリプトを参照してください。

実例:空の projectDir

症状: .git が packages/core/(ソースコード)に作成される

追跡チェーン:

  1. git init が process.cwd() で実行される ← cwd パラメーターが空
  2. WorktreeManager に空の projectDir が渡される
  3. Session.create() に空文字列が渡される
  4. テストが beforeEach より前に context.tempDir にアクセスする
  5. setupCoreTest() が最初に { tempDir: '' } を返す

根本原因: 空の値にアクセスするトップレベル変数の初期化

修正: beforeEach より前にアクセスするとエラーをスローする getter に tempDir を変更

さらに、多層防御も追加:

  • レイヤー 1:Project.create() がディレクトリを検証する
  • レイヤー 2:WorkspaceManager が空でないことを検証する
  • レイヤー 3:NODE_ENV ガードが tmpdir 外での git init を拒否する
  • レイヤー 4:git init の前にスタックトレースをログに記録する

重要な原則

digraph principle {
    "Found immediate cause" [shape=ellipse];
    "Can trace one level up?" [shape=diamond];
    "Trace backwards" [shape=box];
    "Is this the source?" [shape=diamond];
    "Fix at source" [shape=box];
    "Add validation at each layer" [shape=box];
    "Bug impossible" [shape=doublecircle];
    "NEVER fix just the symptom" [shape=octagon, style=filled, fillcolor=red, fontcolor=white];

    "Found immediate cause" -> "Can trace one level up?";
    "Can trace one level up?" -> "Trace backwards" [label="yes"];
    "Can trace one level up?" -> "NEVER fix just the symptom" [label="no"];
    "Trace backwards" -> "Is this the source?";
    "Is this the source?" -> "Trace backwards" [label="no - keeps going"];
    "Is this the source?" -> "Fix at source" [label="yes"];
    "Fix at source" -> "Add validation at each layer";
    "Add validation at each layer" -> "Bug impossible";
}

エラーが現れた場所だけを修正してはいけません。 元のトリガーを見つけるために、さかのぼって追跡してください。

スタックトレースのヒント

テストでは: logger ではなく console.error() を使用してください。logger は抑制される場合があります
操作の前に: 危険な操作が失敗した後ではなく、実行する前にログを記録してください
コンテキストを含める: ディレクトリ、cwd、環境変数、タイムスタンプ
スタックを取得する: new Error().stack で完全な呼び出しチェーンを確認できます

実環境での効果

デバッグセッション(2025-10-03)より:

  • 5段階の追跡で根本原因を発見
  • 発生源で修正(getter による検証)
  • 4層の防御を追加
  • 1847件のテストが成功し、汚染はゼロ

コメント