ClawLite Investigate — 系统化 Debug
核心法则
无根因调查则无修复。
修复症状会产生打地鼠式 debug。每个不解决根本原因的修复都会让下一个 bug 更难找到。找到根因,然后修复它。
阶段 1:根因调查
在形成任何假设之前收集上下文。
- 1. 收集症状: 读取错误消息、堆栈跟踪和复现步骤。如果用户没有提供足够的上下文,一次只问一个问题。
- 2. 读取代码: 从症状追溯到潜在原因的代码路径。使用 Grep 查找所有引用,Read 理解逻辑。
- 3. 检查最近的更改:
git log --oneline -20 -- <受影响的文件>
这之前能工作吗?什么改变了?回归意味着根因在 diff 中。
- 4. 复现: 你能确定性触发这个 bug 吗?如果不能,在继续之前收集更多证据。
输出:"根因假设:..." — 关于什么出错以及为什么的具体、可测试的声明。
阶段 2:模式分析
检查这个 bug 是否匹配已知模式:
| 模式 | 特征 | 查看位置 |
|---|
| 竞态条件 | 间歇性、时间依赖 | 对共享状态的并发访问 |
| Nil/null 传播 |
NoMethodError, TypeError | 可选值上的缺失守卫 |
| 状态损坏 | 数据不一致、部分更新 | 事务、回调、钩子 |
| 集成失败 | 超时、意外响应 | 外部 API 调用、服务边界 |
| 配置漂移 | 本地工作,staging/prod 失败 | 环境变量、特性开关、数据库状态 |
| 陈旧缓存 | 显示旧数据,清除缓存后修复 | Redis、CDN、浏览器缓存 |
还要检查:
- -
TODOS.md 中相关的已知问题 - INLINECODE1 中同一区域的先前修复 — 同一文件中的重复 bug 是架构气味,不是巧合
阶段 3:假设验证
在写任何修复之前,验证你的假设。
- 1. 确认假设: 在可疑的根因处添加临时日志语句、断言或调试输出。运行复现。证据匹配吗?
- 2. 如果假设错了: 返回阶段 1。收集更多证据。不要猜测。
- 3. 三振规则: 如果 3 个假设都失败,停止。使用 AskUserQuestion:
CODEBLOCK1
红旗 — 如果看到这些,放慢速度:
- - "先快速修复一下" — 没有"先"。正确修复或升级。
- 在追踪数据流之前提出修复 — 你在猜测。
- 每个修复都在其他地方揭示新问题 — 错误的层,不是错误的代码。
阶段 4:实现
一旦根因确认:
- 1. 修复根因,不是症状。 消除实际问题最小改变。
- 2. 最小 diff: 改动最少的文件,最少行数更改。抵制重构相邻代码的冲动。
- 3. 写一个回归测试:
- 没有修复时
失败(证明测试有意义)
- 有修复时
通过(证明修复有效)
- 4. 运行完整测试套件。 粘贴输出。不允许回归。
- 5. 如果修复涉及 >5 个文件: 使用 AskUserQuestion 标记影响范围:
此修复涉及 N 个文件。对于 bug 修复来说影响范围很大。
A) 继续 — 根因确实跨越这些文件
B) 拆分 — 现在修复关键路径,延迟其余
C) 重新思考 — 也许有更有针对性的方法
阶段 5:验证与报告
全新验证: 复现原始 bug 场景并确认它已修复。这不是可选的。
运行测试套件并粘贴输出。
输出结构化 debug 报告:
DEBUG 报告
════════════════════════════════════════
症状: [用户观察到的]
根因: [实际出了什么问题]
修复: [改变了什么,带文件:行号引用]
证据: [测试输出,显示修复有效的复现尝试]
回归测试: [新测试的文件:行号]
相关: [TODOS.md 项目、同一区域的先前 bug、架构笔记]
状态: DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════
重要规则
- - 3+ 次失败的修复尝试 → 停止并质疑架构。 错误的架构,不是失败的假设。
- 永远不要应用你无法验证的修复。 如果你无法复现和确认,不要发货。
- 永远不要说"这应该修复它"。 验证并证明它。运行测试。
- 如果修复涉及 >5 个文件 → AskUserQuestion 关于影响范围,然后再继续。
- 完成状态:
- DONE — 找到根因,应用修复,写了回归测试,所有测试通过
- DONE
WITHCONCERNS — 修复但无法完全验证(例如间歇性 bug,需要 staging)
- BLOCKED — 调查后根因不清楚,已升级
ClawLite Investigate — 系统化 Debug
核心法则
无根因调查则无修复。
修复症状会产生打地鼠式 debug。每个不解决根本原因的修复都会让下一个 bug 更难找到。找到根因,然后修复它。
阶段 1:根因调查
在形成任何假设之前收集上下文。
- 1. 收集症状: 读取错误消息、堆栈跟踪和复现步骤。如果用户没有提供足够的上下文,一次只问一个问题。
- 2. 读取代码: 从症状追溯到潜在原因的代码路径。使用 Grep 查找所有引用,Read 理解逻辑。
- 3. 检查最近的更改:
bash
git log --oneline -20 -- <受影响的文件>
这之前能工作吗?什么改变了?回归意味着根因在 diff 中。
- 4. 复现: 你能确定性触发这个 bug 吗?如果不能,在继续之前收集更多证据。
输出:根因假设:... — 关于什么出错以及为什么的具体、可测试的声明。
阶段 2:模式分析
检查这个 bug 是否匹配已知模式:
| 模式 | 特征 | 查看位置 |
|---|
| 竞态条件 | 间歇性、时间依赖 | 对共享状态的并发访问 |
| Nil/null 传播 |
NoMethodError, TypeError | 可选值上的缺失守卫 |
| 状态损坏 | 数据不一致、部分更新 | 事务、回调、钩子 |
| 集成失败 | 超时、意外响应 | 外部 API 调用、服务边界 |
| 配置漂移 | 本地工作,staging/prod 失败 | 环境变量、特性开关、数据库状态 |
| 陈旧缓存 | 显示旧数据,清除缓存后修复 | Redis、CDN、浏览器缓存 |
还要检查:
- - TODOS.md 中相关的已知问题
- git log 中同一区域的先前修复 — 同一文件中的重复 bug 是架构气味,不是巧合
阶段 3:假设验证
在写任何修复之前,验证你的假设。
- 1. 确认假设: 在可疑的根因处添加临时日志语句、断言或调试输出。运行复现。证据匹配吗?
- 2. 如果假设错了: 返回阶段 1。收集更多证据。不要猜测。
- 3. 三振规则: 如果 3 个假设都失败,停止。使用 AskUserQuestion:
已测试 3 个假设,都不匹配。这可能是架构问题而不是简单的 bug。
A) 继续调查 — 我有新假设:[描述]
B) 升级给人审查 — 这需要了解系统的人
C) 添加日志等待 — 标记区域,下次捕获它
红旗 — 如果看到这些,放慢速度:
- - 先快速修复一下 — 没有先。正确修复或升级。
- 在追踪数据流之前提出修复 — 你在猜测。
- 每个修复都在其他地方揭示新问题 — 错误的层,不是错误的代码。
阶段 4:实现
一旦根因确认:
- 1. 修复根因,不是症状。 消除实际问题最小改变。
- 2. 最小 diff: 改动最少的文件,最少行数更改。抵制重构相邻代码的冲动。
- 3. 写一个回归测试:
- 没有修复时
失败(证明测试有意义)
- 有修复时
通过(证明修复有效)
- 4. 运行完整测试套件。 粘贴输出。不允许回归。
- 5. 如果修复涉及 >5 个文件: 使用 AskUserQuestion 标记影响范围:
此修复涉及 N 个文件。对于 bug 修复来说影响范围很大。
A) 继续 — 根因确实跨越这些文件
B) 拆分 — 现在修复关键路径,延迟其余
C) 重新思考 — 也许有更有针对性的方法
阶段 5:验证与报告
全新验证: 复现原始 bug 场景并确认它已修复。这不是可选的。
运行测试套件并粘贴输出。
输出结构化 debug 报告:
DEBUG 报告
════════════════════════════════════════
症状: [用户观察到的]
根因: [实际出了什么问题]
修复: [改变了什么,带文件:行号引用]
证据: [测试输出,显示修复有效的复现尝试]
回归测试: [新测试的文件:行号]
相关: [TODOS.md 项目、同一区域的先前 bug、架构笔记]
状态: DONE | DONEWITHCONCERNS | BLOCKED
════════════════════════════════════════
重要规则
- - 3+ 次失败的修复尝试 → 停止并质疑架构。 错误的架构,不是失败的假设。
- 永远不要应用你无法验证的修复。 如果你无法复现和确认,不要发货。
- 永远不要说这应该修复它。 验证并证明它。运行测试。
- 如果修复涉及 >5 个文件 → AskUserQuestion 关于影响范围,然后再继续。
- 完成状态:
- DONE — 找到根因,应用修复,写了回归测试,所有测试通过
- DONE
WITHCONCERNS — 修复但无法完全验证(例如间歇性 bug,需要 staging)
- BLOCKED — 调查后根因不清楚,已升级