Agents

How to Keep Parallel AI Work From Colliding

A worktree gives each AI worker separate files. Safe parallel work still needs bounded ownership, budgets, independent review, collision tests, and one integration owner.

By Vladislav Zhirnov13 min read

Use this when

you need the work to hold up in real use.

Decide when to run AI coding agents in parallel and implement the ownership, budget, review, collision, and integration controls that worktrees do not provide.

Headline, Separate Files. Shared Risk., beside one conductor blocking incompatible outputs from three mechanical workers in isolated bays.
Separate workspaces prevent direct file overwrites. The conductor still has to stop incompatible decisions at one integration threshold.

Three AI workers start from the same clean commit. Each gets a separate worktree. One changes session expiry in the runtime. One updates the documentation. One adds the tests.

No files overlap. Every branch is clean. The runtime sets expiry to 30 minutes. The documentation promises 24 hours. The test lane never owned the decision, so it checks a third interpretation.

Git did its job. The work still collided.

This is the part people miss when they turn on parallel coding agents. A worktree isolates a checkout. It does not assign ownership, settle shared assumptions, cap the combined budget, choose an independent reviewer, or decide which result may cross the integration threshold.

I learned that distinction while building WarpOS, my agentic operating-system project. Worktree-required dispatch helped keep builders out of the live repository. It did not remove the need for scope contracts, lane records, budgets, coverage checks, and a separate integration decision.

This article assumes you have already chosen work worth delegating. The question here is narrower: should these packages run sequentially, in parallel with review, or remain human-owned? If they run in parallel, what contract keeps three clean branches from becoming one expensive argument?

Key takeaways

  • Use worktrees to isolate file edits, not to infer that product decisions or dependencies are separate.
  • Keep work sequential when packages depend on the same unsettled decision or interface.
  • Give every parallel lane explicit owned and prohibited scope, budgets, return evidence, a reviewer, and an integration owner.
  • Run semantic collision checks after file-path checks and block unresolved shared ownership.
  • Let one independent verdict control what crosses the integration threshold.

What does a worktree actually isolate?

A Git worktree is another working tree attached to the same repository. It gives a worker a separate directory, checkout, HEAD, and index. That is real protection. Edits in one directory do not immediately overwrite the files in another.

The repository is still shared. Git's current manual says linked worktrees share everything except per-worktree files such as HEAD and the index. Most refs are shared. More important for an AI workflow, the product, requirements, dependencies, outside services, cost pool, and release target remain shared even when the files do not.

Claude Code's current documentation draws the same useful line. Its worktree guide describes file isolation, then points to subagents and agent teams for coordination. Its parallel-agent guide says worktrees isolate files while agent-team work still needs partitioned ownership. That is a current product description, not proof that every conflict is caught.

Use a worktree to answer: Can this worker edit without touching another worker's checkout? File isolation is necessary once writers fan out. It is not coordination.

When is parallel work worth the coordination cost?

Parallelism earns its keep when the work packages are independently useful, can make progress without waiting on the same decisions, and can be reviewed before their outputs meet. The speedup must be larger than the cost of scoping, monitoring, reviewing, resolving conflicts, and integrating.

That calculation gets worse quickly when workers touch the same interface, depend on an unsettled requirement, need the same scarce tool, or require one person's judgment. Current Claude Code documentation also warns that parallel workers multiply token use, and its agent-team guide recommends a single session for sequential work, same-file edits, or work with many dependencies.

Do not choose PARALLEL_WITH_REVIEW because three workers are available. Choose it because three packages can remain coherent until a reviewer deliberately brings them together.

Choose the execution shape from dependency and review risk, not worker availability.
VerdictUse it whenRequired controlTypical example
KEEP_SEQUENTIALWork shares a decision, interface, file, or dependency that must settle firstOne owner completes the prerequisite; later work starts from the accepted resultChoose the session-expiry policy before runtime, docs, and tests encode it
PARALLEL_WITH_REVIEWPackages have distinct ownership, limited dependencies, and evidence that can be compared at one integration gateBounded lane contracts, independent reviewer, collision tests, integration order, and one integration ownerUI copy, analytics query, and regression tests for an already frozen behavior
KEEP_HUMAN_OWNEDThe choice is irreversible, accountable, privacy-sensitive, safety-critical, or impossible to review from available evidenceA named person makes or explicitly approves the decision before agents implement bounded partsA production deletion, legal position, pricing exception, or sensitive customer message

