Worktree discipline for parallel agents

Checked 22 Sep 2026 · By Luke Czak

ArticleHow to Use AIFree to read

Every parallel task gets its own isolated working directory, and every one is merged or explicitly surfaced before the orchestrator exits. This is the rule I learned by losing work to an orphaned one.

The moment you run more than one agent against the same repository at the same time, you need an answer to a question that never comes up with a single session: what happens when two workers want to change the same branch at once. The naive answer, let them both work on the checked-out branch and hope their edits do not collide, fails almost immediately, because even non-conflicting edits stomp on each other’s working-directory state, and one worker’s half-finished change is visible to the other as a fact about the repo rather than a work in progress.

The fix is an isolated working tree per parallel task. Each worker gets its own, checked out from the same commit the orchestrating session is on, so it has an isolated working directory and its own branch to commit to, while still sharing the underlying object store with every other working tree of the same repo. Nothing one worker does is visible to another until it is deliberately merged, and nothing an agent commits mid-task can be mistaken for the state of the shared branch, because it is not on the shared branch yet.

The part that actually matters is not the creation, that is one command and easy to remember. It is the teardown. A working tree that finishes its task and gets merged cleanly is fine. One that gets abandoned, because the session that owned it ended, crashed, or was simply forgotten about once its output looked done, is not fine, and it is not obviously not-fine, which is what makes it dangerous. An abandoned tree still holds a real branch with real commits on disk. Nothing errors. Nothing warns. The work just sits there, disconnected from the branch anyone is actually building on, until someone happens to list them and notices an entry they cannot immediately explain.

I lost real work this way before I made the rule explicit. A parallel run finished, the summary looked complete, and I moved on without checking that every tree it had opened was actually merged back. Weeks later the branch was still sitting there, unmerged, holding a fix nobody remembered was needed because the orchestrating session that knew the context was long gone. The commits were recoverable, nothing was destroyed, but the knowledge of why they mattered nearly was not, and reconstructing intent from a stale diff is much harder than reviewing it fresh.

The rule now is unconditional: before any session that spawned parallel working trees is allowed to consider itself finished, it lists every one of them and accounts for every single entry. Each one resolves to exactly one of two states. Either it has been merged back into the active branch, with a non-fast-forward merge so the merge itself is visible in history rather than fast-forwarded into invisibility, with its gates re-run against the merged result, and then removed. Or it is explicitly surfaced as unmerged, with the branch preserved and a clear note about why it was not merged, so the decision to leave it is a decision someone made on purpose rather than an oversight nobody caught.

What this rule refuses to allow is the silent third option, a tree that is neither merged nor flagged, just left, because the session that created it ran out of context or attention before doing the accounting. That third option is exactly how work gets lost: not through any single dramatic failure, but through nobody being the one whose job it was to check.

The overhead of enforcing this is small compared to the cost of skipping it. Listing them takes a second to run and a moment to read. Losing a genuine fix because nobody merged the branch that held it costs far more than that, and it costs it silently, which is the worse half of the problem, you do not find out until you go looking for work that turns out to have never made it into the branch everyone else is building on.

Comments (0)

Sign in to comment.