← Back to blog
Engineering

How we think about orchestration in p0

Abstract purple gradient artwork representing parallel agent orchestration.

The hardest problem in building an autonomous coding workflow isn’t the model. It’s the choreography. A single agent with infinite context can write a function; turning a rough product idea into a reviewed pull request takes a graph of agents, each with a narrow job, handing artifacts to the next.

The shape of the graph

p0 runs four broad stages, and each stage is itself a small fan-out. The orchestrator is the only piece that knows the whole graph:

  1. Spec writer turns a user prompt into a product spec.
  2. Engineering architect decomposes the spec into tickets with explicit file ownership.
  3. Senior engineers implement tickets in parallel, one ticket per agent.
  4. QA loops verify the build and dispatch fixes back to the relevant ticket owner.

The trick is that stages 3 and 4 are not strictly sequential. A QA failure on one ticket can re-enter stage 3 without blocking the others.

Why file ownership matters

When two agents touch the same file, you get merge conflicts at best and silently lost work at worst. The architect’s job is to assign each file to exactly one ticket, so parallel writes never collide. A ticket spec includes a literal Files (create) and Files (modify) list — the senior-engineer agent treats it as a hard contract.

A small TypeScript example of how a ticket announces itself to the status bus:

await purpleStatus({
  ticket: {
    id: "BLOG-2.3",
    status: { status: "in_progress" },
  },
});

That single ticket.id string is the join key across the orchestrator, the UI, and the audit log. Get it wrong and the row in the ticket tree never closes.

What we got wrong on the way here

We initially tried to make the orchestrator infer dependencies from natural-language tickets. It mostly worked, until it didn’t. Now every ticket declares its dependencies explicitly, and the orchestrator just topologically sorts.

— Andres

Share X LinkedIn