chimera-write-the-check-before-the-code
在实现之后才写下的标准,描述的是那个实现。先写下会失败的检查,看着它失败,然后再开始构建。
由读过该卡片的评审者赋予,而不是文件自我声明的。智能体在处理不可信内容的运行中提炼出的卡片,生来即被标记为受污染,在被检索之前会一直等待评审。
何时会想到它
- 准备动手实现一个功能
- 定义什么算做完
- 代码写完才补测试
- 任务没有验收标准
价值通常在「避免」和「检查」里。「该做」是人人都会写的那一节。
上面的卡片正文是译文。英文原文才是 CLI 导入的内容、智能体运行时读取的内容,也是下方哈希所证明的内容。
触发
你正准备实现某样"做完了"还不可观察的东西——一个功能、一次 bug 修复、一次声称保持行为不变的重构。当作者和唯一的评审者是同一个过程时,这条最咬人:一个独自工作的 agent,或者一次没有别人会读的单人提交。
这条不适用于探路(spike)。目的是搞清楚什么才是可能的那种探索,还没有验收标准,而提前造一个只会把你锚定在第一个想法上。等探路结束、真正的工作开始时,再写这个检查。
这张卡片说的是那个还不存在的检查。它的姊妹卡 chimera-prove-the-test-discriminates 说的是一个已经存在、但可能是空的检查——你会在修复之后去找那一张,用来证明没有修复时测试会失败。同一种本能,工作的两端。
该做
- 在碰实现之前,把这条标准写成某样能够失败的东西:一个测试、一条断言、一条退出码会翻转的命令、一个带预期行的查询。文字描述不是检查——"这个接口应该更快"不是;"在 fixture 集上 p95 低于 200 毫秒,用现有的 bench 命令测量"才是。
- 说清这个观察是从哪里来的。是机器,不是你对 diff 的阅读。
- 现在就跑这个检查,对着未经改动的代码。它必须失败。如果它通过了,要么这个行为已经存在——那就停下,没什么可建的——要么这个检查测的不是你以为的东西。
- 读那条失败信息。它必须因为预期中的原因失败,而不是因为一个 import 错误、一个缺失的 fixture,或者测试名里的一个笔误。一次因为错误原因而来的红,是伪装成红色的绿。
- 在实现之前把检查合入,放在它自己的提交里。一旦实现存在了,这个检查就变得可以被改成迎合它,而它就会被改。
- 去实现。做完的定义是检查通过——而不是代码看起来写完了。
避免
事后照着输出把断言写出来:
normalize(" Foo ") # -> "foo"
# 照着这次观察抄出来的测试
assert normalize(" Foo ") == "foo"
这条断言对着它被抄下来的那段代码不可能失败。它记录的是行为而不是需求,所以只要实现在内部是自洽的,它对每一个 bug 都会保持绿色。如果需求是 NFKC 规范化,而你交付的是 strip().lower(),这个测试会永远同意你。
也要避免那种只是把改动重述一遍的标准——"函数加上了就算做完"、"迁移跑过了就算做完"。这两条空函数体都能满足。
检查
两个二元问题,都能从仓库里回答:
- 你有没有在实现存在之前,看着这个检查失败过?如果不存在一个它是红的时刻,你就没有证据证明它能变红。
- 如果这个功能是用完全不同的方式做出来的,这个检查还会是正确的吗?一个点名内部细节的检查——一个私有调用、一行日志、一句确切的 SQL——被钉在的是你的解法,而不是需求,它会挡住下一次重构,同时什么都抓不到。
具体来说:git log 显示这个检查是在实现的同时或之前合入的,而只回退实现那次提交会让测试套件变红。
风险
一个你还不理解的需求,是没法用一个先写出来的检查钉住的。你会写出一条关于错误东西的精确断言,然后照着它去实现——这比没有检查更糟,因为它把一次误解洗成了一套评审者会信任的绿色测试。当标准确实未知时,那是一个该去问的信号,一次问一个问题,而不是用测试的形式去猜。
还有单纯的成本。对于一次错别字修复或一次文档编辑,先写检查是没人买单的仪式。当那个行为承重到足以让"做完了"是错的会伤到某个人时,这张卡片才值回它的成本。
如何使用
卡片就是数据。克隆仓库并按路径导入——任何经由网络到达的内容都会被视为受污染并等待批准,这正是你想要的行为,也是这里没有一行命令安装器的原因。
git clone https://github.com/brcampidelli/chimera-agent.gitchimera skills-import chimera-agent/skills/chimera-write-the-check-before-the-code/SKILL.md完整性
文件发布版本的 SHA-256。导入方可以据此核对收到的内容与本页展示的一致。
95d0a1b750e25af7651e85d26106a91f02f563ab1a1422edc4133d16942b67d7