平台工程

全站文字截断体检 · 检测工具本身要先被证伪

入档:2026-07-26 来源:PB Arena(pb.tiaozhuxiansheng.com)后台下拉框显示不全的修复会话,1 个提交(f510fe5)已部署上线并封版 v2026.07.26 状态:已上线并线上实测;四条 insight 均为本次首次发现 ⚠️;核心律「检测工具本身要先被证伪」已于 2026-07-27 跨项目二次验证(网络测速探针,见 ping通不等于路通_fake-ip假信号与节点带宽实测选型_v1),其余三条仍待验证 ⭐⭐⭐⭐ 核心律第四次现形(2026-08-05),且是新亚型:前三次都是「工具算错了」,这次是工具没算错,是我把它的输出读成了别的意思——git check-ignore -v 在空模式行上返回形如 .gitignore:28:\t<path> 的输出(第 28 行其实是空行、模式字段为空),看着像匹配,据此宣称”已忽略”是错的。权威判据是 git status:真被忽略的路径根本不会出现在里面。2026-08-05_公众号稿送审翻车_弃读点与框架错误复盘_v1 ⭐⭐⭐⭐⭐ 第五次现形(2026-08-08),回到「工具算错了」亚型,但假阳性的代价升了一档:视频切点检测器用「帧差 ÷ 全片最大帧差」归一化再取相对阈值,在一段完全连续、只有噪声的样本上报出 26 处假切点——没有真信号时,分母塌了,纯噪声被拉满 0~1,必然撞穿任何相对阈值。新维度:当测量工具的输出就是结论本身(而非待人工复核的线索清单)时,假阳性不产生「多余的工作」,只产生「错误的知识」——那次实验的全部产出就是「有没有分段」一个判断,工具报错方向会直接把结论翻转,还附一张精确到帧的时间戳表当背书。见 2026-08-08_后室大逃亡S43长镜头_归因未遂与生死线次序复盘_v1 ⭐⭐⭐⭐⭐⭐ 第六次现形(2026-08-19),第三种亚型:工具的判断机制本身有偏。前几次的「工具」都是脚本,这次是一支被明确要求「尽力反驳」的 agent 复核团——46 条提案,驳回 0 条。不是算错、也不是我读错,而是复核方拿到一段看起来合理的分析文本时倾向于确认而不是去跑一遍;光在 prompt 里写「默认怀疑」「证据不足判 false」不管用。新判据:复核结果的驳回率本身就是可信度指标——全过或全不过都不可信,必须抽最严重的几条自己验。 那次抽验纠正了两条最严重的描述偏差,而这两条纠正直接改变了修法(一条要顺手清生产 HTML 里的占位假数据、一条的止血点是没包 try/catch 的定时器而不是接口层)——照单全收会修错地方。同一毛病也发生在人身上:我写回归测试时凭印象写 action 名与路由路径,挂了两条,同样是「觉得自己知道于是没去查」。见 自检46条零驳回_同类中的异类才是缺陷藏身处_v1 🧑 人肉版第三次现形(2026-08-20),并已改成动作:本律的对象一直是「工具」,但同一种失败在身上同样成立——「我的记忆也是待验证的假设」。三次全在写回归测试时凭印象手打字符串:action 名 finished 写成 finish、好友接受漏了 /respond、赛事列表接口误加 admin 前缀。前两次在复盘里写了「要先查」,没用,第三次照犯。光记住不管用,已固化成动作:写任何调用接口的测试前,先 grep 出路由定义与 action 白名单,把实际字符串贴过来,不手打。零路由补路由_普查要能推翻已写的代码_v1 ⭐⭐⭐⭐⭐⭐⭐ 第七次现形(2026-08-21),第四种亚型:工具没算错、我也没读错,是它回答的不是我以为的那个问题。同一天连撞三次,形态完全一样: ① --window-size=390 截出来的图右侧被切,我判成「手机端横向溢出」并改了一轮响应式——--dump-dom 量出 viewport 489、docScrollWidth 489、越界元素 0这个参数控的是截图取景,不是布局视口; ② curl -o 抓线上构建 grep 零命中,险些判成「发布的是旧版」——实际是没解压,拿到的是 gzip 流,--compressed 之后全部命中; ③ git status 显示 ahead 44,我据此给出「44 个提交会一起上线、其中 6 个重启后端服务」的风险评估git fetch 之后真正没推的只有 2 个。 共同判据:问一句「这个工具回答的是哪个问题」——截图工具答的是取景不是视口,curl 答的是字节流不是文本,git status 答的是「相对我本地记的那个远端」不是真实远端。第三例最贵:它没有浪费时间,而是产出了一个错误的风险评估,差点让人为此做不必要的取舍。 另附一个次生教训:为假问题做的改动里可能混着对的东西,要分开处置——那轮改的栅格 minmax(0,1fr) 是对的实践留下了,而为假问题加的 overflow-x:hidden 会把真溢出藏起来,比不加更糟,撤掉了。见 2026-08-21_一小时分享会_从设计到投影现场_全链路复盘_v1 同项目前情:零作品的比赛_界面演完不等于链路存在_v1 · 赛事状态机到点不切换_写入方不等于推进方_v1

