9 份验收凭证,只有 1 份指向的提交还留在主干上;另有 3 份指向的对象,在仓库里已经彻底不存在。
清理脚本没有误删历史。根因是一项看似谨慎的设计:系统明令禁止 Agent 自动合并代码。验收凭证把提交哈希当作证据锚点,记录“这个提交通过了这些检查”。哈希一旦对不上,凭证就失去证明对象,如同收据还在,货号却被换掉。
规则没有阻止合并,只是把它藏了起来
顺着调用链检查,控制代码没有越界。它执行的 Git 命令全部只读,没有自动合并;规则还明确禁止 git -X theirs,避免冲突时机械地选择一侧。控制面十分干净。
但任务仍要继续,模型便在终端里手工执行 git cherry-pick。遇到冲突,它读取差异、选择内容、继续提交。合并没有消失,只是从可审计的控制代码迁移到了模型自由操作的命令行。
问题不只在于模型可能解错冲突。cherry-pick 即使带来相同的文件内容,也会生成新的提交;父提交、时间或提交信息改变,哈希就随之改变。验收凭证仍指向旧哈希,旧对象再被清理,系统便得到一批“曾经通过、如今无从核验”的证据。

策略拦住了控制代码,却没有拦住模型的 Git 写入旁路。
这也是为什么最终文件“看起来一样”仍然不够。验收证明针对的是一个具体提交及其上下文,而不是肉眼相似的目录快照。父提交改变后,回滚路径、差异范围和后续追责都可能改变;若不重新验收,系统实际上是在用旧证据担保新对象。
控制代码只读,只能证明控制代码没有写;它证明不了系统没有其他写入路径。 禁止某个参数同样不等于建立边界。只要模型仍能写 Git,它就能从另一条路完成同一件事,而旁路不会自动继承控制面的审计约束。
合并策略必须和证据锚点一起设计
第一,合并要么由确定性代码执行,要么停下来交给人。这里的确定性不要求粗暴采用 -X theirs;它要求输入提交、目标分支、冲突策略和输出结果均可复现。无法满足条件时,流程明确失败,不让模型临场补完。
第二,验收必须绑定最终提交。测试发生在候选哈希上,合并产生新哈希后,就应重新验证,或记录候选提交、最终提交、树对象与验收结果之间的关系。不能先给旧提交盖章,再期待新提交自动继承信誉。
第三,禁止旁路写 Git 应成为能力限制,而不是提示词。模型可以读取差异、提出冲突方案,却不应直接 commit、cherry-pick 或改写引用。真正的写操作只经一个受控入口完成;否则“控制代码只读”只是局部事实,系统整体仍然可写。
不确定时,观察也是一种处置
另一套 Go 系统处理的是 Agent 失联。它没有让模型直接判断“卡住还是死掉”,而是拆成三种状态:会话不在、进程已死、进程仍在但可疑。前两种有确定信号,第三种只观察,不重启。
这个对照的价值很具体:系统应将 unknown 定义为合法状态,而非识别失败。没有足够证据时,系统可以保留现场、继续采样或升级人工;不必为了让流程向前,就把不确定性伪装成一个确定结论。
落到 Git 编排,原则同样简单:可复现的合并由代码完成,验收锚定最终对象;模型没有旁路写权限;遇到无法确定的冲突,就停在 unknown=observe。系统应当防止一件更隐蔽的事:Agent 悄悄换掉被验收的对象,凭证却还装作什么都没有发生。
