About build-in-waves
build-in-waves is an agent skill for completing an approved continuous plan through dependency-aware scheduling. It coordinates per-task implementation and review, parallelizing only independent tasks with isolated worktrees.
Key features
- 01Dependency-aware task scheduling
- 02Parallel worktrees for disjoint tasks
- 03Per-task implementation and review
- 04Wave-level compile and lint gate
- 05Ledger-based progress tracking
Use cases
- 01Executing a multi-task continuous plan
- 02Running independent tasks in isolated worktrees
- 03Checking merged work before advancing
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ jayden-dang/ skills --skill build-in-wavesAfter installing, type/build-in-wavesin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
eval.jsonstory-unit-mode.mdTESTS.mdtemplates/skills-ephemera-paths.mdDetails
From the project READMEEphemera paths: resolve FEATURE_CODE / <CODE> then follow templates/skills-ephemera-paths.md (feature root .skills/<CODE>/). Resolve pack seeds in this order, first path that exists: (1) templates/ beside this SKILL.md, (2) ${CLAUDE_PLUGIN_ROOT}/templates when that variable is set, (3) ../../../templates relative to this SKILL.md.
Build In Waves
Drive an approved continuous plan to completion through one dependency-aware scheduler. A ready set of one task runs serially; a ready set of independent, surface-disjoint tasks may run in parallel worktrees. Related tasks in one dependency lane may reuse bounded worker and reviewer leases. Every task keeps its own commit, report, evidence, and two verdicts; there is no human pause between tasks.
Context rule: a fresh context is the default at a semantic-unit boundary or
after a hard lease trigger. Inside a valid lane lease, resume the role context
and pass only the task delta. Bulk artifacts travel as file paths under
.skills/, never as pasted text.
Narration: at most one short line between tool calls. Ledger + tool results carry the record.
Shared controller recipe: REQUIRED SUB-SKILL: use execute-common.
Load ../execute-common/SKILL.md when Setup preflight / ledger / todos or
After the Last Task starts. That file is the one home for those steps and
for the close-sequence predicates.
This file owns continuous-mode scheduling and barriers. The shared task
lifecycle lives in ../execute-common/task-lifecycle.md and is loaded once.
Mode ownership
Invoking this skill selects continuous execution. Align tasks.md to that
route and continue:
Execution-mode: on tasks.md | Action |
|---|---|
continuous | Proceed |
story-unit | REQUIRED SUB-SKILL: use build-by-story |
missing / unset / invalid | Write Execution-mode: continuous into tasks.md (commit if tracked). Proceed |
Unit barriers, unit derivation, and human unit stops live only in
build-by-story.
| Thought | Reality |
|---|---|
| "Header says story-unit — stay and run waves anyway" | Hand off to build-by-story |
| "I'll derive units as a size signal then continuous" | Waves come from Depends-on only |
| "Lead wants human stops — pause inside continuous" | Human-gated stops are build-by-story |
| "The tasks are small and fully specified — I'll write them myself" | Size never changes the route. Code written by the controller is build-inline; here every task gets its own implementer dispatch and its own review. In the baseline, 2 of 4 runs wrote all four tasks in the controller and only then dispatched reviewers — one reviewed all four in a single batch |
Setup
- Mode ownership. Apply the table above. Done when: header is
continuousand you stay on this skill, or you have handed off tobuild-by-story. - Session preflight. Apply
../execute-common/SKILL.mdSession preflight. Done when: that section's Done when holds. - Ledger check. Apply
../execute-common/SKILL.mdLedger check. Done when: next task is known. - Read the plan. Read
tasks.mdin full once. Record the Global Constraints path and content hash for dispatch; the brief points to the canonical section instead of pasting it into every reviewer prompt. Ifdocs/agents/project.mdis missing, say so, suggestconfigure-repo, and take verify commands from Global Constraints. When## Teamhas roster/band, load band packaging only — never skip dual-verdict review for Solo. Done when: constraints captured word-for-word. - Todos — GATE. Apply
../execute-common/SKILL.mdTodos — GATE. Done when: the list mirrors the plan and includes the Close branch todo. - Pre-flight plan review. Scan once for internal defects (contradictions, assertion-free tests, copy-pasted logic the plan mandates). Batch ALL findings into ONE question to the user before dispatch. Clean scan → no comment. Done when: conflicts ruled or none.
- Ready-set planning. Read every task's
Depends-on:andFiles:block. Named tasks must land first;Depends-on: nonemeans no prerequisite; an absent line means every earlier task is a prerequisite. Compute the next ready set from the dependency graph. A ready set may fan out only when its surfaces are disjoint and the runtime has safe worktree isolation. Apply an approvedMax-concurrencycap when present; missing meansauto. Done when: every task has a dependency position, surface-overlap result, and effective lane/concurrency decision.
Continuous scheduler
Load ../execute-common/task-lifecycle.md for the one task loop. The scheduler
supplies the task ID, lane, current base revision, brief path, report path,
review package path, and active lease IDs; the lifecycle owns dispatch, status,
review, fix, evidence, and ledger rules.
Before each worker or reviewer resume, run the lease preflight from
../execute-common/SKILL.md:
- Semantic boundary: rotate at the end of the bounded unit or when the next task changes the role's required context materially.
- Context safety: estimate system instructions, tools, retained history, capsule, task delta, and output reserve against the active context limit.
- Price safety: apply the dated provider/model
pricing_policy. If the projected request crosses an all-token cliff, or continuing costs materially more than a fresh role context, rotate before dispatch. - Hard rotation: rotate after compaction, broad scope/invariant change, harness change, or first context-confusion signal. Record the reason and preserve continuity through the capsule and ledger.
Ready sets, lanes, and barriers
- Compute the next ready set from
Depends-on:. A task is ready only after all prerequisites are ledgered clean. - If the set has one task, run the shared task lifecycle on the feature branch.
- If the set has multiple tasks, prove each pair's
Files:surfaces are disjoint and checkworktree_isolation. Overlap or missing isolation reduces the effective set to serial; record the degradation in the runtime sidecar. - For a parallel set, record
WBASE. Each lane keeps one worktree for the whole run so its build cache stays warm — a fresh worktree per task rebuilds from cold. First use:git worktree add .worktrees/<branch>-lane<k> -b <branch>-taskN WBASE; later sets:git -C .worktrees/<branch>-lane<k> switch -c <branch>-taskN WBASE. Invoke the shared lifecycle. A worker/reviewer lease may continue across ready sets only along its own dependency lane. - After every task in the set has clean Standards and Spec verdicts, merge in
deterministic task order. A conflict stops the scheduler; it is never solved
blind. Then run the wave gate at the merged HEAD: compile and lint every
target in the workspace (
project.mdWave gate, else its typecheck and lint commands), judged against the lint baseline. Red → no ledger lines; REQUIRED SUB-SKILL: useroot-cause, one fix dispatch, gate again. Green → one ledger line per task. Remove lane worktrees after the last ready set. - Recompute the ready set. There is no permission pause between tasks in continuous mode, and no task advances while its review barrier is open.
Implementer Status Handling
| Status | Your move |
|---|---|
| DONE | Package the diff → task review. |
| DONE_WITH_CONCERNS | Read concerns and .skills/<CODE>/implementation-notes.md. Entries must match the nine-field Deviations recipe in implementer-prompt.md. Missing notes path, incomplete fields, or five-field-only while claiming deviation → incomplete — re-dispatch to log first. Map impact reroute-plan / realign-spec or plan-falsifying → REQUIRED SUB-SKILL: use reroute-plan (do not accept as clean DONE). |
| NEEDS_CONTEXT | Supply what was named; re-dispatch same model. |
| BLOCKED | Context → supply; ceiling → stronger model; too large → split; plan wrong → REQUIRED SUB-SKILL: use reroute-plan. |
Cap redispatches at 2 per task; still not DONE → escalate to the user. Never force the same model to retry with nothing changed.
The operator's message changes the plan — adds a constraint, cuts scope, drops a
requirement → REQUIRED SUB-SKILL: use reroute-plan before any spec or code edit.
Model Tiering
State the model explicitly on every dispatch — omitted model inherits the session's (usually most expensive).
- Cheap: transcription / single-file mechanical fixes.
- Mid floor: every reviewer; every implementer working from prose.
- Top: design judgment, broad codebase understanding, whole-branch review.
Scale reviewer tier to diff size and risk.
Reviewer-Prompt Hygiene
- A plan-mandated defect is still a finding — ask which governs.
- No open-ended "check everything" without a concrete task-specific reason.
- Do not re-run tests the implementer already evidenced in the report.
Durable Progress
Todos are the live session view; the ledger survives compaction. After
compaction, trust the ledger and git log over conversation memory.
- Crash mid-wave → discard unmerged task branches, switch lane worktrees back
to WBASE, and re-run the whole wave off WBASE; if
.skills/(git-ignored) is wiped, reconstruct fromgit log.
After the Last Task
Apply ../execute-common/SKILL.md Close sequence in full. Do not
restate or subset those steps here.
Done when: that section's Done when holds.
Inline route
Controller-side sequential execution (no implementer subagents) is owned by
build-inline. If the user chose inline, or the environment cannot fan out
implementers: REQUIRED SUB-SKILL: use build-inline. Do not half-run this
skill's subagent loop without dispatches.
Red Flags — Never
- Run this loop when
Execution-modeisstory-unit(hand off tobuild-by-story) - Stay on this skill when the user chose inline / no subagents (hand off to
build-inline) - Run unit barriers, unit derivation, or human unit stops under continuous
- Pause between tasks to ask permission to continue
- Run two implementers in the same worktree, or parallel without isolated isolate-workspace and a disjoint-surface check
- Merge a parallel wave before every task in it passed review, or ledger it before the wave gate is green
- Hand a subagent the whole plan file — the brief is its world
- Skip re-review after a fix, or accept a review missing either verdict
- Move to the next task with open Critical/Important findings
- Write a task's code in the controller instead of dispatching its implementer
- Review several tasks in one reviewer dispatch
- Let implementer self-review substitute for task review
- Tell a reviewer what not to flag, or pre-rate severity in the dispatch
- Dispatch a reviewer without a diff package
- Re-dispatch a task the ledger marks complete