# Debug

> 调查 bug、测试失败、异常、错误行为、偶发问题、性能退化、构建失败、集成失败或其他非预期行为；复现并确定根因，提交修复方案等待用户批准，获批后把 approved-fix 交给 implement 实施。

- Skill: `swm8023/debug` (Agent Skill)
- Install (CLI): `npx skillmds@latest add swm8023/debug`
- Raw SKILL.md: https://api.skillmd.com/api/skills/swm8023/debug/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: swm8023 (https://skillmd.com/u/swm8023)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/swm8023/debug

---


# debug

## 概览

debug 是处理 bug 的调查与决策入口。默认产物是诊断结论和经用户批准的修复契约；代码实施、验证和 Git 收尾统一交给 `implement`。

非 bug 的功能、设计、需求澄清走 `scope`。

## 铁律

```
先复现。追根因。给方案。等确认。再修复。
```

没有验证信号、根因证据、用户批准的修复计划，不写生产修复代码。

用户最初说“修一下”“帮我修”只表示目标，不等于批准修复方案。批准必须发生在你提交第 6 阶段内容之后。

禁止：

- 看症状直接改代码。
- 没有复现就猜原因。
- 用临时绕过冒充根因修复。
- 用户确认前写生产修复代码。
- 一次改多个变量。
- 在失败修复上继续叠补丁。

## 修复闸门

写任何生产修复代码前，先自检：

- 已用验证信号复现或锁定现象。
- 已找到有证据支撑的根因。
- 已向用户提交根因、证据、修复方案、验证计划和风险。
- 用户已在看到计划后明确同意继续。

任一项不成立，就停在调查或计划阶段，不要修改生产代码。

## 诊断阶段 Git 边界

- 只读调查、运行现有测试和不落盘实验不调用 Git skill。
- 如果复现需要把测试、脚本、日志配置或临时埋点写入仓库，首次写入前调用 `git-workflow` 的 `prepare` 阶段。
- 诊断阶段执行过 `prepare` 后，等待批准和继续调查沿用同一 Git 生命周期，不因内部阶段切换重复 `prepare` 或 `finalize`。
- 任务取消、阻塞、验证失败或外部 handoff 时，按真实结果调用 `finalize`；不得把诊断产物当成已完成修复提交。
- 用户批准后把诊断产物列入修复契约；执行过 `prepare` 时向 implement 传递 `git_state: prepared`，纯只读诊断传递 `git_state: unprepared`。

## 工作流

### 1. 明确问题与验证信号

先定义问题，再选择能判断 bug 存在/消失的信号。

确认：

- 实际行为和预期行为。
- 触发条件：输入、环境、配置、版本、账号、时间窗口、操作步骤。
- 影响范围：路径、调用方、平台、数据集。
- 最近变化：代码、依赖、配置、数据、部署。

选择最便宜可靠的验证信号：失败测试、命令/脚本、真实材料、临时复现脚手架、A/B 对照、人工复现步骤。

没有验证信号就停下，说明已尝试什么，并向用户要复现环境、材料，或临时埋点许可。

### 2. 复现并锁定现象

用验证信号看着 bug 出现。确认：

- 失败模式就是用户描述的 bug。
- 多次运行可复现；非确定性 bug 至少有足够复现率。
- 捕获了精确症状：错误消息、输出、状态、时序、截图或 trace。

### 3. 追根因

沿数据流和控制流找到源头：

1. 读完整错误、警告、调用栈、错误码和路径。
2. 查最近 diff、commit、依赖、配置、环境变化。
3. 追踪错误值在哪里产生、传递、变坏。
4. 多组件系统要检查边界输入、输出、配置传播和状态。
5. 底层报错要沿调用链向上追到最初触发点。

不要只修症状位置，除非已经证明那里就是源头。

### 4. 对照正常模式

找相邻的正常实现，完整阅读后比较差异：

- 调用顺序、初始化、配置、依赖、环境假设。
- 数据结构、状态检查、错误处理。
- 好路径和坏路径在边界上的输入输出。

不要预设小差异没有影响。

### 5. 验证假设

生成 3-5 个排序后的可证伪假设。每个假设都写预测：

> 如果 X 是原因，那么改变 Y 会让 bug 消失，或改变 Z 会让 bug 更明显。

