LEARN CLAUDE CODE

S12: Worktree + Task Isolation — 目录隔离

问题:共享目录导致文件冲突

到 S11 为止,多个 Teammate 都在同一个工作目录里操作。这在实际中会导致严重的文件冲突——agent-A 正在修改 src/auth.ts,agent-B 同时也在改同一个文件。结果就是覆盖、冲突、代码丢失。

冲突场景: Agent-A: 打开 src/auth.ts → 修改第30行 → 保存 Agent-B: 打开 src/auth.ts → 修改第45行 → 保存 (覆盖了 A 的修改!) ┌─── 共享工作目录 ───┐ │ src/ │ │ auth.ts ← A 在改│ │ auth.ts ← B 也在改│ ← 冲突! │ db.ts │ │ api.ts │ └────────────────────┘

解法:Git Worktree 绑定任务 ID

Git Worktree 是 Git 的一个内置功能——它允许从同一个仓库创建多个工作目录,每个工作目录有自己独立的分支和文件。S12 的设计是:每个任务绑定一个 Worktree,实现完全的文件隔离。

隔离方案: ┌─── .worktrees/task-001/ ───┐ ┌─── .worktrees/task-002/ ───┐ │ branch: task-001 │ │ branch: task-002 │ │ src/ │ │ src/ │ │ auth.ts ← A 独占修改 │ │ auth.ts ← B 独占修改 │ │ db.ts │ │ db.ts │ │ api.ts │ │ api.ts │ └───────────────────────────┘ └───────────────────────────┘ │ │ └───────── 互不干扰 ────────────────┘ │ 最后通过 Git merge 合并

双平面架构

S12 引入了一个清晰的架构分离——控制平面和执行平面:

平面目录内容角色
Control Plane(控制平面) .tasks/ 任务 JSON 文件、状态、依赖关系 描述"要做什么"——任务的元数据和协调信息
Execution Plane(执行平面) .worktrees/ 每个任务的独立工作目录、Git 分支 执行"怎么做"——实际的代码修改在这里发生
双平面架构图: ┌──────────────────────────────────────────────────────────┐ │ Control Plane │ │ │ │ .tasks/ │ │ ├── task-001.json { status: "in_progress", ... } │ │ ├── task-002.json { status: "pending", ... } │ │ └── task-003.json { status: "completed", ... } │ │ │ │ 协调层:任务状态、依赖关系、Owner 分配 │ ├──────────────────────────────────────────────────────────┤ │ Execution Plane │ │ │ │ .worktrees/ │ │ ├── task-001/ ← Agent-A 的独立工作目录 │ │ │ └── (完整的项目文件副本,branch: task-001) │ │ ├── task-002/ ← Agent-B 的独立工作目录 │ │ │ └── (完整的项目文件副本,branch: task-002) │ │ └── events.jsonl ← 事件流 │ │ │ │ 隔离层:每个任务独立修改文件,互不干扰 │ └──────────────────────────────────────────────────────────┘

Events 流

.worktrees/events.jsonl 记录了所有 Worktree 相关的事件——创建、切换、合并、删除。这是一个只追加的日志文件,用于审计和崩溃恢复。

{"event":"worktree_created", "taskId":"task-001", "branch":"task-001", "ts":"2025-01-15T10:00:00Z"}
{"event":"agent_entered", "taskId":"task-001", "agentId":"agent-frontend", "ts":"2025-01-15T10:00:01Z"}
{"event":"agent_exited", "taskId":"task-001", "agentId":"agent-frontend", "ts":"2025-01-15T11:30:00Z"}
{"event":"worktree_merged", "taskId":"task-001", "branch":"task-001", "ts":"2025-01-15T11:35:00Z"}

崩溃恢复:从磁盘状态重建

如果代理进程崩溃了怎么办?S12 的设计保证了完全可恢复——因为所有状态都在磁盘上:

  1. 扫描 .tasks/——重建任务图,知道哪些任务在进行中
  2. 扫描 .worktrees/——知道哪些 Worktree 存在、对应哪个任务
  3. 读取 events.jsonl——知道崩溃前的最后状态
  4. 恢复——对于 in_progress 状态的任务,重新启动代理进入对应的 Worktree 继续工作
进程崩溃
重启
扫描 .tasks/
扫描 .worktrees/
重建状态
继续执行

对比:共享目录 vs Worktree 隔离

维度共享目录(S09-S11)Worktree 隔离(S12)
文件冲突频繁发生不可能(物理隔离)
Git 操作所有代理共用一个分支每个任务独立分支
合并策略需要锁或协调标准 Git merge/rebase
回滚困难——修改交织简单——删除 Worktree 即可
崩溃恢复状态不确定从磁盘完全重建
磁盘占用一份每任务一份副本(Git 优化后较小)

对应官方工具

EnterWorktreeTool / ExitWorktreeTool

EnterWorktreeTool 创建或进入一个与任务绑定的 Git Worktree,自动创建对应分支。ExitWorktreeTool 退出 Worktree 并回到主目录。官方实现自动处理了 Worktree 的创建、分支管理和清理,代理只需要说"进入"和"退出"。

关键洞察:S12 的双平面架构体现了一个重要的工程原则——控制平面和数据平面分离。.tasks/ 是控制平面(协调信息),.worktrees/ 是数据平面(实际执行)。这和 Kubernetes 的架构思想一致——etcd 存控制状态,Pod 做实际计算。分离后,崩溃恢复变得简单,因为控制状态是独立且持久的。