# Action: Debug With File

假设驱动调试，记录理解演变到 understanding.md，支持 Gemini 辅助分析和假设生成。

## Purpose

执行假设驱动的调试流程，包括：
- 定位错误源
- 生成可测试假设
- 添加 NDJSON 日志
- 分析日志证据
- 纠正错误理解
- 应用修复

## Preconditions

- [ ] state.initialized === true
- [ ] state.status === 'running'

## Session Setup

```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()

const sessionFolder = `.workflow/.loop/${state.session_id}`
const debugFolder = `${sessionFolder}/debug`
const understandingPath = `${debugFolder}/understanding.md`
const hypothesesPath = `${debugFolder}/hypotheses.json`
const debugLogPath = `${debugFolder}/debug.log`
```

---

## Mode Detection

```javascript
// 自动检测模式
const understandingExists = fs.existsSync(understandingPath)
const logHasContent = fs.existsSync(debugLogPath) && fs.statSync(debugLogPath).size > 0

const debugMode = logHasContent ? 'analyze' : (understandingExists ? 'continue' : 'explore')

console.log(`Debug mode: ${debugMode}`)
```

---

## Explore Mode (首次调试)

### Step 1.1: 定位错误源

```javascript
if (debugMode === 'explore') {
  // 询问用户 bug 描述
  const bugInput = await AskUserQuestion({
    questions: [{
      question: "请描述遇到的 bug 或错误信息：",
      header: "Bug 描述",
      multiSelect: false,
      options: [
        { label: "手动输入", description: "输入错误描述或堆栈" },
        { label: "从测试失败", description: "从验证阶段的失败测试中获取" }
      ]
    }]
  })

  const bugDescription = bugInput["Bug 描述"]

  // 提取关键词并搜索
  const searchResults = await Task({
    subagent_type: 'Explore',
    run_in_background: false,
    prompt: `Search codebase for error patterns related to: ${bugDescription}`
  })

  // 分析搜索结果，识别受影响的位置
  const affectedLocations = analyzeSearchResults(searchResults)
}
```

### Step 1.2: 记录初始理解

```javascript
// 创建 understanding.md
const initialUnderstanding = `# Understanding Document

**Session ID**: ${state.session_id}
**Bug Description**: ${bugDescription}
**Started**: ${getUtc8ISOString()}

---

## Exploration Timeline

### Iteration 1 - Initial Exploration (${getUtc8ISOString()})

#### 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.files.join(', ')}
- Key findings: ${r.insights}
`).join('\n')}

#### Next Steps

- Generate testable hypotheses
- Add instrumentation
- Await reproduction

---

## Current Consolidated Understanding

${initialConsolidatedUnderstanding}
`

Write(understandingPath, initialUnderstanding)
```

### Step 1.3: Gemini 辅助假设生成

```bash
ccw cli -p "
PURPOSE: Generate debugging hypotheses for: ${bugDescription}
Success criteria: Testable hypotheses with clear evidence criteria

TASK:
• Analyze error pattern and code search results
• Identify 3-5 most likely root causes
• For each hypothesis, specify:
  - What might be wrong
  - What evidence would confirm/reject it
  - Where to add instrumentation
• Rank by likelihood

MODE: analysis

CONTEXT: @${understandingPath} | Search results in understanding.md

EXPECTED:
- Structured hypothesis list (JSON format)
- Each hypothesis with: id, description, testable_condition, logging_point, evidence_criteria
- Likelihood ranking (1=most likely)

CONSTRAINTS: Focus on testable conditions
" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```

### Step 1.4: 保存假设

```javascript
const hypotheses = {
  iteration: 1,
  timestamp: getUtc8ISOString(),
  bug_description: bugDescription,
  hypotheses: [
    {
      id: "H1",
      description: "...",
      testable_condition: "...",
      logging_point: "file.ts:func:42",
      evidence_criteria: {
        confirm: "...",
        reject: "..."
      },
      likelihood: 1,
      status: "pending"
    }
    // ...
  ],
  gemini_insights: "...",
  corrected_assumptions: []
}

Write(hypothesesPath, JSON.stringify(hypotheses, null, 2))
```

### Step 1.5: 添加 NDJSON 日志

```javascript
// 为每个假设添加日志点
for (const hypothesis of hypotheses.hypotheses) {
  const [file, func, line] = hypothesis.logging_point.split(':')

  const logStatement = `console.log(JSON.stringify({
    hid: "${hypothesis.id}",
    ts: Date.now(),
    func: "${func}",
    data: { /* 相关数据 */ }
  }))`

  // 使用 Edit 工具添加日志
  // ...
}
```

---

## Analyze Mode (有日志后)

### Step 2.1: 解析调试日志

```javascript
if (debugMode === 'analyze') {
  // 读取 NDJSON 日志
  const logContent = Read(debugLogPath)
  const entries = logContent.split('\n')
    .filter(l => l.trim())
    .map(l => JSON.parse(l))

  // 按假设分组
  const byHypothesis = groupBy(entries, 'hid')
}
```

### Step 2.2: Gemini 辅助证据分析

