Worktree + Изоляция задач
КоллаборацияIsolate by Directory
Each works in its own directory; tasks manage goals, worktrees manage directories, bound by ID
s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > [ s12 ]
"Каждый работает в своём каталоге, без помех" -- задачи управляют целями, worktrees управляют каталогами, связаны по ID.
Проблема
В s11 агенты могут забирать и завершать задачи автономно. Но каждая задача выполняется в общем каталоге. Два агента, рефакторящие разные модули одновременно, столкнутся: агент A модифицирует config.py, агент B модифицирует config.py, неустановленные изменения смешиваются, и никто не может чисто откатиться.
Доска задач отслеживает что делать, но не имеет мнения где это делать. Решение: дать каждой задаче свой собственный git worktree. Задачи управляют целями, worktrees управляют контекстом выполнения. Связать по ID задачи.
Решение
План управления (.tasks/) План выполнения (.worktrees/)
+------------------+ +------------------------+
| task_1.json | | auth-refactor/ |
| status: in_progress <------> branch: wt/auth-refactor
| worktree: "auth-refactor" | task_id: 1 |
+------------------+ +------------------------+
| task_2.json | | ui-login/ |
| status: pending <------> branch: wt/ui-login
| worktree: "ui-login" | task_id: 2 |
+------------------+ +------------------------+
|
index.json (worktree registry)
events.jsonl (lifecycle log)
Машины состояний:
Задача: pending -> in_progress -> completed
Worktree: absent -> active -> removed | kept
Как Это Работает
- Создать задачу. Сначала персистировать цель.
TASKS.create("Implement auth refactor")
# -> .tasks/task_1.json status=pending worktree=""
- Создать worktree и связать с задачей. Передача
task_idавтоматически переводит задачу вin_progress.
WORKTREES.create("auth-refactor", task_id=1)
# -> git worktree add -b wt/auth-refactor .worktrees/auth-refactor HEAD
# -> index.json gets new entry, task_1.json gets worktree="auth-refactor"
Связь записывает состояние с обеих сторон:
def bind_worktree(self, task_id, worktree):
task = self._load(task_id)
task["worktree"] = worktree
if task["status"] == "pending":
task["status"] = "in_progress"
self._save(task)
- Выполнять команды в worktree.
cwdуказывает на изолированный каталог.
subprocess.run(command, shell=True, cwd=worktree_path,
capture_output=True, text=True, timeout=300)
- Завершить. Два выбора:
worktree_keep(name)-- сохранить каталог для последующей работы.worktree_remove(name, complete_task=True)-- удалить каталог, завершить связанную задачу, отправить событие. Один вызов обрабатывает демонтаж + завершение.
def remove(self, name, force=False, complete_task=False):
self._run_git(["worktree", "remove", wt["path"]])
if complete_task and wt.get("task_id") is not None:
self.tasks.update(wt["task_id"], status="completed")
self.tasks.unbind_worktree(wt["task_id"])
self.events.emit("task.completed", ...)
- Поток событий. Каждый этап жизненного цикла отправляет в
.worktrees/events.jsonl:
{
"event": "worktree.remove.after",
"task": { "id": 1, "status": "completed" },
"worktree": { "name": "auth-refactor", "status": "removed" },
"ts": 1730000000
}
События: worktree.create.before/after/failed, worktree.remove.before/after/failed, worktree.keep, task.completed.
После сбоя состояние восстанавливается из .tasks/ + .worktrees/index.json на диске. Память разговора непостоянна; состояние файла долговечно.
Что Изменилось с s11
| Компонент | До (s11) | После (s12) |
|---|---|---|
| Координация | Доска задач (owner/статус) | Доска задач + явная связь worktree |
| Область выполнения | Общий каталог | Изолированный каталог на задачу |
| Восстановление | Только статус задачи | Статус задачи + индекс worktree |
| Демонтаж | Завершение задачи | Завершение задачи + явный keep/remove |
| Видимость цикла | Неявная в логах | Явные события в .worktrees/events.jsonl |
Попробуйте
python agents/s12_worktree_task_isolation.py
Создать задачи для backend auth и страницы frontend login, затем перечислить задачи.Создать worktree "auth-refactor" для задачи 1, затем связать задачу 2 с новым worktree "ui-login".Выполнить "git status --short" в worktree "auth-refactor".Сохранить worktree "ui-login", затем перечислить worktrees и просмотреть события.Удалить worktree "auth-refactor" с complete_task=true, затем перечислить задачи/worktrees/события.
