本层判断标准

这次改动里,哪些判断是机器给不出、必须人看的?谁看过、什么时候看的、依据什么?

答不出「人到底看了什么」,这次评审就只剩一个通过按钮。补法:把这一条写进合并请求说明的「人定的选择」一栏,并签上姓名与日期。

交给机器的七项

这七项不必再看。判据只有一条:门禁退出码是 0,失败时输出必须带文件、行号、规则名。

检查命令阈值失败时
格式化ruff format --check .无差异自动改,不占评审时间
静态检查ruff check .0 条告警修代码,不把规则降级为警告
类型检查mypy app0 条错误改实现或补齐类型标注
单元测试pytest -q全通过,新增行覆盖率 ≥ 70%补实现或补测试,不删断言
复杂度ruff check --select C901 .圈复杂度 ≤ 10,函数 ≤ 50 行拆函数,不调上限
密钥扫描gitleaks detect --no-banner --redact0 命中先轮换密钥,再清提交历史
依赖漏洞pip-audit高危 0,中危 7 天内修升级或替换,超 7 天升为阻断

边界只有一句:在本地手工跑过、仓库里却没有对应工作流的检查,评审时按「未查」处理。只有跑进持续集成、并被分支保护要求通过的检查才算数。入口命令与触发条件的约定见质量门禁。

必须人看的六项

耗时按 300 行改动量算:一次 300 行的合并请求,人工合计约 50 分钟。涨到 600 行,最后三项的时间翻倍——要看懂的东西多了一倍。

检查项谁看单次耗时判据(什么算通过)
说明与实现是否一致评审人5 分钟能指着说明里的一句话,说出它在改动里对应哪几行;对不上就退回补说明
高风险路径是否有人深审指定的复核人30 分钟说明里有姓名、日期、依据(规约条目或测试名)三项齐全;缺一项按未审处理
生成代码出处是否可疑评审人10 分钟没有与项目风格无关的版权头、作者署名、陌生的内部项目名
新增依赖是否有理由评审人3 分钟说明的「新增依赖」一栏填了库名、许可类型、替代方案;空白按未查处理
未查项是否照实写评审人2 分钟说明里「未查」一段非空,或明确写「无」;只写「已检查」不算
约束有没有被删评审人3 分钟改动里没有删断言、加 skip、放宽阈值;出现了就必须拆成单独一次合并请求
可以这么做 指着说明问「哪一行对应这句」;看不懂就直说,要求提出请求的那个同学用一段话讲清边界;把「我没看懂」这件事写进评审记录。
不要这么做 只写「LGTM」;因为持续集成是绿的就不看改动差异;在没看懂的核心逻辑上签名,指望以后有人补上。

助手交出来的样子

## 评审记录
- CI:全绿(132 passed,新增行覆盖率 74%)
- 结论:LGTM
- 备注:改动清晰,符合需求描述

认它的办法:整段里没有一处「我问了什么」或「我要求改什么」。三条都在复述机器已经给出的结果,没有一句来自人。门禁是绿的不等于人看过——评审记录里至少要有机器给不出的那一条:一个问句、一次质疑,或者一句「这里我没看懂」。

最后一项是这六项里唯一不能通融的:删断言和放宽阈值在改动差异里只占几行,却能把前面六项一次性作废。在差异里看到它们,不要顺手放过。检查配置本身的保护写法见指令与配置保护。

谁的精力放在哪

表格里的「一次多久」是时间预算,不是硬要求。超了,说明改动太大或分工不对——先按「改动超过多少行就没法审」拆开,不要加班硬看完。

角色看什么不看什么一次多久
提交的人这次改动的证据:跑了什么命令、结论是什么、哪里没查不解释助手为什么这么写整理 10 分钟
评审的人规约链接、说明与代码是否一致、高风险路径、新增依赖格式、命名风格、语法偏好20 分钟
高风险路径的复核人权限、金额、删除、并发、对外兼容这五处的实现其余部分不看30 分钟
集成环节覆盖率倒退、被跳过的用例、被放宽的规则业务语义自动,无人工

表里没有「谁知道所有细节」这一行,这是故意的。助手把产出速度提上来之后,组里不该再有这种角色:一个人成为唯一看懂某段逻辑的人,就等于这段逻辑以后没人敢改。

改动超过多少行就没法审

助手让大改动变便宜,但没让它变可审。交出一个主题混杂、几百行的合并请求,即使每行都对,也拿不到有效评审:评审人会开始跳读,然后在底部签名。下面四个数字是上限,超限必须在说明里写下拆不动的理由。

单次改动行数
≤ 400 行
不含锁文件和自动生成的代码。超了按主题拆成多次。
单个文件改动
≤ 200 行
在一个文件里改超过 200 行,多半是这个文件同时在做两件事。
一次改动的文件数
≤ 10 个
超过 10 个文件,先确认里面有没有「顺便」改的无关文件。
评审等待时长
≤ 1 个工作日
超过 1 天没人看,评审人读到的是已经放下手的上下文,来回解释比现在看完更慢。
一个合并请求一个主题:把重构和功能分开,把格式化和逻辑分开。
先合接口再合实现:接口与数据结构先合一次,实现再合一次。
先合结构再合逻辑:先提移动与改名的请求,再提改行为的请求——否则差异里看不出哪些是移动、哪些是改逻辑。
超限就写理由:在说明里写清为什么拆不动,不要默默提交一个 800 行的请求。

每种改动的最低证据

附的证据要让复核的人不必重跑一遍就能判断。

改动类型最低证据落在哪
文档、注释、格式无需额外证据,门禁通过即可make check 退出码 0
新增工具函数或模块单元测试,含一条边界用例tests/test_<模块>.py
接口行为变化接口测试,含失败路径;规约里的场景同步更新tests/test_api_*.py
数据模型或迁移迁移脚本与回滚步骤;订正前的 SELECT 记录migrations/,命令输出贴在说明里
权限、金额、删除、并发、对外兼容可复现的检查记录,加上一次人工深审说明里「高风险路径」一栏 + 复核人签名
提示词或模型版本变化评测问题集的通过情况,附运行记录evals/ 运行结果,见评测与回归

写「未查」是合法答案,照实填就行。把它写成「通过」才是危险动作——那样下一次没人会再去查。再看第三条:接口测试只证明这条路径按当前用例工作,不证明权限判定发生在正确的层,后者仍要亲自读一遍。