crav1-plan-from-spec
Turn an accepted spec into a file-level plan.md and independently testable tasks.md. Use when spec.md exists and the user wants an implementation plan. Do not write application code.
SKILL.md.claude/skills/crav1-plan-from-spec/SKILL.md
GitHubPlan from spec
You turn a spec into a reviewable implementation plan and task list. You do not implement. You do not expand v0. You do not reopen rejected ADRs or non-goals.
Read this skill’s assets/plan.md and assets/tasks.md for shape (same files as docs/specs/_template/). When the spec is partial or ## In the code names paths, read that committed code in Built pieces before naming files or writing a task. When the spec has no code behind it, search the open repo before naming files.
Find the spec
Use the spec the user @-mentions. Otherwise the most recently edited tree under docs/specs/ excluding _template/. If several, ask which slug.
Read spec.md, plus diagrams.md, adr/, export/ if present. Treat spec.md as source of truth. Exports and diagrams must not add behavior; if they contradict the spec, stop and tell them to /crav1-tighten-spec or /crav1-export-spec.
Gate (no files yet)
Not ready — stop and send them back — if any of these is true:
- No primary user, no v0 vs later, or no non-goals
- Missing happy/fail/empty path
- Acceptance lines that are not yes/no
- Open questions that block the demo (auth model, source of truth, “what is v0”) with no keep-open-and-plan-around path
Say which gate failed. Next command: /crav1-tighten-spec and/or /crav1-resolve-open-questions. Do not draft a fake plan.
Ready with leftovers: kept-open questions that do not block a first demo become Risks / “do not implement until resolved” — not silent answers.
Stale research does not fail this gate. A Stale since line under ## Research findings, or a stale block on a note that section links to, is listed under Risks. Follow the readers section of crav1-add-to-spec references/research-stale.md (drop-in: .claude/skills/crav1-add-to-spec/references/research-stale.md; plugin: sibling skills/crav1-add-to-spec/references/research-stale.md). Do not block the plan. Do not clear the mark. Do not treat the stale research as current.
If two architecture shapes still fit the spec (ADR still proposed, no constraint), ask at most 3 multiple-choice questions, then wait. Do not pick a stack they never accepted.
Built pieces (before any task)
Skip this section when the spec has no code behind it. No code behind it means match status not in the code, or the spec never claims existing code (no partial status, no status done, no ## In the code, and it already has Problem, Goals, or Acceptance criteria).
When the spec is partial, or ## In the code names paths, do this before any task is written.
Use the same repo and branch test as /crav1-tighten-spec. The repo is the Match repo line, a Synced at line, or another line in spec.md that names it. The branch is the branch on that line. Do not take them from the open checkout. Do not take a branch from docs/system/repos.md when the spec does not name it.
Several branches and other repos (1.64.0). The spec's work branches are every branch in its Synced at entries, its Match Branch: list and its tasks' (branch: …) parts, minus the base branches and (dropped) entries, as crav1-add-to-spec references/branches.md (drop-in: .claude/skills/crav1-add-to-spec/references/branches.md; plugin: sibling skills/crav1-add-to-spec/references/branches.md) says. Read every work branch without checking it out (git show <branch>:<path>, git diff), from the refs on disk; never fetch. Each built piece says which branch it is on. A piece that only exists on an unmerged branch is labeled only on <branch>, not merged. When the named repo is not the open checkout, read it from ../<repo> as the same file says under Sibling checkout (options-only ask when missing; headless stops with No checkout found for <repo>. Name its path.). Never write in that checkout.
If the open checkout is a different repo, or a branch the spec does not list, stop and name the right ones. Do not read the open tree. Do not treat a stub as the code. A stub is a placeholder, for example a .gitkeep on main. If the paths on the named branch are only a stub, stop and say so.
If the spec names no branch, stop and ask which branch has the code. Do not assume main. Do not assume the open checkout. When that repo lists branches, the options are those branches. Do not pick one. After the user answers, that branch is the read. Do not write the branch onto the spec. That yes or no belongs to /crav1-tighten-spec. This skill leaves spec.md alone.
If the spec is too thin for that read (partial, status done, or ## In the code without a repo or without paths), stop. Name /crav1-add-to-spec when a change already landed on an existing spec. Name /crav1-existing-to-specs when the slice was never matched. Do not guess. Do not write a task.
Read the committed files on that branch. An uncommitted edit is not the fact. List every built piece. Do not drop one to keep the list short.
- A piece that already matches v0 is not a choice. Mark it already there. Give it no rebuild task.
- A piece the code only partly has, where v0 wants the rest, is a choice.
- A disagreement is its own line, before any task exists. Quote what the spec says and what the code does. The spec says one environment and the code enables another is one such line. It is not a match. Do not fold it into another piece.
Each choice says what it means and what it will do. These three are the only choices. Use the questions tool when it is available.
- A. Finish the gap. The code is partly there and v0 wants the rest. Write a task for that gap only. Do not rebuild what already matches.
- B. Add a verify test. The code stays as it is. Write a task for a test that checks what is already there. Do not change the feature.
- C. Leave it. No task. The plan gets one line saying this piece was left as committed. A later run does not turn it into work unless the user says so.
The user can answer one line or a batch (auth A, export C). An unanswered line stays open. Do not write a task until the choices that are open have an answer. A piece marked already there does not wait.
A later run reads ## Left as committed when that heading is already in plan.md. It does not offer those pieces again unless the user says so in this turn.
On the trace, already there and left as committed are not missing tasks. A finish-the-gap task maps only the gap. An add-a-verify-test task maps a test of what is already there and does not change the feature.
Write (after the gate)
When Built pieces left a choice unanswered, stop. Do not write files yet.
Write only:
docs/specs/<slug>/plan.md
docs/specs/<slug>/tasks.md
If export/openspec/design.md or export/openspec/tasks.md already exist, update them to match these files (same tasks, no extra scope). Do not create a full OpenSpec tree unless they asked /crav1-export-spec Format: OpenSpec.
plan.md
Use the template in this skill’s assets/plan.md. Fill:
- Constraints — from spec constraints + accepted ADRs only
- Approach — ordered steps for v0; reference diagrams
- Files likely touched — real paths if a repo exists; otherwise proposed paths consistent with the spec, marked
(proposed) - Linter — whether this repo has a linter or checker for the code those files will hold. See Linter, before Build in
references/checks.md. Specify does not name the linter - Requirements trace — table: acceptance / REQ id → task ids
- Risks — including kept-open questions (when a kept-open question blocks only some tasks, also write
Blocks: T#under it on the spec, as Blocks lines below says), and each stale research finding. One line per mark: the stale line, and the note path when there is one. Stale research does not block the plan. Do not clear the mark. - Out of scope — spec non-goals; do not plan them
- Left as committed — only when the user left a piece. One line per piece:
Left as committed: <piece>.Omit the heading when nothing was left.
Stay inside v0. File-level, not class-by-class essays. No new product behavior. A piece marked already there is named in the trace as already there and has no rebuild task. A left piece is the line above and has no task.
Blocks lines
The one exception to leaving spec.md alone. For each kept-open question under ## Open questions that blocks only some of the new tasks, write one indented line under that question: - Blocks: T2, T4. Follow crav1-add-to-spec references/open-questions.md (drop-in: .claude/skills/crav1-add-to-spec/references/open-questions.md; plugin: sibling skills/crav1-add-to-spec/references/open-questions.md). Do not change the question or its other lines. On a re-plan that renumbers tasks, replace the Blocks: lines this plan wrote. A kept-open question with no Blocks: line blocks the whole slice for /crav1-tasks-ready-to-build (inferred). List each Blocks: line in the recap.
tasks.md
Read this skill’s references/checks.md before writing tasks (drop-in: .claude/skills/crav1-plan-from-spec/references/checks.md; plugin: this skill’s references/checks.md). Name the checks there. Do not write test code.
Independently testable slices. Bad: “add authentication.” Good: “POST /register rejects invalid email (verify: unit — empty email is rejected; unit — malformed email is rejected) (spec: invalid email).”
# Tasks
- [ ] T1: <what> (verify: <kind> — <named check>) (spec: <REQ or acceptance>)
Rules:
- Each task maps to at least one spec acceptance line, REQ, or kept security check
- Every v0 acceptance line maps to at least one task (or an explicit “covered by T#”), or the trace says
already thereorleft as committed - Every kept security check (
docs/system/security.mdor a Security section on the spec) maps to a task, or the trace says which task already covers it - Each verify note names the kind and the checks, per
references/checks.md - Order so each task can be verified before the next depends on it
- When a task needs an earlier task to be done first, end its line with
(after: T1)or(after: T1, T3). Name only real needs. A task with no(after: …)has no recorded dependency, and/crav1-tasks-ready-to-buildthen treats every earlier unticked task as blocking it (inferred) - A task that finishes or tests a built piece found only on one work branch ends its line with
(branch: <name>), after(verify:),(spec:)and(after:). When the spec spans repos, name the repo too:(branch: orders-api feat/orders-retry). New work with no home gets no branch part, and there is no new question. With one branch or none, write no branch part. A task without one usesfeat/<slug>as today - No task is “and also the rest of the app”
After writing
Output only:
- Paths written
- Task count and any acceptance line with no task, not marked
already there, and notleft as committed(must be none, or the plan failed) - Each built piece: already there, finish the gap, add a verify test, or left as committed
- The branch read, when Built pieces ran
- Any verify note with no kind, and any kept security check with no task (must be none, or you failed)
- Kept-open questions parked as risks
- Each stale research finding listed under Risks, or that none was marked stale
- These notes name the checks.
/crav1-verify-build-against-specis the gate that says they passed. Do not run it here. - The linter line: the tool and command, or that this repo has none for the code these tasks will touch.
- Next, when the plan names a linter:
/crav1-review-plan(optional but useful), then/crav1-tighten-planfor planP#s. Build is expected to leave that named check green. - Next, when the plan says there is no linter: stop before Build. Say that. The user decides to add the linter or to go on without one. Do not install one. Do not name
/crav1-build-tasks, or/crav1-build-featuresuntil they choose./crav1-review-planand/crav1-tighten-planstay available. They are not Build. When they choose to go on without one, the Build next step applies, and the plan still says none. - If this branch is
spec/<slug>(specify-only):/crav1-finalize-commit(no push), then they open a PR when they want this spec on the default branch. Do not implement here. After it is on default:/crav1-create-feature-branch→feat/<slug>, then a new chat for/crav1-build-tasks. That implement chat waits until the plan names a linter, or they chose to go on without one. - If this branch is
feat/<slug>(or they stayed on one branch), and the plan names a linter or they chose to go on without one: new chat,/crav1-build-tasks(or/crav1-build-tasks) withplan.md,tasks.md, andspec.mdattached.
Do not start coding in this chat.
Parked and retired specs (1.60.0)
Skip every spec under docs/specs/retired/, and every old-path spec.md that is only a Moved: pointer. A spec whose spec.md has a Parked: line is parked: do not plan it. Say skipped: <slug> (parked) and name /crav1-retire-spec un-park docs/specs/<slug>/. Do not remove the mark.
Hard rules
- Refuse application code — no feature files, no refactors, no “quick scaffold.” If they ask to build, tell them to start a new chat with the plan attached.
- Prefer existing repo patterns when a codebase exists.
- Do not invent endpoints, entities, screens, or a performance goal the spec does not require.
- Do not write test code. Smoke after deploy, chaos, and fuzzing for its own sake stay out.
- Do not run
/crav1-review-security. Map kept checks that are already written. - A kept suggestion from
/crav1-suggest-tests-for-codethat is already an acceptance line maps to a task. A line under## Dismissed test suggestionsis not a task. Do not run/crav1-suggest-tests-for-code. - Do not run
/crav1-review-pr. Specify does not name the linter. Do not install a linter. - Do not name Build when
## Lintersays this repo has no linter or checker for the code these tasks will touch, until the user chooses to go on without one. - Do not write a rebuild task for a piece that already matches v0. Do not write a task for a piece the user left. A later run does not turn that piece into work unless the user says so.
- Finish the gap, add a verify test, and leave it are choices in this skill, before any task exists. A disagreement is its own line with those same three choices.
- Do not treat the host plan UI (Cursor Plan Mode or Claude Code plan mode) as a substitute for writing
plan.mdandtasks.mdunless they said they only want the UI plan and not files. The skill still writes both files.