---
name: systematic-debugging
description: Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes - find the root cause first; symptom patches are failure
---

# Systematic Debugging

## 边界声明

```
先定位根因,再动手修。没有根因假设与证据,不提出修复。
```

理由:乱试修复浪费时间且制造新 bug;症状修补会掩盖真实问题,在库场景下同时击穿所有下游项目。系统化定位对简单 bug 同样更快——简单 bug 也有根因。

## 定位要素(按需取用,不是仪式)

1. **完整读错误信息与堆栈**——它经常直接给出答案。记下行号、文件、错误码。
2. **稳定复现**——不能复现就先收集数据,不要猜。
3. **查最近变更**——`git diff`、新依赖、配置与环境差异。已建 graphify 图谱时,可用 `conda run -n PolyGateway graphify path/affected/explain` 追调用链与影响面,免于盲读。
4. **多组件系统先取证再归因**——在组件边界加日志(进/出数据、配置传播),跑一次拿到"断在哪一层"的证据,再深入该层。深层调用栈用回溯法(见 `root-cause-tracing.md`):坏值从哪来,一路向上追到源头,在源头修。
5. **查结构化运行日志**——若项目有遥测/结构化日志(如 SQLite 遥测表、`research-wiki/schemas/` 登记的表),查事件流与指标趋势,让假设有数据支撑而非纯读码猜测。
6. **对照可工作的样例**——同库相似可用代码、`reference/` 参考实现。逐项列差异,不要跳过"这不可能有影响"的差异;参考实现要读完整,不要按印象改编。

## 假设与修复(纪律)

- 一次一个假设,写清"我认为根因是 X,因为 Y";用**最小改动**验证,一次只动一个变量。
- 修复前先有失败的复现测试(接 `test-driven-development` 结果门);修复只针对根因,禁止"顺手"重构与打包多个改动。
- 修完验证:该测试通过、其余测试不回归、原症状确实消失。

**3 次修复失败 = 停下质疑架构。** 若每次修复都在别处暴露新问题、或修复需要"大动干戈"才能实施,这不是假设错了,是架构错了——停止继续修,与人类讨论架构后再动。

若彻查后确属环境/时序/外部问题:记录调查过程,实现恰当的处理(重试/超时/报错),加监控埋点。但 95% 的"查无根因"是调查没做完。

## 红线(出现即停,回到定位)

- "先快速修一下,回头再查" / "改改 X 试试看" / "大概是 X,先修了再说"
- 一次提交多个猜测性修改;注释掉测试或跳过校验让报错消失
- 已经失败 2 次还想"再试一个修复"

## 附属技术

- `root-cause-tracing.md` — 沿调用栈回溯到源头
- `defense-in-depth.md` — 找到根因后的多层校验
- `condition-based-waiting.md` — 用条件轮询替代拍脑袋超时

## Wiki 留痕(`research-wiki/` 存在时)

得出值得留存的结论时(尤其影响后续任务的),记 finding:

```bash
.claude/tools/research_wiki.py add_entity research-wiki/ --type finding --id <slug> --title "<问题>"
.claude/tools/research_wiki.py rebuild_index research-wiki/
```

页内记录:症状、根因、验证方法、修复、影响面;若暴露 design/plan 缺陷,加 `reveals` 边。