```bash
ccw cli -p "
PURPOSE: Analyze debug log evidence to validate/correct hypotheses for: ${bugDescription}
Success criteria: Clear verdict per hypothesis + corrected understanding

TASK:
• Parse log entries by hypothesis
• Evaluate evidence against expected criteria
• Determine verdict: confirmed | rejected | inconclusive
• Identify incorrect assumptions from previous understanding
• Suggest corrections to understanding

MODE: analysis

CONTEXT:
@${debugLogPath}
@${understandingPath}
@${hypothesesPath}

EXPECTED:
- Per-hypothesis verdict with reasoning
- Evidence summary
- List of incorrect assumptions with corrections
- Updated consolidated understanding
- Root cause if confirmed, or next investigation steps

CONSTRAINTS: Evidence-based reasoning only, no speculation
" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```

### Step 2.3: 更新理解文档

```javascript
// 追加新迭代到 understanding.md
const iteration = state.debug.iteration + 1

const analysisEntry = `
### Iteration ${iteration} - Evidence Analysis (${getUtc8ISOString()})

#### 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- ')}

#### Gemini Analysis

${geminiAnalysis}

${confirmedHypothesis ? `
#### Root Cause Identified

**${confirmedHypothesis.id}**: ${confirmedHypothesis.description}

Evidence supporting this conclusion:
${confirmedHypothesis.supportingEvidence}
` : `
#### Next Steps

${nextSteps}
`}

---

## Current Consolidated Understanding (Updated)

### What We Know

- ${validUnderstanding1}
- ${validUnderstanding2}

### What Was Disproven

- ~~${wrongAssumption}~~ (Evidence: ${disproofEvidence})

### Current Investigation Focus

${currentFocus}

### Remaining Questions

- ${openQuestion1}
- ${openQuestion2}
`

const existingContent = Read(understandingPath)
Write(understandingPath, existingContent + analysisEntry)
```

### Step 2.4: 更新假设状态

```javascript
const hypothesesData = JSON.parse(Read(hypothesesPath))

// 更新假设状态
hypothesesData.hypotheses = hypothesesData.hypotheses.map(h => ({
  ...h,
  status: results.find(r => r.id === h.id)?.verdict || h.status,
  evidence: results.find(r => r.id === h.id)?.evidence || h.evidence,
  verdict_reason: results.find(r => r.id === h.id)?.reason || h.verdict_reason
}))

hypothesesData.iteration++
hypothesesData.timestamp = getUtc8ISOString()

Write(hypothesesPath, JSON.stringify(hypothesesData, null, 2))
```

---

## Fix & Verification

### Step 3.1: 应用修复

```javascript
if (confirmedHypothesis) {
  console.log(`\n根因确认: ${confirmedHypothesis.description}`)
  console.log('准备应用修复...')

  // 使用 Gemini 生成修复代码
  const fixPrompt = `
PURPOSE: Fix the identified root cause
Root Cause: ${confirmedHypothesis.description}
Evidence: ${confirmedHypothesis.supportingEvidence}

TASK:
• Generate fix code
• Ensure backward compatibility
• Add tests if needed

MODE: write

CONTEXT: @${confirmedHypothesis.logging_point.split(':')[0]}

EXPECTED: Fixed code + verification steps
`

  await Bash({
    command: `ccw cli -p "${fixPrompt}" --tool gemini --mode write --rule development-debug-runtime-issues`,
    run_in_background: false
  })
}
```

### Step 3.2: 记录解决方案

```javascript
const resolutionEntry = `
### Resolution (${getUtc8ISOString()})

#### Fix Applied

- Modified files: ${modifiedFiles.join(', ')}
- Fix description: ${fixDescription}
- Root cause addressed: ${rootCause}

#### Verification Results

${verificationResults}

#### Lessons Learned

1. ${lesson1}
2. ${lesson2}

#### Key Insights for Future

- ${insight1}
- ${insight2}
`

const existingContent = Read(understandingPath)
Write(understandingPath, existingContent + resolutionEntry)
```

### Step 3.3: 清理日志

```javascript
// 移除调试日志
// (可选，根据用户选择)
```

---

## State Updates

```javascript
return {
  stateUpdates: {
    debug: {
      current_bug: bugDescription,
      hypotheses: hypothesesData.hypotheses,
      confirmed_hypothesis: confirmedHypothesis?.id || null,
      iteration: hypothesesData.iteration,
      last_analysis_at: getUtc8ISOString(),
      understanding_updated: true
    },
    last_action: 'action-debug-with-file'
  },
  continue: true,
  message: confirmedHypothesis
    ? `根因确认: ${confirmedHypothesis.description}\n修复已应用，请验证`
    : `分析完成，需要更多证据\n请复现 bug 后再次执行`
}
```

## Error Handling

| Error Type | Recovery |
|------------|----------|
| 空 debug.log | 提示用户复现 bug |
| 所有假设被否定 | 使用 Gemini 生成新假设 |
| 修复无效 | 记录失败尝试，迭代 |
| >5 迭代 | 建议升级到 /workflow:lite-fix |
| Gemini 不可用 | 回退到手动分析 |

## Understanding Document Template

参考 [templates/understanding-template.md](../../templates/understanding-template.md)

## CLI Integration

### 假设生成
```bash
ccw cli -p "PURPOSE: Generate debugging hypotheses..." --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```

### 证据分析
```bash
ccw cli -p "PURPOSE: Analyze debug log evidence..." --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```

### 生成修复
```bash
ccw cli -p "PURPOSE: Fix the identified root cause..." --tool gemini --mode write --rule development-debug-runtime-issues
```

## Next Actions (Hints)

- 根因确认: `action-validate-with-file` (验证修复)
- 需要更多证据: 等待用户复现，再次执行此动作
- 所有假设否定: 重新执行此动作生成新假设
- 用户选择: `action-menu` (返回菜单)
