SKILL.md
只读
名称
backprop
描述
Bug 到 Spec 的反向回溯协议。当发现 Bug 或测试失败时,追查根因,判断新增 §V 不变量是否能防止复发,并将记录追加至 §B。这是 SDD(规范驱动开发)区别于常规“先规划后执行”模式中最精妙的一环。触发场景包括:测试失败、Bug 报告、事故复盘或用户明确要求。
backprop — bug → spec
常规的“先规划后执行”模式改完代码就忘。
而 SDD(规范驱动开发)在修复代码的同时还会修改 Spec(规范),从源头绝杀此类 Bug 的复发可能。
这次规范修改,就是 backprop(反向回溯)。
什么时候执行 BACKPROP
- 在
/build校验阶段测试失败。 - 用户反馈了 Bug。
- 线上故障复盘(Post-mortem)。
- 执行
/check报了 VIOLATE(违反规范)且已定位到根因。
六步流程
1. 追查 (TRACE)
阅读报错输出或 Bug 报告。
定位到异常行为的具体文件与行号(file:line)。
用一句极其简短的大白话概括根因。
2. 分析 (ANALYZE)
问自己三个问题:
- 新增一个 §V 不变量能拦住这类 Bug 吗?(绝大多数情况:能)
- 是 §I 写错了?——即 Spec 宣称的功能,代码结构根本承载不了?(偶尔会有)
- 是 §T 写错了?——即我们从一开始就做错方向了?(罕见但确实存在)
3. 提案 (PROPOSE)
起草 Spec 的修改内容。§B 必填;§V/§I/§T 视具体情况而定。
模板:
§B row: B<next>|<date>|<root cause>|V<N>
§V line: V<next>: <testable rule that would have caught it>
示例:
§B row: B3|2026-04-20|refund job ran twice on retry|V7
§V line: V7: ∀ refund → idempotency key check before charge reversal
4. 生成测试 (GENERATE TEST)
光有不变量没有测试就是画饼。必须先写一个会报错的测试(failing test)。
测试命名要明确引用对应的不变量,例如:TestV7_RefundIdempotent。
5. 验证 (VERIFY)
修复代码。运行测试,必须通过。运行完整测试套件,绝不能出现回归问题。
6. 记录 (LOG)
将 Spec 修改 + 测试 + 代码修复打包提交。
Commit 信息:backprop §B.<n> + §V.<N>: <一句话根因>。
什么是好的不变量
- 代码可测(可 grep 检查或可用断言 assert 验证)。
- 作用域限定在某种“行为”,而非某个具体“文件”。
- 尽量采用正面表述(优先用
! 维持,而非⊥ 禁止)。 - 在适用处引用对应的 §I 声明层。
反面教材: V8: 代码应该是正确的。
正面示范: V8: ∀ pg_query ! params interpolated via driver, ⊥ string concat.
什么时候不需要新增 §V
- Bug 纯粹是手抖写错的无规律打字错误(比如临时代码里的
i++写成了i--)。 - 修复属于一次性的数据迁移。
- 根因出在外部依赖库上(这种情况应该升级依赖包,并在 §C 中做好记录)。
不过依然需要追加 §B 记录——证明你评估过这种失效模式。以后遇到同类疑难杂症,搜一下 §B 就能看到前车之鉴。
产出物形态
每次 backprop 运行会产出:
- §B 记录(必定产生)。
- §V 记录(通常产生)。
- 测试文件(新增 §V 时产生)。
- 代码修复。
- 一次 Commit。
不需要仪表盘,不需要乱七八糟的日志文件。SPEC.md + git 就是最完整的历史履历。






