Different agents should not grab the same tree.
"Isolate by directory, coordinate by task ID." Two planes, do not interfere with each other.
A difficult problem with parallel agents
s09-s11 allows you to start multiple teammates at the same time, but there is a pitfall: They are all in the same working directory. alice is changing auth.py, and bob is also changing auth.py at the same time - git conflicts, file confusion, and mutual contamination of tests.
The solution to s12 is git worktree: for the same warehouse, you can checkout different branches in different directories through git worktree add. Each agent gets its own worktree and works in its own directory, invisible to each other.
my-repo/ # Main workspace (for lead) .worktrees/ alice-auth/ # alice’s isolation directory (branch: wt/alice-auth) bob-api/ # bob’s isolation directory (branch: wt/bob-api) index.json # worktree registry events.jsonl # Life cycle event log
Division of labor in two planes
s12 Explicitly split the system into two planes:
- Control plane: JSON file in
.tasks/. Task is an abstract unit of "what to do", including dependencies, owner, and status. - Execution plane: Directory in
.worktrees/. Worktree is the physical container of "where to do it", a directory + a branch.
The two are bidirectionally bound through task.worktree and worktree.task_id.
This kind of decoupling allows you to: Reuse the task management mechanism but change the execution environment (for example, not git worktree, but docker container). Or change the task mechanism but reuse the worktree (for example, not a JSON file but a database).
life cycle demonstration
Go through it completely below: create task → create worktree → run commands → keep or remove. Each step is recorded in the Event log (events.jsonl), which is used for observability in production.
keep vs remove
There are two endings when worktree completes its mission:
remove:git worktree remove --force, directory deletion. Branches are also generally cleaned up. It's equivalent to "I don't want this exploration anymore."keep: Markstatus: keptonly in.worktrees/index.json, the physical directory is reserved. It's equivalent to "I'm going to get this result, wait until I merge it."
Common mode: subagent runs an experimental refactor → runs with good results → keep → human review → merges into the main branch → manually removes. Poor effect? Just remove and throw it away.