全站文字截断体检 · 检测工具本身要先被证伪
入档: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
事实记录(不可修改区)
-
触发:用户截图后台轮次列表,「参与范围」下拉只显示「所有人可」,并要求「顺便查一下类似的问题一并修复」
-
做法:写脚本遍历全部页面 + 11 个后台面板 + 各弹窗,扫 320 / 375 / 900 / 1000 / 1100 / 1280 / 1440 七档宽度
-
判据换过三版,对同一个元素给出三种不同结论(以
#adminEventStatusFilter、宽 96px 为例):版本 判据 对该元素的结论 v1 canvas 量文字宽 + padding + border + 经验值箭头宽 22px 差 3px,判为截断 ❌ v2 克隆一个 width:auto的同款 select,问浏览器要多宽不截断 ✅ v3 逐项选中,读元素自身 scrollWidth > clientWidth不截断 ✅ -
v1 共报 14 条,其中 8 条是后台筛选下拉「差 3px」、1 条是房间人数下拉「差 9px」——全部是误报
-
我据 v1 的误报给房间人数下拉加过一行
flex: none;做 A/B 对照(加与不加各量一遍)后发现两种情况宽度都是 50px、都不截断,已撤回 -
v3 的信号有效性单独验证过:把该下拉故意压到 30px,
scrollWidth34 >clientWidth30,确认信号能反映真截断 -
最终确认的真缺陷 3 处,修复后七档宽度 + 各弹窗零命中;后端测试 9/9 通过
一句话总结
体检脚本吐出来的「缺陷清单」本身就是一个待验证的假设——先用已知正常和已知损坏的样本把工具两端标定过再信它;否则你会拿着一张很权威的清单,去改一堆没坏的代码。
四条可复用 insight
1. 含经验常数的判据 = 未验证的假设,但它输出的是权威清单 ⚠️首次
v1 判据里只有一个拍脑袋的数:下拉箭头占 22px。就这一个数,把 8 个完全正常的元素判成了缺陷。
危险的地方在于输出形态:它不像一句「我觉得应该能行」那样一眼可疑,它是一张带元素选择器、带「需要 98px / 实际 95px」的表格,看起来已经量过了。人天然倾向于相信「工具找到了问题」,而不是「工具算错了」。
正确做法:先拿一个已知正常的元素和一个已知损坏的元素各跑一遍,确认工具在两端都判对,再信它对中间地带的判断。 本次最后就是靠「把下拉故意压到 30px,看它报不报」这一步,才确认 v3 的信号真的有效。
假阳性比假阴性更贵:假阴性只是漏掉一个 bug;假阳性会让你去改没坏的代码,同时放大工作量和回归风险。
2. 能问浏览器就别自己算,而且要问对问题 ⚠️首次
三版判据的演进方向,是越来越少自己算:
- v1:自己量文字 + 自己估箭头 + 自己加 padding → 三个中间量,三个偏差源
- v2:克隆一个自由宽度的元素,问浏览器「你要多宽」 → 好很多,但仍高估约 10px
- v3:让元素处在真实状态(逐项选中),直接读它自己的
scrollWidth/clientWidth→ 对
判据:凡是「渲染结果对不对」的问题,答案应该由渲染引擎给出,不由你的模型给出。 你自己算的每一个中间量都是一个偏差源。
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 的另一个化身。
顺手教训
- 用户说「顺便查一下类似的问题」时,交付物里要包含排查覆盖面:查了哪些页面、哪些宽度、用什么判据、哪些报了但复核后判定不是问题。否则「我查过了」是不可核验的一句话。本次把「排查后确认不是问题(未改动)」单独写进了文档,和「已修复」并列。
- 带版本号的静态资源,改文件必须同步改版本号——这条在 赛事状态机到点不切换_写入方不等于推进方_v1 里已经记过一次,本次改
styles.css时主动改了?v=20260726,并在部署后单独核对线上 HTML 引用的确实是新版本号。记过的坑要在下一次主动触发,而不是等它再犯。 - 线上没有可复现的数据时,注入渲染器实际产出的那段结构来量线上 CSS:生产库里没有进行中的赛事,页面渲染不出轮次卡片。做法是把
renderRoundList实际产出的 HTML 注入线上页面 DOM 再量——量到的是部署后的样式,不是本地的,且全程只读、不写任何数据。
下次改进
- 写体检 / 扫描类脚本时,第一步不是跑全量,是造一个已知正常样本和一个已知损坏样本,确认工具两端都判对。
- 判 UI 渲染结果时,优先读元素自身在真实状态下的几何属性;要自己算之前先问一句「这个量浏览器是不是已经算好了」。
- 每条「顺带修的」改动都配一份 A/B 证据,拿不出来就撤回。
- 找「同类问题」时 grep 的是写法(这里是固定像素列宽),不是页面名。
关联文档
- ⭐ 交付前实测证伪律_v1 —— 直接同族的另一半:那条管「别把没验证过的方案当能行」,本篇管「别把没验证过的检测工具的输出当事实」;两条合起来才是完整的「不把未验证当已验证」
- ⚠️ 赛事状态机到点不切换_写入方不等于推进方_v1 —— 同项目,且是本篇的正对照:那篇的教训是「决定性的一步是量,不是猜」(量到胶囊文字实际 56px / 需要 86px);本篇补上后半句——量的方法本身也可能是错的,量之前先标定
- ⚠️ 零作品的比赛_界面演完不等于链路存在_v1 —— 同项目上一会话:那篇是「别用界面验收功能,要用数据」,本篇是「用来验收的工具也要先被验收」
- ⚠️ Claude预览环境不派发滚动事件_滚动类功能无法行为验证_v1 —— 同族「验证手段本身失效」:那篇是环境不派发事件导致压根测不了,本篇是判据算错导致测出一堆假的
- ⚠️ reduced-motion本机陷阱_动效降级纯淡入而非跳过_v1 —— 同族「本机测量骗了你」:那篇是本机偏好开关让自测毫无变化,本篇是自制判据让正常元素显示为缺陷
- ⚠️ 美工改稿全站落地_跨稿重复才是规范_v1 —— 同项目后续会话、同一纪律的第三次现形:本篇是自制判据把正常元素判成缺陷,那篇是拿规范文字当待办清单、把两处已经实现的功能误报成「还没做」;共同解法都是报缺陷前先回原地核实。另,本篇顺手教训里的版本号一条在那次被扩展成「版本号要覆盖会一起变的那一组文件」——
styles.css有?v=而app.js没有,只 bust 一半等于新样式配旧 DOM - ⭐ ping通不等于路通_fake-ip假信号与节点带宽实测选型_v1 —— 本篇核心律的跨项目二次验证(首次出圈:上次是浏览器 UI 体检脚本,这次是网络测速脚本):探针参数超限被 403,把 14 个正常节点判成「全挂」,形态是一列整齐的 0——和本篇「一张带数字的表格」同构,都是工具的输出形态很像事实;那篇补上操作层判据「
0同时意味着『测到 0』和『没测成』,探针必须输出http_code/size_download这类能区分二者的字段」 - ⭐ 构建产物的脏改动不是事故_复发是归因错了的信号_v1 —— 本篇核心律的第三次现形(2026-07-28),三条合起来覆盖了三个信息源:本篇管工具的输出要先证伪,ping通不等于路通_fake-ip假信号与节点带宽实测选型_v1 管诊断的信号要打在真实链路上,那篇管你自己写下的历史归因要先证伪——且那篇指出最后一种最危险:它不会被质疑(自己写的),还会主动加速下一次误判
- ⭐ 2026-08-05_公众号稿送审翻车_弃读点与框架错误复盘_v1 —— 本篇核心律的第四次现形,补上第四个信息源:前三条管「工具的输出」「诊断的信号」「自己写下的历史归因」,这条管标准工具输出的格式本身——
git check-ignore -v的空模式假阳性。区别在于前三次工具是错的、这次工具是对的,错的是我对它输出的解读;因此解法也不同:不是标定工具,是换一个更朴素、语义无歧义的判据(git status)。另,该篇「弃读点比错误点信息量大」与本篇「假阳性比假阴性更贵」同构——都是在错误的清单里,位置信息比内容信息更可靠 - 复盘事实先行原则 —— 本篇顶部事实冻结区按它执行
- 09_平台工程索引 —— 平台工程区入口
- ⚠️ 2026-08-19_vpn-guard出口归属门槛与四处假绿修复_迭代复盘_v1 —— 新变体(2026-08-19):本篇管工具的判据不可信,那篇是哨兵被自己的样本中和——为「不得把裸词 data 加进机房词表」写的守卫,样本 ISP 里带了
Telecom命中运营商词表 −3,正好抵消待测的 +3,那条断言在任何情况下都触发不了。断言写对了、样本选错了,症状是永远绿、与「真的没问题」完全一致。对口手法=投毒:写完测试先证明它会失败,三种投毒里正是这条暴露了哨兵是坏的