事实记录(不可修改区)

一句话总结

体检脚本吐出来的「缺陷清单」本身就是一个待验证的假设——先用已知正常和已知损坏的样本把工具两端标定过再信它;否则你会拿着一张很权威的清单,去改一堆没坏的代码。

四条可复用 insight

1. 含经验常数的判据 = 未验证的假设,但它输出的是权威清单 ⚠️首次

v1 判据里只有一个拍脑袋的数:下拉箭头占 22px。就这一个数,把 8 个完全正常的元素判成了缺陷。

危险的地方在于输出形态:它不像一句「我觉得应该能行」那样一眼可疑,它是一张带元素选择器、带「需要 98px / 实际 95px」的表格,看起来已经量过了。人天然倾向于相信「工具找到了问题」,而不是「工具算错了」。

正确做法:先拿一个已知正常的元素和一个已知损坏的元素各跑一遍,确认工具在两端都判对,再信它对中间地带的判断。 本次最后就是靠「把下拉故意压到 30px,看它报不报」这一步,才确认 v3 的信号真的有效。

假阳性比假阴性更贵:假阴性只是漏掉一个 bug;假阳性会让你去改没坏的代码,同时放大工作量和回归风险。

2. 能问浏览器就别自己算,而且要问对问题 ⚠️首次

三版判据的演进方向,是越来越少自己算:

判据:凡是「渲染结果对不对」的问题,答案应该由渲染引擎给出,不由你的模型给出。 你自己算的每一个中间量都是一个偏差源。

v2 已经在问浏览器了,为什么还不对?因为我问错了问题:「浏览器认为一个自由宽度的 select 该多宽」和「这个 select 现在有没有截断」是两个不同的问题——前者的答案里含浏览器留的富余量。从「自己算」升级到「问引擎」只是第一步,还得确认你问的正是你要判的那件事。

3. 误报会伪装成「顺手修一下」混进提交 ⚠️首次

那行 flex: none 只有一个属性,看起来完全无害,而且「防止 flex 子项被压缩」这个理由本身还挺像回事。要不是最后做了 A/B 对照,它会作为「顺带修复」留在提交里,变成一行为不存在的问题而存在、后人也不敢删的代码(因为没人知道它在防什么)。

判据:每一条「顺带修的」改动,都要能单独拿出「改之前确实坏、改之后确实好」的证据。拿不出来就撤回。 不要用「反正无害」当理由留着——无害的代码也是债,债在于它让后来者无法判断它的必要性。

4. 「同类问题」要按写法搜,不按页面搜 ⚠️首次

三处真缺陷的共同点不是「都在后台」,而是同一种 CSS 写法:固定像素列宽 + 一个会自适应的邻居

位置写法后果
后台轮次列表(用户截图处)80px 145px minmax(180px,1fr) 三列却放了五个子元素两个下拉掉进 80px 的标题列,最长选项要 181px
后台新增轮次表单两个下拉写死 160px最长选项要 182px / 170px
前台赛事卡片轮次行95px 1fr auto固定列 + auto 列把中间的题目挤成 15px(要 66–99px)

第三处最严重,却在用户截图的那个宽度下完全正常,只在 1100px 附近才现形;而且它在前台,不在后台。

所以:按「再看看后台别的页面」去找会漏掉它;按「再看看 1440px 下还有没有」去找也会漏掉它。要按写法搜(grep 固定像素列宽)+ 按宽度扫,才能捞到同一个 bug 的另一个化身。

顺手教训

下次改进

关联文档

类型/平台工程