backprop

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

backprop — bug → spec

回溯(backprop)—— Bug → 规范

Plan-then-execute fixes the code & forgets. SDD fixes the code AND edits spec so recurrence is impossible. That edit is backprop.
先规划后执行的模式只会修复代码然后就不再管了。 SDD模式会修复代码,同时编辑规范,确保问题不会再次发生。 这种编辑操作就是回溯(backprop)。

WHEN TO BACKPROP

何时执行回溯

  • Test failed at
    /build
    verification.
  • User reports bug.
  • Post-mortem after production incident.
  • /check
    flags VIOLATE with root cause found.
  • /build
    验证阶段测试失败。
  • 用户提交Bug报告。
  • 生产事故后的事后复盘。
  • /check
    工具标记违规且已找到根本原因。

SIX STEPS

六个步骤

1. TRACE

1. 追溯

Read failure output / bug report. Find exact file:line of wrong behavior. Name root cause in one caveman sentence.
查看失败输出/Bug报告。 定位到问题行为对应的具体文件和行号。 用一句直白的话描述根本原因。

2. ANALYZE

2. 分析

Ask three questions:
  • Would a new §V invariant catch this class of bug? (most common: yes)
  • Is §I wrong — did spec claim shape the code cannot deliver? (sometimes)
  • Is §T wrong — did we build the wrong thing? (rare but real)
提出三个问题:
  • 新增一条§V不变量是否能捕获这类Bug?(大多数情况下答案是肯定的)
  • §I是否存在错误——规范中要求的内容是代码无法实现的?(有时会出现这种情况)
  • §T是否存在错误——我们是否开发了错误的功能?(虽然罕见但确实存在)

3. PROPOSE

3. 提出方案

Draft the spec change. Never skip §B; §V/§I/§T are case-by-case.
Template:
§B row: B<next>|<date>|<root cause>|V<N>
§V line: V<next>: <testable rule that would have caught it>
Example:
§B row: B3|2026-04-20|refund job ran twice on retry|V7
§V line: V7: ∀ refund → idempotency key check before charge reversal
起草规范变更内容。永远不要跳过§B的更新;§V/§I/§T的更新则视情况而定。
模板:
§B条目:B<序号>|<日期>|<根本原因>|V<对应序号>
§V条目:V<序号>: <可测试的规则,用于提前捕获该问题>
示例:
§B条目:B3|2026-04-20|退款任务重试时重复执行|V7
§V条目:V7: 所有退款操作→在撤销扣款前必须检查幂等键

4. GENERATE TEST

4. 生成测试

New invariant without test = lie. Add failing test first. Name test so it cites the invariant:
TestV7_RefundIdempotent
.
没有测试的新不变量毫无意义。先添加一个会失败的测试用例。 测试用例的命名要关联对应的不变量:
TestV7_RefundIdempotent

5. VERIFY

5. 验证

Fix code. Run test. Must pass. Run full suite. Must not regress.
修复代码。运行测试,必须通过。运行完整测试套件,确保没有回归问题。

6. LOG

6. 记录

Commit spec edit + test + code fix together. Commit msg:
backprop §B.<n> + §V.<N>: <one-line cause>
.
将规范修改、测试用例和代码修复一起提交。 提交信息格式:
backprop §B.<n> + §V.<N>: <一句话描述原因>

WHAT MAKES A GOOD INVARIANT

优质不变量的标准

  • Testable in code (grep-able or assert-able).
  • Scoped to a behavior, not a file.
  • Stated positively when possible (
    ! hold
    over
    ⊥ forbid
    ).
  • References §I surface where it applies.
Bad: V8: code should be correct. Good: V8: ∀ pg_query ! params interpolated via driver, ⊥ string concat.
  • 可通过代码测试(可通过grep查找或断言验证)。
  • 针对特定行为而非单个文件。
  • 尽可能用肯定句式描述(优先使用
    ! hold
    而非
    ⊥ forbid
    )。
  • 关联到适用的§I相关内容。
反面示例:V8: 代码应保证正确。 正面示例:V8: 所有pg_query操作→参数必须通过驱动程序插值,禁止字符串拼接。

WHEN NOT TO ADD §V

何时无需新增§V

  • Bug was purely mechanical typo with no class (
    i++
    vs
    i--
    in throwaway).
  • Fix is a one-time migration.
  • Root cause is external dep (upgrade deps instead, note in §C).
Still append §B entry — record that this failure mode was considered. Future bug with same smell → §B search shows precedent.
  • Bug纯粹是无规律的机械性拼写错误(比如临时代码中的
    i++
    写成
    i--
    )。
  • 修复是一次性的迁移操作。
  • 根本原因是外部依赖问题(此时应升级依赖,并在§C中记录)。
即使无需新增§V,仍需追加§B条目——记录该故障模式已被评估。未来出现同类特征的Bug时,可通过搜索§B找到先例。

OUTPUT SHAPE

输出内容

Every backprop run produces:
  1. §B entry (always).
  2. §V entry (usually).
  3. Test file (when §V added).
  4. Code fix.
  5. One commit.
No dashboards. No log files. SPEC.md + git is the full history.
每次回溯操作都会生成:
  1. §B条目(必选)。
  2. §V条目(通常会有)。
  3. 测试文件(当新增§V时)。
  4. 代码修复。
  5. 一次提交。 无需仪表盘,无需日志文件。完整历史记录存储在SPEC.md和git中。