September 17, 2026 · Harness Engineering · Coding Agents · How-to · EN

Task Decomposition for Multiple Coding Agents

A dependency-first method for splitting software work between coding agents without creating hidden contract conflicts, duplicated work, or an impossible integration queue.

Task Decomposition for Multiple Coding Agents

Task Decomposition for Multiple Coding Agents

Task decomposition for coding agents means splitting one software outcome into independently verifiable work nodes, connecting those nodes through explicit dependencies, and running only the nodes whose inputs are already stable.

The common mistake is to start with the available tools:

Claude Code handles the API.
Codex handles tests.
Cursor handles the UI.

That looks parallel. It says nothing about whether the API contract is settled, whether the tests validate accepted behavior, whether the UI consumes generated types, or which branch must land first.

Start with the work graph instead:

accepted behavior
  -> public contract
       -> server implementation
       -> generated client
            -> UI consumer
  -> integration proof

Tools receive nodes only after the graph is coherent. Parallelism is a result of independent nodes, not a target agent count.

This guide covers the planning stage before branches and worktrees exist. For the full operating model, read How to Manage Multiple Coding Agents in One Repository.

Why a flat task list fails

A flat checklist hides direction:

- update API
- update client
- update UI
- add tests
- update docs

Every item appears equally ready. In reality, the client consumes the API schema, the UI consumes the client, tests may encode either old or new behavior, and documentation should describe the accepted result.

If five agents start at once, each invents the missing future state. Their branches can be locally correct and mutually incompatible.

A useful task plan must answer:

  • What does this node produce?
  • What accepted inputs does it consume?
  • Which contract or decision owns those inputs?
  • What may the worker change?
  • What must remain untouched?
  • Which command proves this node’s claim?
  • Which downstream nodes become ready after acceptance?
  • Who integrates the final result?

Without those answers, a task list is only a collection of prompts.

Choose the execution topology before assigning agents

Not every change should use the same topology.

TopologyUse whenAvoid when
Single workerchange is small or tightly coupledindependent long-running nodes already exist
Serial checkpointseach step defines the next step’s inputnodes do not actually depend on each other
Parallel independent tasksinputs are stable and outputs do not overlapworkers share a contract owner or mutable resource
Phased fan-out and fan-inone foundation unlocks several independent consumersfoundation is still changing during fan-out
Best-of-N explorationcomparing disposable approaches before choosing oneseveral branches would all mutate production code

Best-of-N and cooperative implementation are different workflows. Exploratory agents may solve the same problem independently because only one result will survive. Cooperative agents should not duplicate ownership unless comparison is the explicit goal.

Ask one question first:

If every worker returned a green branch today, could we state the correct integration order without reading their chats?

If not, the decomposition is incomplete.

Find the shared foundation

Most failed parallel plans hide one unstable foundation beneath several apparent tasks.

Typical foundations include:

  • public API or event schemas;
  • database migrations and persisted formats;
  • shared types and generated sources;
  • authentication or authorization policy;
  • architecture decisions;
  • cross-cutting configuration;
  • package boundaries;
  • release or compatibility policy.

Suppose a feature adds avatar uploads. The requested surface includes API work, storage, generated clients, web UI, and tests. Before fan-out, the team must stabilize at least:

accepted file types
maximum size
storage ownership
request and response schema
error behavior
compatibility requirement

Those facts form the foundation node. If three workers infer them separately, file isolation will not prevent a contract conflict.

A foundation is stable enough for fan-out when:

  • its authoritative source is named;
  • the accepted behavior is explicit;
  • consumers can reference an exact revision;
  • incompatible alternatives are closed or intentionally deferred;
  • a validation command covers the contract;
  • changes require an explicit replan, not silent drift.

Do not confuse “written down” with “accepted.” A draft schema still under negotiation is not a safe dependency.

Build a producer-consumer graph

Every task node should declare what it consumes and produces.

id: avatar-contract
consumes:
  - product/avatar-upload-decision@7
produces:
  - openapi/avatar-upload@v1
  - avatar-error-codes@v1

A consumer references those outputs:

id: avatar-client
consumes:
  - openapi/avatar-upload@v1
produces:
  - typescript-avatar-client@v1

The graph becomes:

F0 accepted behavior
 |
 v
A  API contract
 |\
 | \-> B server implementation
 |
 \----> C generated client
          |\
          | \-> D web UI
          |
          \----> E CLI consumer

B + D + E -> F integration proof

Only B and C can start together after A is accepted. D and E wait for C. F waits for every required producer.

File independence is not contract independence

Two nodes may edit different directories while depending on the same unstable behavior:

