Specialists

Build in parallel

One repo, two agents, zero blocking. Give each a worktree instead of a branch, and neither has to wait for the other.

Behrad Mirafshar
Behrad Mirafshar
Founder, Bonanza Design
8 min read

What you end this module with

Specialist, optional. Once you have a working Context Engineering for Claude Code project, some of what's left to build genuinely doesn't depend on the rest. This module is for running two agents on two of those pieces at once, without either one blocking the other or quietly overwriting its work.

You end with two pieces of real work landed on main, each built in its own worktree, and an integration review that checked them together, not just apart.

The lessons

In order. Each one answers a specific way parallel work goes wrong.

  1. Why a branch alone blocks main
    One working copy can only be checked out to one branch at a time. A second agent who wants to start something else has to wait, stash, or step on the first agent's half-finished change.
  2. The Claude Code worktree layout
    One folder per feature, each checked out to its own branch, sitting beside the main folder, not inside it. Main stays on main the whole time.
  3. Naming: dev-doc, worktree, branch
    The three names should be traceable to each other, so anyone can find the dev-doc from the branch or the worktree from either. The exact naming recipe is part of the work-record skill and isn't published here. Keep your own three consistent and it works.
  4. Splitting work that is genuinely independent
    Two units of work are safe to parallelise only if neither one's outcome changes what the other should do. Overlapping edits to the same file are a warning sign, not an automatic blocker: it depends on what kind of edit.
  5. Model roles
    Opus scopes each worktree's piece of work before it starts. Sonnet does the building, one per worktree. Fable reviews the merged result: a model that didn't write either branch, checking both at once.
  6. Integration review
    Two branches with no git conflicts can still be wrong together. The integration review opens the merged files, not the two diffs separately.

The assignment

Starts from

The core project, with two competitors still to add. On your own project, that's whatever two units of work you can genuinely run side by side: see splitting work that's genuinely independent below.

Required output

Two competitors added in two worktrees, merged, reviewed.

Passes when

Both land on main without overwriting each other, and the integration review names at least one thing that had to be reconciled.

Why a branch alone blocks main

One working copy can only be checked out to one branch at a time. That's fine for one agent. It stops being fine the moment a second one wants to start.

A worktree per feature

Main folder stays checked out to main, untouched.
Agent A works in example-app-workstreams/add-search.
Agent B works in example-app-workstreams/fix-checkout-bug at the same time.
Neither folder's state affects the other. Nobody waits.

One branch, one working copy

Agent A checks out feat/add-search and starts editing.
Agent B wants to start fix-checkout-bug in the same folder.
Checking out main now would discard A's half-finished change, or force a stash A has to remember to restore.
B waits, or the two agents take turns.

The Claude Code worktree layout

Demonstrated on a dummy project, not a real one. Main always stays checked out in the project folder; every feature gets its own folder beside it, in a sibling *-workstreams/ directory.

folder layout
~/projects/
├── example-app/                        # main is always checked out here
└── example-app-workstreams/
    ├── add-search/                     # one worktree per feature
    └── fix-checkout-bug/

The exact commands: add a worktree, work in it, remove it once the branch is merged.

worktree add / remove
# from inside example-app, on main
git worktree add ../example-app-workstreams/add-search -b feat/add-search

# work happens in the new folder (main is untouched)
cd ../example-app-workstreams/add-search

# ...build, commit, push, open the PR from here...

# once the branch is merged, remove the worktree
cd ../../example-app
git worktree remove ../example-app-workstreams/add-search

Not the same thing

Claude Code's own built-in worktrees (.claude/worktrees/, inside the project) are for a throwaway experiment you'll discard either way. Real feature work gets a named worktree in the sibling *-workstreams/ folder above, where it survives review and merge like any other branch.

Splitting work that's genuinely independent

More worktrees isn't automatically more speed. Two units of work are only safe to parallelise if neither one's outcome changes what the other should do.

