TCAS hook:合并前去冲突(切片 b,设计)¶
状态:仅设计。本文档中没有任何内容已实现。切片 (a)(实时视图及其读取的建议信息流)已在 VIEW-CONTRACT.md 中发布。
目标¶
阻止两个 agent 完成重叠编辑后在合并处相遇。扫描已经知道两个工作集何时收敛;hook 的作用是在任一 agent 提交之前,将该知识转化为框架内部的一次机动。
推送计划措辞:“一个 PreToolUse/Edit hook,读取建议信息流,并为较低优先级的 agent 返回 steer、pause 或 wait,记录到胶囊。”
输入¶
- 事件信息流:本地控制面板上的
GET /api/control-plane/events,或者对于没有控制面板的会话,由scripts/proximity-tick.js --json将同一文档写入文件。类型为proximity.advisory的事件,其action.type为transmit或steer,并具有确定性的id。 - hook 自身的 session id。Claude Code 通过 stdin 传递
session_id;ECC 会话适配器将其映射到扫描使用的 ECC2sessions.id。Codex 和 Hermes 使用基于指令的等价机制(见下文)。 - 工具调用:对于 Edit、Write 和 MultiEdit,使用
tool_name和tool_input.file_path。Bash 不在 v1 范围内。
决策¶
对于每个 subject 包含本会话的 advisory 事件:
| 事件 | 本会话是 | 机动 | Hook 结果 |
|---|---|---|---|
traffic,操作 transmit |
任一侧 | transmit:将另一个 agent 的工作集作为系统消息注入 | exit 0,stderr 上输出消息(警告,永不阻塞) |
resolution,操作 steer |
hold |
hold:继续 | exit 0,简短说明 |
resolution,操作 steer |
steer,且 file_path 在另一个 agent 的工作集中 |
pause:停止编辑该文件,直到另一个 agent 的 diff 落地 | exit 2 并附带原因(阻塞这一次工具调用) |
resolution,操作 steer |
steer,且 file_path 不在另一个 agent 的工作集中 |
wait:允许,但被告知只处理不重叠的文件 | exit 0,stderr 上输出消息 |
resolution,操作 steer |
steer,且存在 steer 目标 |
steer:建议 agent 应迁移到的不相交文件或子树 | exit 0,消息;仅当编辑位于共享文件上时 exit 2 |
机动是确定性的:两个 agent 读取同一事件,hold 和 steer 在其中被命名,因此两侧永远不会选择相同的移动。这是 TCAS 协调属性,也是视图集中一次性计算优先权的原因,而不是每个 hook 自行决定。
pause 阻塞单个工具调用,而不是会话。agent 会看到原因并可以选择另一个文件。阻塞受事件的 at 限制:比控制面板的轮询间隔乘以三更旧的事件已过期,hook 不会基于它进行阻塞。
优先级¶
优先权来自事件(action.hold、action.steer)。视图按以下顺序计算它:更多进度,然后更早开始,然后稳定 id(scripts/lib/agent-proximity/distance.js 中的 rightOfWay)。hook 从不重新计算它。
记录到胶囊¶
每个决策都是会话胶囊日志中的一条条目(scripts/lib/eval-harness/capsule.js,哈希链接 NDJSON):
{
"kind": "tcas.decision",
"event_id": "proximity.advisory:session-a|session-b:resolution",
"session": "session-b",
"tool": "Edit",
"file": "src/api/users.js",
"maneuver": "pause",
"blocked": true,
"risk": 1,
"threshold": { "ta": 0.35, "ra": 0.7, "source": "static" },
"at": "2026-09-11T20:01:03.000Z"
}
胶囊是 85% 目标的基线计数器:每周的 rebase 和合并冲突分诊事件数从这些条目加上 git rerere 和冲突标记中计数,在 hook 启用前两周和启用后两周。在那之前不声称任何百分比。
接入位置¶
- Claude Code:
hooks/hooks.json中有一个PreToolUse条目,matcher 为Edit|Write|MultiEdit,通过scripts/hooks/run-with-flags.js路由,以便ECC_HOOK_PROFILE和ECC_DISABLED_HOOKS对其进行门控。脚本位于scripts/hooks/tcas-pre-edit.js,辅助函数位于scripts/lib/control-pane/tcas.js。预算:低于 200 ms,除 loopback 外无网络,任何解析或获取错误均 exit 0。 - Codex:没有 PreToolUse。基于指令的等价机制是 tick 已经写入 ECC2
messages表的proximity_steer/proximity_hold消息,并在下一轮次中呈现。pause降级为强指令。 - Hermes:工具调用路径上的 gateway hook,相同的决策表,相同的胶囊条目。
关闭开关与安全¶
- 默认禁用。通过
ECC_TCAS_HOOK=1或 hook 配置档启用。 - 对控制面板只读。它从不写入 sessions 或 messages 表。
- 不获取租约。持久租约是切片 (c),即 ecc2
session/store.rs中messages旁边的 worktree 租约表;在此之前,pause是每次调用的阻塞,而不是锁,两个 hook 在同一文件上竞争是可能的但无害(两者看到相同的事件和相同的steer)。 - 失败开放。任何错误都是 exit 0,并在 stderr 上输出一行
[TCAS]。
需要随其编写的测试¶
- 决策表:上述每一行一个测试,由 fixture 事件信息流和 stdin 负载驱动。
- 过期:比窗口更旧的事件不会阻塞。
- 失败开放:不可达的控制面板、格式错误的 JSON、缺失的 session id。
- 胶囊:每个决策一条条目,哈希链完整,重放可复现相同字节。
- 集成:两个具有重叠工作集的假会话,较低优先级的一方在共享文件上得到 exit 2,在不相交文件上得到 exit 0。
(b) 的范围外¶
学习阈值、关闭率升级、mesh 模式、跨机器空域、x_sem、x_vec、x_freq 通道(切片 g)以及租约表(切片 c)。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC