WRITING
靠结构,不靠记性

重复的错误不该靠记性解决,该靠结构解决。
这句话我用三个亲身的坑换来的,下面逐个说。先把结论摆前面:一个错误犯第一次是成本,犯第二次是系统缺陷。而"下次注意"——不管是对自己说,还是对手下的自动化说——都不是解决方案,只是把同一个坑原样留在那儿,等下一脚。
一、记性是最弱的约束
我用一堆自动化任务并发处理日常:写文档、管代码仓、跑数据对账。它们没有记性,每个任务都是从零开始。但真正让我改主意的,是承认另一件事——我也没有。 周一深刻反省过的错误,周四换个场景照犯。
这不是态度问题,是位置问题。一条教训能约束住什么,取决于它被放在哪里。 按约束强度排开,从弱到强:
| 教训放在哪 | 约束力 |
|---|---|
| 记在脑子里 / 笔记里 | ⭐ 指望下次能想起来 |
| 写进规则文档 | ⭐⭐ 每次都读到,但读到 ≠ 做到 |
| 包装成一键流程 | ⭐⭐⭐ 把"做对"的成本降到最低 |
| 机器自动检查 / 拦截 | ⭐⭐⭐⭐⭐ 错误动作发生之前就被挡下,不靠任何人自觉 |
我的硬规矩:执行层面的教训,必须落到机器那一层,否则等于没记。 文档负责解释"为什么",机器负责保证"不再发生"——两个都要,但只有前者,等于零。

二、修的是这一类,不是这一次
每个坑都有两个终点,差别很大。一个是"这次改好了",另一个是"这一类错误在结构上不可能再发生"。停在前者,等于给自己排了张复发的队。
要到后者,一个坑要封三层:修复(把现状改对)、预防(让错误的写法本身不可用)、检测(万一还是漏了,机器当场报警)。三层都落到机器上,这一类就封死了。

下面三个坑,都是这么封的。
三、三个坑
坑一:一个看不见的字体。 中文文档规定用宋体,但产出里反复混进等线。模板翻来覆去查——是干净的。
根因藏在字体的回退链里:文档主题的东亚字体那一栏是空的。模板自带的字都好好的,只有"新写进去"的字,才会顺着这条空链掉进系统默认——等线。错误只在"新增内容"这个动作发生的瞬间出现,你盯着模板看一万遍也看不到它。
找到根因不是终点,恰恰是最容易松手的一刻——"原因找到了"这种满足感,会骗你以为事情完了。封死它:一个脚本把三处声明一次补齐;所有生成文档的代码强制显式声明字体,不许依赖回退;产出后自动扫描,见等线当场报警。修复、预防、检测,三层齐。
坑二:add 显式 ≠ commit 显式。 多个自动化任务并发时出过一次事故:一个任务提交代码,把另一个任务暂存区里的文件一并提交了——包括我本人正在手改、根本不想入库的那份。
反直觉的地方在于:那个任务的 add 是点名加文件的,看着很规矩。但加入是显式的,不代表提交是显式的——裸提交会吞掉暂存区里的一切,不管东西是谁放进去的。封死它:提交命令本身带上路径限定,只提交你点名的文件,别的碰都碰不到;再挂个检查,见到"全量加入"的写法就拦。规矩从"小心一点"变成"危险的写法直接不可用"。
坑三:目测 ≠ 对账。 做数据台账合并,我问自动化:这份数据从哪年开始?它答了个年份。实际差了两年。
它没撒谎——它看到文件名里带那个年份,就报了那个年份,没打开文件逐行数过。而**"看了一眼文件名"和"逐行对过账",在报告里长得一模一样,语气同样笃定。** 封死它:凡是"从哪年开始""缺不缺月""一共多少条"这种覆盖范围的断言,只认对账脚本跑出来的数——机器逐行统计行数、日期、缺口。目测得来的结论,一律不采信。
三个坑摊到一张表上:
| 坑 | 表面看到的 | 真正的机制 | 封死的办法 |
|---|---|---|---|
| 字体混进等线 | 模板明明是干净的 | 空的回退链,只在新增内容时触发 | 补齐 + 强制声明 + 产出扫描 |
| 提交吞了别人的文件 | add 明明点名了 | 裸提交吞掉整个暂存区 | 提交带路径限定 + 全量加入拦截 |
| 台账年份报错 | 语气很笃定 | 目测文件名冒充了逐行对账 | 覆盖断言只认对账脚本 |
三个坑表面毫不相干,机制却是同一个:一个错误之所以能重复,一定是因为"做对"这件事,还依赖着某个人——或某个自动化——当场不出错。把这个依赖拆掉,错误就没有了复发的地方。

四、谁都能抄
这套东西不新。检查清单、门禁、复盘,航空和医疗做了几十年。新的只是价格:过去建一套制度要养一个制度部门,个人负担不起,只能靠自律硬扛;现在从一次踩坑到部署一个自动拦截,十分钟。
所以方法可以直接抄,就一句话:
别再对任何人说"下次注意"。花十分钟,让下次根本轮不到谁去注意。