debug-with-file について
debug-with-file は、証拠を記録しながら仮説を更新して複雑な不具合を調査するデバッグスキルです。ファイルに調査結果を残し、ログに基づく見直しから修正と検証までを追跡します。
主な機能
- 01検証可能な仮説の生成
- 02NDJSON 形式の証拠ログ
- 03understanding.md での調査経過記録
- 04仮説の判定と履歴管理
- 05修正検証と計測コードの削除
活用シーン
- 01複数回の調査が必要な不具合の分析
- 02チーム向けの証拠と推論の記録
- 03再発する不具合に備えた根本原因の保存
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ catlog22/ claude-code-workflow --skill debug-with-fileインストール後、Claude Code で/debug-with-fileを入力して読み込まれたか確認します。
詳細
Codex ファイルを使ったデバッグ用プロンプト
概要
調査プロセスを文書化する、証拠に基づく強化版デバッグです。理解の変化を記録し、知見を集約して、分析を用いて誤解を修正します。
基本的なワークフロー:調査 → 文書化 → 記録 → 分析 → 理解の修正 → 修正 → 検証
/prompts:debug からの主な強化点:
- understanding.md:調査と学習のタイムライン
- 分析による修正:仮説を検証して修正します
- 集約:誤りと判明した理解を簡潔にまとめ、煩雑さを避けます
- 学習内容の保持:失敗した試みから得た内容も含め、学んだことを保持します
対象のバグ
$BUG
プロジェクトのコンテキスト
既知の問題、回避策、根本原因に関するメモを確認するには、ccw spec load --category debug を実行します。
実行プロセス
Session Detection:
├─ Check if debug session exists for this bug
├─ EXISTS + understanding.md exists → Continue mode
└─ NOT_FOUND → Explore mode
Explore Mode:
├─ Locate error source in codebase
├─ Document initial understanding in understanding.md
├─ Generate testable hypotheses with analysis validation
├─ Add NDJSON logging instrumentation
└─ Output: Hypothesis list + await user reproduction
Analyze Mode:
├─ Parse debug.log, validate each hypothesis
├─ Use analysis to evaluate hypotheses and correct understanding
├─ Update understanding.md with:
│ ├─ New evidence
│ ├─ Corrected misunderstandings (strikethrough + correction)
│ └─ Consolidated current understanding
└─ Decision:
├─ Confirmed → Fix root cause
├─ Inconclusive → Add more logging, iterate
└─ All rejected → Assisted new hypotheses
Fix & Cleanup:
├─ Apply fix based on confirmed hypothesis
├─ User verifies
├─ Document final understanding + lessons learned
├─ Remove debug instrumentation
└─ If not fixed → Return to Analyze mode
実装の詳細
セッションの設定とモードの検出
ステップ 0:プロジェクトのルートを特定する
プロジェクトのルートディレクトリを検出し、.workflow/ の成果物が正しい場所に配置されるようにします。
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
まず git でリポジトリのルートディレクトリを取得します。git プロジェクトでない場合は、pwd を使って現在の絶対パスを取得します。
これを {projectRoot} として保存します。以降のすべての .workflow/ パスには、この値を前置する必要があります。
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
const projectRoot = bash('git rev-parse --show-toplevel 2>/dev/null || pwd').trim()
const bugSlug = "$BUG".toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 30)
const dateStr = getUtc8ISOString().substring(0, 10)
const sessionId = `DBG-${dateStr}-${bugSlug}`
const sessionFolder = `${projectRoot}/.workflow/.debug/${sessionId}`
const debugLogPath = `${sessionFolder}/debug.log`
const understandingPath = `${sessionFolder}/understanding.md`
const hypothesesPath = `${sessionFolder}/hypotheses.json`
// Auto-detect mode
const sessionExists = fs.existsSync(sessionFolder)
const hasUnderstanding = sessionExists && fs.existsSync(understandingPath)
const logHasContent = sessionExists && fs.existsSync(debugLogPath) && fs.statSync(debugLogPath).size > 0
const mode = logHasContent ? 'analyze' : (hasUnderstanding ? 'continue' : 'explore')
if (!sessionExists) {
bash(`mkdir -p ${sessionFolder}`)
}
調査モード
ステップ 1.1:エラーの発生源を特定する
// Extract keywords from bug description
const keywords = extractErrorKeywords("$BUG")
// Search codebase for error locations
const searchResults = []
for (const keyword of keywords) {
const results = Grep({ pattern: keyword, path: ".", output_mode: "content", "-C": 3 })
searchResults.push({ keyword, results })
}
// Identify affected files and functions
const affectedLocations = analyzeSearchResults(searchResults)
ステップ 1.2:初期の理解を文書化する
understanding.md を作成します。
# Understanding Document
**Session ID**: ${sessionId}
**Bug Description**: $BUG
**Started**: ${getUtc8ISOString()}
---
## Exploration Timeline
### Iteration 1 - Initial Exploration (${timestamp})
#### Current Understanding
Based on bug description and initial code search:
- Error pattern: ${errorPattern}
- Affected areas: ${affectedLocations.map(l => l.file).join(', ')}
- Initial hypothesis: ${initialThoughts}
#### Evidence from Code Search
${searchResults.map(r => `
**Keyword: "${r.keyword}"**
- Found in: ${r.results.files.join(', ')}
- Key findings: ${r.insights}
`).join('\n')}
#### Next Steps
- Generate testable hypotheses
- Add instrumentation
- Await reproduction
---
## Current Consolidated Understanding
${initialConsolidatedUnderstanding}
ステップ 1.3:仮説を立てる
バグを分析し、検証可能な仮説を 3~5 個立てます。
// Hypothesis generation based on error pattern
const HYPOTHESIS_PATTERNS = {
"not found|missing|undefined|未找到": "data_mismatch",
"0|empty|zero|registered": "logic_error",
"timeout|connection|sync": "integration_issue",
"type|format|parse": "type_mismatch"
}
function generateHypotheses(bugDescription, affectedLocations) {
// Generate targeted hypotheses based on error analysis
// Each hypothesis includes:
// - id: H1, H2, ...
// - description: What might be wrong
// - testable_condition: What to log
// - logging_point: Where to add instrumentation
// - evidence_criteria: What confirms/rejects it
return hypotheses
}
hypotheses.json に保存します。
{
"iteration": 1,
"timestamp": "2025-01-21T10:00:00+08:00",
"hypotheses": [
{
"id": "H1",
"description": "Data structure mismatch - expected key not present",
"testable_condition": "Check if target key exists in dict",
"logging_point": "file.py:func:42",
"evidence_criteria": {
"confirm": "data shows missing key",
"reject": "key exists with valid value"
},
"likelihood": 1,
"status": "pending"
}
]
}
ステップ 1.4:NDJSON 計測コードを追加する
各仮説について、指定された場所にログ出力を追加します。
Python テンプレート:
# region debug [H{n}]
try:
import json, time
_dbg = {
"sid": "{sessionId}",
"hid": "H{n}",
"loc": "{file}:{line}",
"msg": "{testable_condition}",
"data": {
# Capture relevant values here
},
"ts": int(time.time() * 1000)
}
with open(r"{debugLogPath}", "a", encoding="utf-8") as _f:
_f.write(json.dumps(_dbg, ensure_ascii=False) + "\n")
except: pass
# endregion
JavaScript/TypeScript テンプレート:
// region debug [H{n}]
try {
require('fs').appendFileSync("{debugLogPath}", JSON.stringify({
sid: "{sessionId}",
hid: "H{n}",
loc: "{file}:{line}",
msg: "{testable_condition}",
data: { /* Capture relevant values */ },
ts: Date.now()
}) + "\n");
} catch(_) {}
// endregion
ステップ 1.5:ユーザーに出力する
## Hypotheses Generated
Based on error "$BUG", generated {n} hypotheses:
{hypotheses.map(h => `
### ${h.id}: ${h.description}
- Logging at: ${h.logging_point}
- Testing: ${h.testable_condition}
- Evidence to confirm: ${h.evidence_criteria.confirm}
- Evidence to reject: ${h.evidence_criteria.reject}
`).join('')}
**Debug log**: ${debugLogPath}
**Next**: Run reproduction steps, then come back for analysis.
分析モード
ステップ 2.1:デバッグログを解析する
// Parse NDJSON log
const entries = Read(debugLogPath).split('\n')
.filter(l => l.trim())
.map(l => JSON.parse(l))
// Group by hypothesis
const byHypothesis = groupBy(entries, 'hid')
// Validate each hypothesis
for (const [hid, logs] of Object.entries(byHypothesis)) {
const hypothesis = hypotheses.find(h => h.id === hid)
const latestLog = logs[logs.length - 1]
// Check if evidence confirms or rejects hypothesis
const verdict = evaluateEvidence(hypothesis, latestLog.data)
// Returns: 'confirmed' | 'rejected' | 'inconclusive'
}
ステップ 2.2:証拠を分析し、理解を修正する
デバッグログを確認し、各仮説を評価します。
- すべてのログエントリを解析する
- 仮説 ID ごとにグループ化する
- 証拠を想定される基準と比較する
- 判定する:確認済み | 棄却 | 判断不能
- 以前の理解に含まれる誤った前提を特定する
- 修正内容を作成する
ステップ 2.3:修正内容を理解に反映する
understanding.md に新しいイテレーションを追記します。
### Iteration ${n} - Evidence Analysis (${timestamp})
#### Log Analysis Results
${results.map(r => `
**${r.id}**: ${r.verdict.toUpperCase()}
- Evidence: ${JSON.stringify(r.evidence)}
- Reasoning: ${r.reason}
`).join('\n')}
#### Corrected Understanding
Previous misunderstandings identified and corrected:
${corrections.map(c => `
- ~~${c.wrong}~~ → ${c.corrected}
- Why wrong: ${c.reason}
- Evidence: ${c.evidence}
`).join('\n')}
#### New Insights
${newInsights.join('\n- ')}
${confirmedHypothesis ? `
#### Root Cause Identified
**${confirmedHypothesis.id}**: ${confirmedHypothesis.description}
Evidence supporting this conclusion:
${confirmedHypothesis.supportingEvidence}
` : `
#### Next Steps
${nextSteps}
`}
---
## Current Consolidated Understanding (Updated)
${consolidatedUnderstanding}
ステップ 2.4:hypotheses.json を更新する
{
"iteration": 2,
"timestamp": "2025-01-21T10:15:00+08:00",
"hypotheses": [
{
"id": "H1",
"status": "rejected",
"verdict_reason": "Evidence shows key exists with valid value",
"evidence": {...}
},
{
"id": "H2",
"status": "confirmed",
"verdict_reason": "Log data confirms timing issue",
"evidence": {...}
}
],
"corrections": [
{
"wrong_assumption": "...",
"corrected_to": "...",
"reason": "..."
}
]
}
修正と検証
ステップ 3.1:修正を適用する
確認済みの仮説に基づいて、影響を受けるファイルに修正を実装します。
ステップ 3.2:解決内容を文書化する
understanding.md に追記します。
### Iteration ${n} - Resolution (${timestamp})
#### Fix Applied
- Modified files: ${modifiedFiles.join(', ')}
- Fix description: ${fixDescription}
- Root cause addressed: ${rootCause}
#### Verification Results
${verificationResults}
#### Lessons Learned
What we learned from this debugging session:
1. ${lesson1}
2. ${lesson2}
3. ${lesson3}
#### Key Insights for Future
- ${insight1}
- ${insight2}
ステップ 3.3:クリーンアップ
リージョンマーカーを検索して、デバッグ用の計測コードを削除します。
const instrumentedFiles = Grep({
pattern: "# region debug|// region debug",
output_mode: "files_with_matches"
})
for (const file of instrumentedFiles) {
// Remove content between region markers
removeDebugRegions(file)
}
セッションフォルダーの構成
{projectRoot}/.workflow/.debug/DBG-{date}-{slug}/
├── debug.log # NDJSON log (execution evidence)
├── understanding.md # Exploration timeline + consolidated understanding
└── hypotheses.json # Hypothesis history with verdicts
理解ドキュメントのテンプレート
# Understanding Document
**Session ID**: DBG-xxx-2025-01-21
**Bug Description**: [original description]
**Started**: 2025-01-21T10:00:00+08:00
---
## Exploration Timeline
### Iteration 1 - Initial Exploration (2025-01-21 10:00)
#### Current Understanding
...
#### Evidence from Code Search
...
#### Hypotheses Generated
...
### Iteration 2 - Evidence Analysis (2025-01-21 10:15)
#### Log Analysis Results
...
#### Corrected Understanding
- ~~[wrong]~~ → [corrected]
#### Analysis Results
...
---
## Current Consolidated Understanding
### What We Know
- [valid understanding points]
### What Was Disproven
- ~~[disproven assumptions]~~
### Current Investigation Focus
[current focus]
### Remaining Questions
- [open questions]
デバッグログ形式(NDJSON)
各行は JSON オブジェクトです。
{"sid":"DBG-xxx-2025-01-21","hid":"H1","loc":"file.py:func:42","msg":"Check dict keys","data":{"keys":["a","b"],"target":"c","found":false},"ts":1734567890123}
| フィールド | 説明 |
|---|---|
sid | セッション ID |
hid | 仮説 ID(H1、H2、...) |
loc | コードの場所 |
msg | 検証対象 |
data | 取得した値 |
ts | タイムスタンプ(ms) |
イテレーションの流れ
First Call (BUG="error"):
├─ No session exists → Explore mode
├─ Extract error keywords, search codebase
├─ Document initial understanding in understanding.md
├─ Generate hypotheses
├─ Add logging instrumentation
└─ Await user reproduction
After Reproduction (BUG="error"):
├─ Session exists + debug.log has content → Analyze mode
├─ Parse log, evaluate hypotheses
├─ Update understanding.md with:
│ ├─ Evidence analysis results
│ ├─ Corrected misunderstandings (strikethrough)
│ ├─ New insights
│ └─ Updated consolidated understanding
├─ Update hypotheses.json with verdicts
└─ Decision:
├─ Confirmed → Fix → Document resolution
├─ Inconclusive → Add logging, document next steps
└─ All rejected → Assisted new hypotheses
Output:
├─ {projectRoot}/.workflow/.debug/DBG-{date}-{slug}/debug.log
├─ {projectRoot}/.workflow/.debug/DBG-{date}-{slug}/understanding.md (evolving document)
└─ {projectRoot}/.workflow/.debug/DBG-{date}-{slug}/hypotheses.json (history)
エラー処理
| 状況 | 対応 |
|---|---|
| debug.log が空 | 再現時に対象のコードパスが実行されたか確認します |
| すべての仮説が棄却された | 否定された前提に基づいて、新しい仮説を立てます |
| 修正が機能しない | 失敗した修正の試みを文書化し、理解を深めて反復します |
| 5 回を超えるイテレーション | 集約した理解を見直し、すべてのコンテキストを添えてエスカレーションします |
| 理解が長くなりすぎた | 積極的に集約し、古いイテレーションを別ファイルにアーカイブします |
集約ルール
「現在の集約された理解」を更新する際は、次のルールに従います。
- 否定された項目を簡潔にする:「否定されたこと」に移し、1 行で要約します
- 有効な知見を残す:確認された結果を「分かったこと」に昇格させます
- 重複を避ける:集約セクションでタイムラインの詳細を繰り返さないようにします
- 現在の状態に焦点を当てる:調査の経緯ではなく、現時点で分かっていることを記載します
- 重要な修正を保持する:学習に役立つ、重要な誤りから正解への変化を残します
悪い例(煩雑):
## Current Consolidated Understanding
In iteration 1 we thought X, but in iteration 2 we found Y, then in iteration 3...
Also we checked A and found B, and then we checked C...
良い例(集約済み):
## Current Consolidated Understanding
### What We Know
- Error occurs during runtime update, not initialization
- Config value is None (not missing key)
### What Was Disproven
- ~~Initialization error~~ (Timing evidence)
- ~~Missing key hypothesis~~ (Key exists)
### Current Investigation Focus
Why is config value None during update?
主な機能
| 機能 | 説明 |
|---|---|
| NDJSON ログ記録 | 仮説の追跡を含む構造化デバッグログ |
| 仮説の生成 | 分析を活用した仮説の作成 |
| 調査内容の文書化 | タイムライン付きの understanding.md |
| 理解の変遷 | タイムラインと修正の追跡 |
| エラーの修正 | 誤った想定への取り消し線と根拠 |
| 学習内容の集約 | 現在の理解のセクション |
| 仮説の履歴 | 判定結果付きの hypotheses.json |
| 分析の検証 | 重要な意思決定ポイントで実施 |
使用する場面
次のような場合に最適です:
- 複数回の調査が必要な複雑なバグ
- デバッグプロセスから学ぶことに価値がある
- チームがデバッグの根拠を理解する必要がある
- バグが再発する可能性があり、文書化が予防に役立つ
バグに対して、debug-with-file ワークフローを実行します:$BUG