---
name: build-wave
description: "Drive ONE disjoint wave of ≤N workflow sweeps end-to-end through six phases (admission, provision, staged fan-out, per-sweep gates, cross-sweep review, and serial integration). Usage: /build-wave <WaveNumber>"
---
> **Specialization:** Read `CLAUDE.md` first and bind every `<…>` placeholder and every "per `CLAUDE.md`" reference from it (stack, project/module names, paths, design-system prefix, naming grammar, domain compliance). This file hard-codes no project or domain value. If a needed value is missing from `CLAUDE.md`, STOP-and-ask. See `SPECIALIZE.md`.


You are the **orchestrator** for one full wave of ≤N concurrent workflow sweeps. You are the **single writer of the wave** (Law 3): you sequence phases, provision and tear down worktrees, dispatch agents with explicit context (Law 4), enforce every gate, and are the ONLY actor that writes shared trackers, closes cross-module seams, and integrates branches into `main`. You write no production code yourself.

## Preconditions

- The foundation is built (SharedKernel, Contracts, Infrastructure behaviours, app shell, design-system extraction). If not, STOP — that is human-in-the-loop work, not a wave.
- Read `CONSTITUTION.md` §7, `CLAUDE.md`, `PROGRESS.md`, `LESSONS.md`, and the project's wave schedule (the `WAVE_PLAN.md` equivalent) first. Resolve the target wave number's ≤N workflow IDs and their batched-C1 group from the schedule. If the wave number is out of range or the schedule entry is missing, STOP-and-ask.
- Any infrastructure required for the project's integration tests (e.g. a container runtime) must be running — the capstone integration test requires it.

## The six phases (run in order)

### Phase 0 — Wave admission / span re-verify

Dispatch the wave's ≤N `spec-architect` agents **concurrently** in enrich-only mode. Each reconciles its workflow spec to the current design (rendered prototype + reconstructed UI) and emits its **true span block**: `{ id, modules[], addedContractTypes[], touchesSharedKernel }`. Dispatch `spec-researcher` for each workflow alongside (advisory; findings feed Checkpoint 1 but do not gate Phase 0). Collect the spec-researcher findings; Must-have items feed directly into the Checkpoint 1 bundle.

Assemble the emitted span blocks into the approval-inbox staging file (e.g. `docs/APPROVAL_INBOX/wave-<N>-emitted-spans.json`; schema = the `spans.json` rows mined per `tools/PARALLELISM.md`), then run the kit's **wave-disjointness verifier** against the emitted spans. It dot-sources the scheduler, so the conflict rule can never drift between planning and verifying:

```
powershell -NoProfile -File .claude/tools/Verify-WaveDisjoint.ps1 -Verify -EmittedPath docs/APPROVAL_INBOX/wave-<N>-emitted-spans.json
```

**Hard gate — non-zero exit blocks fan-out:**
- Exit 1 (conflict detected): patch the offending row(s) in your wave schedule's `spans.json`, re-run `.claude/tools/Compute-WaveSchedule.ps1 -Render` for a revised wave assignment, drop the conflicting sweep to a later wave, and proceed with the surviving disjoint set. A wave NEVER fans out on stale disjointness assumptions.
- Exit 2 (bad arguments): fix the invocation and re-run.
- Exit 0: wave is disjoint — proceed.

### ■ Checkpoint 1 (batched)

Present **all ≤N delta reports** together — reconciled spec deltas, Must-have research findings, and any design gaps — in one session. Wait for human approval. On approval, you (single writer) fold the approved deltas into the ≤N workflow specs. Do not continue without it.

**Design-backlog triage (sub-step of batched C1):** collect all `DesignBacklog:` entries emitted across the ≤N spec-researchers and present them as a consolidated table. Per row, decide with the human:
- **Must-have, no prototype coverage** → **(a) park** the affected sweep (it will not enter Phase 1; file the row to the project's design backlog per `CLAUDE.md` with status `☐` and the Claude Design prompt from `PROMPT_TEMPLATES.md §J`) — or **(b) proceed with stub** (`Marked-stub` affordance; row still filed as `☐`). A parked sweep follows the same failure-isolation rules as a Phase 2 park — the rest of the wave continues.
- **Nice-to-have** → proceed; write a `☐` row to the project's design backlog (severity Nice-to-have) and mark its affordance `Marked-stub`.

All triage decisions are written to the project's design backlog by you (single writer) before leaving C1. **For each `☐` row filed across the wave, emit its design-tool brief** via the **`design-prompt-authoring`** skill into the design-prompts companion board (per `CLAUDE.md`) — batched with the wave's other rows — so every filed row ships ready-to-send.

### Phase 1 — Provision worktrees

Create ≤N git worktrees off `main`, one per surviving sweep:

```
git worktree add ../wave-<N>-<WORKFLOW-ID> -b wave-<N>/<WORKFLOW-ID>
```

**Invariant:** record each worktree's absolute path immediately. Every agent dispatched for a sweep receives and operates in that sweep's worktree absolute path — never the main working tree. Verify the path exists before dispatching any agent.

### Phase 2 — Staged fan-out

Run the five build stages in order, dispatching all surviving sweeps' agents **concurrently within each stage**, then waiting for the **stage barrier** before advancing. Stages:

- **B1:** ≤N `backend-builder` agents (one per sweep, each in its worktree)
- **B2:** ≤N `migration-engineer` agents
- **B3:** ≤N `seed-builder` agents
- **B4:** ≤N `crosscutting-weaver` agents
- **B5:** ≤N `module-wirer` agents

(Stage labels B1-B5 are local shorthand for this command; the agent names are the canonical reference.)

**Destructive-migration gate fires per-sweep** (at B2): if a `migration-engineer` reports a destructive change, stop that sweep at the gate and wait for human approval before applying; the other sweeps in the stage continue unblocked.

**Failure isolation:** a sweep that FAILS or BLOCKS at any stage is **parked** — it is dropped from all remaining stages and a structured report is filed to the approval inbox (`docs/APPROVAL_INBOX/`). The rest of the wave continues. A parked sweep's WORKFLOW_REGISTRY row stays `◐`/`⚠` with an approval-inbox pointer.

**Per-sweep build mechanics within each stage are exactly `/build-workflow` step 3 (build the slices) — enrich was completed in Phase 0. Reference that command for the per-agent inputs, routing table, and module-dependency ordering — do not duplicate them here.**

### Phase 3 — Per-sweep gates

For each surviving worktree, concurrently run the existing `/build-workflow` steps 4–5:

- `test-engineer` — xUnit + integration + contract + Playwright e2e + NetArchTest + a11y + visual regression; **also produces `<X>_MANUAL.md`** (project workflow spec path per `CLAUDE.md`) as a required Phase 3 artifact per surviving sweep.
- The project's preflight gate — full run (exit 0 required before advancing).
- `interaction-auditor` — affordance ledger complete (zero unmarked stubs, zero mis-wired seams).
- `reviewer` — PASS verdict vs Constitution + `CLAUDE.md`.

On FAIL, route to the owning agent (see `/build-workflow` routing table), **capped at 2 retries**, then park. Refer to `/build-workflow` step 5 for the reviewer FAIL routing rules — do not duplicate them here.

### Phase 4 — Cross-sweep wave-reviewer

Dispatch the `wave-reviewer` agent over the **union diff** of all surviving branches. Pass it: the list of surviving worktree absolute paths, their workflow IDs, their span records, and the paths to `CONSTITUTION.md` and `CLAUDE.md`. Collect its structured findings (duplicate design-system classes, Contracts append collisions, duplicated cross-cutting behaviors, intra-wave seam interference).

### ■ Checkpoint 2 (batched)

Present the **wave digest** in one session — per-sweep evidence (diffs, test counts, gate results, risk-tagged affordances) and the `wave-reviewer` cross-sweep findings — and obtain a single merge approval for the wave. Do not fold any branch without this approval.

### Phase 5 — Single-writer serial integration

Fold surviving branches into `main` **one at a time**, **contract-emitters first** (sweeps that added new types to `<App>.Contracts`), then the rest in any order.

**Before folding each branch**, verify `<X>_MANUAL.md` exists in that sweep's worktree (at the project's workflow spec path per `CLAUDE.md`). Missing = Phase 3 is incomplete — park that sweep rather than folding without the manual.

After **each fold**, run the wave-integration gate using the project's preflight check (fast mode). Non-zero exit signals cross-sweep interference (broken shared build, missing migration manifest entry, leaked literal binding, etc.). Fix in place (capped at 2 retries) or `git revert` + park the fold before proceeding to the next. **Never fold onto a failing tree.**

**Capstone after the last fold:** run the project's migrate-all + seed-all integration test (the project's preflight test suite that exercises all module contexts together). This is the deepest proof that all concurrent migrations compose. Non-zero → investigate and resolve before declaring the wave complete.

After the capstone passes:

1. Close every cross-module seam surfaced by agents during the wave.
2. Graduate the `wave-reviewer`'s flagged design-system class duplicates using the established primitive discipline (emit the class verbatim into the project's shared design-system primitive directory (named in `CLAUDE.md`) + a golden component test, then refactor consumers).
3. Update the registries' Sync state for all ≤N workflows.
4. Append ≤N lines to `PROGRESS.md` (one per completed workflow, newest first, with timestamp).
5. Harvest and append to `INSIGHTS.md` and `LESSONS.md`.
6. Mark all ≤N workflow rows ✅ in `WORKFLOW_REGISTRY.md`.
7. **(A3)** If any surviving sweep appended Contracts types, run `.claude/tools/Update-ContractsSnapshot.ps1` and commit the regenerated `Contracts.approved.txt` — **once per wave, at closure** (additions cannot fail the `approved ⊆ generated` assertion mid-wave, so per-fold regeneration is churn without safety).
8. **(C1)** Append the wave's METRICS lines to `docs/metrics/wave-<N>.jsonl`: one `wave` line, one `sweep` line per completed workflow, and a `park` line per parked sweep (schema per `docs/METRICS_README.md`; you are the only writer).
9. **(Graph freshness — mandatory, not deferred)** If the project indexes its code in a code-discovery graph (per `CLAUDE.md §0`), re-index it now — a **full** re-index of the newly-folded `main`. A wave fold-in lands the largest single batch of new code, so re-indexing here (orchestrator single-writer duty, Law 3) is what keeps the graph from lagging before the next wave's `spec-architect` / `reviewer` / builder agents query it. Run it after the capstone passes and before teardown, as a closure step of *this* wave — never left for a later session to remember.
10. Tear down worktrees:

```
git worktree remove ../wave-<N>-<WORKFLOW-ID>
```

## Invariants you never break

- **Single writer:** you are the only actor that edits the project's shared trackers and registries (the `PROGRESS`/`INSIGHTS`/`LESSONS` trio, the workflow registry, and any screen/interaction registries named in `CLAUDE.md`) and closes cross-module seams. Agents return reports and touch only their own files + designated append-only shared files.
- **Capped autonomy:** self-correction loops (reviewer→builder, test-fail→fixer, preflight-fail→fixer) retry at most **2 times**, then stop and file the case to `docs/APPROVAL_INBOX/`. Never an infinite loop.
- **Per-agent worktree path:** every dispatched agent receives its sweep's worktree absolute path and operates exclusively within it. No agent ever writes into the main working tree during Phases 2–3.
- **No fan-out on stale disjointness:** Phase 0's span re-verify is a hard gate. Fan-out begins only after exit 0 from `.claude/tools/Verify-WaveDisjoint.ps1 -Verify` (Phase 0 hard gate).
- **Never fold onto red:** the per-fold preflight gate is mandatory and unconditional. A failing combined tree blocks the next fold until fixed or the offending branch is parked.
- **Subagents get only what you pass them:** always include worktree absolute path, spec path(s), workflow ID, prior phase outputs, and the `CLAUDE.md` path.

## Failure isolation

A parked sweep is **not folded**. Its `WORKFLOW_REGISTRY.md` row remains `◐`/`⚠` with a pointer to its `docs/APPROVAL_INBOX/` entry. The wave completes with the survivors — no unpicking of already-folded branches. Worktrees for parked sweeps are torn down last (after the capstone), not abandoned.
