analysis_claude_code/docs/ja/s12-worktree-task-isolation.md
CrazyBoyM a9c71002d2 the model is the agent, the code is the harness
Comprehensive rewrite establishing the harness engineering narrative
across the entire repository.

README (EN/ZH/JA): added "The Model IS the Agent" manifesto with
historical proof (DQN, OpenAI Five, AlphaStar, Tencent Jueyu),
"What an Agent Is NOT" critique, harness engineer role definition,
"Why Claude Code" as masterclass in harness design, and universe
vision. Consistent framing: model = driver, harness = vehicle.

docs (36 files, 3 languages): injected one-line "Harness layer"
callout after the motto in every session document (s01-s12).

agents (13 Python files): added harness framing comment before
each module docstring.

skills/agent-philosophy.md: full rewrite aligned with harness
narrative.
2026-03-18 01:19:34 +08:00

5.5 KiB

s12: Worktree + Task Isolation

s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > [ s12 ]

"各自のディレクトリで作業し、互いに干渉しない" -- タスクは目標を管理、worktree はディレクトリを管理、IDで紐付け。

Harness 層: ディレクトリ隔離 -- 決して衝突しない並列実行レーン。

問題

s11までにエージェントはタスクを自律的に確保して完了できるようになった。しかし全タスクが1つの共有ディレクトリで走る。2つのエージェントが同時に異なるモジュールをリファクタリングすると衝突する: 片方がconfig.pyを編集し、もう片方もconfig.pyを編集し、未コミットの変更が混ざり合い、どちらもクリーンにロールバックできない。

タスクボードは何をやるかを追跡するが、どこでやるかには関知しない。解決策: 各タスクに専用のgit worktreeディレクトリを与える。タスクが目標を管理し、worktreeが実行コンテキストを管理する。タスクIDで紐付ける。

解決策

Control plane (.tasks/)             Execution plane (.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)

State machines:
  Task:     pending -> in_progress -> completed
  Worktree: absent  -> active      -> removed | kept

仕組み

  1. タスクを作成する。 まず目標を永続化する。
TASKS.create("Implement auth refactor")
# -> .tasks/task_1.json  status=pending  worktree=""
  1. 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)
  1. worktree内でコマンドを実行する。 cwdが分離ディレクトリを指す。
subprocess.run(command, shell=True, cwd=worktree_path,
               capture_output=True, text=True, timeout=300)
  1. 終了処理。 2つの選択肢:
    • worktree_keep(name) -- ディレクトリを保持する。
    • worktree_remove(name, complete_task=True) -- ディレクトリを削除し、紐付けられたタスクを完了し、イベントを発行する。1回の呼び出しで後片付けと完了を処理する。
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", ...)
  1. イベントストリーム。 ライフサイクルの各ステップが.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からの変更点

Component Before (s11) After (s12)
Coordination Task board (owner/status) Task board + explicit worktree binding
Execution scope Shared directory Task-scoped isolated directory
Recoverability Task status only Task status + worktree index
Teardown Task completion Task completion + explicit keep/remove
Lifecycle visibility Implicit in logs Explicit events in .worktrees/events.jsonl

試してみる

cd learn-claude-code
python agents/s12_worktree_task_isolation.py
  1. Create tasks for backend auth and frontend login page, then list tasks.
  2. Create worktree "auth-refactor" for task 1, then bind task 2 to a new worktree "ui-login".
  3. Run "git status --short" in worktree "auth-refactor".
  4. Keep worktree "ui-login", then list worktrees and inspect events.
  5. Remove worktree "auth-refactor" with complete_task=true, then list tasks/worktrees/events.