--- name: specs-to-plan description: "Stage 2 of the feature workflow. Use when a written spec exists under docs/specs/ and no implementation plan has been written for it yet. Reads the spec, every ADR its front matter lists, and the CONTEXT.md glossary terms it depends on, then writes a task by task implementation plan to docs/plans/ with TDD steps, exact file paths, real code, the tests each task adds or affects, and a per task commit message. Refuses to run without a spec. Do not use to write the spec itself, which is interview-to-specs, and do not use to execute a plan, which is plan-to-code." metadata: version: 1.0.0 stage: 2 of 4 derived-from: writing-plans original-author: Jesse Vincent (obra) upstream: https://github.com/obra/superpowers upstream-path: skills/writing-plans license: MIT --- # Specs to Plan Stage 2 of 4. Consumes a spec, its ADRs, and the glossary. Produces one plan. Downstream, `plan-to-code` executes that plan one task per session. **Announce at start:** "Using specs-to-plan to turn this spec into an implementation plan." Write the plan assuming the implementer has zero context for this codebase and questionable taste. They are a skilled developer who knows almost nothing about this toolset or problem domain, and who does not know good test design. Document everything: which files to touch, the actual code, how to test it, what a pass looks like. DRY. YAGNI. TDD. One commit per task. ## 1. Find the spec, or refuse A plan is an argument from a spec. Without one there is nothing to argue from, and inventing requirements is the single worst failure this skill can produce. - **A spec path was given.** Use it. - **No path was given.** List `docs/specs/` and take the newest spec whose `status` is `approved` or `draft`. Show it and ask before proceeding, using the text below. - **`docs/specs/` is empty or absent.** Stop. **When a spec must be confirmed, print exactly:** ``` No spec path was given. The newest spec in docs/specs/ is: feature: slug: status: Confirm this is the spec to plan against, or give me a different path. I will not write a plan until you answer. ``` **When there is no spec at all, print exactly and then stop:** ``` There is no spec in docs/specs/, so there is nothing to plan against. Run interview-to-specs first: Use the interview-to-specs skill I will not invent requirements. ``` **If a plan already exists for this spec's slug, print exactly and then stop:** ``` A plan for this spec already exists: One spec produces exactly one plan. Tell me whether to revise that plan or replace it. I will not write a second one. ``` ## 2. Read the upstream artifacts Read all of these before drafting anything, then state in one short block which you read. | Artifact | Where it is named | |---|---| | The spec | the path from step 1 | | Every ADR | the spec's `adrs` front matter list, by exact path | | The glossary | the file named by the spec's `context` field, usually `CONTEXT.md` | Two rules bind what you read. - **Plan language uses the glossary's canonical terms.** Every type, method, and file name in the plan uses the word `CONTEXT.md` endorses, never a word from its `_Avoid_` list. The plan is where those names get fixed into code, so drift starts here. - **A recorded ADR is not yours to overrule.** If a task you would write contradicts an ADR, stop. Do not plan around it, do not note it and continue. **On an ADR conflict, print exactly and then stop:** ``` This spec cannot be planned without contradicting a recorded decision. ADR: It says: "" The plan would need to: The remedy is a new ADR that supersedes that one, which is a decision, not a planning choice. Reopen interview-to-specs: Use the interview-to-specs skill I will not plan around a recorded decision. ``` ## 3. Map the file structure Before defining tasks, map which files get created or modified and what each is responsible for. This is where decomposition gets locked in. - Design units with clear boundaries and defined interfaces. One responsibility per file. - Prefer smaller focused files. You reason best about code you can hold in context at once, and edits to focused files are more reliable. - Files that change together live together. Split by responsibility, not by layer. - In an existing codebase, follow established patterns. Do not unilaterally restructure, though splitting a file you are already modifying and that has grown unwieldy is fair. ## 4. Right-size the tasks A task is the smallest unit that carries its own test cycle and is worth a fresh reviewer's gate. Fold setup, configuration, scaffolding, and documentation into the task whose deliverable needs them. Split only where a reviewer could meaningfully reject one task while approving its neighbour. Every task ends with an independently testable deliverable. Each step inside a task is one action taking two to five minutes. Write the failing test. Run it and watch it fail. Write the minimal implementation. Run it and watch it pass. Every task names the tests it adds and the existing tests it puts at risk, and says what a passing result looks like. That naming is the entire handover to the user at stage three, so a task whose tests are vague produces a verification the user cannot act on. Every task cites what it satisfies. A task that satisfies no requirement, acceptance criterion, or ADR is scope creep and does not belong in the plan. ## 5. Write the plan Full document shape, header fields, task structure, and the commit message convention are in [PLAN-FORMAT.md](./PLAN-FORMAT.md). Read it before writing. Save to `docs/plans/-.md`, where both the date and the slug come from the spec's front matter, not from today's date and not from the spec's filename. The four artifacts of a feature share one filename stem. **Before writing, run `git check-ignore -q docs/plans/-.md`. If it is ignored, print exactly and stop:** ``` docs/plans/ is covered by .gitignore. plan-to-code commits the plan file alongside each task, so a gitignored plan means progress is never recorded and code-to-review has nothing to check. Fix .gitignore, or tell me a different path. I will not write until you answer. ``` ## 6. Self review Run this yourself against the finished plan. It is a checklist, not a subagent dispatch. 1. **Spec coverage.** Walk every `R` and `AC` identifier in the spec and name the task that covers it. Report the result as a table, including the uncovered ones. Never proceed silently past a gap. Add the missing task, or say out loud that the requirement is deliberately unplanned and why. 2. **Placeholder scan.** Search for every red flag in the No Placeholders list in PLAN-FORMAT.md and fix what you find. 3. **Type consistency.** Do the types, signatures, and property names in later tasks match what earlier tasks defined? `clearLayers()` in Task 3 and `clearFullLayers()` in Task 7 is a bug, not a synonym. 4. **Glossary conformance.** Does every name in the plan use the canonical term? Check the `_Avoid_` lists specifically. 5. **ADR conformance.** Does any task contradict an ADR you read in step 2? If so, go to the stop text in step 2. Do not fix it in the plan. Fix what you find inline. No second review pass. ## 7. Hand off Print exactly this, filled in: ``` specs-to-plan complete. Written: docs/plans/-.md tasks Read: docs/specs/-.md Spec coverage: of requirements planned. Next stage: plan-to-code, in a fresh session, one task at a time, starting with Task 1. Use the plan-to-code skill with docs/plans/-.md task 1 Run one task per session. When every task is ticked, and only then, run code-to-review once against the whole plan. Do not review task by task. This session is done. ``` Then stop. Do not offer to execute the plan, and do not execute it. ## Refuse rather than improvise - No spec means no plan. Never infer a requirement the spec does not state. - An ADR conflict is escalated to `interview-to-specs`, never resolved here. - An uncovered spec requirement is reported out loud, never quietly dropped.