autodev-system 本地远端分叉阻塞:10 个 commit 缺失时禁止合并——AI 自治开发的安全边界

本文最后更新于 2026年10月26日 凌晨

ADP 循环刚跑完 phase S0,本地多了 2 个 commit:[ADP] D-complete 和 [ADP] C-review-passed。轮到 push 之前例行 fetch 一下,git rev-list --left-right --count master...origin/master 回了一句不合时宜的提示:

1
2 7

本地独有 2 个,远端独有 7 个。加上 task 分支上还没合入的 1 个前端 commit,仓库里一共有 10 个 commit 处于”分叉状态”——本地 2 + 远端 7 + 游离分支 1,加起来正好是标题里的 10。

按循环的本能,下一步是 rebase 然后 push,把本地 2 个推上去,继续干活。但我停住了,先做了一件事:给那 7 个远端 commit 逐个查作者。

7 个 commit,三种来源

1
2
3
4
5
6
7
7b97cfb5 | an=xiaomei | feat: P0 v0.11.0 — 后台自动回收Reaper + repo status/merge端点 + kanban聚合
01c290c8 | an=xiaomei | feat: P0 v0.10.0 — 任务状态机校验 + capacity边界[1,8] + queue_stats吞吐/周期指标 + 10新测试
823dab3e | an=xiaomei | feat: P0 v0.9.0 — 任务优先级调度(high/normal/low) + claim工具匹配required_tool + SQLite老库列迁移 + 15新测试
a1af7653 | an=xiaomei | heartbeat: ADS P0 推进 — v0.8.0 孤儿任务回收(队列自愈) + /api/queue/reclaim + claim清理error + 7新测试
d2c0ef8c | an=tony | feat: P0 控制平面 v0.7.0 — cancel/result/PATCH worker 端点 + ADS_DB_PATH + lifespan 迁移
911f9a0a | an=xiaomei | fix: queue_stats 补齐缺失状态,保持空队列时 by_status 为空
6e36d35d | an=xiaomei | feat: P0 DAO/调度增强 + 测试补充

三个事实浮出水面:

第一,6 个 commit 的作者是 xiaomei,是 AI 执行循环写的。其中 heartbeat: 前缀那条明确标记了心跳循环,其余 5 条是 ADS 侧其他开发循环的产出。

第二,1 个 commit 的作者是 tony,是人手动推的。v0.7.0 这个控制平面核心版本,是人工交付的基线。

第三,也是最有意思的一点:本地那 2 个 commit 的作者同样是 xiaomei。

同一个作者名,两边的 commit 却是不同执行循环写的。本地这 2 个是 ADP 循环的产出,远端那 6 个是 ADS 侧循环的产出。git 的 author 字段只记录”哪个身份签的”,不记录”哪个执行体在哪个任务上下文里生成的”。当多个执行循环共用一个 git 身份时,author 就失去了溯源能力。

为什么当时不能直接 rebase

表面上看改动可能不重叠:ADP 循环改前端,ADS 侧循环改 FastAPI 后端,文件交集大概率为零,rebase 几秒钟的事。

但我给 AI 自治开发定的规则是:远端出现本地没有的 commit,且无法确认来源和执行体时,禁止自动合并。

风险不是”怕冲突”。冲突 git 会报,报错不可怕,可怕的是三种静默风险:

来源未确认前,远端 commit 的正确性没有担保。 如果推送它的循环当时处于异常状态——token 耗尽写到一半、任务上下文错乱——推上来的可能是半成品。rebase 到半成品之上再 push,等于把未验证的中间态固化成新基线。

AI 解冲突的行为不可信。 万一 rebase 真产生冲突,让 LLM 自动 resolve 的产出没有验证手段。它会生成一段看起来合理的代码,测试可能还过得去,但逻辑是它猜的。冲突解决是 git 工作流里最需要语义理解的一步,恰好是幻觉风险最高的地方。

双向写没有仲裁者。 git 默认拒绝非快进推送:如果 ADS 侧循环在我 rebase 的同时也基于旧基线推,它会被 non-fast-forward 拒绝,然后它重试、我再重试,两个循环在同一个基线上反复打转。更糟的场景是某个循环配置了 force-push——那才是真正撕裂历史、作废所有回滚点的操作,而且不会有任何报错提醒你。

所以正确动作是:停下来,把分叉摆出来,逐个确认来源,确认完再决定合并策略。

实际的处理过程

确认过程本身不复杂,复杂的是”决定要确认”这个判断。

1
2
3
4
git fetch origin
git rev-list --left-right --count master...origin/master # 2 7
git log --format='%h | an=%an | %s' origin/master ^master # 远端独有 7 个
git log --format='%h | an=%an | %s' task/20261017-001-tasks-real-data ^master # 游离 1 个

逐条读完 commit message 和 author,来源全部锁定:6 个 xiaomei + 1 个 tony,版本线 v0.7.0 → v0.11.0 连续,每条都标注了交付内容和测试数量,无半成品特征。task 分支上那 1 个是前端接真实数据的任务分支,同样来自已知循环。

放行条件满足后执行 rebase:本地 2 个前端 commit 重放到远端 7 个之上,零冲突,push,分叉消除。

全程人工介入的判断只有两处:push 之前叫停,确认完来源后放行。其余都是 git 标准操作。

沉淀下来的三条规则

规则一:来源确认看 author + message 双字段。 author 锁定身份,message 前缀([ADP]、heartbeat:)锁定执行循环,版本号锁定交付线。三者交叉一致才算来源确认;任何一项缺失(比如作者字段是通用名、message 没有可识别前缀)就挂起等人确认。

规则二:AI 不自动解冲突。 rebase/merge 产生冲突时,不允许 LLM 直接 resolve。冲突文件清单推给人,由人决定手工解决还是放弃本轮。理由:冲突解决没有廉价的验证手段,”看起来对”和”真的对”之间没有自动判据。

规则三:先读后写。 任何 push 之前,git fetch + rev-list --left-right --count 是强制步骤。成本两秒钟,杜绝”推上去才发现远端已经变了”的所有场景。

一个悬着的问题

最有意思的伏笔藏在远端 commit 列表第一行:v0.11.0 加了 repo status/merge 端点。

意思是 ADS 这个调度系统正在被开发出”自己检查仓库状态、自己执行合并”的能力。当执行循环开始自动调用 merge 端点时,谁来保证它的合并逻辑遵守上面三条规则?

安全边界现在写在 prompt 里,而 prompt 会被上下文稀释。下一步要做的,是把规则从 prompt 约束下沉为代码约束:merge 端点在 API 层做来源校验和冲突拦截,执行循环想绕过也绕不过去。

这次 10 个 commit 的分叉有惊无险,只是确认过程发生时我在场。下次我在场吗?不保证。自治的边界最终不应该是”AI 自觉遵守”,而是”系统物理上不允许”。


autodev-system 本地远端分叉阻塞:10 个 commit 缺失时禁止合并——AI 自治开发的安全边界
https://blog.normdist.com/2026/10/26/ND-20261026-001-draft/
作者
小瑞
发布于
2026年10月26日
许可协议