本层判断标准

对任一次关键改动,能不能在 5 分钟内说清它用了哪个工具与模型、提示词是哪个版本、哪几行是人定的、谁负责?

在 5 分钟内答不出,说明这次改动只剩代码、没有痕迹。补法:把下面这四个尾部字段补进那一次提交,并在 docs/traceability.md 补上对应的一行。

记什么,记在哪

不必每次都记,只记关键改动:权限、数据、金额、对外接口,以及提示词和模型版本变化。全记的结果是没人记,只记关键才有人做。表里每样信息都有固定落点,不靠记忆去找它。

记什么落在哪具体字段或命令
规约链接合并请求说明的提案路径openspec/changes/<变更名>/
模型与工具版本提交信息尾部字段Assisted-by: <工具名>
提示词版本化的 prompts/ 目录Prompt-Version: prompts/x.v3
人工决定提交信息尾部字段或说明的「人定的选择」Human-Decision: <一句话>
深审记录docs/reviews/Deep-Review: docs/reviews/日期-名.md
验证证据测试命令输出、评测运行记录 idmake check 退出码与通过条数

边界:这四个字段靠手写,不用钩子强制就会有人跳过。减少漏写的办法有两个:把尾部字段写进提交信息模板(见下一节),并让评审的人在第二步专门核对这几行。他核对要 2 分钟;漏掉,复盘时全组要重新读一遍那次改动的差异。

提交信息模板与尾部字段

Git 把信息末尾形如 Token: 值 的行当作尾部字段,可以用 git log --format='%(trailers:...)' 直接统计。把版本信息写进尾部字段,不要写在正文里——正文会被 squash 改写,尾部字段可以查询。

提交信息(放在 .gitmessage,或写进模板目录)

前两行是正文,最后四行是尾部字段。工具与版本以 AGENTS.md 的工具清单为准,不要在提交信息里手写版本号。

[#412] 笔记列表改为按会话范围分页

改动:notes 列表分页,游标不参与权限判定。
验证:make check 通过;跨 scope 接口测试返回 404。

Assisted-by: Claude Code(版本见 AGENTS.md 工具清单)
Prompt-Version: prompts/notes-paging.v3
Human-Decision: 分页默认 20 条,助手建议 50 条已否掉
Deep-Review: docs/reviews/2026-10-03-notes-paging.md

启用模板与核对命令

跑这三条命令:把模板变成默认行为,并在合并前核对、在季度末统计。

# 让每次 commit 默认带上模板
git config commit.template .gitmessage

# 核对本次分支的 trailer 是否齐全
git log --format='%(trailers:key=Assisted-by,valueonly)' origin/main...HEAD
git log --format='%(trailers:key=Prompt-Version,valueonly)' origin/main...HEAD

# 统计本季度用了哪些工具(复盘用)
git log --format='%(trailers:key=Assisted-by)' | sort | uniq -c

助手交出来的样子

[#412] 笔记列表改为按会话范围分页
改动:notes 列表分页。
Assisted-by: Claude Code
Prompt-Version: prompts/notes-paging.v3
Human-Decision: 分页默认 20 条
Deep-Review: docs/reviews/2026-10-03-notes-paging.md

认它的办法:挑一个字段,去查它指向的东西在不在。四个字段齐全不等于可溯源:Prompt-Version 有值,可 prompts/notes-paging.v3 在仓库里并不存在;Deep-Review 指向的记录文件是空的。助手会照着模板把四行都填上——它填的是格式,不是事实。

溯源表

尾部字段跟着提交走,适合单次定位;季度末要回答「我们用过哪些工具、哪些提示词版本」,就需要一张跨改动的表。

docs/traceability.md

一行一次关键改动。责任人一列必须与合并请求作者一致,对不上就是错的。

# 溯源表

只记关键改动:权限、数据、金额、对外接口,以及提示词与模型版本变化。

| 日期 | 改动 | 规约 | 工具与模型 | 提示词版本 | 人定的选择 | 验证证据 | 责任人 |
|---|---|---|---|---|---|---|---|
| 2026-10-03 | #412 笔记分页 | openspec/changes/notes-paging/ | Claude Code | prompts/notes-paging.v3 | 分页默认 20 条 | make check + 接口测试 | 张三 |
| 2026-10-05 | #418 导出 CSV | openspec/changes/export-csv/ | Cursor | prompts/export.v1 | 导出上限 5000 行 | make check | 李四 |

## 本季度待办
- 并发写入同一行 note 的行为:无压测环境,未查(2026-10-03 记录)

这张表的用处是复盘时不必翻提交历史。代价是每行手工补,一个季度约 20 到 30 行;超过这个量,说明把「关键改动」判得太宽,收回到权限、数据、金额、对外接口这四类。

责任怎么落到人和文件上

「署名即担责」要能落到具体的人,否则它只是一句口号。

提交用真实姓名:跑 git config user.name "张三",不用昵称。跑 git log --format='%an' | sort | uniq -c,一旦出现昵称,就说明本组有人没配。
CODEOWNERS 写真实账号:写高风险路径时指向具体账号(@zhangsan),别写「后端组」这类集合——写集合等于没人。
溯源表的责任人一列要对上:这一列和合并请求作者不一致时,按记录错误处理,不按笔误处理。责任人写错,这次改动的可追溯性就是零。
助手的产出同样要署名:Assisted-by 记工具,user.name 记人。署名提交的代码,在评审、安全和事故追责上等同于手写,「这是助手写的」不是免责理由。

这些规定不是为了追责,是为了让人在下手前多停一秒。助手最容易带来的问题不是代码变差,而是让每个人都觉得自己只是个传递者——反正不是我想的、不是我写的。责任一旦被稀释,红线就没人守,质量红线也就不再是红线。

复盘要问的四个问题

出了一次事故或一次严重错误之后,按表上的顺序问四个问题。每个答案对应一种修补动作,也对应一份要改的文件。

问题答案动作改哪份文件
规约里有没有这一条?没有补规约openspec/changes/,最常见的原因
有规约,实现没做?是门禁没覆盖,补一条检查Makefile 或 pyproject.toml
门禁覆盖了,却放过了?是检查本身写错了,修检查工作流或规则集,不修数据
规约、检查都对,还是出事?是规约本身错了,改规约改规约并写进决议的「不采纳」

四个问题走完,落在「多写一条文档」上的情况其实很少,多数落在「补一条检查」。判断本组的规范有没有真跑起来,只看一件事:复盘结论里检查变多了,它是活的;每次都只补文档,说明它没拦住任何东西。