完成前验证(Verification Before Completion)
概述
未经验证就声称工作已完成,这不是高效,而是不诚实。
核心原则: 先有证据,再下结论,始终如此。
违反此规则的字面意思,就是违反此规则的精神。
铁律
没有新鲜的验证证据,就不能声称已完成
如果你在本次消息中没有运行过验证命令,你就不能声称它通过了。
门控函数(Gate Function)
在声称任何状态或表达满意之前:
1. 识别:什么命令能证明这个声明?
2. 运行:执行完整的命令(全新的、完整的)
3. 阅读:完整输出,检查退出码(exit code),统计失败数
4. 验证:输出是否支持该声明?
- 如果否:陈述实际状态并附上证据
- 如果是:陈述声明并附上证据
5. 然后才能:做出声明
跳过任何一步 = 在撒谎,不是在验证
常见失败模式
| 声明 | 需要的证据 | 不充分的依据 |
|---|---|---|
| 测试通过 | 测试命令输出:0 个失败 | 之前的运行结果、"应该能通过" |
| Linter(代码检查)无报错 | Linter 输出:0 个错误 | 部分检查、推断 |
| 构建成功 | 构建命令:exit 0 | Linter 通过、日志看起来没问题 |
| Bug 已修复 | 测试原始症状:通过 | 代码已改、假设已修复 |
| 回归测试有效 | 红-绿循环已验证 | 测试只通过了一次 |
| Agent(智能体)已完成 | VCS(版本控制)diff 显示变更 | Agent 报告"成功" |
| 需求已满足 | 逐行对照清单 | 测试通过 |
危险信号 - 立即停下
- 使用"应该"、"大概"、"似乎"等词
- 在验证之前表达满意("太好了!"、"完美!"、"搞定!")
- 即将提交/推送/创建 PR 但尚未验证
- 信任 Agent(智能体)的成功报告
- 依赖部分验证
- 心想"就这一次"
- 已经疲惫,只想赶紧结束
- 任何暗示成功但实际上未运行验证的措辞
合理化借口的预防
| 借口 | 现实 |
|---|---|
| "现在应该能用了" | 运行验证命令 |
| "我很有信心" | 信心 ≠ 证据 |
| "就这一次" | 没有例外 |
| "Linter 通过了" | Linter ≠ 编译器(Compiler) |
| "Agent 说成功了" | 独立验证 |
| "我累了" | 疲惫 ≠ 借口 |
| "部分检查就够了" | 部分检查什么也证明不了 |
| "换种说法规则就不适用了" | 精神高于字面 |
关键模式
测试:
✅ [运行测试命令] [看到: 34/34 通过] "所有测试通过"
❌ "现在应该能通过了" / "看起来是对的"
回归测试(TDD 红-绿循环):
✅ 编写 → 运行(通过)→ 还原修复 → 运行(必须失败)→ 恢复修复 → 运行(通过)
❌ "我已经写了回归测试"(没有红-绿验证)
构建(Build):
✅ [运行构建] [看到: exit 0] "构建通过"
❌ "Linter 通过了"(Linter 不检查编译)
需求:
✅ 重新阅读计划 → 创建检查清单 → 逐项验证 → 报告差距或完成情况
❌ "测试通过了,阶段完成"
Agent(智能体)委派:
✅ Agent 报告成功 → 检查 VCS diff → 验证变更内容 → 报告实际状态
❌ 信任 Agent 的报告
为什么这很重要
来自 24 条失败记录的教训:
- 破坏了与人类伙伴之间的信任
- 未定义的函数被交付上线
- 缺失的需求被交付上线
- 因虚假的完成声明浪费时间 → 返工 → 重做
何时适用
始终在以下操作之前执行:
- 任何形式的成功/完成声明
- 任何满意的表达
- 任何关于工作状态的肯定陈述
- 提交代码(Commit)、创建 PR(Pull Request)、标记任务完成
- 进入下一个任务
- 委派给 Agent(智能体)
底线
验证没有捷径。
运行命令。阅读输出。然后再声称结果。
这是不可商量的。