| name | to-plan |
| description | Capture the chat into `.task/task/<slug>.md` with `## Description` plus `## Plan` (Goal/Touches/Logic) — the deepest one-task capture. |
| disable-model-invocation | true |
| user-invocable | true |
Distil the chat discussion so far (or a roadmap item) into .task/task/<slug>.md — ## Description and ## Plan (Goal/Touches/Logic steps), plus ## Tests when the testing policy calls for it, and the standard ## Execution block. The deepest of the three capture skills (to-task / to-plan / to-roadmap): use it when you know enough about the approach to hand straight to implementation, or run it again on a to-task-only file to add the Plan in place. The slug is the filename; the artifact path is the handle.
Input: $ARGUMENTS — optional. Recognized forms:
- (empty) — draft from the chat discussion so far, or continue a task this conversation is clearly about (see Step 1).
<slug> or a path to an existing .task/task/<slug>.md — target that file directly.
<roadmap-slug> or <roadmap-slug>#<N> — open from that roadmap item instead of the chat.
- anything else — free-form context to fold into the draft alongside the chat discussion.
Format contract: docs/contract.md is the single source of truth for the output structure — read it if anything below is ambiguous.
Step 0: Setup gate
Check whether .task/config/config.md exists — resolve the pipeline root via skills/_lib/resolve-ws.sh (source it; it exports AI_DIR).
- Absent → inline setup. Run the inline setup gate exactly as
skills/to-task/SKILL.md Step 0 does (detect stack → ONE AskUserQuestion confirmation with Accept / Edit / Decline chips → write config.md + git config --local task.root "$ROOT" + exclude .task). to-task's Step 0 is the single source of truth for the sub-steps; do not defer to a separate setup command. Two to-plan-specific notes: create .task/task/ alongside config.md, and on Decline report "config.md not written. → Next: run /task:to-plan again when ready" and stop. On success, continue to the validate call below with the original $ARGUMENTS unchanged.
- Present → skip silently, proceed to validate.
Then run bash "${CLAUDE_PLUGIN_ROOT}/skills/validate/validate.sh" all as a self-check — v3 has no gate, so report any findings and continue rather than blocking. Only a config-precondition failure (exit 2) should stop the flow.
Step 1: Resolve the target and capture mode
The artifact path is the handle. Resolve a target reference, in order:
- Explicit slug or path in
$ARGUMENTS matching .task/task/<slug>.md (existing or not) → that path is the target.
- Roadmap reference in
$ARGUMENTS (<roadmap-slug> or <roadmap-slug>#<N>, matching an existing .task/roadmap/<slug>.md) → resolve the item (Step 2a's item-picking logic) and derive its target path .task/task/<item-slug>.md from the item title.
- No positional reference, but the chat is clearly continuing or refining a task this session already captured (a
to-task/to-plan run earlier in this conversation, or the user names an existing task by title/slug) → that file is the target. If more than one file could plausibly match, ask via AskUserQuestion (convention (c)) rather than guessing.
- Nothing resolves → no target; go to Step 2 for a fresh capture with no prior reference.
Once a target reference is resolved (1–3), branch on whether the file exists:
- Target file does not exist yet → fresh capture at that path. If it came from a roadmap reference, continue at Step 2a; otherwise treat the resolved slug/title as a starting point and continue at Step 2b.
- Target file exists, no
## Plan heading present → promote mode. This is the flag-free way to turn a to-task capture into a plan: skip Step 2 entirely — header and ## Description already exist and are untouched. Go straight to Step 3 using the existing Description as context, then in Step 7 insert ## Plan (and ## Tests) rather than create.
- Target file exists,
## Plan already present → revise mode. to-plan was already run on this file. Skip Step 2, go straight to Step 3 using the existing Description (and the current chat) as context, then in Step 7 replace the existing ## Plan (and ## Tests only if the user's edit touches it) rather than create or blindly append a duplicate section.
No target at all (case 4): if one or more .task/roadmap/*.md files have an unchecked (- [ ]) item and there is no chat discussion to draft from, present an AskUserQuestion fork (convention (c)): "How do you want to start this task?" — Draft from this chat / Open from a roadmap. The latter opens a second AskUserQuestion listing the roadmap slugs, then proceeds as Step 2a with the chosen slug. If there is chat discussion to draft from, proceed as Step 2b. If there is neither a chat discussion nor any unchecked roadmap item to draw on (nothing to capture), stop and ask the user what to capture rather than drafting from nothing.
Step 2: Fresh capture — Title and Description
Only for fresh capture (skip entirely for promote/revise — see Step 1).
Step 2a: From-roadmap
- Resolve
<slug> to .task/roadmap/<slug>.md; if ambiguous or missing — stop and ask.
- Pick
<N>: if given, use it. Otherwise collect open items (- [ ] checkbox headings); if none — stop: "all items in <slug> are closed; pick one explicitly with <slug>#<N>, or draft from chat instead." More than one open item → ask via AskUserQuestion (chip per #<N> — <title>, first/lowest default); exactly one → auto-pick it.
- Read the item's
### Context / ### Goal / ### Outcomes / ### Invariants / ### Acceptance criteria block. ### Context becomes the Description's "why"; the rest folds into the "what". ### Acceptance criteria entries are good candidates to carry into ## Tests (Step 4) verbatim as test intents when tests are required.
- Note the specs this item relies on: any
### Spec references → <spec-slug> §N in the item body, plus the roadmap's own Spec: <slug> header lines. Read each .task/spec/<spec-slug>.md now — carry them into Step 3 as pinned anchors (see Step 3's note), and hold the distinct <spec-slug>s for the Spec: headers in Step 7's write.
- Derive the slug: kebab-case of the item title (2–4 words). If it collides with an existing, unrelated
.task/task/<slug>.md, disambiguate with a short qualifier (e.g. append a second distinguishing word) rather than overwriting.
- Hold, for Step 7's write, the header lines in the shape Step 7 writes —
# {Item title} plus Roadmap: / Source item: and a Spec: line per cited spec — and the drafted ## Description body (why from Context, what from Goal/Outcomes/Invariants/Acceptance criteria). Continue to Step 3 — do not write the file yet; the full task.md (Description + Plan + Tests) is assembled and written once, together, in Step 7.
Step 2b: Chat-draft
- Slug. Generate a short kebab-case slug (2–4 words) from the chat's essence, in English regardless of
config.md → Language (the slug is a filename, a parser-stable string). If it collides with an existing, unrelated task file, disambiguate rather than overwriting.
- Distil the chat. Read back over the discussion in this conversation (not the codebase yet) and draft
## Description — the why + what, in the user's own framing. Use ### Problem / ### Outcome / ### Scope / ### Constraints sub-headers where the discussion gives signal for them; omit a sub-header rather than inventing content. Do not fabricate anything not actually discussed.
- Hold the header line
# {Short task title} (no Roadmap: / Source item: lines in this mode) and the drafted Description for Step 7's write. If the discussion clearly relies on a spec in .task/spec/, hold a Spec: <slug> header line for each relevant one too (never invent a reference; never author the spec — that is to-spec's job). Continue to Step 3.
Step 3: Analyze the codebase
Shared by every mode (fresh chat-draft, fresh from-roadmap, promote, revise): ## Plan steps need real paths, not paraphrase.
Use the Description (fresh capture) or the existing ## Description (promote/revise) as the "what" to ground against real code. Read code in ascending cost order per config.md → Code Navigation (MCP tools first, built-ins as fallback):
- From modules/packages/files named or implied in the Description — get a structural overview.
- Read symbol bodies selectively — only those directly affected.
- Identify dependencies and usage locations.
- Find existing patterns in neighboring code for reuse.
- Assess impact on adjacent modules/components.
Reads within a tier are independent — issue them as one parallel batch, not one round-trip at a time.
Pinned technical decisions. If the task carries (or, on fresh capture, will carry) any Spec: <slug> header, read each .task/spec/<slug>.md and treat its decisions as a fixed anchor — ## Plan must honor them, not re-derive a different technical choice. No Spec: header at all → no anchors, proceed on the Description alone.
Stop analysis as soon as you can name every file each step will touch and how — deeper investigation than that belongs to the implementing session's own reasoning, not to planning.
Step 4: Resolve tests_required
From .task/config/config.md → Testing Policy → Mode:
always → tests_required = true.
never → tests_required = false.
on-demand → true only if the Description (or the chat discussion) explicitly asks for tests (phrases like "with tests", "add tests", "write tests"). Otherwise resolve two remaining cases distinctly:
- Silent — nothing about tests anywhere →
tests_required = false, no prompt.
- Testing-adjacent but unclear — tests/testing mentioned but not whether new tests are wanted → in an interactive run, ask one yes/no question before drafting
## Tests; in a non-interactive run (no user to ask — e.g. to-plan invoked as roadmap-to-workflow's per-item planning agent) do not block, default to false.
to-task never writes ## Tests (only to-plan does), so there is nothing to reuse from a prior to-task capture — resolve fresh here. In revise mode, reuse the prior ## Tests resolution unless the current chat discussion or edit explicitly changes the testing ask.
Step 5: Draft the Plan (and Tests)
Write ## Plan using the three-layer step contract from docs/contract.md:
## Plan
### Step 1: {short action title}
**Goal:** {the observable end state this step reaches — detailed enough that an
executor understands intent and result without guessing. Do not compress into
one line if the task has nuance; do not pad it with filler either.}
**Touches:** `{full path}` `{full path}` {…as many as this step actually changes}
**Logic:** {optional — pseudocode clarifying non-obvious branching/flow. Omit
entirely when Goal + Touches leave no ambiguity. Never include for a
straightforward step.}
### Step 2: ...
Rules:
- Full paths from the project root in
Touches; no placeholders like ... outside a Logic block.
- If a step is a new file,
Goal states its role and Touches still names it; if a step modifies an existing file, Goal states the nature of the change and, where the file holds more than one unrelated concern, name the specific symbol(s) touched alongside the path (e.g. `src/auth/session.ts` (exports `refreshToken`)) so the implementing session doesn't have to guess.
Logic is the only place a pseudocode block or a ... placeholder belongs.
- Dry technical text throughout — but never at the cost of
Goal being too thin to execute against.
- Order steps so no step depends on a fact that only a later step establishes.
If tests_required (Step 4) is true, append:
## Tests
### Test 1: {what is asserted}
{file path; one line: the arrange/act/assert in prose. No code yet — the implementing session writes the real test.}
### Test 2: ...
Each ## Plan step that satisfies a test references it by number in its Goal (e.g. "…; satisfies Test 2"). If tests_required is false, omit ## Tests entirely — do not emit an empty heading.
Dropped on purpose: no Implement-Model: stamp (model hints live only on roadmap items as **Model:**), no ## Verification, no ## Risks — the task.md format ends at Execution.
Step 6: Self-check before writing
Run through this checklist against the draft; fix inline before the write (Step 7), don't write something you already know is broken:
Step 7: Write
Write the file directly — no in-chat draft, no confirmation prompt. The chat discussion (and, in promote/revise, the existing Description) was the review; the written file is the deliverable, and Step 8's digest lets the user judge whether to open it.
Fresh capture:
mkdir -p .task/task
Header + body, in order:
# {Title}
Roadmap: {slug} (from-roadmap only)
Source item: #{N} (from-roadmap only)
Spec: {spec-slug} (one line per relevant spec; omit if none)
---
## Description
{drafted body}
## Plan
{drafted steps}
## Tests
{drafted body, only if tests_required}
## Execution
> If `Spec:` headers are present, read each `.task/spec/<slug>.md` first and honor its
> decisions as fixed. `.task/` is pipeline-internal and invisible to the repo: never name
> `.task/` paths, spec/roadmap/task slugs, or `§` numbers in code, comments, commits, or PR
> text. Implement the Plan above (or the Description if none) with the tools in
> `.task/config/config.md` → Code Navigation / Code Editing. Run `/verify` end-to-end and
> `/code-review`, applying fixes ONLY within **Touches** (report the rest); with no `## Plan`,
> scope fixes to what you changed. Commit per `.task/config/config.md` → Commit Format. If
> `Roadmap:` + `Source item:` are present, tick item #N's checkbox in `.task/roadmap/<slug>.md`.
Promote: edit the existing .task/task/<slug>.md in place — insert the new ## Plan block (and ## Tests, if added) between ## Description's content and the existing ## Execution block (a to-task-written file has no ## Tests, so ## Plan (+ new ## Tests) is always inserted directly before ## Execution). Do not touch the header, the --- separator, ## Description, or ## Execution itself.
Revise: edit the existing .task/task/<slug>.md in place — replace the whole prior ## Plan block with the new one (same position, still before ## Execution). Replace ## Tests only if the current chat's edit touched it; otherwise leave it exactly as it was. Leave ## Execution untouched (re-stamp it only in the defensive case it's missing).
Then validate the written file: bash "${CLAUDE_PLUGIN_ROOT}/skills/validate/validate.sh" task <slug> — surface any WARN/ERROR in Step 8's digest; only a config-precondition failure (exit 2) hard-stops.
Step 8: Output — digest
Print the structural digest of what was written (convention (b)) as message text — enough for the user to judge at a glance whether to open the file, without re-reading a full draft. Tailor it to the mode:
Wrote `.task/task/<slug>.md` ({fresh | promote | revise})
# {Title}
Sections: Description, Plan ({N} steps)[, Tests ({N})], Execution
Plan:
- Step 1: {short title}
- Step 2: {…}
validate: {OK — 0 errors, N warning(s) | the FAIL lines}
For promote / revise, note plainly what stayed untouched (Description, and pre-existing Tests unless the edit touched them). The file is already written — to change anything, just say so. Then close with the handoff footer (convention (a), flag-free):
→ Next: implement it now, or in a fresh session run: \implement .task/task/.md``
Forbidden
- Overwrite or paraphrase-away an existing
## Description in promote or revise mode — only ## Plan (and, narrowly, ## Tests) are in scope for those modes.
- Pick a new slug / target path in promote or revise mode — the existing file resolved in Step 1 is reused as-is.
- Modify the source roadmap file or any referenced
.task/spec/<slug>.md — all are read-only from here; checkbox auto-marking is the executing session's (or, for a roadmap run, the driver's) job, and specs are authored only by to-spec.
- Invent or resolve an active-task pointer — none exists in v3; the target file is resolved per Step 1 every run.
- Leave
## Plan present with zero ### Step N: blocks, or ## Tests present with zero ### Test N: blocks — both fail validate.sh.