AI 编码合并前风险登记:merge 之前要追踪的条目

AI 编码合并前风险登记:merge 之前要追踪的条目
Spec Coding 编辑部 · Spec-First 工程实践内容

专门给 AI 生成代码准备的合并前风险登记册:LLM 不会主动提示的七类风险、每个 PR 一行的风险备注,以及什么情况阻塞合并、什么情况只是警告。

发布于 2026-03-10 · ✓ 已更新 2026-06-02 · 阅读约 7 分钟 · 主题:合并前风险登记 · 作者:Spec Coding 编辑部 · 审校:编辑与事实核查政策

我为什么开始给 AI 代码单独记一份风险登记

我不想再多一个模板。我只想在生产环境里别再被吓一跳。在第三次出事之后——某个 AI 生成的 PR 上线了我自己手写绝不会上线的东西——我终于接受一个事实:助手和我对"风险"的权衡完全不是同一套。助手优化的是"看起来像样、能编译通过"的代码;我要优化的是"合并之后我晚上还能不能睡着"。

于是我开始在每一个 AI 协作过的 PR 上写一行风险备注。不是文档,就是一句话:这次改动可能破坏什么,我为此做了什么。这一句话就是整份登记册。它写在 PR 描述里,被 CI 强制要求,也是我做评审时最先读的那一行。

模型不会主动标出的七类风险

七个分类。每个 PR 在写风险备注之前,都要对照这七类逐一过一遍:

那一行风险备注到底长什么样

这是我实际使用的格式。它故意写得很无聊。无聊,才能在赶时间时一眼读完。

Risk: 新增一个接收用户输入 ORDER BY 的 GET 接口——SQL 注入类风险。Mitigation: 对列名做白名单。

就这么一句。一个分类提示、具体可能出什么事、为此做了什么。如果我写不出这一句,这个 PR 就还没准备好。如果缓解措施写的是"无",这个 PR 同样还没准备好——"无"是一个信号,不是一条捷径。

绿、黄、红:合并门禁矩阵

每个 PR 根据七类风险被打上一个颜色,颜色决定接下来会发生什么:

作者写备注,评审者负责质疑

不可谈判的一条:是谁对着 AI 下的 prompt,就由谁来写风险备注。不是评审者,不是模型,不是机器人。作者才有上下文——他向模型要了什么、模型返回了什么、他又基于信任接受了哪些部分。评审者的工作重心也随之转变:从"挑出 bug"变成"质疑风险备注"。作者是不是漏了一类?缓解措施是真做了,还是只是口头理想?标成黄色的是不是其实该是红色?

这个翻转很关键。从风险备注读起的评审者,比从 diff 读起的评审者抓到的问题更多——因为备注把作者的推理过程暴露出来了。备注写得敷衍,代码通常也敷衍。

让 AI 自己先把风险说出来

在我让它写实现之前,我会先让它写风险。prompt 是这样:在写任何代码之前,列出这次改动最高的三个风险,以及你会怎么缓解每一个。它给出的答案质量不稳定,但这个动作迫使模型去审视这次改动,而不是一上来就开始吐代码。我把它给的这三行贴在草稿注释里,然后在旁边写我真正的那一行风险备注。

这里有一个陷阱,也正是这份登记册存在的全部理由。AI 生成的代码看起来往往风险很低。变量名温和、注释礼貌、函数短小。人类读者会根据"语气"去模式匹配。这份登记册就是对抗这种偏见的强制机制:不管代码看起来多友好,风险备注照写不误。

一个真实例子:没做租户隔离的用户搜索接口

最近有个 PR 新增了一个 GET /api/users/search?q= 接口。代码写得很干净,测试全部通过,助手用了参数化的 LIKE 查询,看起来挺像样。作者包了一层薄薄的 wrapper 就把 PR 提上来了。

是写风险备注这个动作抓住了它。先是踩中安全,接着是性能,然后是合规——作者在第三类上停了一下,才意识到这个查询根本没按租户做作用域隔离。任何登录进任何账号的人,都能搜到系统里的每一个用户。代码严格按照写的那样运行着,同时也是一起随时会爆发的跨租户数据泄露。风险备注把它标成了红色。修复只有两行。那起没有发生的事故,才是我在意的东西。

给登记册本身写 Given/When/Then 验收标准

这份登记册只有作为 CI 检查才管用,作为"礼貌建议"是没用的。我把它规格化如下:

