不可能逐行读完助手生成的代码:花在空格与命名上的每一分钟,都是从那三行权限判断里挪走的。
如果是被组长派去审别人的改动、不知道该看哪几行,先看必须人看的六项。
这次改动里,哪些判断是机器给不出、必须人看的?谁看过、什么时候看的、依据什么?
答不出「人到底看了什么」,这次评审就只剩一个通过按钮。补法:把这一条写进合并请求说明的「人定的选择」一栏,并签上姓名与日期。
这七项不必再看。判据只有一条:门禁退出码是 0,失败时输出必须带文件、行号、规则名。
| 检查 | 命令 | 阈值 | 失败时 |
|---|---|---|---|
| 格式化 | ruff format --check . | 无差异 | 自动改,不占评审时间 |
| 静态检查 | ruff check . | 0 条告警 | 修代码,不把规则降级为警告 |
| 类型检查 | mypy app | 0 条错误 | 改实现或补齐类型标注 |
| 单元测试 | pytest -q | 全通过,新增行覆盖率 ≥ 70% | 补实现或补测试,不删断言 |
| 复杂度 | ruff check --select C901 . | 圈复杂度 ≤ 10,函数 ≤ 50 行 | 拆函数,不调上限 |
| 密钥扫描 | gitleaks detect --no-banner --redact | 0 命中 | 先轮换密钥,再清提交历史 |
| 依赖漏洞 | pip-audit | 高危 0,中危 7 天内修 | 升级或替换,超 7 天升为阻断 |
边界只有一句:在本地手工跑过、仓库里却没有对应工作流的检查,评审时按「未查」处理。只有跑进持续集成、并被分支保护要求通过的检查才算数。入口命令与触发条件的约定见质量门禁。
耗时按 300 行改动量算:一次 300 行的合并请求,人工合计约 50 分钟。涨到 600 行,最后三项的时间翻倍——要看懂的东西多了一倍。
| 检查项 | 谁看 | 单次耗时 | 判据(什么算通过) |
|---|---|---|---|
| 说明与实现是否一致 | 评审人 | 5 分钟 | 能指着说明里的一句话,说出它在改动里对应哪几行;对不上就退回补说明 |
| 高风险路径是否有人深审 | 指定的复核人 | 30 分钟 | 说明里有姓名、日期、依据(规约条目或测试名)三项齐全;缺一项按未审处理 |
| 生成代码出处是否可疑 | 评审人 | 10 分钟 | 没有与项目风格无关的版权头、作者署名、陌生的内部项目名 |
| 新增依赖是否有理由 | 评审人 | 3 分钟 | 说明的「新增依赖」一栏填了库名、许可类型、替代方案;空白按未查处理 |
| 未查项是否照实写 | 评审人 | 2 分钟 | 说明里「未查」一段非空,或明确写「无」;只写「已检查」不算 |
| 约束有没有被删 | 评审人 | 3 分钟 | 改动里没有删断言、加 skip、放宽阈值;出现了就必须拆成单独一次合并请求 |
## 评审记录 - CI:全绿(132 passed,新增行覆盖率 74%) - 结论:LGTM - 备注:改动清晰,符合需求描述
认它的办法:整段里没有一处「我问了什么」或「我要求改什么」。三条都在复述机器已经给出的结果,没有一句来自人。门禁是绿的不等于人看过——评审记录里至少要有机器给不出的那一条:一个问句、一次质疑,或者一句「这里我没看懂」。
最后一项是这六项里唯一不能通融的:删断言和放宽阈值在改动差异里只占几行,却能把前面六项一次性作废。在差异里看到它们,不要顺手放过。检查配置本身的保护写法见指令与配置保护。
表格里的「一次多久」是时间预算,不是硬要求。超了,说明改动太大或分工不对——先按「改动超过多少行就没法审」拆开,不要加班硬看完。
| 角色 | 看什么 | 不看什么 | 一次多久 |
|---|---|---|---|
| 提交的人 | 这次改动的证据:跑了什么命令、结论是什么、哪里没查 | 不解释助手为什么这么写 | 整理 10 分钟 |
| 评审的人 | 规约链接、说明与代码是否一致、高风险路径、新增依赖 | 格式、命名风格、语法偏好 | 20 分钟 |
| 高风险路径的复核人 | 权限、金额、删除、并发、对外兼容这五处的实现 | 其余部分不看 | 30 分钟 |
| 集成环节 | 覆盖率倒退、被跳过的用例、被放宽的规则 | 业务语义 | 自动,无人工 |
表里没有「谁知道所有细节」这一行,这是故意的。助手把产出速度提上来之后,组里不该再有这种角色:一个人成为唯一看懂某段逻辑的人,就等于这段逻辑以后没人敢改。
助手让大改动变便宜,但没让它变可审。交出一个主题混杂、几百行的合并请求,即使每行都对,也拿不到有效评审:评审人会开始跳读,然后在底部签名。下面四个数字是上限,超限必须在说明里写下拆不动的理由。
附的证据要让复核的人不必重跑一遍就能判断。
| 改动类型 | 最低证据 | 落在哪 |
|---|---|---|
| 文档、注释、格式 | 无需额外证据,门禁通过即可 | make check 退出码 0 |
| 新增工具函数或模块 | 单元测试,含一条边界用例 | tests/test_<模块>.py |
| 接口行为变化 | 接口测试,含失败路径;规约里的场景同步更新 | tests/test_api_*.py |
| 数据模型或迁移 | 迁移脚本与回滚步骤;订正前的 SELECT 记录 | migrations/,命令输出贴在说明里 |
| 权限、金额、删除、并发、对外兼容 | 可复现的检查记录,加上一次人工深审 | 说明里「高风险路径」一栏 + 复核人签名 |
| 提示词或模型版本变化 | 评测问题集的通过情况,附运行记录 | evals/ 运行结果,见评测与回归 |
写「未查」是合法答案,照实填就行。把它写成「通过」才是危险动作——那样下一次没人会再去查。再看第三条:接口测试只证明这条路径按当前用例工作,不证明权限判定发生在正确的层,后者仍要亲自读一遍。