Wave Planning: What a Wave Actually Is
I wrote about wave planning a little while ago: breaking a project into steps, phases, and waves so independent work can run in parallel across AI agents instead of one task at a time. The response was good, but the sharpest pushback was fair:
Isn't this just parallel execution on a dependency graph?
Fair question, and worth answering precisely, because there's a real category difference between wave planning and the execution tools it gets compared to. Projects like GSD, Polywave, Tessl's wave execution planner, and Claude Code's agent teams are schedulers: hand them an already-decomposed set of tasks, and they run the independent ones together and the dependent ones in order, inside isolated worktrees, with file-level locking. That's infrastructure. It starts after the decomposition already happened, and it doesn't care who or what produced the task list.
What's actually different here
Wave planning operates one level above that, on the part none of those tools touch: how the plan itself gets built before anything runs.
- It's a planning discipline, not infrastructure. There's no orchestrator to install. There's a person who fully scopes the project, writes the full dependency tree down, and owns catching what it misses. Schedulers assume that tree already exists and is correct — wave planning is how it gets built in the first place.
- The orchestrator reasons, it doesn't just queue. A higher-tier model owns dependency analysis and wave sequencing, and only hands off fully-scoped phases to subagents. The schedulers above treat "the orchestrator" as infrastructure running a queue; here it's a model making planning decisions.
- The claim is about how projects get planned, not how tasks get run. Sprints group work by time because engineer-hours used to be the scarce resource. Wave planning's actual argument is that dependency, not the calendar, should be the unit a project is organized around once agent capacity stops being scarce. That's a management-methodology claim — a different kind of claim than "here's a faster scheduler."
- Safety is four graphs, not one. Dependency, ownership, context, and validation, checked together, decide whether a wave is safe. The tools above mostly cover dependency and ownership (worktrees, file locks) — context and validation aren't usually part of the same scheduling decision.
Put plainly: those tools answer "how do I run this efficiently." Wave planning answers "how should this even be organized in the first place," and the scheduling step is just where that plan eventually lands.
The actual idea, in one line
Sprints group work by time. Wave planning groups work by dependency.
A sprint exists because a team has a fixed number of people and a fixed number of hours in a week, so you fill the week with whatever fits. A wave doesn't care about the calendar. It only asks one question about each piece of work: is everything it depends on already done? If yes, it runs now, alongside everything else that also just became ready. If no, it waits.
A wave is a schedule, not a container
Step → Phase is a real hierarchy: steps are the actual work, phases are groups of related steps. A wave sits one level above that, and it's a different kind of thing. A wave isn't a container of work, it's a schedule — the output you get after you look at the dependencies between phases and ask which ones can start right now.
The waves aren't part of the project's structure. They fall out of it, once you know what depends on what.
So a wave, defined plainly: the biggest group of phases you can run at the same time, because none of them are waiting on each other, and none of them are likely to step on the same files or the same part of the system.
Five simple things worth measuring
Once a wave is a real thing you compute rather than a vibe, you can describe a project with a few plain numbers. None of these need a tool to calculate by hand on a small project — they're just questions worth asking on purpose instead of by accident.
- Wave width — how many phases are running at the same time in a given wave. Wider means more of the project got unlocked at once.
- Critical path — the one chain of phases that has to happen in order no matter what, from start to finish. This is the floor on how fast the project can go, even with unlimited agents.
- Dependency density — roughly, what fraction of the project is actually forced to be sequential versus free to run in parallel. A project that's mostly independent pieces benefits a lot from this approach. A project that's one long chain barely benefits at all.
- Conflict surface — how likely two agents in the same wave are to touch the same file or the same piece of shared state. This is usually the real reason a wave fails, not a wrong dependency.
- Validation depth — how much checking a wave needs before you trust its output and let the next wave start. Shallow (lint, types) at the phase level, deeper (does the logic actually hold up) at the wave level.
That last one, conflict surface, is worth dwelling on. Two phases can be fully independent on paper — no shared dependency — and still collide if they both need to edit the same config file or the same shared module. Dependency and conflict are two different checks, and a scheduler that only runs the first one will happily group phases that are doomed to step on each other.
That's why a wave needs more checks than "is everything it depends on done." A real wave scheduler is really looking at four different graphs underneath the one everyone thinks about:
- Dependency graph — what has to finish before what. Schema before API, API before UI.
- Ownership graph — who's allowed to touch what.
One agent on
/backend/auth/*, another on/frontend/*, never both on the same path. - Context graph — what an agent actually needs to know to do its part correctly: the schema, the requirements, the contract it has to honor.
- Validation graph — what has to pass before the result is trusted: typecheck, then unit tests, then integration tests.
Wave width, critical path, dependency density, conflict surface, and validation depth are all just different questions asked of these four graphs. A scheduler that only reads the dependency graph is reading one of four inputs it needs.
The 600 hours to 5 hours claim, said more carefully
I said this has taken projects that would traditionally need around 600 hours of sequential work and brought them under 5 hours. That's true, but it's easy to misread as "AI cut 600 hours of engineering effort down to 5 hours." That's not the claim. The actual claim is about wall-clock time, not total effort:
Total work done did not shrink to 5 hours. The time you have to wait for it did.
The work still adds up to roughly the same amount of "hours" spent, just spent by many agents at once instead of one person moving through a list. Planning and review are separate again here, and they still take real, sequential, human time. Nothing above touches that.
Why this is bigger than "run agents in parallel"
Traditional project planning quietly assumes that engineer-hours are the scarce resource, so you plan around people and their calendars. Agentic development changes what's actually scarce: it's context, coordination, and validation, not hours. Once hours stop being the limit, planning by the calendar stops making much sense. Planning by dependency does.
That reframes the agent a bit. It starts looking less like "a person who writes code" and more like a compute worker. The interesting question stops being who should do this task and becomes when does this task become ready to run, and what does it need to run correctly. That's a scheduling question, not a staffing one.
The bottleneck isn't parallelism, it's the split
It's tempting to assume more agents just means more speed. It doesn't. A June 2026 paper, "When Parallelism Pays Off: Cohesion-Aware Task Partitioning for Multi-Agent Coding," found that how you split work across agents matters as much as how many agents you use — their cohesion-aware partitioning reported up to a 2.10x wall-clock speedup, a 14% pass-rate improvement, and 35% lower API cost versus naive parallel splits, on their evaluated tasks. Claude Code's own agent teams documentation says the plainer version of the same thing: parallel agents work well on genuinely independent tasks, and coordination cost climbs with team size, especially once file ownership overlaps.
Ranked by how much each one actually decides whether a wave works:
Most of the excitement in this space is aimed at the bottom of that list — spawning more agents, running more of them at once. The harder, more valuable problems sit at the top, and they're mostly unglamorous: figuring out what actually depends on what, drawing clean interfaces so agents don't have to guess at each other's output, and deciding what "done" means before an agent starts.
Two different kinds of parallel
There's also a use for parallel agents that has nothing to do with speed. Humans avoid having two people solve the same problem independently, because it's wasteful. Agents are cheap enough that it stops being wasteful and starts being useful.
Throughput parallelism
Different agents on different work. The goal is covering more ground at once. Everything above in this post is about this.
Epistemic parallelism
Different agents on the same problem, then a reviewer picks the best result. The goal is a better answer, not a faster one.
Most of what I run is throughput parallelism. Epistemic parallelism is the more useful one for the phases I'm genuinely unsure have one obvious right approach.
What the dashboard might stop looking like
If work gets tracked by dependency instead of by sprint, the natural dashboard probably isn't Jira. It's closer to a scheduling board: what's ready to run, what's stuck waiting on something, what's running right now, and the one chain of work that decides how long everything takes no matter what.
Ready
- Auth service
- Search index
- UI components
- Analytics schema
Blocked
- Checkout API ← Auth
- Dashboard ← Analytics
Running
- 12 agents
- 4 models
Critical path
- Schema
- → API
- → Integration
- → Deployment
The question a human asks stops being "what is everyone doing this week" and becomes "what's currently blocked, and why."
Where this goes next
Right now I build the dependency graph and group it into waves by hand, as part of writing the plan. The next obvious step is to stop doing that part manually: feed the dependency graph in, and let the orchestrator compute the wave schedule itself — wave width, critical path, conflict surface, all of it, calculated instead of eyeballed.
At that point wave planning stops being a way I personally organize projects and becomes closer to an algorithm anyone's orchestrator could run. The distinction that matters holds either way:
Schedulers
Run the plan
Take a decomposed task list and execute it efficiently in parallel.
Wave planning
Builds the plan
Dependency, not the sprint, as the unit a project gets organized around in the first place.
What's still open
The split itself
The four-graph check — dependency, ownership, context, validation — is still done by hand.
The person who owns the plan is still responsible for catching what the dependency tree misses. Hidden dependencies — the ones nobody wrote down — are the actual unsolved problem here, not spawning agents, and not running them in parallel.
A wave isn't a bigger phase. It's the schedule the dependency graph gives you, once you stop assuming the work has to happen one person at a time. Parallelism was never the hard part — knowing what's actually independent is.