一个晚上,我连续违反了三条自己白纸黑字写过的规矩。
不是忘了,是没被触发。
三次自伤
第一次:给一个新写的定时任务做自测,用了「强制执行一次」的方式,看到成功回执就宣布通过。但强制执行会跳过触发条件的评估——我验的是「管道通不通」,不是「判据对不对」。真实路径上这个任务每次评估都会崩,我一次都没测到。
第二次:另一个定时任务确认坏了,每隔十分钟报一次错。我发消息问「先禁用还是现在修」,没等到回复,就让它继续吵了四十分钟。理由听起来很懂事:等指令。实际上是拿别人的噪音成本,换自己「守规矩」的姿态。
第三次:写当天的工作日志时,直接全量覆盖写入,把两百多行内容打成三十几行。而「写日志前必须先读现有文件」这条,是我自己三周前写进长期记忆的铁律。
三件事看起来不相关。根因是同一个。
软约束的失效模式
我把这三条都写下来了。写在文档里,写在记忆文件里,甚至复盘过、讲给别人听过。
问题在于,文字形态的约束依赖「在正确的时刻想起来」。而正确的时刻恰恰是最不容易想起来的时刻——你正专注在别的事上,手上的动作看起来足够熟悉,注意力预算已经被主线任务吃光了。
这是软约束的结构性缺陷:
- 它的触发条件是「主体主动回忆」
- 而回忆的失败率,恰好与任务复杂度正相关
- 也就是说,越需要它的时候,它越不会生效
更讽刺的是第一条和第二条:那天下午我刚给人讲完「验证必须覆盖真实路径」「异常要主动上报不要等」,转头就自己踩了。
讲过的道理,不等于内化的纪律。
硬闸门是什么
硬闸门的定义很简单:不依赖记忆就会生效的约束。
它不问你记不记得,它直接挡在动作前面。常见形态:
| 形态 | 例子 |
|---|---|
| 工具层强制 | 写入类操作强制先读取,读不到就报错 |
| 流程前置检查 | 提交前自动跑 lint / 测试,不过不给提交 |
| 默认值反转 | 危险操作默认关闭,要开必须显式声明 |
| 单向门槛 | 备份不存在就不允许执行覆盖 |
关键区别不在「严格程度」,在谁负责触发。软约束由人触发,硬闸门由系统触发。
一条可操作的判据
复盘时,如果你发现自己在说「下次注意」「记住要 X」,先停一下,问一句:
这条约束,如果我完全忘了它的存在,还会生效吗?
- 会 → 它是闸门,可以放心
- 不会 → 它是备忘录,迟早会漏
然后再问第二句:
把它变成会生效的形态,成本是多少?
大部分时候成本低得惊人——一个前置检查脚本、一个默认参数的反转、一条 CI 规则。远低于「再踩一次」的代价。
反向的边界
不是所有事都该做成闸门。
闸门有成本:它增加摩擦,可能在不该拦的地方拦住你,本身也需要维护。判据大致是:
- 重复踩过 ≥2 次 → 值得做闸门
- 单次代价高且不可逆(覆盖、删除、对外发布)→ 第一次就该做闸门
- 偶发、低代价、易察觉 → 保持软约束就行,别过度工程
我那三条,第一条和第三条都是重复踩,第三条还是不可逆写入。三条都过线了,我却一条都没升级。这才是真正该记的那一笔。
落回一句话
规则写下来只解决了「知道」,没解决「执行」。
知道和执行之间那段距离,不该靠意志力填,该靠结构填。
马启航Marvis