把假设列表给用户看；如果用户不在，按排序继续。每轮只测 top 1 假设，一次只改一个变量。

临时埋点必须服务于某个预测。优先调试器、REPL、性能分析器、查询计划、计时脚手架、二分定位；日志要打在能区分假设的边界，并加唯一标记，例如 `[DEBUG-a4f2]`。

### 6. 提交诊断结论与修复计划

写任何生产修复代码前，先向用户提交结论和计划：

- **根因**：哪一层、哪个条件、哪条数据流或调用关系导致问题。
- **证据**：哪个验证信号、日志、断点、diff、trace 或实验支持结论。
- **修复方案**：准备改哪里、为什么这样改、排除了哪些替代方案。
- **验证计划**：如何证明修好了；哪些测试、脚本、人工步骤或观察信号会重跑。
- **Git 计划**：确认后由 `implement` 继承已有 Git 生命周期或执行 `prepare`，并负责后续 `checkpoint`、`finalize` 及 commit/push/merge/cleanup。
- **风险**：可能影响哪些路径，修复后要检查什么。

没有用户明确确认，不进入修复阶段。如果根因仍是猜测，明确说“还不能修”，回到假设验证。

### 7. 等待批准并形成 handoff

用户看到第 6 阶段的完整结论后明确同意，才形成以下实施契约：

```yaml
root_cause: 已证实的根因
evidence: 复现、日志、trace、diff 或实验
repro: 可重复验证信号
fix_scope: 准备修改的文件、行为和排除项
acceptance: 修复完成必须满足的可观察结果
verification: 原始 repro、回归测试和相关测试
risks: 影响路径和回归风险
diagnostic_artifacts: 已写入仓库的诊断文件或临时埋点
```

契约缺少根因证据、repro、fix scope、验收或验证计划时不得交接。用户只说“继续看看”不等于批准修复。

### 8. 交给 implement 实施

用户批准后调用 `implement`，传入 `source_kind: approved-fix`、`source: <完整修复契约>`（含 `diagnostic_artifacts`）、`wiki_target: <已确认目标或 none>`，以及与诊断阶段一致的 `git_state: prepared | unprepared`。不要在 debug 内重复实现、checkpoint 或最终汇报。

从此由 `implement` 独占：

- Git 生命周期所有权；仅 `unprepared` 时执行 `prepare`，并负责 `checkpoint`、`finalize`
- 对话 Todo 和文件所有权
- 测试先行的 RED、最小 GREEN、重构和回归验证；优先复用 debug 交接的失败测试或 repro
- 原始 repro、回归测试和相关测试
- 临时诊断产物清理
- commit、push、merge、cleanup 和最终完成报告

实施发现根因错误或关键假设被推翻时，`implement` 停止并把证据退回 debug；不要在执行阶段重新猜根因。

## 方法准则

### 调用栈深处的错误

不要只修底层报错点。沿调用链问：谁传入了坏值，坏值在哪里创建，为什么上游允许它进入系统。

### flaky / race / timeout

不要猜 sleep 时间。等待真实条件：事件出现、状态 ready、文件存在、计数达到、队列为空、请求完成。

### 纵深防御

如果根因是非法数据、危险状态或错误环境，沿数据流补防御：入口校验、业务校验、环境守卫、必要取证。

### 人工复现

必须由用户点击或观察时，写清步骤、要捕获的输出和判断标准，再把反馈转成可验证事实。

## 看到就停下

| 念头 | 现实 |
| --- | --- |
| "先临时修一下" | 这是绕过，不是根因修复。 |
| "八成是 X，我直接改" | 没有预测和证据就不是假设。 |
| "一次改多处省时间" | 你会不知道哪一处有效。 |
| "问题简单，不需要流程" | 简单 bug 也有根因。 |
| "测试后面再补" | 没有失败测试，无法证明修复针对原 bug。 |
| "再试一个 fix" | 失败后先重新调查。 |
| "日志全打上再说" | 临时埋点必须服务于具体预测。 |
| "这里太难测" | 可能是 seam 不对，也可能是设计阻止验证。 |
| "用户会同意这个修法" | 先列根因和方案，等用户确认。 |

用户说 "Stop guessing"、"Will it show us...?"、"Is that not happening?" 或类似话时，立即回到根因调查。