Given an AI-assisted pull request is opened
When the PR description does not contain a line matching "Risk:"
Then CI fails with a message pointing to the risk register policy

Given a PR is marked red by the risk matrix
When the author attempts to merge without a linked redesign issue
Then the merge is blocked until a reviewer with the risk-gate role approves

Given a PR passes all seven category checks with no trips
When the author writes "Risk: none"
Then the PR may proceed through normal review at yellow-equivalent speed

这个检查本身故意写得很笨。它只是在 PR 正文里查字面字符串 Risk:。判断本身仍然由人做。这扇门只是拒绝让你跳过做判断这件事。

每周一次横扫:把登记册当成数据集来读

每周五我会扫一遍本周的所有风险备注——不是 PR,是备注本身。规律出现得很快。如果本周黄色备注里有一半都写了"N+1",那说明我们有的是查询层问题,而不是评审问题。如果"新依赖"反复出现,就该有人来搞一个包选型策略了。如果某个团队的合规类风险从来没出现过,他们要么是运气好,要么就是没在看。这样一来,登记册就不再只是文书工作,而变成了一个弱信号传感器。它的价值也正是在这里兑现——不在任何单个 PR 上,而在聚合视角里。我对登记册的原则和我对它所守护的代码的原则是同一条:如果它不能帮我决定什么事,它就不该存在。

可以直接放进 PR 模板的风险登记

风险登记不需要长。它只要逼着作者把“哪里可能出事”写成一句可检查的话。AI 生成的 PR 最需要这一格,因为模型通常会解释自己做了什么,却不会主动说自己没验证什么。

AI risk register:
- Scope risk: touched files outside src/billing/**? no
- Data risk: migration changes existing rows? yes, backfill dry-run attached
- Contract risk: public response shape changed? no, schema diff attached
- Rollback risk: feature flag billing_proration_v2 can disable new path
- Evidence gap: load test not run against production-size invoice table

边界:不要把低风险文案 PR 也塞满风险表。只要改动碰到数据、权限、钱、外部 API、迁移、后台任务或用户可见契约,就必须登记。

可复制产物:AI 编码评审包

在 AI 生成 diff 进入代码评审前使用。它把提示词范围、允许变更和证据要求合并成一个可审查产物。

AI 编码评审包:AI 编码合并前风险登记:merge 之前要追踪的条目

本次要做的决策:
- 确认 AI 只在批准范围内生成变更,并为每条验收标准提供证据。

责任人检查:
- 产品责任人:
- 工程责任人:
- QA 或运维评审:

范围边界:
- 本次包含:
- 本次不包含:
- 仍需确认的假设:

验收证据:
- 测试或 fixture:
- 日志、指标或截图:
- 人工复核步骤:

AI 边界:生成变更必须留在书面范围内,每条验收标准都要能找到证据。

评审追问:
- 没参加需求会的人还会误解哪里?
- 哪个证据能证明这次改动足够安全,可以发布?

AI 生成改动的风险登记示例

AI 代码的风险说明要写出模型可能“脑补”的具体行为。“看起来没问题”不是评审证据。

风险AI 为什么容易漏合并门禁
搜索接口返回跨租户用户。Prompt 只写了 admin search,没有写 tenant 边界。使用两个 tenant fixture 的权限测试。
迁移脚本把 null role 回填成 admin。模型从样例数据里推断了默认值。migration dry-run 和 row-count diff。
重试循环重复发送通知。生成代码重试的是副作用,不是幂等操作。replay 测试证明每个 event_id 只发一次。

案例:AI 生成的租户数据泄漏

生成代码通过了所有 happy path 测试。风险登记表要求评审人写出哪些数据可能跨账号流动,因此发现了缺失的 tenant 边界。

合并前风险说明:
- 改动:给 support console 增加用户搜索 endpoint
- AI 生成查询:SELECT * FROM users WHERE email ILIKE $1
- 缺失边界:tenant_id 和 support role scope
- 影响面:任何 support user 都可能跨租户搜索
- 必需证据:
  - cross-tenant denial test
  - audit log 包含 actor_tenant_id
  - query plan 显示 tenant_id predicate
  - reviewer 确认允许的 support roles
关键词:AI 代码评审 · 合并前风险登记 · AI 生成代码安全 · PR 风险备注 · 合并门禁