作者发现使用 AI 编程工具时,Agent 完成工作后自行写入 tracker,缺少独立验证环节,导致项目记录与实际代码持续漂移。指出 tracker 本质是档案柜,而非真相来源。
7 月 27 日,我打开一个用 Claude Code 搭建的项目,同时发现三件事成真了:
一张卡片携带了一个 null commit 持续了两天
spec 里包含了九条错误的陈述
五百行代码被写进了一张仍躺在 Backlog 的卡片名下,因为没有人调用 start
这些都不是 agent 写出了烂代码。代码本身没问题。是 agent 对代码的记录悄悄散架了,而由于没有任何值得注意的异常,我压根没发现。
我错怪它好几个星期了。
这类工具的共同形态
我试了显而易见的修复方案。更严苛的 CLAUDE.md、更优提示词的 tracker、不断唠叨的 hooks。它们都有点帮助,但没有一个触碰到真正的问题——这个问题是结构性的:
agent 干活,agent 给自己写报告。
就这样。这就是全部的失败模式。你的 tracker 只是一个文件柜:agent 说"搞定了,测试通过",看板存储了字符串"搞定了,测试通过",但没有任何地方去追问这是真的吗?
所以,断言与项目记忆之间唯一站立的人是你——你去读 diff。你就是那个验证步骤。这就是为什么你不能在它运行的时候走开,也是为什么看板和仓库在你停止关注的那一刻就开始分道扬镳。
建议修复不了这个问题。我知道,因为我就是写建议的那个人。这个项目的整个 MCP server 搭建过程中 start 从未被调用过——那张卡片躺在 Backlog 里,同时五百行代码被写到了它名下。如果协议的制定者在握着它做上下文的同时在一个 session 内就已经游离了,那协议就不是机制,只是一厢情愿。
我不再试图让 agent 变得更可靠,转而开始对看板上每个事实提出不同的问题:谁有权来断言这件事?
命令通过了吗?机器说了算。当 agent 把卡片交回时,tracker 先运行项目的检查,只有检查 exit code 为 0 时才授予状态。关键在于:检查是一个在项目配置中由人声明的 argv 数组——没有任何 agent 能触及的工具可以写入它。agent 可以选择一个已声明的检查,但不能定义一个。如果 agent 能写出一条给它自己打分的命令,那不过是用更多步骤给自己打分而已。
工作落地了吗?Git 说了算。如果一张卡片的 commit 已经是 main 的祖先,那么在 session 启动时看板就会自动更正,无需询问。只向前:它填补空白、确认已落地的工作,绝不会覆盖你做出的决定——因为没有任何 commit 记录了意图。
这条记录还成立吗?diff 说了算。每条记录都保存了它为真时的 sha。之后看板会告诉你从那之后树移动了多远,并区分"没有任何东西落地"和"我无法检查"。在别处,三周前的记录看起来和今天早上的一模一样。
两件事矛盾了吗?看板会主动告诉你。提供了一个视图来呈现与 git 矛盾的断言、分支没有卡片归属、以及卡片在从未运行过检查的情况下被关闭。
把看板存在 git 里是存储——好几个工具都这么做。让 git 否决你的看板是裁决。这就是差别,也是整个产品的全貌。
我弄错的部分,错了两次
有两件事我要告诉在这个领域里做开发的所有人。
验证关乎的是哪个层面可以建立命令,而不是如何逃避它。我把检查做成了 argv 数组,用 shell: false 运行,以为大功告成。后来我发现本地 web UI 的 PUT 会替换整个文档——包括 checks map——而且它设计上就是无认证的。所以任何能触及那个端口的东西都可以把 ["/bin/sh", "-c", "…"] 安装为检查,而下一次交回时会直接运行它。我从端到端复现了:200 OK、schema 合法、payload 执行了。当 argv 是一个 shell 时,shell: false 毫无防御能力。
还有"已测量"意味着"在我的机器上已测量",在 CI 存在之前都是如此。一个用于捕获检查尾输出的宽限期是被仔细测量的——从一百字节到一百万字节,各十次运行,外加故意的 CPU 饱和。这一切都是在一台 8 核笔记本上完成的。它遇到的的第一个 2 核 CI runner 在第一个 job 就丢了一行。这个项目里已经有三处独立的时间假设因此崩塌。
一次通过只能证明一个声明的命令在指定的树上 exit zero。它不能证明工作是正确的。一个为坏代码写出了通过测试的 agent 可以完全击败这个机制,而工具在卡片上——而不是脚注里——说明了这一点。
在你声明一个检查之前,它什么也证明不了——卡片凭 agent 的话移动,和其他地方一样。没有依赖图。而且是一个开发者、一台机器:没有账户、没有权限、没有团队功能。
它用自己构建了自身
每个功能都用来构建下一个功能,而仓库里的看板才是真正的看板——75 张卡片、274 条记录,约 43,000 字,由 agent 在工作过程中写成,包括那些错误。一只无声丢失写入的锁定性 bug。一条安全检查的错误处理把崩溃变成了彻底的沉默。一条对 tracker 自身刚刚修改过的文件通过的测试——被几小时前发布的那个功能逮住了,而那个功能立刻也逮住了它的作者。
最后这条是这个项目里我最爱的部分。这个工具的第一次真正的捕获,是工具捕获了我。
github.com/albertoclemente/shipward — MIT,无需依赖,无需构建步骤,Node 20+。547 个测试。
如果你也在跑 coding agent,我真心想知道你是否也遇到过同样的情况:agent 关闭了某件事,后来发现其实不成立。我还不确定自己是否特殊。