Rejected: Not actually independent. Both would edit the same CLAUDE.md and the same dev-docs/ folder as the project moves forward, so the split isn't actually independent: it's the same files, just at different times. The two agents can't see each other's in-progress decisions, so they'll make inconsistent calls on the same open questions and one merge will have to unpick the other's assumptions. Split on the thing that doesn't need the other's outcome to know what to do: here, that's one competitor per worktree, each adding its own row to data.js.

Model roles

The same three roles as the rest of the course, applied per worktree instead of per session.

  • Opus Scopes each worktree's piece of work before either one starts: this is what makes the split in the section above something you decided, not something that just happened.
  • Sonnet Builds: one Sonnet per worktree, working from that worktree's own scope only.
  • Fable Reviews the merged result: a model that wrote neither branch, checking both at once. That's the integration review, next.

Integration review

Two branches with no git conflicts can still be wrong together. Would you approve this?

Rejected: No integration read. Git only checks whether the same lines changed. Both worktrees added a competitor by appending a row to data.js: no line overlap, so the merge is clean by git's definition. But each worktree's agent assumed it was adding the sixth row, and the page that reads data.js assumed exactly five. The merge is clean and the page is still wrong, and nothing in either diff shows it. Only opening the merged page does. That's what an integration review is for: it reads the merged files, not the two diffs on their own.

Give two pieces of work their own space

One command sets up a separate work area per feature so neither blocks the other, and one prompt reviews the two once they are back together.

One folder, one branch

  • Both jobs share the same folder, so the second one waits for the first to finish before it can even start.
  • Switching between them mid-flight leaves half-finished files behind and loses the thread.

One folder per piece of work

A separate work area per feature (Main stays checked out and clean)
What changes
Setupgit worktree add ../worktrees/add-competitor -b feat/add-competitor: one command, its own folder, its own branch.
Why it frees youEach job has its own files on disk, so two can run at the same time without blocking or overwriting each other.
Finishinggit worktree remove ../worktrees/add-competitor once it is merged, so old work areas do not pile up.
The catchGit merging cleanly is not the same as the two changes fitting together. The integration review prompt is what checks that.

Related reading: Move from idea to evidence shares the research-to-build route two parallel worktrees each still have to follow, and the Claude Agents toolkit covers running several agents on one project beyond just worktrees. Automate recurring work is what each worktree's Sonnet is usually running once it's a repeated procedure, and Run research you can trace is the specialist most worth pairing with a worktree per source.

Unlock all course materials

One email unlocks every material in the course. Verify, and they open in that browser.

FAQ

You can switch branches, but only one at a time, on the one working copy. The moment a second agent wants to start something else, one of them has to stash, commit early, or wait. A worktree gives each agent its own folder and its own checkout, so switching branches for one never disturbs the other.

In a sibling folder next to the project (<project>-workstreams/), with the main project folder always left on main. Claude Code's own built-in .claude/worktrees/ exists too, but that one is for a throwaway experiment you plan to discard, not for feature work you intend to merge.

Ask whether either one's outcome changes what the other should do. If the answer is no, and any file overlap is purely additive (like two competitors each appending their own row), it's safe. If both would touch the same open decision, keep them in one worktree instead of two.

Not necessarily. Git checks line overlap, not meaning. Two branches can each look correct on their own and still be wrong once merged: see the integration review example above, where two clean merges silently assumed the same row position.

You need some consistent link between the three, so you, or anyone else, can find one from another. The exact naming recipe we use internally is part of a separate, unpublished skill; pick your own convention and keep it consistent, and it does the same job.

The same layout still helps: one worktree per feature means you can leave a half-finished change checked out in its own folder, switch to a hotfix on main without touching it, and come back later exactly where you left off.

Want your team actually running two agents at once?

A working session on splitting real work, wiring up worktrees, and reviewing what comes back.

Book the workshopLearn more