Multi-agent workflow

One agent on one repository is a chat. Several agents on one repository is a team, and teams need rules: who owns what, how work passes from one member to the next, and what happens when two of them reach for the same file. This page is the working model 0dai uses for that — concept first, then roles, the handoff protocol, swarm delegation, and conflict resolution.

The concept: files as the coordination surface

The premise is narrow and load-bearing: coordination state lives in the repository as files, not in a broker or a long-lived process. A task is a JSON record. A persona is a YAML file. An active session is a file. An outcome is an appended line in a log. Because every coordination fact is a file in git, any agent on any machine can read it, and the history of who did what is just git log.

That choice rules some things out — there is no central scheduler handing out work in real time — and rules other things in. Agents from different CLIs can cooperate without sharing a session. Work can span days and hosts. The operator can review the queue before anything merges. The trade-offs of file-queue coordination versus an in-process agent runtime are laid out in detail in the subagents comparison; this page assumes the file-queue model and shows how to work inside it.

Role allocation

Agents are not interchangeable. Different CLIs and different models are good at different things, and assigning work by strength is most of what makes a multi-agent setup pay off. 0dai expresses this in two layers: which CLI does the work, and which persona it adopts while doing it.

The routing layer matches the kind of task to the kind of agent. The full table lives in the delegation policy; the short version:

Agent CLIStrengthTypical assignment
claudeReasoning, architecture, debuggingDesign the change, untangle the hard bug
codexFast edits, scaffoldingImplement endpoints, mechanical changes
geminiLarge-context analysisRead the whole module, write or review docs
aiderGit-native focused editsWrite tests, apply tight diffs
opencodeGeneral-purposePrototyping, glue work

The persona layer is the social structure. Persona files under ai/personas/ (templated from templates/layer/ai/personas/*.yaml) carry more than a system prompt. Each one declares references — the practitioners whose taste anchors the role — and ownership edges: defers_to and escalates_to. A content editor defers to the creative director on voice. QA escalates to the architect on a structural test gap. Security can block a merge on auth, payments, or secrets. The point is that ownership is written down, so an agent knows when a decision is not its to make.

The handoff protocol

A handoff is the moment one agent stops and another continues the same task. Done badly, the second agent re-reads everything and re-derives the plan. Done well, it reads a short record and picks up the next step.

The unit of handoff is the active session. Before stopping, an agent writes what matters: the goal, the plan and which steps are done, the files it touched, the decisions it made, and a free-text note for whoever comes next.

# Agent A, finishing its slice
0dai session save --goal "implement auth" \
  --summary "API + handlers done; tests + docs remain; \
             chose argon2id over bcrypt — see decisions.md"

Agent B — possibly a different CLI on a different machine — detects the session on start and continues from the handoff note instead of from a blank context. The full schema, what transfers, and the file layout are in Session roaming. The protocol rule worth stating here: an agent that picks up a task it did not start reads the handoff first, and an agent that stops a task it did not finish writes the handoff before it leaves. Skipping either half is how context gets lost.

Long-running interactive sessions add one more obligation. Before a CLI compacts or clears its context, the in-flight work is committed, pushed, and parked on a branch, so a context reset never silently deletes an unsaved change. The handoff and the commit are the two things that make a reset safe.

Swarm delegation

Handoffs are sequential — one agent then the next. Swarm delegation is the parallel and asynchronous case: an agent decomposes a goal into tasks and writes them to a queue for other agents to claim. The queue is a directory of JSON files; there is no broker.

0dai swarm plan --goal "add user auth"
# 1. [claude] Design auth architecture
# 2. [codex]  Implement endpoints      (after 1)
# 3. [aider]  Write tests              (after 2)
# 4. [gemini] Review                   (after 2,3)

Each task names the agent type it suits and the tasks it depends on. Workers pick the next eligible task, run it, and mark it done — and any worker can write a new task back to the queue, so decomposition is not a one-shot plan but something the team refines as it learns. Spend is bounded: a per-task budget and a daily budget stop execution before a runaway loop drains a wallet. The command surface and the budget knobs are in the swarm reference.

Two policies keep delegation honest. First, work is assigned to an agent type — claude, codex— not to a human's live session, so a person's interactive terminal never gets a task queued into it. Second, a worker only takes work its CLI is actually permitted to do; the capability matrix is checked before a task is dispatched, and a mismatch is rejected with a suggested alternative rather than silently run by the wrong agent.

Conflict resolution

The failure mode that makes people give up on multi-agent work is two agents editing the same file at the same time and one quietly clobbering the other. The defenses are layered, and most of them are about prevention, not cleanup.

  • File-scope declaration. An agent claiming work declares the paths it expects to touch. Another agent about to take an overlapping slice can see the claim and wait or pick something else. The claim is a recorded event, not an honor-system comment.
  • Disjoint ownership on parallel edits. When editing agents run in parallel, they get non-overlapping file scopes by construction. Two agents do not own the same file at the same time; if a change needs both, it is sequenced, not raced.
  • Branch per slice. Each task works on its own branch off the issue, commits after each logical unit, and opens a pull request. Conflicts surface at the merge as ordinary diffs a reviewer can read, not as lost edits inside a shared working tree.
  • A review gate before merge. Tasks pass a tier-gate and a veto check before they land. A higher-risk change asks the operator; a user-facing change pulls in the creative director. The gate is the last place a collision or a bad change is caught.

When prevention fails anyway, resolution is deliberately boring: it is a git merge conflict on a pull request, resolved by a reviewer, with the decision written back to ai/docs/decisions.md so the same collision does not recur. The aim is to turn an invisible race into a visible diff.

A worked example

Putting it together for a single feature — add authentication to an existing app:

  1. A reasoning agent (claude) designs the approach, records the choice of password hash in decisions.md, and decomposes the work with 0dai swarm plan.
  2. A fast-edit agent (codex) claims the implementation task, declares its file scope (routes/auth.*, lib/session.*), and writes the endpoints on its own branch.
  3. A test-writing agent (aider) claims the tests task once the endpoints exist, on a non-overlapping scope (tests/auth/).
  4. A review agent (gemini) reads the whole change once tests and code are in, and the change passes the merge gate.
  5. If the reasoning agent had to stop mid-design, it would session save a handoff so a different agent could finish the design without re-deriving it.

No broker ran. No agent shared a session. The coordination was a queue of JSON files, a set of branches, and a session record — all in the repo, all reviewable.

When not to use several agents

Multi-agent work is not always the right shape, and pretending it is would waste your time and tokens. Coordination has a cost — declaring scopes, writing handoffs, reviewing more branches — and that cost is only worth paying when the work is genuinely larger than one agent in one sitting can hold.

  • Small, single-file changes. A one-file fix does not need a plan, a queue, or a handoff. One agent, one branch, done. Reach for delegation when the work spans subsystems or days, not before.
  • Tightly coupled changes. If two parts of a change must land together and constantly reference each other, splitting them across agents creates more synchronization than it saves. Keep them in one agent and sequence the work internally.
  • Exploratory work. When you do not yet know what the change is, a decomposition is premature — you would be planning a thing you cannot see. Let one agent explore, record what it learns, and decompose once the shape is clear.

The rule of thumb: decompose when the work is big enough that the coordination cost is smaller than the cost of one agent thrashing in a context it cannot fit. Below that line, a single agent with good project memory beats a committee every time.


Next up

Related reading: Why AI agents need shared context and Claude Code vs Codex vs OpenCode. New here? Start with Why 0dai, check the changelog, or run a guided play like migrating Prisma to Drizzle.