Multi-agent coding · several agents, one repository

Coordinate the Agent Fleet

As you scale from one agent to many, coordination becomes the bottleneck. Nool provides the shared state and signaling layer for autonomous teams.

  • Real-time intent contention detection.
  • Synchronized semantic state across distributed agents.
  • Leases prevent concurrent writes to the same symbol; conflicts surface before editing, not at merge.
Three agents, one repository, no shared working tree
# Each agent takes an isolated worktree and an atomic lease on its scope.
# A foreign hold makes the command exit 3 before anything is written.
nool try new api-rate-limit --worktree --nodes src/api/ --intent "Add rate limiting to the public API"
nool try new billing-webhooks --worktree --nodes src/billing/ --intent "Retry failed Paddle webhooks"
nool try new docs-refresh --worktree --nodes docs/ --intent "Refresh the install guide"

# Who holds what, with fencing numbers
nool announce status

# Overlapping intent shows up before anyone commits
nool discover conflicts src/api/ src/billing/

# Land the first branch: 3-way merge against what main changed since the base.
# A true same-symbol conflict stops with diff3 markers and a non-zero exit.
nool try promote api-rate-limit

Every command runs inside the branch's own worktree under .nool/try/. The same flow drives a fleet with nool fleet plan --run --isolation worktree.

The failure mode: parallel agents, one working tree

Running two or three coding agents on the same repository sounds like a throughput multiplier and usually behaves like a coordination tax. In a shared working tree the second agent discovers the first agent's edits when its own build breaks. Git worktrees fix the file-level collision and leave the real one untouched: two agents in separate worktrees can still change the same function from different callers, rename the same field, or both satisfy a task by weakening the same invariant. Their branches merge cleanly, because Git merges text, and the architecture is broken anyway. The more capable the agents, the faster this happens, because capable agents finish tasks that reach across module boundaries.

Leases, worktrees and a real merge

Since Nool 7.0 every agent gets its own room with a lock the others have to check. nool try new with --worktree checks a branch out under .nool/try/<name>/ and, with --nodes, files a lease on the paths that branch will touch. If another agent already holds those paths the command exits with code 3 before it writes anything. Leases carry a fencing number assigned at grant and checked again at seal, so an expired or superseded lease cannot land work even if it looked valid when the agent started. nool announce wait blocks until a scope is free, which replaces messaging the other agent. When the work is done, nool try promote computes what main changed since the branch's base and three-way merges it path by path. If two agents genuinely changed the same symbol, promote stops with diff3 markers and a non-zero exit instead of guessing. Agents on different machines get the same fenced leases through a hub server, and Git-only teams get them as compare-and-swap refs with no server at all.

Semantic conflicts, not just text conflicts

The lease prevents two agents from editing the same scope at once. The semantic check catches what leases cannot: changes in different places that are incompatible together. nool discover conflicts reports overlapping intent before either agent commits, and blast radius at proposal time shows which boundaries a change crosses. With --full validation, Nool checks the merged result against the architecture model and its invariants. In the coordination benchmark that check blocked both real contract breaks in the workload with zero false alarms, on changes whose text would have merged without complaint.

What coordination costs, measured

The nool-bench v2 harness ran nine coordination arms over an identical 38-task workload for ten seeds, with one shared oracle that inspects only the final repository tree. In run 9, on nool 6.14.1, Nool's bare coordination path landed 718.5 valid tasks per hour against 635.4 for git worktrees, spawned 77 child processes against 444, and stalled 0.2 seconds on average against 0.3. With full semantic validation on, throughput was 647.7, not significantly different from git worktrees after correction, while average stall was about 0.2 seconds worse. The published caveats matter: agents were synthetic, timings vary with machine load while correctness metrics did not move across runs, and same-symbol concurrency serializes by design in every arm. The run predates 7.0's fenced leases; the lease protocol as measured then cost more than the git baseline on everything except process count (242.2 tasks per hour, 78 retries, 14.4 percent token waste). A re-run on 7.10.0 is scheduled.

Starting a fleet from a task list

For more than two or three agents, plan rather than launch. nool fleet advise takes each task's footprint and reports whether a single agent, parallel independent agents or a builder with a reviewer quorum fits the signals. nool fleet plan partitions tasks into waves whose node sets are disjoint, with a hard cap on concurrent runs per wave that defaults to eight, and with --run executes each task under its own branch, agent id and lease. With worktree isolation, --overlap parallel runs every task at once and orders the landings; --keep retains branches that landed nothing, for inspection. Everything the fleet does is recorded per task, so a wave that went wrong is replayable rather than a mystery.

Frequently asked questions

Can I run five Claude Code agents on one repository?
Yes. Give each one its own try branch with --worktree and --nodes, or let nool fleet plan partition the tasks into waves whose blast radii do not overlap and run them with --isolation worktree. Each agent gets its own branch, agent identity and lease, and promote merges them back one at a time.
Do I still need git worktrees?
Nool creates them for you under .nool/try/<name>/ and adds what worktrees lack: an atomic lease on the scope, a fencing number checked at seal, and a semantic conflict check before merge. You can keep using plain worktrees; you lose the coordination guarantees.
What happens when two agents change the same function?
The lease stops the second agent from taking that scope while the first holds it. If both changed the same symbol anyway, from different scopes, nool try promote stops with diff3 conflict markers rather than guessing, and same-symbol concurrency serializes by design.
Does governance slow the fleet down?
The benchmark measured governed Nool at 648 valid tasks per hour against 635 for git worktrees, with synthetic agents on nool 6.14.1: not a significant difference after multiple-comparison correction, though average stall was about 0.2 seconds higher. The content-policy arm, which blocks the most violations, trails git by about 52 tasks per hour; you choose how much checking to pay for.
How many agents can run at once?
As many as have disjoint scopes. nool fleet plan caps concurrent runs per wave, eight by default and adjustable with --width, and places overlapping tasks in later waves. With worktree isolation each run has its own branch, identity and lease, so the practical limit is your machine and your budget, not the repository.