Wave Execution Planner
Groups plan phases and tasks into dependency-ordered waves for parallel subagent execution via git worktrees. Builds a task dependency DAG, assigns wave numbers via topological sort, emits a living wave document that tracks status as work lands, and updates wave progress when tasks complete. Use when asked to: group tasks into waves, plan parallel execution, schedule worktrees, create a wave breakdown, wave planning, dependency grouping, update wave statuses, parallel subagents, which tasks can run in parallel.
npx skills add github:pantheon-org/tekhne --skill project-mgmt--planning-toolkit--wave-execution-plannerGroups tasks into dependency-ordered waves so multiple subagents can work concurrently in isolated git worktrees.
Core Principles
- Waves enforce ordering, not scheduling — a wave boundary exists only where a real dependency forces sequential execution. Parallel is the default.
- One branch per parallel workstream — each phase in a parallel wave gets its own branch and worktree; agents never share a working tree.
- The wave document is the source of truth — status lives in the wave plan, not scattered across individual task files.
- Gates before advancing — ALWAYS verify the current wave fully passes before starting the next one. A broken wave in production is harder to debug than a delayed start.
- Every wave boundary must be a safe deploy point — after any wave merges, all functionality outside the scope of this plan must continue to work. Three patterns break this: a stranded consumer (code that depends on something removed in a prior wave), a premature consumer (code that requires something not yet deployed), and a breaking contract change (interface change that invalidates existing consumers before they are updated). All three require must land together grouping or explicit expand-contract sequencing.
Quick Start
- Provide requirements, a PRD, or an existing plan.
- Invoke Mode A to generate the wave document at:
.context/plans/<plan-slug>.md - Work waves in order; run Mode B after each wave to tick off statuses.
When to use
| Signal | Mode |
|---|---|
| New requirements / PRD with no existing plan | Mode A |
| Existing flat plan, phase list, or task breakdown | Mode A (from existing plan) |
| Wave document exists; tasks have been completed | Mode B |
| “Which wave is unblocked?” / “Update status” | Mode B |
When not to use
- The plan has only 1–2 tasks with no parallelism — a plain checklist is simpler.
- Tasks are all sequential with no independent workstreams — a single branch is enough.
- The caller has explicitly structured their own wave plan and only needs status updates (use Mode B directly).
Recognition examples
Input that triggers Mode A:
"Create a wave plan for this refactor. Tasks: extract lib (no deps),
scaffold CLI (needs lib), add commands A/B/C (needs CLI), cleanup (needs all commands)."
Expected output skeleton:
Wave 1 (parallel): extract-lib
Wave 2 (sequential): scaffold-cli ← depends on Wave 1
Wave 3 (parallel): command-A, command-B, command-C ← depend on Wave 2
Wave 4 (sequential): cleanup ← depends on Wave 3
Mode A — Create Wave Plan
See references/wave-format.md for output format and full examples.
Steps
- Read inputs — requirements doc, PRD, or existing plan file.
- Extract tasks — list every task with an ID, description, and explicit dependencies. If none are stated, infer from logical ordering (a test task depends on the implementation task).
- Build dependency DAG — see references/dependency-analysis.md.
- Assign waves — Wave 1 = tasks with no dependencies; Wave N = tasks whose all dependencies are in waves 1..N-1.
- Decide execution mode — a wave with >1 independent task is
parallel; a wave with 1 task (or tasks that must run in order) issequential. Then apply the safe intermediate state check to every wave boundary: “If this wave deploys and the next has not landed yet, does any existing functionality break?” If yes, merge the tasks on both sides of that boundary into a single must land together wave — see references/dependency-analysis.md for patterns and detection guidance. - Write output: emit
<plan-slug>.mdto the plans location shown in Quick Start, using the format in references/wave-format.md. - Validate — every task appears in exactly one wave; no wave contains tasks that depend on each other.
Mode B — Update Wave Status
See references/status-tracking.md for the full update protocol.
Steps
- Read wave document: load the current wave document for the plan slug (see Quick Start for its location).
- Run verification gate — execute the commands listed in the completed wave’s
Verification:checklist:# example gate for a test-coverage wave bun run test --coverage bun run typecheck git log --oneline main..HEAD - Update statuses — tick checkboxes or update
Statuscolumn cells. - Mark wave — append
— DONEto the wave heading when all verifications pass. - Announce next wave — state which wave is now unblocked and whether it is parallel or sequential.
- Save — write the updated document back.
Status transitions
Pending → In Progress → Done
↓
Blocked (add a > BLOCKED: note)
Anti-patterns
Each entry gives the rule, WHY it exists, then a BAD and GOOD example.
NEVER put dependent tasks in the same wave
WHY: agents working in parallel worktrees assume no ordering, so placing dependent tasks together causes undefined behaviour or overwrite conflicts.
BAD: Wave 2 (parallel): scaffold-cli, add-commands where the commands need the scaffold.
GOOD: Wave 2: scaffold-cli, then Wave 3 (parallel): command-A, command-B, command-C.
NEVER label a wave parallel if it contains only one task
WHY: parallel signals subagent tooling to spin up worktrees; a single-task wave wastes setup overhead and misleads reviewers.
BAD: Wave 1 (parallel): extract-lib.
GOOD: Wave 1 (sequential): extract-lib.
NEVER advance to Wave N+1 before Wave N verification passes
WHY: a broken merge point in production compounds into every parallel branch; early detection is always cheaper.
BAD: mark Wave 2 in progress while one Wave 1 verification check is still unticked.
GOOD: name the failing check, hold Wave 2 as pending, and tell the user what must pass first.
NEVER track status inside individual task files
WHY: distributed status creates stale reads and coordination failures when multiple agents update concurrently.
BAD: add a status: done line to each phase file and treat those as the record.
GOOD: update checkboxes or the Status column in the single wave document.
NEVER invent dependencies that are not stated in the requirements
WHY: fabricated ordering reduces parallelism, slows execution, and breaks the contract between the plan and the actual work.
BAD: serialise two unrelated documentation tasks because they “feel” related.
GOOD: infer only logical ordering (a test task depends on its implementation task) and leave the rest parallel.
NEVER create an unsafe intermediate deploy state at a wave boundary
WHY: each wave merge is a potential release point. Runtime dependencies (config values, API contracts, schema columns, env vars, permission grants, event topics) are invisible to the code-level DAG but fatal when missequenced. Three failure modes: (1) stranded consumer, a resource is removed before all code that uses it is also removed or updated; (2) premature consumer, code that requires a resource (new env var, schema column, endpoint) deploys before that resource exists; (3) breaking contract change, an interface changes incompatibly before all consumers are updated.
BAD: Wave 1 removes an SDK-backed infrastructure resource and Wave 2 updates the services that still call it.
GOOD: group tasks that must deploy atomically into a single must land together wave, or use explicit expand-contract sequencing across waves. See references/dependency-analysis.md.
NEVER share a working tree between parallel agents
WHY: agents editing the same tree overwrite each other and leave no clean merge point per workstream.
BAD: two phases in a parallel wave both commit to the same branch checkout.
GOOD: each phase in a parallel wave gets its own branch and worktree, listed in the Branch Strategy table.
NEVER declare a wave done without running its verification checklist
WHY: “it looks right” is not a gate, and an unverified wave hides defects until the next merge.
BAD: append — DONE to the wave heading after reading the diff.
GOOD: run every command in the wave’s Verification: list, tick each item, and only then mark the wave done.
NEVER leave a task missing from, or duplicated across, the waves
WHY: a task absent from every wave is never executed, and one present in two waves is built twice.
BAD: a plan with nine tasks whose waves list eight, or list one task twice.
GOOD: validate that every task appears in exactly one wave before writing the output.
References
- references/wave-format.md — Wave document format, sections, and worked examples
- references/dependency-analysis.md — Building the DAG and assigning wave numbers
- references/status-tracking.md — Status update protocol and verification gates
- references/wave-document.yaml — Copy-paste template for a new wave document
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
Expert-only knowledge the AI couldn't derive on its own — domain-specific patterns, production gotchas, decision frameworks, and non-obvious tool behaviour. High scores mean <5% redundancy with what the model already knows.
A clear philosophy plus numbered step-by-step workflows with explicit entry/exit points. Should answer: what is the core principle, how to execute it, and when (and when not) to apply it.
Explicit NEVER/WHY/consequence triplets with side-by-side bad/good examples. Generic warnings score low — concrete failure modes with real impact (security, correctness, performance) score high.
Proper frontmatter, single-task focus, activation keywords, and cross-harness portability. Skills must work across 40+ agentic harnesses without hardcoded paths or agent-specific references.
SKILL.md as a <100-line navigation hub pointing to focused references/ files. Content should be lazy-loaded on demand, not front-loaded. Includes actionable 'When to Use' conditions per reference.
Appropriate rigidity for the skill type: strict rules for critical/security skills, balanced steps for process skills, flexible options for tool skills. Mismatched calibration (too rigid or too loose) reduces score.
Rich activation keywords and trigger scenarios in the description so the skill fires when needed. Best descriptions read like an exhaustive list of the tasks and concepts that should invoke this skill.
Copy-paste-ready code, complete runnable examples, real file paths and commands. Pseudocode and abstract descriptions score low — concrete, executable content scores high.
Runtime validation via eval scenarios proving the skill actually changes agent behaviour. Requires evals/ directory, instructions.json, ≥3 scenarios, and ≥80% instruction coverage in summary.json.
No eval scenarios available.
Dependency Analysis
How to build a task dependency DAG and assign tasks to waves.
Step 1 — Extract tasks
List every task with:
- ID — short identifier (
T1.1,P0,phase-3, etc.) - Description — what the task does
- Dependencies — IDs of tasks that must complete first (empty = none)
If dependencies are not stated in the source document, infer them:
| Signal in source | Inferred dependency |
|---|---|
| “after X is done” / “once X lands” | task depends on X |
| “requires X to exist” | task depends on X |
| Test task for feature F | depends on F implementation |
| Merge / cleanup task | depends on all tasks being merged |
| Validation task | depends on all implementation tasks |
| Deployment task | depends on validation task |
| Tasks touching the same file | sequential dependency on earlier task |
| Tasks touching independent files | no dependency (can be parallel) |
| Infrastructure task removes a resource (config value, secret, permission grant, env var, queue) that the live application still reads at runtime | both the infrastructure removal and the consumer code removal must land together — flag for Step 5 |
| New code requires a resource (env var, schema column, API endpoint) that does not yet exist in the deployed environment | both the resource-creation task and the consumer code task must land together, or the resource-creation wave must precede the consumer wave — flag for Step 5 |
| A task changes an interface (API contract, event schema, DB column type) in a way that is incompatible with existing consumers | use expand-contract sequencing: Wave N adds the new alongside the old, Wave N+1 migrates consumers, Wave N+2 removes the old — flag for Step 5 |
Step 2 — Build the DAG
Represent the graph as an adjacency list:
T1.1 → [] (no dependencies)
T1.2 → []
T2.1 → [T1.1] (depends on T1.1)
T2.2 → [T1.2]
T3.1 → [T2.1, T2.2]
Check for cycles — a cycle means the requirements are contradictory. Surface this to the user before proceeding.
Step 3 — Assign waves (topological sort)
Wave(task) = 1 if task has no dependencies
Wave(task) = 1 + max(Wave(dep) for dep in dependencies)
All tasks with the same wave number can execute concurrently.
Example:
T1.1 deps=[] → Wave 1
T1.2 deps=[] → Wave 1
T1.3 deps=[] → Wave 1
T2.1 deps=[T1.1] → Wave 2 (1 + max(1) = 2)
T2.2 deps=[T1.1, T1.2] → Wave 2
T3.1 deps=[T2.1] → Wave 3
T3.2 deps=[T2.1, T2.2] → Wave 3
T4.1 deps=[T3.1, T3.2] → Wave 4
Step 4 — Label waves
Give each wave a short descriptive label:
| Pattern | Example label |
|---|---|
| Diagnostics / audits | “Diagnostics & Design” |
| Setup / scaffolding | “Bootstrap & Extract” |
| Core implementation | “Fix & Build” |
| Tests / coverage | “Coverage & Validation” |
| Integration / merge | “Integration & Wrap-up” |
| Pre-requisites | “Pre-work” |
| Final checks / PR | “Wrap-up” |
Step 5 — Decide parallel vs sequential
A wave is parallel when:
- It contains 2 or more tasks that touch different files/modules, AND
- There is no ordering constraint among those tasks.
A wave is sequential when:
- It contains only 1 task, OR
- Tasks within the wave must run in a specific order (e.g. “apply migration THEN verify”), OR
- A critical shared resource prevents concurrent work (e.g. single CloudFormation stack).
A wave is must land together when:
- Tasks within the wave must be committed/deployed atomically because any intermediate deployed state would break a live service.
How to detect it: For every wave boundary, ask: “If this wave deploys and the next has not landed yet, does any existing functionality break?” If yes, tasks on both sides must be in the same must land together wave. Three patterns trigger this:
| Pattern | Broken intermediate state | Fix |
|---|---|---|
| Stranded consumer | A resource (config, env var, permission, queue) is removed in Wave N; code that still reads it is only removed in Wave N+1 | Merge both tasks into one must-land-together wave |
| Premature consumer | Code that requires a new resource (env var, schema column, API endpoint) ships in Wave N; the resource is created in Wave N+1 | Create the resource first (earlier wave), or merge into must-land-together |
| Breaking contract | An API, event schema, or DB column changes incompatibly in Wave N; consumers that rely on the old contract are only updated in Wave N+1 | Use expand-contract sequencing: add new alongside old → migrate consumers → remove old |
Common triggers:
- Removing a configuration value, secret, or permission grant that the live service reads at startup or runtime
- Removing a queue, topic, or storage resource that the live service publishes or reads from
- Deploying a service that reads a new required env var before that variable is provisioned
- Adding a NOT NULL database column before the code that writes to it is deployed
- Changing an API contract (removing a field or endpoint) before all consumers are updated
Note: the code-level dependency graph will NOT catch these. Runtime dependencies have no source imports, so a naive topological sort assigns the tasks to different waves. You must reason about the deployed runtime state, not the source tree.
Step 6 — Assign branches
For parallel waves, assign one branch per workstream:
<type>/<scope>-<slug>
Examples:
refactor/scripts-lib-httpfeat/phase-3-clean-lambdatest/baselineci/deployment-automation
For sequential waves, one branch covers the whole wave:
<type>/<wave-label-slug>
DAG diagram format
Emit in the Dependency Graph section of the wave document:
Wave 1 (parallel)
T1.1 <description> ─┐
T1.2 <description> ─┤─► Wave 2
T1.3 <description> ─┘
Wave 2 (parallel, unblocked after Wave 1)
T2.1 <description> (← T1.1) ─┐
T2.2 <description> (← T1.2) ─┤─► Wave 3
T2.3 <description> (← T1.3) ─┘
Wave 3 (sequential)
T3.1 <description> (← all Wave 2)
Rules:
- Use
─┐,─┤,─┘for parallel merges. - Use
(← X)to annotate the specific dependency. - Use
─►to show the wave that unblocks.
Edge cases
Task with many dependents
If T1.1 is a prerequisite for 10 tasks, those 10 tasks are still all Wave 2 — they just all depend on T1.1. Do not create an intermediate wave just to “stage” them.
Circular dependency detected
Surface to user:
ERROR: Circular dependency detected: T2.1 → T3.1 → T2.1
Cannot assign wave numbers until this is resolved.
Suggested fix: [description of how to break the cycle]
Tasks with unknown dependencies
When a task says “depends on the above” without specifying, treat it as depending on all tasks earlier in the same phase/section.
Large waves (>5 tasks)
Split large parallel waves into sub-groups by semantic domain, keeping them in the same wave number. Use phase rows in the table to separate the groups visually.
Unsafe intermediate deploy states
The naive topological sort assigns waves based on code-level imports. It cannot detect runtime dependencies. Three patterns produce an unsafe intermediate state; all require manual correction.
Stranded consumer
When a wave removes an infrastructure resource AND a later wave removes the consumer code that still references it, deploying the first wave alone breaks the live service.
Fix: merge both tasks into the same must-land-together wave. They can be worked in parallel worktrees but must deploy together.
Example (decommissioning a third-party SDK):
WRONG — separate waves:
Wave 2: remove config parameter, permission grant, env var (infrastructure)
Wave 3: remove SDK client & dead code paths (application code)
→ Deploying Wave 2 alone breaks the live service
CORRECT — same wave:
Wave 2 (must land together):
Phase 1: remove config parameter, permission grant, env var (infrastructure)
Phase 2: remove SDK client & dead code paths (application code)
> Phases 1 and 2 must deploy atomically.
Premature consumer
When a wave deploys code that depends on a resource that does not yet exist in the environment (new required env var, NOT NULL schema column, new API endpoint), the service fails on startup or at the call site.
Fix: either create the resource in an earlier wave (safe default), or merge resource-creation and consumer into a single must-land-together wave.
Example (adding a required external API key):
WRONG — consumer first:
Wave 1: deploy service code that reads NEW_API_KEY env var
Wave 2: provision NEW_API_KEY in the environment
→ Wave 1 fails at startup: env var missing
CORRECT — resource first:
Wave 1: provision NEW_API_KEY in the environment
Wave 2: deploy service code that reads NEW_API_KEY
Breaking contract change
When a wave changes an interface (REST endpoint shape, event schema, DB column type) in a way that is incompatible with current consumers, deploying the change alone breaks every caller that has not yet been updated.
Fix: use expand-contract sequencing across three waves. Never remove the old version until all consumers have migrated.
Example (renaming an API field):
WRONG — big-bang:
Wave 2: rename field user_id → userId in both API and all consumers
→ Any consumer not yet deployed breaks
CORRECT — expand-contract:
Wave 2: API emits both user_id and userId (backwards-compatible)
Wave 3: migrate all consumers to read userId
Wave 4: remove user_id from the API response
Status Tracking
How to update a wave document as work progresses (Mode B).
Status vocabulary
Task-level (checkbox format)
- [ ] T1.1 — description ← Pending
- [~] T1.2 — description ← In Progress (use [~] or [/] per project convention)
- [x] T1.3 — description ← Done
Phase-level (table format)
| Value | Meaning |
|---|---|
Pending |
Not started |
In Progress |
Agent is actively working on this phase |
Done |
All tasks complete, verification passed |
Blocked |
Blocked by an unresolved issue (add a note) |
Wave-level (heading badge)
Append a status tag to the wave heading:
### Wave 1 — Diagnostics & Design (parallel) ✅ done
### Wave 2 — Fix & Build (parallel) 🔄 in progress
### Wave 3 — Coverage & Validation (parallel) ⏳ pending
Or plain ASCII equivalents (preferred for agent-authored docs):
### Wave 1 — Diagnostics & Design (parallel) — DONE
### Wave 2 — Fix & Build (parallel) — IN PROGRESS
### Wave 3 — Coverage & Validation (parallel) — PENDING
Document-level header
**Status**: In Progress ← update when first wave starts
**Status**: Complete ← update when all waves done and final checks pass
**Status**: Blocked ← update with a reason note when stuck
Mode B update protocol
Run after a wave’s work is committed and merged:
- Run verification commands listed in the completed wave’s
Verification:checklist. - For each passing check: tick the checkbox
- [ ]→- [x]. - For each phase row: update
Statuscell fromIn Progress→Done. - When all verifications pass: mark the wave heading
— DONE. - Update next wave: change its phases from
Pending→In Progressif agents are starting. - Update document header: set
**Status**: In ProgressorCompleteas appropriate. - Save and report: write the file, then report which wave is now unblocked.
Verification gate before next wave
NEVER advance to wave N+1 if wave N has:
- Any failing verification check.
- Any phase still in
In Progressstate. - Any open blocker note.
Example gate check protocol:
**Before starting Wave 2:**
Run the following and confirm all pass:
- `vitest run` — all tests green
- `tsc --noEmit` — no type errors
- `git log --oneline main..HEAD` — all Wave 1 commits present on main
Handling partial completion
If a wave is partially done (some tasks complete, some not):
- Tick completed task checkboxes.
- Set partially-done phase rows to
In Progress(notPending). - Leave wave heading as
— IN PROGRESS. - Do NOT advance to the next wave.
Handling blocked tasks
If a task is blocked:
- Add a
> BLOCKED:note immediately after the task entry. - Set phase status to
Blocked. - Set wave heading to
— BLOCKED. - Surface to the user with: what is blocked, why, and the suggested unblocking action.
- [~] T2.3 — Fix e2e polling
> BLOCKED: Playwright browser download fails in CI — pending infrastructure ticket #4521.
Worktree cleanup after wave merge
After a parallel wave’s branches are all merged:
# List worktrees
git worktree list
# Remove each worktree that was used for this wave
git worktree remove <path>
# Delete merged branches
git branch -d <branch-name>
Add a Cleanup: subsection to the wave if worktrees were used:
Cleanup (after merge):
- [ ] Remove worktrees: `git worktree remove <path>`
- [ ] Delete branches: `git branch -d <branch>`
Example — updated wave document snippet
### Wave 1 — Extract shared lib (parallel) — DONE
> Gate: None — start immediately.
- [x] T1.1 — `scripts/lib/http.ts` — branch `refactor/scripts-lib-http`
- [x] T1.2 — `scripts/lib/dates.ts` — branch `refactor/scripts-lib-dates`
- [x] T1.3 — `scripts/lib/wikidata.ts` — branch `refactor/scripts-lib-wikidata`
- [x] T1.4 — `scripts/lib/paths.ts` — branch `refactor/scripts-lib-paths`
Verification:
- [x] All merged; `main` CI green
- [x] No direct imports of old paths remain
Cleanup:
- [x] Worktrees removed
- [x] Branches deleted
### Wave 2 — Scaffold CLI (sequential) — IN PROGRESS
> Gate: Wave 1 verified ✓
- [~] T2.1 — Install Cliffy + scaffold `scripts/cli.ts` — branch `refactor/scripts-cli-scaffold`
Verification:
- [ ] `deno task cli --help` exits 0
- [ ] No old script imports remain in `cli.ts`
Wave Document Format
The wave document is the living execution record for a plan. It is written once (Mode A) and updated in-place as waves complete (Mode B).
File location
.context/plans/<plan-slug>.md
Use the plan slug from the requirements or a short descriptive identifier (e.g. scripts-cli-refactor, infra-cleanup, auth-migration).
Document structure
# <Plan Title>
**Ticket / ref**: <link or N/A>
**Status**: <In Progress | Complete | Blocked>
**Assignee**: <name or team>
## Goal
<One paragraph: what success looks like.>
## Conditions of Satisfaction
- [ ] <observable outcome 1>
- [ ] <observable outcome 2>
## Dependency Graph
<ASCII DAG — see dependency-analysis.md>
## Waves & Phases
### Wave 1 — <Label> (<parallel | sequential>)
> <Gate note: what must be true before this wave starts. "None — start immediately" for Wave 1.>
| Phase | Focus | Tasks | Status | Model |
|-------|-------|-------|--------|-------|
| [N](phase-N-<slug>.md) | <description> | <count> | Pending | standard |
Verification:
- [ ] <command or check that must pass before Wave 2 starts>
### Wave 2 — <Label> (<parallel | sequential>)
> Gate: Wave 1 verified ✓
...
## Branch Strategy
| Branch | Tracks | Base |
|--------|--------|------|
| `<branch-name>` | <tasks or phases> | `<base>` |
Merge order: <branch A> → <branch B> → ...
## Definition of Done
- [ ] All wave verification gates pass
- [ ] All branches merged to <main branch>
- [ ] CI green on <main branch>
- [ ] <project-specific criterion>
Wave section rules
- Wave heading:
### Wave N — <short label> (<parallel | sequential>)parallel= 2+ phases with no mutual dependency; each gets its own branch + worktree.sequential= 1 phase, or phases that must run in order within the wave.
- The table lists phases (rows), not individual tasks. For small plans with no formal phases, list tasks directly.
- Status values:
Pending→In Progress→Done - Add a
> Gate:blockquote at the top of each wave (except Wave 1). - Add a
Verification:checklist at the bottom of each wave. - Model column (optional): specifies the agent capability tier for each phase. Valid values:
fast,standard,smart. Omit the column or leave a cell blank to default tostandard. Thewave-executorskill resolves these to concrete model IDs via itsreferences/model-map.yamlat execution time.
Phase row format
| Column | Content |
|---|---|
| Phase | Link to phase file, or inline phase ID [N](path) |
| Focus | 3–6 word description of what the phase accomplishes |
| Tasks | Integer count of discrete tasks inside the phase |
| Status | Pending / In Progress / Done |
| Model | (optional) fast / standard / smart — agent capability tier. Defaults to standard if omitted. |
If the plan has no separate phase files, use task IDs directly (e.g. T1.1, T2.3).
Inline task format (no phase files)
Use this for smaller plans where phases are not broken into separate files:
### Wave 1 — Extract shared lib (parallel)
> Gate: None — start immediately.
Run **T1.1–T1.4 in parallel, each in its own worktree.**
Each agent works independently; tasks touch different files with no overlap.
- [ ] **T1.1** — `scripts/lib/http.ts` — branch `refactor/scripts-lib-http` — model: `fast`
- [ ] **T1.2** — `scripts/lib/dates.ts` — branch `refactor/scripts-lib-dates` — model: `standard`
- [ ] **T1.3** — `scripts/lib/wikidata.ts` — branch `refactor/scripts-lib-wikidata` — model: `standard`
- [ ] **T1.4** — `scripts/lib/paths.ts` — branch `refactor/scripts-lib-paths` — model: `fast`
**Wave 1 merge**: after all branches pass validation, merge in order:
`refactor/scripts-lib-http` → `refactor/scripts-lib-dates` → `refactor/scripts-lib-wikidata` → `refactor/scripts-lib-paths`
Verification:
- [ ] All merged; `main` CI green
- [ ] No direct imports of old paths remain
The — model: fast|standard|smart suffix is optional on inline tasks. Omit it to default to standard.
Dependency graph format
Place the DAG immediately after the Goal section.
## Dependency Graph
```text
Wave 1 (parallel)
T1.1 task-a ─┐
T1.2 task-b ─┤─► Wave 2
T1.3 task-c ─┘
Wave 2 (parallel, unblocked after Wave 1)
T2.1 task-d (← T1.1) ─┐
T2.2 task-e (← T1.2) ─┤─► Wave 3
T2.3 task-f (← T1.3) ─┘
Wave 3 (sequential)
T3.1 task-g (← all Wave 2)
```
Worked example — phases in table (infrastructure cleanup)
## Waves & Phases
### Wave 1 — Pre-work (sequential)
> Gate: None — start immediately.
| Phase | Focus | Tasks | Status |
|-------|-------|-------|--------|
| [0](infra-cleanup/phase-0-validation.md) | Validation & Coordination | 5 | Done |
Verification:
- [x] All validation checks pass; no regressions introduced
### Wave 2 — Cloud Infrastructure (must land together)
> Gate: Wave 1 verified ✓
| Phase | Focus | Tasks | Status |
|-------|-------|-------|--------|
| [1](infra-cleanup/phase-1-resource-removal.md) | Remove Unused Resource | 4 | Done |
| [2](infra-cleanup/phase-2-consumer-updates.md) | Update Consumers | 3 | Done |
> Phases 1 and 2 must deploy atomically — stage together before applying.
Verification:
- [x] Infrastructure diff shows only expected deletions
- [x] Plan/dry-run exits 0
### Wave 3 — Code Cleanup (parallel, same PR)
> Gate: Wave 2 verified ✓
| Phase | Focus | Tasks | Status |
|-------|-------|-------|--------|
| [3](infra-cleanup/phase-3-clean-business-logic.md) | Clean Up Business Logic | 7 | Done |
| [4](infra-cleanup/phase-4-clean-tests.md) | Clean Up Tests | 6 | Done |
> Phases 3 and 4 touch independent files and can be worked in parallel.
Verification:
- [x] Test suite exits 0
- [x] No references to removed resource remain