# Planning Skill (Vanilla Reference) Turn a goal into a machine-executable, wave-structured implementation plan that a fleet of parallel coding agents can run without drifting. > Vanilla reference skill — adapt the placeholders (``, ``, ``) to your project. --- ## Purpose A plan is not a description of work; it is a **contract the executor parses mechanically**. The output of a planning pass is a structured document — waves of tasks, each with exact file boundaries, a pasted code pattern, a forbidden list, dependencies, and acceptance criteria — such that an agent (or a person) can execute one task in isolation and produce a correct, reviewable result. If your plan reads like prose an engineer skims, it is not done. If an executor could parse it into a task queue, it is. --- ## The core principle > **The cost of a long plan is paid once; the cost of a wrong plan is paid every time an agent drifts.** Self-contained plans beat terse ones. A task that references "follow the standard" or "match the existing pattern" invites drift, because agents read their **own prompt body** reliably but referenced files **unreliably**. So the plan must carry, inline, everything the executor needs to be correct. Spend the tokens up front. Redundancy in a plan is not waste — it is the mechanism that keeps twelve parallel agents on the same page. --- ## Right-size first Before structuring anything, state the **smallest change that meets the goal**. Write it in one or two sentences. Then, if the plan grows beyond that minimal change, **justify each addition explicitly**. "While we're here" is not a justification. Scope creep in a plan multiplies across every task and every agent that executes it. - What is the goal, stated as an observable outcome? - What is the minimal set of edits that achieves it? - Does any proposed task exceed that minimum? If so, why is it load-bearing for the goal? Cut anything that cannot answer the last question. --- ## Anatomy of a task Every task in the plan is a self-contained unit. It carries all of the following: ### 1. Files (exact paths) The precise list of file paths the task is **allowed to touch** — nothing else. This is the boundary that makes parallel execution safe. An executor that needs to edit a file not in this list is a signal the task was mis-scoped, not a license to wander. ### 2. A verbatim canonical code pattern Paste the **real, compiling example** the task should imitate — not a description of it, not a link to it, the actual code. This is the single most important part of a task. Agents read their own prompt body reliably and referenced files unreliably. A task that says "follow the repository's standard service pattern" will drift; a task that pastes the standard service pattern as a code block will not. The pattern block is the shape the output must match: same imports, same structure, same layering. Include enough that a stranger could reproduce the idiom without opening another file. ```text # Task body carries the pattern inline, e.g.: // the real, compiling reference for this kind of change, // pasted verbatim from a known-good example in ``` ### 3. A forbidden list An explicit **"Do not…"** enumeration of the anti-patterns this task must avoid — the specific mistakes an agent is likely to make here. Examples of the *shape* of such rules (adapt to ``): - Do not touch files outside the Files list. - Do not introduce a parallel type/definition when one already flows from the canonical source. - Do not add features, tests, or files beyond what the task specifies. - Do not weaken or reshape an interface other tasks depend on. The forbidden list is the negative space of the pattern. Together they pin the output from both sides. ### 4. Dependencies Which other tasks (or waves) must complete before this one can start. Dependencies are what assign a task to a wave (see below). A task with no dependencies belongs in Wave 1. ### 5. Acceptance criteria Observable, checkable conditions that define "done" for this task. Prefer criteria an executor can verify mechanically — a command that passes, a file that exists, a symbol that resolves — over subjective judgments. `` passing is a good acceptance criterion; "the code is clean" is not. --- ## Waves: grouping for safe parallelism Independent tasks run in parallel; dependent tasks run in sequence. A **wave** is a batch of tasks that can all execute at the same time. **The hard rule for a wave: no two tasks in the same wave may touch the same file.** A shared file between two tasks is a write conflict waiting to happen — it forces those tasks into **different waves** (a wave split). File-disjointness is what makes a wave safe to fan out. - **Wave 1** contains only tasks with **no dependencies**. They can all start immediately. - **Each later wave** depends on one or more earlier waves — it starts only after its dependencies complete. - Within any single wave, every task is **file-disjoint** from every other task in that wave. To build the waves: 1. List every task and its dependencies. 2. Place all dependency-free tasks in Wave 1. 3. For the remaining tasks, place each in the earliest wave after all its dependencies — but if it would share a file with a task already in that wave, push it to the next wave. 4. Repeat until every task is placed. The result is a layered execution graph: maximum parallelism per wave, zero file conflicts within a wave, correct ordering across waves. --- ## Blast-radius enumeration Whenever a task **renames, removes, or reshapes** a symbol (a function, type, constant, export, config key — anything with readers), you must find **every reader** and account for it. For each such change: 1. Grep the entire project for the symbol — **including test files and documentation**, not just source. 2. Every location that reads the old shape must either be updated by this task or by a dependent task. 3. Add those files to the task's **Files** list (or split them into a properly-ordered dependent task). A rename that updates the definition but misses three call sites and a doc example is a broken plan. The blast-radius pass is what turns "change the thing" into "change the thing and everything that depends on it." Do it before you finalize the Files lists, because it directly determines them — and therefore determines the wave structure. --- ## Status lifecycle A plan moves through explicit states. Track the current state on the plan itself. ```text DRAFT → APPROVED → IN_PROGRESS → PR_CREATED → POSTMORTEM_COMPLETE ``` - **DRAFT** — being written; not yet reviewed or approved. - **APPROVED** — reviewed and signed off; ready to execute. - **IN_PROGRESS** — execution underway. - **PR_CREATED** — work landed on a branch and a change request opened against ``. - **POSTMORTEM_COMPLETE** — execution reviewed; lessons folded back into your process. Do not skip states. In particular, do not begin execution before **APPROVED**, and do not run a postmortem before execution is actually complete. --- ## Close the planning pass with a devil's-advocate Before **any human sees the plan**, spawn a **devil's-advocate** pass whose only job is to attack the plan — assume it is flawed and hunt for the real problems (see the devil's-advocate skill). Have it look for: - Right-sizing failures — scope beyond the minimal change, unjustified additions. - Missed blast radius — a reshaped symbol with unlisted readers. - Wave hazards — two tasks in one wave sharing a file, or a task ordered before its true dependency. - Weak acceptance criteria — "done" conditions that can't be checked mechanically. - Missing or thin patterns — tasks that say "follow the standard" instead of pasting it. - Forbidden-list gaps — likely anti-patterns the task doesn't warn against. Fold every valid concern back into the plan, then move the status to **APPROVED** only after the plan survives the attack. Catching a flaw here costs one revision; catching it during execution costs every agent that already drifted on it. --- ## Where plans live Keep plans as durable, reviewable artifacts — for example under `~/plans//`, with any project-specific planning conventions kept in ``. A plan is a document you approve, execute against, and review afterward; treat it as a first-class artifact, not a throwaway. --- ## Checklist Before marking a plan **APPROVED**: - [ ] The minimal change is stated; every addition beyond it is justified. - [ ] The plan is machine-parseable into a task queue — structured, not prose. - [ ] Every task lists exact **Files** it may touch. - [ ] Every task carries a **verbatim, compiling code pattern** — not a reference to one. - [ ] Every task has a **forbidden list** of anti-patterns to avoid. - [ ] Every task declares its **dependencies**. - [ ] Every task has **acceptance criteria** that can be checked mechanically (e.g. ``). - [ ] Every renamed/removed/reshaped symbol has had its **blast radius** grepped (source, tests, docs) and readers added to the right task's Files. - [ ] Tasks are grouped into **waves**; no two tasks in a wave share a file; Wave 1 is dependency-free. - [ ] The plan carries a **status** and started at **DRAFT**. - [ ] A **devil's-advocate** pass attacked the plan and its valid concerns were folded in — before any human review.