What should every parallel lane own?

A lane is a bounded work contract, not a branch name. The contract should make unauthorized overlap visible before the merge.

Files are only one part of owned scope. Add product decisions, data contracts, routes, schemas, prompts, metrics definitions, outside actions, and user promises when they matter.

The session-expiry example has three different files but one shared decision. Assign that policy to one lane. The runtime, documentation, and test lanes then depend on the same accepted decision record. If two lanes both claim it, the system should stop before integration, even when Git reports no conflict.

Budgets belong in the same contract. Parallel workers can turn a cheap task into several simultaneous tool calls, review queues, and retries. Set ceilings per lane and for the whole run. A lane that spends its way past the value of parallelism has failed even if its branch is technically valid.

The smallest useful contract for a bounded parallel lane.
FieldWhat it controls
lane_idStable identity for the workstream and its records
ownerOne worker accountable for returning the lane packet
workspaceExact worktree, branch, sandbox, or read-only environment
owned_scopeFiles, systems, product decisions, and interfaces the lane may change
prohibited_scopeFiles, systems, actions, and decisions the lane must not change
dependenciesAccepted inputs the lane may rely on, with revision or decision identity
shared_decisionsNamed decisions that need one owner before dependent lanes proceed
budgetTime, tokens, cost, tools, retries, privacy, and risk ceilings
return_packetArtifact, changed scope, test receipts, decisions, risks, and recovery state
reviewerIndependent person or system allowed to return a binding verdict
verdictsAPPROVED, REVISE, BLOCKED, or HUMAN_DECISION_REQUIRED
integration_orderDependencies and sequence for combining accepted outputs
integration_ownerOne accountable owner for the final combined state
stop_conditionsOverlap, drift, budget, evidence, permission, or recovery failures that halt the lane

What happens when file isolation passes but ownership collides?

I built a side-effect-free Node.js fixture to test the distinction. It creates three temporary workspaces, writes one different file into each, validates the lane fields, checks duplicate file claims, and then checks duplicate product-decision claims.

The runtime lane owns src/auth/session.ts and proposes a 30-minute session-expiry-policy. The documentation lane owns docs/auth.md and proposes 24 hours for the same policy. The test lane owns tests/auth/session.test.ts and a separate coverage decision.

The first check returns green. Three workspaces exist. Every owned path is different. File isolation passes. The second check blocks. Two lanes claim session-expiry-policy with incompatible values. The final verdict is BLOCKED_SEMANTIC_OWNERSHIP_CONFLICT.

The resolution is boring and correct: give the policy to one owner, make the other lanes depend on that accepted decision, and rerun independent review.

The experiment does not prove that exact decision IDs catch every semantic conflict. Under-declared scope still slips through. It proves one narrower point: a green file-isolation check cannot support a claim that parallel work is safe to integrate.

The file-level checks pass before the semantic ownership gate blocks integration.
CheckObserved resultVerdict
Workspace isolationThree distinct temporary workspacesPASS
Contract completenessRequired lane fields presentPASS
File ownershipZero duplicate path claimsPASS
Decision ownershipTwo lanes claim one policy with 30-minute and 24-hour valuesBLOCKED
IntegrationShared decision owner unresolvedBLOCKED_SEMANTIC_OWNERSHIP_CONFLICT

How should independent review and integration work?

Do not let each worker approve its own lane and call the bundle reviewed. The integration reviewer has a different job from the builders.

The reviewer compares all return packets against the same accepted requirements and shared decisions. They check the combined diff, not three summaries in isolation. They verify prohibited scope, dependencies, budgets, evidence, migration order, and whether one result invalidates another.

The independent verdict is binding. REVISE returns the lane with specific failed criteria. BLOCKED stops integration when ownership or evidence is unresolved. HUMAN_DECISION_REQUIRED names the decision and accountable person. Only APPROVED moves the lane to the integration owner.

