cd /news/ai-agents/one-worktree-per-task-where-a-coding… · home › topics › ai-agents › article
[ARTICLE · art-141702] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

One worktree per task: where a coding agent's work actually goes

A developer built Ordewell, an Apache 2.0 tool that gives each parallel coding-agent task its own git worktree so concurrent sessions cannot silently overwrite each other's files. The system creates worktrees from the run's integration tip, links in ignored artifacts like node_modules and virtualenvs, and lands each task as a merge commit on an integration branch through a serialized queue, aborting and preserving refs when a task fails to land. Conflicts are surfaced to the user rather than resolved silently by a model.

by read5 min views1 publishedSep 29, 2026

Run two coding agents at once in the same checkout and you have two writers on one tree. Both sessions look fine, both print a marker, and one has already overwritten the other's file. The fix is not a better prompt, it is a boundary: every task gets its own git worktree, and the results stay apart until you decide what lands.

Disclosure: I build Ordewell, so this is how it does it rather than a survey of the field. It is free and Apache 2.0. The mechanics matter whether or not you install it, because every harness that runs several sessions answers the same question.

The first version is a directory and a loop: several sessions run in the workspace root, and the prompt asks the planner to keep parallel tasks on different files. That is advice to a model, not a boundary.

It fails in both directions. Two tasks that genuinely need the same file get serialized behind an invented dependency, which costs the parallelism you were paying for. And when the overlap happens anyway, it fails silently: runner B rewrites the file runner A just changed, A's completion marker still appears, and A verifies as passed against a tree that no longer holds A's work. There is a second loss too: no per-task record of what changed, so no way to undo one task without unpicking the others.

When the workspace is a git repository, each task runs in its own worktree, created from the integration tip of the run rather than from your working tree. The worktrees sit under .ordewell/worktrees//-, which is already git-ignored, and each task carries its own branch.

The runner is handed a cwd and nothing else. Git never enters the runner adapters, so Claude Code, Codex and OpenCode cannot develop three different ideas about how work is isolated. A workspace that holds more than one repository is treated as a group: one worktree per repository per task, all on the same branch name.

A fresh worktree with no node_modules cannot run your tests, so ignored artifacts are linked in: dependency folders, virtualenvs, environment files, agent config directories. .ordewell/ is never linked, because session and skills state belongs at the main root where a runner cannot corrupt it. A configured setup command replaces the linking where sharing is wrong.

Two details bite. Links are recorded per task, because an ignore rule such as node_modules/ does not match a symlink, and without that record they would be committed into the task's branch. And a whole folder link is wrong for workspaces: npm and pnpm install a workspace package as a link inside node_modules, which through a folder link resolves from the main checkout, so a task changing a package tests its dependents against the stale copy there. Entries are mirrored one at a time instead, and workspace links are recreated to resolve inside the worktree.

Isolation makes overlap safe. It does not make overlap free. Verdicts can arrive at the same moment, so landing is a queue: one task at a time, with the lowest plan order going first among the tasks already waiting.

Each task lands as a merge commit on the run's integration branch, not as loose files copied over your code. A merge commit preserves any commits the runner made itself, shows who did what in git log, and leaves the task branch an ancestor, which is what makes deleting it safe.

A task that did not land is not a lost cause. The merge is aborted and both refs are kept, so the work is still there to inspect, retry or hand to a repair attempt. Landing across several repositories is atomic: if one repository conflicts, the merges already made for that task in the others are rolled back, so the task is conflicted as a whole rather than half landed.

Resolving a conflict means deciding which of two changes wins. Handing that to a model silently rewrites a merge nobody reviewed, and it makes the outcome depend on a model's word, the thing an evidence based verdict exists to avoid.

So the conflict is surfaced with the files that conflicted, and resolving it is opt in. A bounded repair attempt can run as a new attempt of the conflicted task in its own worktree, and it still lands through the same queue with the same checks: its branch has to contain the tip the repair started from and add no leftover conflict markers. If the repair did not really bring the branch along, it conflicts again rather than being taken at its word.

Ordewell never merges into the branch you have checked out on its own. That is the one irreversible step, and your tree may hold work in progress. A run ends with the integration branch parked for review, the base ref it came from, and a list of what landed.

Merging on request preflights every repository first: no merge already in progress, no conflict against what you have checked out, no uncommitted edit to a file the merge would change. If any repository fails the preflight, nothing is merged anywhere. Discarding removes the worktrees and task branches, and never deletes landed work you have not merged yourself.

ordewell run --stash
ordewell run --without-isolation

ordewell handoff review
ordewell handoff merge
ordewell handoff discard

The decisions above are written down in the repository rather than summarised from memory: ADR 0013, worktree isolation, ADR 0014, multi-repo workspaces, ADR 0015, conflict repair, the isolation interface, and github.com/ordewell/ordewell.

── more in #ai-agents 4 stories · sorted by recency
── more on @ordewell 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/one-worktree-per-tas…] indexed:0 read:5min 2026-09-29 · —