工程规范从文档变成门禁,最难的是判它判错了怎么办|洹拓科技

一、一条规范能不能被自动执行,先过四问
把规范从文档变成门禁,第一件要做的不是写规则,而是筛出哪些规范有资格变成规则。公开报道里那家公司的做法值得学的不是识别数量,被识别与驳回的量级我们不作为效能证明来引用,它真正给出的是”规范可以变成主动执行的控制系统”这个方向。方向落到自己的仓库里,要先用四个问题过一遍,任何一问没有明确答案,这条规范就还不该进流水线。
第一问:有没有可判定的对象。这条规范约束的是一次变更里的文件路径、依赖声明、日志字段,还是”这次改动是否合理”这种只存在于评审人判断中的东西?前者可判定,后者的判定对象是意图,模型只能给出一个读起来像结论的说法,而说法无法复核。
第二问:有没有明确的边界与例外。”错误要带上下文向上抛”这类规则,边界在哪里?底层组件为了兼容既有版本必须吞掉某一类异常时算不算违反?没有写例外条款的规范一旦变成门禁,第一个迭代周期就会被绕过,而绕过比违反更难治理,因为它在规则之外。
第三问:违反的后果是驳回还是提示。这一问决定规则的容错要求。提示可以容忍较高误报,驳回不行,驳回直接占用别人的时间。多数团队把两者混在同一套规则里,结果是提示被当成噪音,阻断又不够坚决。
第四问:判定错误的代价是不是双向。漏判有代价,误判也有代价,两个方向是否都进了设计?只考核”拦住了多少”的系统会自然长成高误报的系统,因为拦错了不扣分。看上去这是度量问题,实际上决定这套系统能不能长期活下来。
四问之外还要补一句:执行主体从静态检查器换成模型之后,四问的难度整体上升一档。静态工具的判定是确定的,可以逐条写测试用例;模型的判定带波动,同一段代码两次运行可能给出不同结论。于是”边界与例外”不能只写成给人看的条文,还要写成规则条目里随附的判定说明,让执行主体在边界情况上有可依循的表述。
二、适合与不适合:分档比选哪个模型更重要
适合机器执行的规范有一个共同特征,判定对象是文本结构而不是意图。下面这张表是我们内部给规则分档时用的口径,分档结果直接决定阻断权限。
| 档位 | 典型规范 | 权限 | 误报率上限要求 |
|---|---|---|---|
| 可阻断 | 命名与目录约定、依赖引入与许可证、日志字段与级别、错误处理格式、接口版本兼容 | 命中即驳回合并 | 最严,超限自动降级 |
| 只提示 | 函数长度、注释完整度、复杂度阈值、重复片段提示 | 写入检查报告,不拦合并 | 可放宽,主要看噪音量 |
| 不适合自动执行 | 架构合理性、改动的必要性判断、性能与可读性之间的权衡 | 不建规则 | 不适用 |
第三档的处理方式是这类系统里最容易被跳过、又最容易引起反感的一段。我们的替代做法有两条。一条是只做提示不做门禁,把这类判断降级为”供参考的观察”,明确写进界面文案,让作者知道这不是待办事项;另一条是把它改成检查清单,要求作者在提交说明里自评并留下理由。第二条的价值被低估了:架构合理性判断没法机器裁决,但”作者有没有想过这个问题”是可以检查的,自评理由还会在评审时省掉大量来回。
把不适合的那一档强行做成规则,后果不是漏判而是错误定义被固化。一条规则的标准随系统演进变化最快,过去合适的阻断规则,条件一变就会退化成纯粹的障碍,而撤销一条阻断规则的成本远高于新增,这是后面第四节要谈的版本化问题。
三、误报是真正的成本中心,要设计四件机制
一套自动执行规范的系统,最贵的部分不是规则编写,是误报处理。误报的直接成本是作者停下来自证清白,间接成本是整套门禁的正当性被消耗。四件机制缺一不可。
- 每条规则单独统计误报率并设上限。统计口径要落在”被作者申诉且申诉成立”上,而不是模型自己的置信度。上限按档位不同:可阻断档位的上限要比提示档位低一个数量级,超限的规则不再享受阻断权限。
- 作者能对单条判定提异议,且不消耗审批人时间。异议入口必须挂在判定条目本身,而不是靠工单。流程上要保证提出异议不会让变更被退回队列,否则没人会提。
- 异议样本回流成规则修订的输入。成立与不成立的申诉都要留档,按规则聚合后定期复盘。成立率高说明边界条款缺失,不成立率高说明文案表述让人误解规则意图,两种情况的修法不同。
- 连续高误报的规则自动降级为提示。降级要写成策略而不是靠人开会决定,触发条件明确到”在多少个样本内申诉成立率超过阈值”。降级后保留观察期,攒够新的样本再评估是否恢复。
这四件里第三件最常被省掉,省掉的后果是规则库停止演化。一套两年不改的规范规则库,它的误报率一定是上升的,因为代码库在变,判定分布也在变。
四、驳回权归属与规则版本化
模型驳回一次合并,实质是工程判断权从评审人手里转移到规则维护人手里。这件事的组织后果比技术后果大,要正面回答一个问题:谁有权让一条规则具备阻断力。我们的做法是把阻断权限作为一种需要审批的能力,规则作者默认只有提示权限,申请阻断时要写明误报处置方案、例外条款和回退条件,由一个跨团队的小组批准。审批的意义不在于卡人,在于让”增加阻断”这件事有成本,而”减少阻断”没有成本,这个不对称方向是对的。
与之配套的是规则版本化。每条规则要有版本号、生效流程与变更记录,至少包含四栏:本次修改的判定范围变化、影响到的历史驳回统计、生效前的观察期结果、以及回滚方式。没有版本号的规则出问题只能整体关掉,而整体关掉的成本极高,于是坏规则会长期挂在门禁上,这就是大家开始绕过流程的起点。
规则生效也应走流程而不是即时全量。新改定的规则先进观察期,只出报告不阻断,攒够样本并确认误报水位后再升为阻断。这个顺序对模型执行的规则尤其重要,因为静态检查器可以靠单元测试保证改动符合预期,模型规则只能靠线上样本。
五、度量口径:三种失真与四个替代指标
把规范执行做成系统之后,报表上的数字很容易变得不可用。三种常见口径各有失真。
- 识别问题数不等于修复数。识别量随规则数量线性增长,多写十条规则就能把数字做大,而它完全不反映质量变化。
- 驳回数不等于质量提升。驳回数上升也可能意味着规则粒度太粗,把本该在设计阶段讨论的问题推到了合并阶段,反而增加了返工。
- 覆盖提交比例不等于有效覆盖。接入流水线的仓库比例是配置项,一个从不命中任何规则的接入仓库对质量没有贡献。
更可信的四个替代指标是我们实际在用的口径。一是每千行变更的净拦截数,把拦截量除以变更量,规则变多不再自动让数字变好。二是申诉翻案率,直接衡量误报水位,也是判断哪条规则该降级的唯一依据。三是规则命中后的平均修复时长,它反映判定是否可执行,一条让人不知道该怎么改的规则修复时长一定长。四是绕过与例外申请的分布,按团队和规则两个维度统计,集中出现的绕过位置就是规则本身有问题的地方。
这四个指标的共同点是都不适合用来对外宣传,这恰恰说明它们更接近真实。
六、豁免的工程形态,以及为什么迁移顺序不能反
例外与豁免不能是口头约定,它要有工程形态,四件是最低配置:豁免记录必须带有效期,无期限豁免等于删掉一条规则;必须双人批准,申请人与批准人不得同部门;到期复审,复审不通过自动收回而不是继续顺延;绕过次数进入团队级趋势,只有聚合到团队维度,”某个组一直在绕过同一条规则”这件事才会浮出水面。
迁移路径分三步,顺序不能反过来。第一步是只读观察若干周,全量规则只出报告不阻断,用来量出每条规则的真实误报水位,同时让开发者先适应判定文案。第二步按风险分档阻断,只对可阻断档里误报率已经稳定达标的规则开启驳回,其余保持提示。第三步才是把这套东西当作门禁对外承诺,配套上面那套豁免与申诉机制。
顺序反过来会失败的原因是,阻断权限一旦开出去就极难收回。第一天就驳回的团队,会在第一周遇到集中申诉,处理方式是临时放宽或整体关闭,两种都让规则库失去严肃性;而只读观察期积累下来的误报数据,正好是后来申请阻断权限时的证据。洹拓内部推这套东西时踩过的坑就是第三步走得太早,规则库的公信力只能靠观察期一点点攒回来。
最后留一句给准备做这件事的团队:这套系统的产出不是”拦截数量”,而是让规范文本变得可以讨论。一条能被申诉、能被降级、能被版本化修订的规则,才是活的规范;写在文档里没人引用的那种,只是历史记录。