Parallel Coding Agents for Large Refactors
A coding agent can often complete a focused change: fix one bug, update one component, or repair one failing test.
A repository-wide refactor is different. It may touch hundreds of files, cross several ownership boundaries, and require intermediate states that must continue to build. One agent can run out of useful context, repeat an early mistake across the codebase, or stop after completing only part of the migration.
Parallel-agent orchestration addresses that problem by treating the refactor as a coordinated program of smaller changes.
In beginner terms:
- map the large change
- divide it into reviewable batches
- identify which batches depend on others
- give ready batches to isolated coding agents
- verify every result
- merge accepted batches in a controlled order
- run whole-system checks before completing the migration
The important idea is not “use more agents.” It is make the work divisible, independently verifiable, and safe to integrate.
How This Differs From One Long-Running Agent
Section titled “How This Differs From One Long-Running Agent”A single long-running agent owns one conversation and one evolving context. It can inspect, plan, edit, test, and recover over many steps.
Parallel orchestration creates several bounded workers. A coordinator, usually application code plus human oversight, decides what each worker receives and when its result can be accepted.
| One long-running agent | Parallel coding agents |
|---|---|
| One task trajectory | Several bounded task trajectories |
| One working copy | Separate branches, worktrees, or sandboxes |
| Context accumulates in one conversation | Each worker receives task-specific context |
| Fewer merge conflicts | Faster independent work, but integration is harder |
| Best when steps are tightly connected | Best when meaningful batches can run independently |
Use Prompting Long-Horizon Coding Agents when one agent can reasonably own the complete change. Use parallel editing only when the work can be partitioned without several agents modifying the same state at the same time.
Four Different Kinds Of Parallelism
Section titled “Four Different Kinds Of Parallelism”The phrase “parallel agents” is used for several different designs.
| Level | What runs concurrently | Example |
|---|---|---|
| Parallel tools | One agent requests several independent tool calls | Read three files or call three read-only APIs |
| Parallel subagents | A parent delegates independent investigations | One checks tests while another checks documentation |
| Parallel coding workers | Separate agents edit isolated copies of a repository | Migrate independent components on separate branches |
| Repository fleet | An orchestrator dispatches work across many repositories | Apply one dependency or security change across an organization |
This page focuses on the third level and the architecture that can later scale to the fourth.
Parallel reads are comparatively easy. Parallel writes are where dependency planning, isolation, verification, and integration become mandatory.
The End-To-End Architecture
Section titled “The End-To-End Architecture”flowchart TD
A["Migration goal and acceptance criteria"] --> B["Discovery<br/>Map files, interfaces, and dependencies"]
B --> C["Human-approved batch plan"]
C --> D["Dependency-aware scheduler"]
D --> E1["Agent A<br/>isolated workspace"]
D --> E2["Agent B<br/>isolated workspace"]
D --> E3["Agent C<br/>isolated workspace"]
E1 --> F1["Batch verification"]
E2 --> F2["Batch verification"]
E3 --> F3["Batch verification"]
F1 --> G["Review and integration queue"]
F2 --> G
F3 --> G
G --> H["Repository-level verification"]
H -->|Pass| I["Merge migration stage"]
H -->|Fail| J["Diagnose integration failure"]
J --> C
The coordinator should own:
- the migration goal and non-goals
- the batch graph
- workspace creation and cleanup
- concurrency limits
- verification policy
- retries, timeouts, and cancellation
- integration order
- human approval gates
- the final repository-wide result
An individual coding agent should own only its assigned batch.
Choose Tasks That Are Actually Parallelizable
Section titled “Choose Tasks That Are Actually Parallelizable”Good candidates usually have four properties.
1. The transformation repeats
Section titled “1. The transformation repeats”Examples include:
- upgrading a dependency across many packages
- migrating components from one library to another
- adding type information across a codebase
- replacing a deprecated API
- applying a well-defined security remediation
- removing a known code smell
- updating generated or repetitive configuration
The individual changes may require judgment, but the target pattern remains recognizable.
2. A batch can produce independent value
Section titled “2. A batch can produce independent value”One completed batch should be reviewable and, ideally, mergeable without waiting for every other batch.
This matters because some workers will fail, stall, or discover blocked cases. A workflow that produces 80 safe pull requests and 20 explicit blockers is often more useful than one giant run that returns nothing until every case succeeds.
3. Correctness can be checked
Section titled “3. Correctness can be checked”Useful verification signals include:
- unit and integration tests
- compiler or type-checker output
- lint and formatting checks
- API compatibility tests
- schema validation
- security scanners
- snapshot or visual regression checks
- a precise search proving that a deprecated construct is gone
If nobody can state how to verify a batch, dispatching more agents only creates more unverified code.
4. Write boundaries can be separated
Section titled “4. Write boundaries can be separated”The safest batches own different files, modules, packages, services, or repositories.
Parallel agents are a poor fit when:
- every batch must edit the same central file
- one worker’s output constantly changes another worker’s assumptions
- the target architecture is still undecided
- tests are missing and behavior is poorly understood
- a migration requires one indivisible transaction
- merge conflicts would dominate the work
- the change affects safety-critical behavior without strong review controls
Start With Discovery, Not Dispatch
Section titled “Start With Discovery, Not Dispatch”Do not ask ten agents to begin editing from a one-sentence migration request.
First build a current map of the repository:
- locate every use of the old interface
- identify entry points and public contracts
- map build, test, and deployment boundaries
- find generated code and files that must not be edited
- identify owners and high-risk modules
- establish characterization tests for behavior that must remain unchanged
- record known exceptions and unsupported cases
The discovery output is not merely a list of files. It should explain relationships that affect execution order.
For an unfamiliar repository, begin with Codebase Onboarding with Coding Agents and Finding Unknowns Before Agentic Work.
Design PR-Sized Batches
Section titled “Design PR-Sized Batches”A useful batch is small enough for one agent to finish and one person to understand, but large enough to represent a coherent change.
Good boundaries include:
- one package and its tests
- one service
- one UI component family
- one database access layer
- one group of files that share an internal interface
- one repository in a cross-repository campaign
Avoid assuming that one file equals one task. A file may be meaningless without its tests, generated types, fixtures, or closely coupled dependencies.
A batch contract
Section titled “A batch contract”Every batch should have an explicit contract:
Batch: migrate account-settings state management
Owns:- src/account-settings/**- tests/account-settings/**
Goal:- replace the old state API with the approved adapter- preserve current user-visible behavior
May read but not edit:- src/shared/state/**
Must not change:- public component properties- persistence format
Prerequisites:- compatibility adapter merged
Verification:- account-settings unit tests- type check- production build- no imports from the deprecated package inside owned paths
Output:- focused commit or pull request- verification evidence- discoveries that affect other batches- unresolved blockersThe ownership list prevents two workers from silently editing the same files. The prerequisite and verification fields let the scheduler decide when the batch is ready and whether it is complete.
Build A Batch Dependency Graph
Section titled “Build A Batch Dependency Graph”A file-level dependency graph may be too detailed to schedule directly. Convert it into a smaller batch graph:
- each node represents one reviewable batch
- each edge means one batch must be completed before another can safely begin or merge
flowchart LR
A["Compatibility adapter"] --> B["Account settings"]
A --> C["Checkout"]
A --> D["Notifications"]
B --> E["Remove old dependency"]
C --> E
D --> E
E --> F["Delete migration scaffolding"]
In this example, Account settings, Checkout, and Notifications can run concurrently after the compatibility adapter is ready. Removing the old dependency must wait for all three.
How to form the batches
Section titled “How to form the batches”Possible strategies include:
| Strategy | Useful when | Risk |
|---|---|---|
| Directory or package boundaries | Repository structure matches ownership and behavior | Related code may live elsewhere |
| Dependency graph communities | Imports reveal meaningful clusters | Generated or dynamic dependencies may be missed |
| Domain or service boundaries | Architecture has clear business modules | Shared infrastructure still creates coupling |
| Search-result groups | Transformation is syntactically regular | Similar syntax may hide different semantics |
| Ownership boundaries | Teams review and deploy independently | Ownership may not match runtime dependencies |
Use repository structure as evidence, not as proof. Confirm the proposed batches against tests, interfaces, and human knowledge.
Handle cycles deliberately
Section titled “Handle cycles deliberately”If batch A depends on B and B also depends on A, they are not independently schedulable in their current form.
Options include:
- combine them into one batch
- introduce a temporary compatibility interface
- split out their shared contract first
- complete the cycle serially under one worker
Pretending a dependency cycle does not exist creates repeated integration failures later.
Schedule Only Ready Work
Section titled “Schedule Only Ready Work”A batch is ready when:
- its prerequisites are merged into its starting point
- its owned files are not assigned to another active worker
- its required context and verification commands are available
- no unresolved design decision blocks it
flowchart TD
P["Pending batch"] --> R{"Prerequisites satisfied?"}
R -->|No| P
R -->|Yes| W["Create isolated workspace"]
W --> A["Agent implements batch"]
A --> V["Run batch verification"]
V -->|Fail| X["Return focused failure evidence"]
X --> A
V -->|Pass| H["Human or policy review"]
H -->|Changes requested| A
H -->|Accepted| M["Merge batch"]
M --> U["Unlock dependent batches"]
The scheduler should not rely on agents remembering the entire graph. It should represent batch state explicitly in code, a database, a workflow engine, or at minimum a versioned task file.
Useful states include:
pendingreadyrunningverification_failedawaiting_reviewacceptedmergedblockedcancelled
This state model makes partial progress and failure visible.
Isolate Every Editing Worker
Section titled “Isolate Every Editing Worker”Do not run multiple editing agents in the same working directory. They can overwrite files, invalidate each other’s tests, stage unrelated changes, or interpret temporary state as committed architecture.
| Isolation method | Strength | Main limitation |
|---|---|---|
| Git branch in a separate clone | Familiar and strongly separated | More disk and setup work |
| Git worktree with its own branch | Lightweight and shares repository objects | Still shares host credentials and resources |
| Container workspace | Isolates dependencies and filesystem state | Container security and resource policy still matter |
| Remote sandbox or VM | Stronger execution and scaling boundary | Higher operational cost and credential complexity |
The Git worktree documentation explains how several working trees can share one repository while keeping separate checked-out branches. The existing Claude Code guide covers the basic worktree workflow.
Isolation is not complete security by itself. Each worker also needs:
- least-privilege credentials
- restricted network and filesystem access
- resource, time, token, and cost limits
- explicit rules for external side effects
- secret redaction in logs and prompts
- cleanup after completion or cancellation
A container that receives an unrestricted production token is still dangerous.
Use A Layered Verifier
Section titled “Use A Layered Verifier”Verification should be designed before workers start.
Run the cheapest and most deterministic checks first:
- changed-file and ownership checks
- format and syntax checks
- compiler, type checker, or linter
- focused unit tests
- package or service integration tests
- repository build
- broader end-to-end or visual checks
- semantic review where code cannot decide correctness
flowchart LR
A["Agent patch"] --> B["Scope check"]
B --> C["Static checks"]
C --> D["Focused tests"]
D --> E["Package integration"]
E --> F["Human or semantic review"]
F --> G["Accepted batch"]
Verifier and fixer are different roles
Section titled “Verifier and fixer are different roles”The worker that wrote a patch should run tests, but its declaration of success is not sufficient evidence.
Use an independent verifier to:
- execute checks in a clean environment
- confirm the diff stayed inside the ownership boundary
- detect missing tests or changed public contracts
- record exact commands, versions, and results
- reject a patch without trying to explain it away
If verification fails, pass focused evidence back to the fixer:
Failed check: package type checkCommand: npm run typecheck --workspace checkoutError: CheckoutStore no longer satisfies PersistedStore at src/checkout/store.ts:84Allowed scope: src/checkout/** and tests/checkout/**Do not modify the shared PersistedStore interface.This is more useful than “the tests failed, fix it.”
Where an LLM verifier fits
Section titled “Where an LLM verifier fits”An LLM can review semantic concerns such as whether a refactor preserved intent or whether a new abstraction violates documented architecture.
Do not use an LLM judge as a substitute for a compiler, test suite, or security scanner. Model-based verification is nondeterministic and can share the same mistaken assumptions as the coding agent.
Use it after deterministic checks, with a narrow rubric and access to the actual diff and evidence.
Add Temporary Migration Scaffolding When Needed
Section titled “Add Temporary Migration Scaffolding When Needed”Some migrations cannot move each component directly from old to new while keeping the application runnable.
A temporary compatibility layer can create an intermediate state:
flowchart TD
A["Current system<br/>old interface only"] --> B["Add compatibility layer"]
B --> C["Old and new implementations can coexist"]
C --> D1["Migrate batch A"]
C --> D2["Migrate batch B"]
C --> D3["Migrate batch C"]
D1 --> E["All consumers use new interface"]
D2 --> E
D3 --> E
E --> F["Remove compatibility layer and old dependency"]
Examples include:
- an adapter that presents one interface over old and new libraries
- dual readers during a storage-format migration
- a compatibility API while callers move incrementally
- a feature flag that selects old or new behavior
- temporary shims for renamed types or methods
Scaffolding must have:
- an owner
- a removal condition
- tests for both temporary paths
- a tracked final cleanup batch
- a limit on how long the dual state may remain
Without a removal plan, temporary migration code becomes permanent complexity.
Share Context Without Sharing Every Transcript
Section titled “Share Context Without Sharing Every Transcript”Giving every worker every other worker’s conversation recreates one oversized context window. It also spreads irrelevant details, stale guesses, and accidental instructions.
Use layered context instead.
Stable campaign context
Section titled “Stable campaign context”Every worker may need:
- migration goal and non-goals
- approved architecture decisions
- repository conventions
- verification policy
- prohibited changes
- security boundaries
Keep this small, versioned, and human-reviewed.
Batch-local context
Section titled “Batch-local context”Each worker receives:
- owned files and allowed dependencies
- prerequisite commit or artifact versions
- relevant interfaces and tests
- batch-specific acceptance criteria
- known risks and exceptions
Promoted discoveries
Section titled “Promoted discoveries”A worker may learn something that affects other batches. It should propose a structured discovery rather than broadcast its transcript:
Discovery: persistence middleware assumes store keys remain stableEvidence: src/shared/persistence.ts and tests/persistence/restore.test.tsAffected batches: account-settings, checkoutProposed action: preserve existing keys during migrationConfidence: confirmed by testsA human or coordinator reviews the discovery before promoting it into shared campaign context.
This prevents one worker’s hallucination from becoming a fleet-wide instruction.
Integrate In Controlled Stages
Section titled “Integrate In Controlled Stages”A passing batch is not proof that several accepted batches work together.
Use an integration branch or equivalent staging environment:
- update the branch from the approved base
- merge ready batches in dependency order
- resolve conflicts with ownership and design context available
- run affected package checks after each merge
- run repository-wide verification at defined checkpoints
- stop and diagnose when a regression first appears
- tag or record known-good integration points
Avoid merging dozens of branches and testing only at the end. When the combined build fails, the search space is much larger.
Interface changes need special treatment
Section titled “Interface changes need special treatment”Shared interfaces, schemas, generated clients, build configuration, and dependency lockfiles are conflict hotspots.
Prefer one of these strategies:
- merge the shared interface change first, then rebase workers onto it
- assign the shared file to one integration owner
- generate shared artifacts centrally after batch merges
- serialize batches that must modify the same contract
Parallel execution does not require parallel merging.
Keep Humans At High-Leverage Gates
Section titled “Keep Humans At High-Leverage Gates”Human review is most valuable where the system cannot cheaply recover from a wrong decision.
Useful gates include:
| Gate | Human decision |
|---|---|
| Before dispatch | Are the architecture and batch boundaries correct? |
| After a new discovery | Does this change the campaign plan? |
| Before accepting a batch | Is the patch understandable, scoped, and supported by evidence? |
| Before shared-interface changes | Are downstream effects understood? |
| Before removing scaffolding | Have all consumers migrated and rollback needs expired? |
| Before final merge | Does the integrated system meet the original acceptance criteria? |
The goal is not necessarily complete automation. It is to automate repetitive execution while keeping architectural judgment, risk acceptance, and final accountability visible.
Failure Handling Is Part Of The Design
Section titled “Failure Handling Is Part Of The Design”At scale, some workers will fail. Plan for it.
A worker stalls
Section titled “A worker stalls”- enforce a maximum runtime and model-call budget
- capture its current diff and verification state
- retry only if the failure is transient
- split the batch when the task was too broad
- escalate a real design ambiguity to a human
A worker edits outside its scope
Section titled “A worker edits outside its scope”- fail the ownership check
- discard or manually isolate the out-of-scope changes
- clarify the contract before retrying
- do not automatically expand permissions to make the patch pass
Two batches conflict
Section titled “Two batches conflict”- inspect whether the original decomposition was wrong
- serialize the affected work or introduce a shared prerequisite
- assign one owner to the contested interface
- update the dependency graph
Verification passes locally but integration fails
Section titled “Verification passes locally but integration fails”- identify the first combined checkpoint that fails
- add the missing cross-batch test
- update future batch contracts with the discovered invariant
- avoid patching the integration branch without feeding the learning back into the plan
The migration cannot reach 100 percent
Section titled “The migration cannot reach 100 percent”- merge independently safe batches when policy allows
- record blocked cases and reasons
- retain compatibility scaffolding only with explicit ownership
- decide whether remaining exceptions justify a different design
Partial progress is useful only when it remains supportable.
Measure The Workflow, Not Just Agent Output
Section titled “Measure The Workflow, Not Just Agent Output”Track whether orchestration improves delivery rather than merely increasing activity.
Useful measures include:
- batches accepted without rework
- first-pass verification rate
- human review time per batch
- merge-conflict rate
- integration failures caused by cross-batch assumptions
- elapsed time from ready to merged
- model and infrastructure cost per accepted batch
- stalled and cancelled batches
- regression rate after integration
- percentage of the migration completed without permanent exceptions
Compare those with a baseline such as one human team, one agent, or a smaller pilot. A large number of simultaneous workers is not success if reviewers become the bottleneck or integration quality falls.
A Practical Rollout
Section titled “A Practical Rollout”Adopt the pattern incrementally.
- choose a reversible, repetitive migration
- define five to ten coherent batches
- run only a few editing workers concurrently
- keep deterministic verification mandatory
- review every batch and measure rework
Expand
Section titled “Expand”- automate workspace creation and cleanup
- persist explicit batch states and dependencies
- standardize batch contracts and evidence
- add integration checkpoints
- promote only reviewed discoveries into shared context
- route pull requests to code owners
- enforce organization-wide permission and cost limits
- isolate credentials per repository or campaign
- add durable scheduling, retries, and cancellation
- monitor quality by repository, transformation, and agent configuration
When runs must survive process failures, long waits, or approval delays, combine this pattern with Durable AI Agents with Temporal or another durable workflow runtime.
What Remains Current From The Source Talk
Section titled “What Remains Current From The Source Talk”The source workshop demonstrates these durable ideas:
- repository-wide changes should be decomposed before editing
- dependency-aware batches are safer than arbitrary parallel tasks
- each batch needs a verifier and a bounded fixer
- isolated agents can work concurrently on ready batches
- temporary scaffolding can make incremental migration testable
- humans should review intermediate outputs and integration decisions
- context should be curated instead of copied everywhere
The workshop also contains OpenHands installation steps, a live vulnerability-remediation exercise, product-specific APIs, and productivity claims. Those details are not the basis of this guide.
Current OpenHands documentation still describes its Software Agent SDK as supporting major multi-agent tasks such as refactors and rewrites. It also supports local, Docker, and remote workspaces. However, its parallel tool-execution feature is currently marked experimental and warns about shared-state races. That reinforces the conservative rule used here: parallelize only independent operations and keep write isolation explicit.
Checklist
Section titled “Checklist”Before dispatch:
- The target behavior and non-goals are explicit.
- Current repository behavior has been mapped.
- Batches are coherent and reviewable.
- Dependencies and cycles are represented.
- File ownership does not overlap between active workers.
- Every batch has deterministic verification where possible.
- Credentials and execution environments are isolated.
- Human approval gates are defined.
Before completing the migration:
- Every accepted batch includes verification evidence.
- Shared discoveries were reviewed and recorded.
- Batches were integrated in a controlled order.
- Repository-wide tests and builds pass.
- Temporary scaffolding has been removed or explicitly retained.
- Deprecated dependencies and interfaces are actually gone.
- Known exceptions, costs, and residual risks are documented.
- Rollback or recovery remains possible.