The integration owner then combines approved work in dependency order, reruns the combined checks, and verifies the actual target. Three green lane tests can still fail after merge because the interaction exists only in the combined state.

What did WarpOS teach me about parallel work?

WarpOS already required build-chain roles to run in isolated worktrees. Its dispatch validator rejected a missing worktree path and rejected the canonical repository root. Its lane documentation captured the worktree HEAD for drift detection. Those controls dealt with a real class of accidents.

The frozen code also shows why I no longer treat isolation as the full answer. Its documented conflict check compared declared surface strings literally. Under-declared surfaces could slip through. src/foo.js and src/foo.ts did not collide even if they touched the same conceptual module. The lane cap was advisory. The scope-contract hook blocked missing or malformed scope declarations during normal operation, but its header explicitly said hook bugs or load failures were fail-open.

That evidence is useful because it includes the debt. The system had worktree enforcement, role budgets, scope contracts, backed completion records, artifact proof, and cross-provider review rules. It also had report-only review-lane behavior and detection boundaries that could miss undeclared semantic overlap.

The hardening lesson is not that WarpOS solved parallel agents. It is this: every isolation control needs a named consumer, an enforcement state, a failure mode, and an integration decision. If a control only warns, say it warns. If scope is self-declared, test under-declaration. If a hook can fail open, put a binding gate somewhere else.

Which conditions should stop parallel work?

A stop condition is useful only when the workflow cannot quietly continue past it.

When a lane blocks, do not keep all workers running while ownership gets debated. Freeze dependent lanes, record the decision that is missing, and either serialize the work or return it to a human owner.

How do you run the first bounded parallel job this week?

Pick one job with two or three packages that are independently useful. Do not start with a repo-wide migration, production release, or unsettled architecture.

Write the shared decisions first. Create one lane contract per package. Give each lane its own workspace and one owner. Name prohibited scope. Set per-lane and total budgets. Define the return packet, independent reviewer, integration order, and stop conditions before dispatch.

Plant one collision fixture. Give two lanes different files but the same named decision. Your gate should block them. Then remove the overlap, run the lanes, compare the return packets, and integrate in one owned sequence.

After the contract works once, expand it from real failures. Keep the first version small enough that the integration owner will actually read every lane packet.

FAQ

Do Git worktrees prevent AI agents from conflicting?

They prevent workers from editing the same checkout directly. They do not prevent overlapping product decisions, incompatible assumptions, shared dependency changes, duplicated cost, weak review, or unsafe integration.

Should every AI coding agent get its own worktree?

Give each parallel writing worker an isolated workspace when file edits could collide. Read-only research may not need one. Isolation still needs a lane contract and integration review.

When should AI work stay sequential?

Keep work sequential when packages share an unsettled decision, interface, file, or dependency, or when one result must be accepted before the next can be specified correctly.

What is a semantic conflict between AI agents?

A semantic conflict happens when two changes are individually valid at the file level but make incompatible claims about the same behavior, interface, policy, requirement, or product decision.

Who should review parallel AI work?

Use an independent reviewer who compares all lane packets against the same accepted requirements and shared decisions. The integration owner should combine only approved work and rerun checks on the combined state.

How many AI agents should run in parallel?

Use the smallest number of lanes that creates meaningful independent progress. Stop adding workers when coordination, review, budget, or integration cost approaches the time saved.

Conclusion

A worktree gives an AI worker a separate place to edit. That matters. It does not give the work a separate reality.

The product decision, dependency graph, budget, reviewer, and release target still meet at one integration threshold. Name their owners before the workers start. Require evidence when they return. Let one independent verdict control what crosses.

Separate files. Shared risk.

Sources

Next move

Want me to audit your AI workflow?

Bring one product-delivery bottleneck, operations workflow, or early MVP. I will help decide what AI should own, where human judgment stays, and how to measure the result.

Talk about an AI workflow

About the author

Portrait-style placeholder for Vladislav Zhirnov

Vladislav Zhirnov

Product and AI systems leader

Vlad helps founders, product teams, and operations leaders use AI to improve delivery, streamline work, and build useful MVPs.

Related articles

Keep going

All articles