packages/api/**       changes error schema
packages/web/**       assumes error schema

Git predicts no conflict. The graph predicts a consumer dependency.

Review both kinds of overlap:

Overlap typeQuestion
FileCould workers modify the same path?
ContractCould workers define or assume the same behavior?
Generated sourceIs one node changing the source of another node’s output?
Runtime resourceDo workers share ports, databases, queues, caches, or credentials?
ApprovalDo several nodes cross the same human decision gate?
ReleaseMust outputs ship atomically for compatibility?

A safe plan handles all six, not only file paths.

Cut tasks by outcome, not tool or layer

A good task node produces a reviewable result. “Work on frontend” describes a location. “Render accepted avatar validation errors using generated types” describes an outcome.

Compare these plans.

Weak layer split

Agent A: backend
Agent B: frontend
Agent C: tests

Problems:

  • no contract owner;
  • tests are separated from the claims they should prove;
  • frontend may invent fixtures before backend behavior is accepted;
  • “backend” and “frontend” are too broad to validate as single claims.

Strong outcome split

A: define and validate avatar upload contract
B: implement server behavior against accepted contract
C: generate and compile client from accepted contract
D: render upload and error states using generated client
E: prove the integrated upload flow

Each implementation node owns its focused tests. Node E owns only cross-boundary proof, not all testing.

When package-based splitting is safe

Package boundaries work when each package has:

  • a stable public contract;
  • one clear owner for contract changes;
  • independently runnable validation;
  • no hidden generated-source relationship;
  • explicit compatibility expectations;
  • a known integration gate.

If those conditions do not hold, package boundaries are directory labels, not execution boundaries.

Write a worker contract

A task node should be runnable without reconstructing the entire planning conversation.

# Task C — generate avatar client

## Outcome
The TypeScript client exposes the accepted avatar upload request, success response,
and structured validation errors.

## Acceptance
- generated API matches `openapi/avatar.yaml@4d31...`
- client compiles
- a second generation run produces no diff
- no hand-written changes remain under `clients/generated/**`

## Base
`origin/main@a13f...`

## Read first
- `AGENTS.md`
- `docs/decisions/0042-avatar-storage.md`
- `openapi/avatar.yaml@4d31...`

## Consumes
- `openapi/avatar-upload@v1`
- `avatar-error-codes@v1`

## Produces
- `typescript-avatar-client@v1`

## Write scope
- generator configuration
- generated TypeScript client
- client compile fixtures

## Do not change
- API schema
- server implementation
- web UI

## Validation
- `scripts/generate-clients`
- `scripts/check-generated-clean`
- `scripts/validate-clients avatar`

## Checkpoint
Commit one coherent generated-client result and report its SHA.

## Handoff
Use the repository's evidence-handoff template. Include consumed contract revision,
commands, results, omissions, residual risk, and downstream-ready outputs.

## Stop conditions
Stop if the accepted schema is incomplete, the generator version is ambiguous,
or generation changes unrelated clients.

This packet limits improvisation without prescribing every code edit.

For the after-state that a worker should return, use the Coding-Agent Handoff Template.

Run a launch review

Before assigning any node, review the entire graph once.

1. Dependency review

  • Does every consumed output have exactly one accepted producer?
  • Are cycles present?
  • Is the critical path visible?
  • Are optional nodes distinguished from release blockers?
  • Does integration order follow producer-consumer order?

2. Ownership review

  • Does each shared contract have one owner?
  • Can any two workers redefine the same behavior?
  • Is one integrator named?
  • Are approval gates assigned to a human or explicit policy?

3. Scope review

  • Are write paths bounded?
  • Are prohibited paths explicit?
  • Are generated paths mapped to their sources?
  • Are temporary task facts kept out of durable repository instructions?

4. Runtime review

  • Do workers need separate ports, databases, queues, caches, or environment files?
  • Could one worker’s migration invalidate another worker’s fixture?
  • Are credentials or external side effects shared?

5. Proof review

  • Does every node have focused validation?
  • Does every contract edge have a producer-consumer check?
  • Is there a final user-visible outcome gate?
  • Are omitted checks and residual risks part of the handoff?

Do not create worktrees until this review passes. Worktrees isolate approved tasks; they do not repair a bad task graph. The Git Worktrees for Multiple Coding Agents guide covers allocation after planning.

Worked example: decompose an avatar-upload feature

The request is:

Let users upload JPEG or PNG avatars up to 2 MB from the web app and CLI.

A useful graph has four phases.

Phase 0: stabilize decisions

F0: avatar behavior decision
Produces:
- accepted formats and size limit
- storage owner
- error semantics
- compatibility requirement

One owner accepts F0. No implementation starts before it is stable.

Phase 1: define the contract

A: API contract
Consumes: F0
Produces: request schema, response schema, error codes
Proof: schema validation + contract examples

Phase 2: fan out where inputs are stable

B: server implementation
Consumes: A
Produces: upload behavior
Proof: service + storage tests

C: generated clients
Consumes: A
Produces: TypeScript and CLI client surfaces
Proof: deterministic generation + compile

B and C can run concurrently because both consume the accepted contract and produce different outcomes.

Phase 3: downstream consumers

D: web flow
Consumes: C
Produces: picker, progress, success, errors
Proof: component + browser flow

E: CLI flow
Consumes: C
Produces: avatar upload command behavior
Proof: CLI integration test

D and E can run concurrently after C is accepted.

Phase 4: integrate and prove

F: integrated candidate
Consumes: B + D + E
Produces: release-ready avatar upload outcome
Proof: API/client compatibility + web smoke + CLI smoke + clean tree

The execution schedule is not “five agents now.” It is:

F0 -> A -> [B || C] -> [D || E] -> F

At most two implementation nodes are ready at once. Adding more agents would add coordination, not throughput.

Make readiness explicit

A small ledger prevents blocked nodes from starting on guessed inputs.

| Node | Produces | Depends on | Owner | State | Evidence |
|---|---|---|---|---|---|
| F0 behavior | accepted decision | — | product owner | accepted | decision 0042 |
| A contract | schema v1 | F0 | agent/contract | ready | schema checks |
| B server | server behavior | A | agent/api | blocked | — |
| C clients | generated clients | A | agent/client | blocked | — |
| D web | web flow | C | agent/web | queued | — |
| E CLI | CLI flow | C | agent/cli | queued | — |
| F integrate | release candidate | B,D,E | integrator | queued | — |

Use precise states:

queued -> ready -> claimed -> working -> verifying -> accepted -> integrated
                       \-> blocked
                       \-> replanning

ready means prerequisites are accepted. accepted means evidence passed. “Done” is too ambiguous for a dependency graph.

Replan when a hidden dependency appears

Even careful plans miss dependencies. The response should preserve evidence and revise the graph.

Suppose the web worker discovers that avatar errors also require a shared localization schema used by the CLI.

Do not let the web and CLI workers independently extend it.

  1. Freeze affected workers at stable checkpoints.
  2. Record the discovered dependency and the assumption that failed.
  3. Identify the canonical owner of localization keys and error codes.
  4. Add a foundation or contract node to the graph.
  5. Decide which existing outputs remain valid.
  6. Update consumed and produced contracts.
  7. Rebase or restart only affected nodes from accepted checkpoints.
  8. Update repository instructions or templates if the dependency should have been discoverable.

The revised graph may be:

A API contract
  -> L localized error contract
       -> C generated clients
            -> [D web || E CLI]

A replan is not a failure of orchestration. Continuing against invalid assumptions is.

If incompatible branches already exist, use the contract-first merge-conflict workflow.

Integrate in graph order

The task graph should survive execution and become the integration plan.

For the example:

  1. accept the API contract;
  2. integrate server behavior or client generation against that exact contract;
  3. verify each producer-consumer boundary;
  4. integrate web and CLI consumers after the generated client is accepted;
  5. run combined outcome proof;
  6. preserve a rollback checkpoint until final acceptance.

Do not merge in completion order. A fast consumer branch is still blocked if its producer has not been accepted.

The full process is covered in How to Integrate Changes from Multiple Coding Agents Safely.

Common decomposition failures

One task per tool

“Claude task,” “Codex task,” and “Cursor task” make vendors the architecture. Define outcomes first, then assign whichever worker fits.

A flat checklist with no edges

A list communicates work but not prerequisites. Add consumes, produces, and acceptance gates.

Parallelizing a chain

If A -> B -> C, three simultaneous workers invent future inputs. Run the chain serially or stabilize mock contracts explicitly and accept the later reconciliation cost.

Multiple owners for one contract

Two workers cannot both own the final schema, migration, or public behavior. Name one producer and make the others consumers.

Splitting tests away from behavior

A separate “tests agent” may encode guessed behavior after implementation. Each node owns focused proof for its claim; a later verification node covers cross-boundary outcomes.

Treating separate files as independent work

Different paths can share a schema, generated source, persisted format, runtime resource, or release gate. Review semantic overlap.

Missing stop conditions

A worker that discovers an ambiguous contract often guesses because the task says only “finish.” Define when to stop and escalate.

No integrator

Parallel branches do not assemble themselves. Name one owner for ordering, conflict decisions, combined validation, and rollback.

No final outcome node

Locally green nodes can still fail together. The graph needs a fan-in gate that proves the requested user-visible behavior.

Should this work be parallel?

Use this decision table before creating another worker.

QuestionIf yesIf no
Is the outcome large enough to justify coordination?continueuse one worker
Can you name independently verifiable nodes?continuekeep serial
Are shared contracts accepted?continuestabilize them first
Does each node have bounded ownership?continueredesign scopes
Can dependencies be drawn without cycles?continueresolve architecture first
Can workers validate locally?continuebuild proof before fan-out
Is one integrator available?continuedo not parallelize writes
Will elapsed time saved exceed coordination cost?fan out approved nodesuse fewer workers

The default should not be maximum concurrency. It should be the smallest graph that reduces elapsed time without weakening evidence.

Copyable task-graph template

# Multi-agent task graph

## Requested outcome
[User-visible behavior]

## Accepted foundation
- Decision:
- Contract owners:
- Exact revisions:
- Compatibility constraints:

## Nodes

### [ID] — [Outcome]
- State: queued | ready | claimed | working | verifying | accepted | integrated
- Owner/tool:
- Base:
- Consumes:
- Produces:
- Write scope:
- Do not change:
- Acceptance:
- Validation:
- Checkpoint:
- Handoff:
- Stop conditions:

## Edges
- [producer] -> [consumer]: [contract]

## Parallel groups
- Phase 1:
- Phase 2:

## Integration order
1.
2.

## Combined proof
- Boundary checks:
- User-visible check:
- Clean-tree check:
- Recovery or rollback check:

## Integrator
- Owner:
- Conflict authority:
- Rollback checkpoint:

Launch checklist

Before starting multiple coding agents:

  • requested outcome is explicit;
  • execution topology is chosen deliberately;
  • shared foundation is accepted;
  • every node has one independently verifiable outcome;
  • every consumed output has one producer;
  • contract overlap is reviewed, not only file overlap;
  • runtime resources are isolated or coordinated;
  • bases, write scopes, and prohibited paths are explicit;
  • focused validation exists for every node;
  • stable checkpoints and handoffs are required;
  • stop conditions prevent workers from guessing;
  • one integrator owns fan-in and conflict decisions;
  • integration follows graph order;
  • final proof covers the user-visible outcome;
  • hidden dependencies trigger visible replanning.

Decompose before you orchestrate

Multiple coding agents are useful when the repository contains real parallelism. They are expensive when several workers are asked to discover the same contract at the same time.

Stabilize the shared foundation. Cut work into outcomes. Record producer-consumer edges. Launch only ready nodes. Keep tests attached to claims. Integrate in graph order. Turn hidden dependencies into explicit replans.

That workflow makes each branch easier to review and every handoff easier to trust. It also keeps the repository—not a transient chat or orchestration UI—as the durable coordination surface.

repository-harness provides a starting structure for task envelopes, authority boundaries, source-of-truth maps, validation contracts, evidence handoffs, and recovery-aware coding-agent workflows.


FAQ

How do you split a software task between multiple coding agents?

Split it into independently verifiable outcomes with explicit inputs, outputs, ownership, dependencies, write boundaries, and validation. Stabilize shared contracts before fan-out, then run only graph nodes whose prerequisites are accepted.

Which coding tasks are safe to run in parallel?

Tasks are safe to run in parallel when they consume stable inputs, produce separate outcomes, do not compete for the same contract or runtime resource, and can be validated independently before a defined integration gate.

Should coding-agent tasks be divided by files, components, or outcomes?

Prefer outcome and contract boundaries. File or component boundaries are useful only when they also represent independent behavior and ownership. Separate files can still depend on the same schema, migration, configuration, or generated source.

How do you represent dependencies between coding-agent tasks?

Give every task explicit consumes and produces fields, then connect producers to consumers in a directed graph. The graph defines launch order, blocked states, the critical path, and the order in which branches must be integrated.

What should every coding-agent task packet include?

Include the outcome, acceptance criteria, exact base revision, read-first context, write scope, prohibited paths, consumed and produced contracts, validation commands, stable checkpoint requirement, handoff format, and stop conditions.

When is one coding agent better than several agents?

Use one agent when the work is small, tightly coupled, dominated by one unstable contract, missing boundary tests, or cheaper to complete serially than to coordinate and integrate. More agents do not create useful parallelism when the dependency graph is a chain.

What should happen when an agent discovers an undeclared shared dependency?

Freeze the affected tasks at stable checkpoints, record the dependency, choose an authoritative owner, stabilize the shared contract, revise the task graph, and restart only the nodes whose assumptions remain valid. Do not let workers negotiate the contract through competing code changes.