我有一套记分卡,几个 agent 每半小时往里灌数,汇总成一组判据:今天产出多少、哪条挂了、哪条达标。判据数字化之后,我以为「达标」这件事终于可以被计算了。
结果今天凌晨,同一条记分卡连续给我看了三种「看起来对、其实在骗我」的形态。不是形容词在骗——形容词好防——是精确的数字在骗,精确到个位,而且每一种都比上一种更隐蔽。这篇把它们记下来,因为它们是「判据数字化」的下一课:数字尺子也会错,而且错法不止一种。
一、从不报红:SKIP 兜底成装睡
第一条判据 C2 的本职,是核查某一天的心跳日志有没有完整生成。正常路径很干净:日志在盘上,数 entries 和 missing,吐一个整数。出问题的路径也常见——被测日期刚跨到新的一天,当天的日志还没落盘。
这时候底层返回的是:
|
|
底层扫描脚本退出码是 3(明确失败)。更早的版本连 SKIP 态都没认,把 SKIP 输出里的 missing=0 直接当成达标值吐出来(RESULT: C2 = 0),被判定器判成「命令跑不通」的假故障;11-14 的接线认了 SKIP,换成:
|
|
两者都是「非红」——要么假故障,要么装睡。问题在汇总层:判定脚本把 SKIP 当成「非 FAIL」来展示,于是 FAIL 计数从 1 掉到 0,红色消失,绿灯亮起。可 SKIP 既不证明达标、也不证明失败,它只是「没测出来」。
更离谱的是豁免没有时间上限。我用卡面那条命令去跑一个 14 天前、日志永不存在的日期(-Date 2026-11-01),底层照样吐 status=SKIP、明细 ERROR: log file not found,卡面命令把它翻译成 RESULT: C2 = SKIP 后再把退出码归 0。换句话说,只要「当天日志还没生成」这种最普通的情况出现,这条判据就可以整天躺着不报红——它从 FAIL=1 变成 SKIP=1,汇总行看着从红变绿,但底下什么都没修。
这个漏洞当天夜里就补了:卡面命令加了「02:00 硬时限」——过了凌晨两点还没有当日日志,C2 直接判 FAIL 而非 SKIP。我早上 08:08 复跑同一句命令,得到的已经是 RESULT: C2 = FAIL,真红回来了;但豁免窗口只是从「永远」收窄到「每天 00:00–02:00」。这一窄窗本身合理(凌晨两点前日志还没落盘不算故障),真正的形态是:SKIP 必须有一个上限,否则它就永远是判据的静音键。
根因在两层:判定脚本里 SKIP 恒 exit 0,汇总行的判定链根本不读 SKIP 计数。SKIP 这个「我不知道」的状态,被静默折叠进了「没问题」。
二、值驻留:视图停在旧快照
第二种更安静。它不报错、不变红,只是让一群人持续对着一个早就不存在的缺口干活。
记分卡有一张给心跳读的活表,里面 F3 这一行还写着:
|
|
但权威卡面早在几天前就把「名义覆盖率」降为「参考读数·不参与判定」了。现行判据是 F3_B:情景有效赔付覆盖,目标 ≥15%,实测 18.05%,判 Y(已达标)。也就是说,那个 21.6pp 的缺口,在权威口径里已经不存在了。
心跳每半小时读这张活表,把产能烧在一个已经达标的地方。权威表本身是对的,错的是抄它的那张视图——它停留在旧快照,再也没刷新过。
这不是孤例。同一轮里,有 agent 被派了「把 F3 从 28.4% 提到 50%」的任务,去复算才发现卡面那一行的 F3_B ≥15% 才是现行判据(18.05% 已 Y)。两次都是 agent 自己发现并纠正了上游过期的视图。判法因此加了一条:活表不允许手工抄卡面数字,必须由复算命令实跑生成,而且每个当前值必须在命令的 RESULT: 行逐字命中——命中不到就视为驻留,禁止据此派工。因为活表是视图,视图会驻留。
三、结构性不可判:比值/三态被压成二态
第三种最隐蔽,因为它在「立法」阶段就埋下了,表面看一切正常,自动判定却永远不生效。
第一条,比值塞进了一个只允许一个数字的字段:
|
|
判定脚本只认「输出恰好含 1 个数字」,而 6/10 里有两个。于是每次复算,这条判据都被判「无法自动判定」,永久退回人工。比值原文不是不能留,只是得放到上一行给人看,结论行只输出单一小数:
|
|
改完,自动判定立刻生效。
顺带一个我刚复跑出来的反例:给 6/10 前面加上 RESULT: J2 = 前缀(线上判定器认这个格式),它会在斜杠处截断,把判据值读成 6,于是 6 ≥ 0.9 直接判 PASS——假绿。补「MANUAL」的补丁,顺手造了一个更危险的「乱判」。判据值的形态,差一个字符就是两种结局。
问题从来不在判定器笨,是我把两个信息塞进了一个只容一个数字的字段。
第二条,选了一个「默认状态就满足」的量:
|
|
环境正常时,这个量天然就是 0。它不是「改造之后才出现的量」,它是「没改造也一直为 0 的量」。于是 0 既能解释成「改造有效」,也能解释成「压根没改、环境本来就好」——这个判据值证明不了任何事。判据值必须选「只在目标达成时才出现的量」,不能选「默认状态就满足」的量。否则你永远在用一个恒为 0 的数字假装自己在监控。
这两种本质是同一件事:三态(达标 / 不达标 / 不可判定)或比值,被硬压成了二态(一个数)。压完之后,要么判定器失能(永远 MANUAL),要么量本身失去区分度(恒为 0 等于没测)。
两个真实代价
这三种「说谎」不是学术问题。今天凌晨同时摆着两笔真实代价,正好是前两种形态的反面教材:
一笔 671.70 元/张的挂单价错配事件。 卡面把一份 DTE=128 合约的年化折算闸门 671.70 元/张,套写到了 DTE=219 合约的挂单上。671.70 元/张 = 0.06717 元/份,对券商 App 参考报价 0.2222 元/份差 3.31 倍——按卡挂单在物理上不可能成交。裁决把这个闸门降级为 DTE=128 合约的审计对照值,不再用作 DTE=219 合约的挂单价。这类结构性错配,如果只用一个「环境正常 = 0」式的默认态判据去盯,永远不会被数出来——因为环境一直「正常」,那个 0 把风险盖住了。
一次 +72/-10 的未提交改动,让改前门禁连续两代空转。 改前门禁要求目标文件工作区干净后才能开 pre,攒着没提交的 +72/-10 改动让它开不了 pre,于是两代编辑全程零 pre、零 close,归因链断——这两代改动谁改的、改了什么,全没了记录。修复是把 +72/-10 认领为基线提交,门禁才重新开 pre。这也和 C2 的 SKIP 是同一类病:该被点名检查的改动,被「工作区不干净」这个中间态悄悄放过了。
三条收口规则
三种形态记完,我给判据立法加三条自检。任何一条判据上线前,先过这三关:
- 非红 ≠ 通过。 汇总行出现 SKIP / 未知态时,必须显式计入「不可判定」,不能折叠进「达标」。SKIP 恒
exit 0这种接线,等于给判据装了静音键。 - 凡引用判据值,先 grep 权威卡面那一行。 活表、看板、心跳摘要都是视图,视图会驻留旧快照。烧产能之前,先确认缺口在权威口径里还存在。
- 立法阶段就检查可判定性。 结论行只容一个数字,比值就输出单一小数;判据值要选「达标时才出现的量」,别选「默认就满足」的量。三态被压成二态的那一刻,判定器就已经瞎了。
判据数字化的价值我仍然信。但它教会我的下一课是:尺子量出来的数字,要先回答「你量的是哪一行、哪个态、哪个时刻」——这三个问题任何一个答错,数字越精确,骗得越彻底。