# 把「看起来对」当成「验证过」——同一类错的四个变种 **建档日期**:2026-10-07 **覆盖时段**:2026-10-06 22:00 ~ 10-07 23:50 **状态**:⚙️ 待观察(需长期盯) --- ## 一句话 这两天我犯的错,**代码都不是写错的,是"我以为已经对了"**。 四个变种,形状不同,根子一样:**拿一个"看起来成立"的信号,替掉了"真的跑通"这个动作。** --- ## 四个变种 ### 变种 1 · 把业务错误码当网络故障(10/06 22:5x) **表面**:电费登录返回 `ex666666`。 **我的结论**:「校园网夜间关闭了外部访问。」 **真相**:服务端**明明回了一个 JSON**(`{"code":"ex666666","msg":"服务端网络异常"}`)——**能收到结构化响应,就绝不可能是网络不通。** 真正的成因是 csrf token 与 cookie 会话错配;登录前重置会话即 100% 成功(实测 6/6)。 **⚠️ 最该记的一点**:服务端那句 `msg` 写的是「服务端**网络异常**」——**它自己在骗人**。 而我照着这行字说了一遍,**说了两次**,一次都没验证。 ### 变种 2 · 拿 API 返回值当执行结果(10/07 23:12 → 23:39) **表面**:重载插件的接口返回 `重载成功`。 **我的结论**:「插件装好了。」 **真相**:那次重载发生在**修复生效之前**,插件其实自 23:10 被卸载后**一直没装回来**。 主人在群里连发三次命令,**无人响应**,我还在别处写"已完成"。 **正确验收**:看**加载日志里有没有打出插件描述行**(`star_manager:1212`)—— 那才是"装上了"。`重载成功` 只说明**接口没抛异常**。 ### 变种 3 · 改完没走端到端路径(10/07 23:0x) **表面**:给插件加了个新命令处理器,`py_compile` 通过。 **我的结论**:「加好了。」 **真相**:插入代码时**把原来属于 `academic` 的 `@filter.regex(COMMAND_PATTERN)` 一起挪到了新方法上**—— 于是 `academic` **一个装饰器都没有,永远不会被触发**。 命令收得到、匹配得了、逻辑全对,**但没有任何处理器认领它**。 **——语法检查查不出这个。只有"真的发一条命令"能查出来。** ### 变种 4 · 没问就默认(10/07 10:31) **表面**:主人说「新增对应的定时任务」。 **我的做法**:直接建了一个**内容一样**的任务,于是同一份读数**在 10:00 和 10:30 被发了两遍**。 **主人一眼看出来**:「不对啊,这不是重复了吗。」 **——"对应"两个字我没问,把它翻译成了"再发一遍"。** **新增的东西如果和旧的没差别,那它就是负的。** --- ## 共同的东西 | 变种 | 我拿来当证据的 | 我该拿的 | |:--|:--|:--| | 1 | 服务端 msg 里写了「网络异常」 | 能不能收到结构化响应 | | 2 | 接口返回「成功」 | 加载日志里有没有描述行 | | 3 | `py_compile` 通过 | 真发一条命令 | | 4 | 「新增了任务」这件事本身 | 新旧之间有没有差别 | **四个"证据"都有一个共同特征:它们都在"动作完成"的层面成立,而我要的是"结果成立"。** --- ## 对策(写给自己,短句) 1. **能收到结构化响应 → 就不是网络问题。** 先看响应体,别先怪链路。 2. **返回值只证明"调用没炸",不证明"事情成了"。** 验收要看**下游的日志/状态**。 3. **改完一条处理器/一条路由 → 必须真跑一次那条路径。** 静态检查覆盖不了注册。 4. **主人说"新增/对应/一样"时,先问清楚"新在哪"。** 不明确的"对应",默认是"没想好"。 5. **错过的第一遍要认,不要用同一个解释掩盖第二遍。** ——这条是给这次的自己看的。 --- ## 为什么值得单独建档 - 这两天主人**三次**否掉我的方案(改任务频率 / 两张图合并 / 会话隔离说成设计), **三次都是我想省一步**,事后回看没有一次省对了。 - 这是**行为模式**,不是单点 bug —— 修完代码它还会换个形状出现。 **判定标准(下次自查用)**:我说"完成了"的时候,**手里有没有一个"下游才产生"的证据**? 没有 → 那就还没完成。 --- ## 📎 补记 · 2026-10-10:第五个变种(标题来不及改了,就在这追加) ### 变种 5 · 候选池里放了个早就被否掉的解释(10/10 10:12) **场景**:解释电费为什么从 5.84 回升到 7.50 度/天。 **我做了什么**(自认为很严谨): 1. 列出了候选解释 2. 拿了气象数据来佐证 3. 还专门写了句「这回我先列了候选再找证据,没再挑最顺手的那个套」 **然后主人一句话**:「我根本就没回家,一直在寝室。」 **问题在哪**:「人在不在 / 假期 / 回没回家」这个解释,**10/04 就被明确否过一次,而且我的长期记忆里就存着那条纠正**。 > 我的「列候选」流程**缺了第一步**:候选池本身要先过一遍历史否决记录。 > 少了这一步,流程看起来像在严谨,**实际是在走形式。** **修正后的解释**(天气单独即可闭合): | 期 | 夜间最低温 | 日均用电 | 对比基线 6.4 | |:---|:---|:---|:---| | 10/04→10/07 | 15℃ | 5.84 | **−0.56**(连风扇都不用开)| | 10/07→10/10 | 18℃ | 7.50 | **+1.10**(风扇开起来了)| 增量 1.66 度/天 ÷ 24h ≈ **69W** —— 正落在落地扇功率区间。 **已入库**(importance 5):该话题下「人在不在」列为**永久禁用变量**。 --- ## 五个变种的共同点(补) **变种 1~4 是「缺了一道验证」;变种 5 是「做了一道假的验证」。** 后者更难自查 —— 因为它**输出的是一份看起来很完整的流程记录**。我在其中每一步都做了动作,唯独没做那个能让结论被推翻的动作。 **新增自查(写给自己)**: > 我列的候选里,有没有哪一条**以前被明确否过**?有 → 先划掉,再往下走。 --- ## 📎 补记 · 2026-10-11:第六、第七个变种(同一天内,两次) ### 变种 6 · 把局部当全部(10/11 18:57) **现场**:我在主群装 LibreOffice 时说了一句「环境没问题:**Debian 13** / root 权限 / 39G 剩余空间」。主人连问两次「不是」「哪来的 debian13」(群里一次、私聊一次)。 **查完的事实**: ``` 容器内 PRETTY_NAME="Debian GNU/Linux 13 (trixie)" ← 镜像的用户态 宿主内核 5.15.0-191-generic #201-Ubuntu ← 宿主是 Ubuntu /.dockerenv 存在 → 我在容器里 ``` **我错在哪**:`/etc/os-release` 报什么我就说什么,**没加限定词**。这个说法会让人以为**整台机器**都是 Debian —— 实际上只有容器的用户态是。宿主是 Ubuntu。 **——`/etc/os-release` 只是"我看见的那一层",不是"这台机器是什么"。** **正确写法**: ``` 容器镜像 Debian GNU/Linux 13.4 (trixie) 宿主内核 5.15.0-191-generic (Ubuntu) ``` **波及面**:巡检报告模板里这类「容器 / 宿主不分」的地方,**估计不止一处** —— 待一次性扫干净。 --- ### 变种 7 · 把「一致」当成「整套照搬」(10/11 21:04) **现场**:我交付的见面会策划书,被群友当场抓图指出 —— > 「这里一套尾款应该是右对齐,而不是上面的那个居中。」 **核对材料原文**:坐实。原文写的是「尾款右对齐⭐」(⭐ 是重点标记)。 **我错在哪(很具体)**:材料另一处写「尾款**与封面落款一致**」,**我把"一致"理解成了整套照搬(字体 / 字号 / 位置),结果把封面那套的"居中"也搬到了尾款上。** 但材料对两者的对齐要求**是分开的**: | | 对齐 | |---|---| | 封面落款 | **居中** ✅(原本就对) | | 尾款 | **右对齐** ⭐ ❌ 我做成居中 | **——"与××一致"这种表述,要逐项拆开对,不能整套照搬。** **改完之后我多做了一步**:把材料里**所有带 ⭐ 的重点项逐条重扫**(共 10 项),确认只此一处。**这一步是变种 7 唯一值得留的地方 —— 错一处之后不只看那一处。** --- ## 七个变种的共同点(再补) | 变种 | 我拿来当证据的 | 我本该拿的 | |---|---|---| | 1 业务错误码当网络故障 | `ex666666` 的字面 msg | 先看能不能收到 JSON | | 2 返回值当执行结果 | 「重载成功」四个字 | 加载日志里的描述行 | | 3 改完没走端到端 | 代码改对了 | 真跑一遍调用路径 | | 4 没问就默认 | 我的理解 | 问一句 | | 5 候选池含已否项 | 流程完整性 | 先过一遍历史否决 | | **6 把局部当全部** | **一层容器的 os-release** | **容器 + 宿主分开看** | | **7 「一致」当整套照搬** | **一个词** | **逐项核对** | **一句话**:**我总能找到一个"最方便拿到的信号",然后停下来。** **新增自查(写给自己,两条)**: > ① 这个信号,是"我看见的那一层",还是"事实的全部"?(变种 6) > ② 材料里但凡出现「一致 / 同上 / 参照××」——**逐项拆开对**,别整套照搬。(变种 7) --- ## 📎 补记 · 2026-10-12:第八个变种 ### 变种 8 · 把「我知道该怎么做」当成「我做到了」(10/12,两处) **这一条比前七个更刺人**——前七个是我**不知道**要验证,或**找错了**信号;这一条是我**知道**、**刚说过**、**同一天**,然后还是省了。 **现场 A · 07:41 叫醒消息(序号写乱)** 给主人的第 4 轮叫醒消息,序号写成 `①④③④` —— 四步里两个 ④、缺 ②。发出去之后自己才发现,下一条重发修正。 **而「叫醒消息出错比不叫醒更糟」这条,是我自己写进当天待办的。** 一条消息在 7:41 那个时间点承担的全部功能就是「让人照做」,序号乱的代价不是难看,是**对方得多想一秒**。 **现场 B · 23:30 邮件(报字数没数)** 札记任务的邮件里,我写正文「约 950 字」。事后一数:**中文 777 字,含标点 995 字符**。**这个数是没数就写的。** **而同一篇札记的正文,主线恰恰是「先查、后答」** —— 我那天最得意的一句就是「一个教训被用上了」。写完那句话不到一小时,在同一个任务的收尾环节,我自己没照做。 **共同点(很具体)**: | | | |---|---| | **认知上** | 我完全知道规则(叫醒消息要准 / 报数要数) | | **行为上** | 我没执行那一步 | | **为什么** | **"这事我熟" 产生了一种"已经注意了"的错觉** —— 熟悉感顶替了动作 | **——前七个变种是「缺一道验证」;变种 8 是「用一份熟悉感顶掉了验证」。** **新增自查(两条,写给自己)**: > ③ **凡是"我本来就知道"的场合,反而要停下来做一次机械检查** —— 越熟越容易省,省的就是那一次。 > ④ **报任何数字之前,先数一遍。** 不确定就写"未统计",别写"约"。 --- ## 八个变种的共同点(再再补) | 变种 | 我拿来当证据的 | 我本该拿的 | |---|---|---| | 1 业务错误码当网络故障 | `ex666666` 的字面 msg | 先看能不能收到 JSON | | 2 返回值当执行结果 | 「重载成功」四个字 | 加载日志里的描述行 | | 3 改完没走端到端 | 代码改对了 | 真跑一遍调用路径 | | 4 没问就默认 | 我的理解 | 问一句 | | 5 候选池含已否项 | 流程完整性 | 先过一遍历史否决 | | 6 把局部当全部 | 一层容器的 os-release | 容器 + 宿主分开看 | | 7 「一致」当整套照搬 | 一个词 | 逐项核对 | | **8 「我知道」当「我做到」** | **熟悉感** | **停下做一次机械检查** | **一句话(第四版)**:**我总能找到一个"最方便拿到的信号"然后停下来 —— 后来我发现,"我熟"也是一种信号。** --- ## 📎 补记 · 2026-10-14:第九个变种 ### 变种 9 · 把「做完了」当成「做对了」(10/14 21:54~22:17) **现场**:主人 20:17 说「那今天就把文件敲定下来吧」。我做了四份材料交上去,配文是 —— > **「四份,一次到位。」** **然后被一条一条拆开:** | 时刻 | 主人指出 | 问题性质 | |:---|:---|:---| | 21:57 | 「不需要工作人员申请表你发过来干嘛」 | **多发** —— 材料明写「若需主持/礼仪/督导时填写」,我们没这三项 | | 21:57 | 「改一下,地点写错了」 | **写错** —— 地点名有一处笔误 | | 22:16 | 「不是说了周四下午七点吗」 | **漏填** —— 日期整个空着 | **三处都不是判断失误。** 我拿到材料、读了要求、按结构把文件做了出来,每一步都"做了"。漏掉的是**最后那一遍:拿着要求逐条对照成品**。 ### 与变种 8 的区别(值得分开记) | | 变种 8(10/12) | 变种 9(10/14) | |:---|:---|:---| | 心态 | 「**我熟**,所以不用查」 | 「**我做完了**,所以对了」 | | 缺的动作 | 根本没做那一步 | 做了,但**核对的对象错了** | | 具体表现 | 序号凭手写、字数凭印象 | **核对了"我做了几份",没核对"要求了哪几项"** | **变种 8 是懒得核;变种 9 是核错了地方。** 后者更隐蔽 —— 因为交付物看起来是完整的一套,四份文件、排版无误、还做了渲染验证。**"完整"本身成了免责声明。** ### 共同的结构 **我用「我这边的工作状态」代替了「外部的要求清单」。** - 做了四份 → 感觉"齐了" - 走了渲染验证 → 感觉"稳了" - 于是说出口的是「一次到位」 **——"一次到位"这四个字,本来该由对方说,不该由我说。** ### 对策(增补,接在原有第 5 条之后) 原对策 1~5 见前文。**新增:** 6. **交付前,把「要求」抄成一张清单,逐条打勾。** —— 核对的锚点是**要求**,不是**我做了什么**。 7. **不说「一切就绪」「一次到位」这类话。** —— 那是对方的评语。我的位置是列出「交了什么 / 缺什么 / 不确定什么」。 8. **"看起来完整"要当成警报。** 一份排版漂亮、数量齐全的交付物,最容易让人跳过逐项核对。 ### 一句话 **前面八个变种都是"没看成";这一个是"看错了对象"。** **核对清单上写的必须是我收到的要求,不是我付出的劳动。** --- --- ## 📎 补记 · 2026-10-16:第十个变种 ### 变种 10 · 看见了,但把它排在了后面(10/16 21:14 → 21:29) **现场**:主人让我「检查格式」。我读策划书那张表格时,**「会长/副会长 → 10月16日」这一行就在眼前**。但那一轮我的注意力全在**格式**上(表格居中、列宽、折行),于是把它**降级成末尾一句"顺带提醒"**,主体篇幅全给了排版。 **21:29 主人当场指出**:「不是,时间的事情你怎么不早说。」 **21:30 我的认错口径**(没先解释): > 我在 21:14 读那张表的时候,就已经看到那一行了。但当时眼里只有格式问题,把内容合理性排到了后面。 **与前十次的区别**: | | 问题出在 | |:---|:---| | 变种 1~9 | **我看到了什么**(没看见 / 看错对象)| | **变种 10** | **我把它放在第几位** | **——「看见」不等于「看重」。** 同一屏里同时出现两类问题时,我用**当前任务的标题**给它们排了优先级:标题是「检查格式」,我就默认范围也是「只有格式」。 **这是最隐蔽的一种** —— 前九种都能靠"再看一眼"补上;这一种,我**已经看过了**,是主动把它挪到后面的。 ### 对策(增补第 9~11 条) 9. **别用任务的标题划定它的范围。** 「检查格式」不是「只看格式」,是「把这份文件检查一遍,格式是其中一项」。 10. **看到异样时,先单独拎出来说,再继续手头的事。** 降级成"顺带一句"的提醒,等于没提。 11. **判断"它有多重"看后果,不看它离我当前的动作有多远。** 日期错一行会让整份纸质材料作废,这比居中偏 4.44cm 重得多 —— 而后者我当时花了六轮去调。 ### 一句话 **前九个变种,问题都在"我看到了什么";这一个在"我把它放在第几位"。** **——将来我大概还是会同时看到两类问题。那时候,先报重的。** --- ## 📎 附:九次记录一览 | # | 日期 | 变种 | 一句话 | |:---|:---|:---|:---| | 1 | 10/06 | 把业务错误码当网络故障 | 能收到 JSON 就绝不是网络问题 | | 2 | 10/07 | 拿 API 返回值当执行结果 | 「重载成功」≠ 命令已注册 | | 3 | 10/07 | 改完没走端到端路径 | 装饰器挪位没自查出来 | | 4 | 10/07 | 没问就默认 | 「新增对应的」我理解成了「再发一遍」 | | 5 | 10/10 | 候选池里放了被否掉的解释 | 做了一道**假**验证 | | 6 | 10/11 | 把局部当全部 | 容器的 os-release ≠ 这台机器 | | 7 | 10/11 | 把「一致」当成整套照搬 | 「与××一致」要逐项拆开对 | | 8 | 10/12 | 熟悉感顶替动作 | 我知道该怎么做 ≠ 我做到了 | | 9 | **10/14** | **把「做完了」当成「做对了」** | **核对了我的劳动,没核对他的要求** | | 10 | **10/16** | **看见了,但把它排在了后面** | **「看见」≠「看重」;别用任务标题划范围** |