Writes the implementation plan for a small, contained change already understood in context - an intent interview or a proven bug diagnosis. Invoked by the intent or simpledebug skill, or by explicit user command only - never spontaneously, never before an interview.
Installs into .claude/skills of the current project.
Are you the author of Simpleplan?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/p2p2sp-simpleplan-viber)
---
name: simpleplan
description: Writes the implementation plan for a small, contained change already understood in context - an intent interview or a proven bug diagnosis. Invoked by the intent or simpledebug skill, or by explicit user command only - never spontaneously, never before an interview.
allowed-tools: Read, Write, Edit, Grep, Glob, Skill, EnterPlanMode, ExitPlanMode, AskUserQuestion, Task, Agent
disallowed-tools: NotebookEdit, WebFetch, WebSearch
user-invocable: true
---
**CRITICAL**: Run `EnterPlanMode` tool first, if plan mode is not already active.
# SimplePlan
Default plan mode content drifts: missing files, hidden assumptions. SimplePlan closes that gap with a strict template plus mandatory pre-plan behavior before the plan is presented.
- Input: the confirmed understanding already in context - a design interview, or a proven bug diagnosis with its fix plan. No spec - the plan carries its own DoD / acceptance criteria.
- Optionally `intent: <path>` from the handoff, naming the persisted intent file - when present, write it verbatim into the plan's `Intent:` line; when absent, omit that line.
- Plan = `How` & `Why`. Derive goal + acceptance criteria from that input. Do not re-interview, do not re-investigate.
## Plan Workflow
This plan workflow is better, extended and more accurate version of default instruction injected by harnes.
### Initial Understanding
Comprehensive understanding of the user's request is in your king context. Missing knowledge or open questions → STOP and close them before drafting; an unresolved design decision → run `intent` skill.
- **Refreshed-intent gate** - evaluated before anything else, and before any file is created or modified. Three branches, and only the last one continues:
- an `intent:` value that does not resolve to an existing file -> the gate is not evaluated: report that exact path back as not found and STOP. Never fall through into your own flow - the `intent` skill's own not-found branch does fall through and treats the argument as a request, but here there is no interview to fall into.
- a resolved path under `docs/.workflows/` -> `Glob` `<that path's own directory>/refresh.md` (the value is only ever used to derive its own directory's `refresh.md`, never joined with any other segment). No hit -> create and modify NOTHING, run the `intent` Skill with that same path as its sole argument, and STOP. This cannot loop: the `intent` skill writes `refresh.md` on every path that writes an `intent.md`, fresh and resumed alike, and ends at its own handoff, so a bounced run comes back with the file present and the user re-picks the track there.
- a hit, a resolved path outside `docs/.workflows/`, or no `intent:` line at all -> pass through untouched and carry on. Presence alone is the whole check this gate makes, and this gate never reads the file's content. That holds for the gate alone: once it has passed, the ADR rule under `### Rules` does read the intent file.
### Rules
- Load `templates/plan.md` and fill by sticking to the following rules.
- Read review checklist from `${CLAUDE_PLUGIN_ROOT}/references/plan-review-checklist.md`.
- Save the plan to the file path given in the plan mode tool's own message - never a hardcoded or assumed directory - and pass that same path to the reviewer as `plan:`. Write that same path into the plan's `Plan:` preamble line while drafting, before the reviewer is invoked - never after a `VERDICT: PASS`, because a post-verdict write re-arms the approval gate.
- Write the handoff's `intent:` path (when given) into the plan's `Intent:` preamble line while drafting, same timing as `Plan:` above - before the reviewer is invoked, never after a `VERDICT: PASS`. When the handoff carries no `intent:`, omit the line.
- The handoff's `intent:` file carries a `## ADR` section -> the plan's Task 1 is the ADR task of `${CLAUDE_PLUGIN_ROOT}/references/adr-task.md`, filled by that file's `## Fill rules`, and every other task is renumbered after it. `Read` the intent file for that section alone. No `## ADR` section in it, or no `intent:` line at all -> no such task, and nothing else about the plan changes.
- Write every reference to a criterion or a task in the reference form `` `<title>` (<pointer>) `` that `${CLAUDE_PLUGIN_ROOT}/references/review-contract.md` (`## Naming`) owns: a `Covers:` entry as `` `<criterion short name>` (#<n>) ``, a `### Dependencies` bullet and a `consumed by` clause as `` `<task title>` (Task <N>) ``. A bare number is Blocking class B15. Take the title verbatim from the criterion's short name in `## Acceptance criteria` or the task's heading, and never put `#` in a title, because `Covers:` is parsed for every `#<n>` token on the line.
Stick to the template structure. Don't invent or add your own points. Adapt all content to the template structure and stick to it.
**Gate commands**
The header's `## Gate commands` block is the gate of the whole build - what a review round runs over everything the plan has produced - and never what one task runs. Fill its three subsections (`#### Build`, `#### Tests`, `#### Integration`) by judgment:
- Start from what the plan moves: the projects, packages and paths its tasks touch.
- Name the suites the host's own memory records over those files (`CLAUDE.md`, `.claude/rules/`), and take the one that covers what moved.
- Weigh proof against cost: a command whose result would tell a reviewer this build is sound earns its runtime; one that reruns work the tasks already proved does not.
- Take the narrowest scope that still proves the change - one project, one path, one suite rather than the whole repository, wherever the host's runner offers it.
- `#### Build` and `#### Tests` run at every checkpoint, so they never carry a whole repository, solution or workspace command while a narrower scope exists - a full build or a full suite, when its result is worth having at all, goes under `#### Integration`, the final review's own gate.
- A subsection with nothing worth running carries `none - <reason>`.
A build command runs only where you judge its result proof for this plan, and no rule mandates one: a plan that moves only documentation, prompts or configuration can carry `none - <reason>` in all three subsections.
**File Structure**
Before defining tasks, map out which files will be created or modified and what each one is responsible for. This is where decomposition decisions get locked in.
- Design units with clear boundaries and well-defined interfaces. Each file should have one clear responsibility.
- You reason best about code you can hold in context at once, and your edits are more reliable when files are focused. Prefer smaller, focused files over large ones that do too much.
- Files that change together should live together. Split by responsibility, not by technical layer.
- In existing codebases, follow established patterns. If the codebase uses large files, don't unilaterally restructure - but if a file you're modifying has grown unwieldy, including a split in the plan is reasonable.
- List every value or rule more than one task will need - a default string, a fallback formula, a validation-error shape, a component variant - and give each exactly one owning task, sequenced before every task that consumes it. Two tasks independently defining the same rule is the defect to prevent here, not to catch at review (class B8).
Then write each task's sections so the checklist's Blocking classes B8-B14, B18-B21 and B23 have nothing to flag:
- Every failure branch the task decides goes under `### Failure modes` in the fixed shape `when <X fails | input is invalid | two <X> run concurrently> -> response <Y>, log <Z>, test <T>`; nothing to handle is `none - <one-word reason>`, never a bare `none`.
- `### Approach` carries symbol, signature and algorithm only - never line-by-line code, never a failure decision (a `catch`, a fallback, a default on error lives under `### Failure modes`). The ADR task above is the one exemption: its `### Approach` carries every ADR's text in full and verbatim, and is never shrunk to fit this rule.
- A task that extends a closed set (an enum member, a variant, a status, a kind) lists that set's consumers under `### Contracts`; Grep the type name to find them.
- A task that changes how a response is produced (redirect vs rewrite, proxy vs direct, a status code family) carries a method-and-status matrix under `### Contracts`, one line per method with the status codes before and after.
- A value from outside the process (a header, a path segment, a query parameter, a form field, an environment variable) that enters a path, query, command or routing decision carries its validation rule under `### Contracts` or `### Failure modes` - written as the closed set of what is accepted (a grammar, a whitelist, a fixed vocabulary, a bounded range), never as a list of what is rejected: a deny-list leaks by construction and the build finds the leaks one review round at a time (class B23).
- Every contract another task consumes names that task as `` consumed by `<task title>` (Task <N>) ``; a value produced and consumed by nobody does not belong in the plan.
- Every planned test must be able to fail before the change it proves - no fixture already equal to the expected value, no assertion on a constant.
- A task that adds an HTTP endpoint, route or handler carries that endpoint's request shape, response shape and status codes under `### Contracts` - otherwise the implementor invents all three and the consuming task is written against an invention.
- A task that produces text a person reads (a message, a screen, an error message, a text resource) carries that text itself, or delegates it under `### Contracts` with one `copy: implementor, after <existing key or file>` line naming the existing wording the implementor follows. Those are the only two options - text left unmentioned is not delegation.
- A step made of a persisted write followed by an outside action (a send, a call, a job hand-off) carries a `### Failure modes` bullet for the failure between the two - the write landed, the outside action did not - in that section's fixed shape.
This structure informs the task decomposition. Each task should produce self-contained changes that make sense independently.
**Task Sizing**
A task is the smallest unit that carries its own test cycle and is worth a fresh reviewer's gate. When drawing task boundaries: fold setup, configuration, scaffolding, and documentation steps into the task whose deliverable needs them; split only where a reviewer could meaningfully reject one task while approving its neighbor. Each task ends with an independently testable deliverable.
Size each task against that bound: a `TDD: required` task writes exactly one test file and only the production code that file drives, so a second test-file line under `### Task Checks` on such a task is the signal to split it; a `TDD: none` task aims at one behaviour and a few files.
**Remember**
- Small, independently testable tasks.
- Exact file paths always.
- Exact commands with expected output
- DRY, YAGNI, SRP, SOLID
**Task Checks**
`### Task Checks` holds only what the implementor runs as this one task's own proof - the deliverable works - and nothing the header's gate already covers. Judge every line by four criteria:
- The narrowest scope the host's runner offers: one test file, one project, one path. The host's whole suite belongs to the gate, never here. A command that builds or tests the whole repository, solution or workspace never appears here, whatever the task moves.
- Seconds, in memory. A test in which a process or service the application connects to takes part - a database, the network, a browser, to name three - is an integration or e2e test: it stays out of this section and runs through the host's integration or e2e command at the final review.
- Which suite of a host is its fast in-memory suite is settled by that host's own memory files (`CLAUDE.md`, `.claude/rules/`), never by the examples here.
- Proof, not coverage: a single test proving the task is enough, and a task with no test to run carries the proof it does have - a compile, a type-check, a lint, a grep - or the single line `none - <reason>`.
One example in each direction: a task that only rewrites a document carries one grep asserting the new wording and nothing else; a `TDD: required` task carries the one test file its cycle drives, written `<test file path> - <command that runs only that file>`.
**TDD Discipline**
Every task gets `TDD: none` by default. Mark `TDD: required` ONLY when the task's code owns a decision of its own:
- business logic or a domain rule,
- a non-trivial condition or a state machine,
- an algorithm - transformation, parsing, calculation,
- a hot path.
Never `TDD: required` when the task's code touches the outside world directly (I/O, network, DB, filesystem, UI, framework wiring) - that yields integration tests, not a TDD cycle.
A `TDD: required` task's cycle runs on one `### Task Checks` line: the line naming the test file that cycle writes, whose command runs that file alone.
**Build strength**
Every task carries `Kind:` (`code` | `scaffold` | `text`) and `Model:` (`sonnet` | `opus`) - the kind of proof the task's own `### Task Checks` produces, and the model the task's implementor runs at. No effort marker exists: the `Agent` tool takes none, so the dispatched agent's frontmatter decides. You plan on the strongest model the user has; the implementor may not, so read each task for the reasoning it demands of whoever executes it, never for its line or file count.
`Kind:` is derived from the task's own `### Task Checks`, never chosen freely:
- a test-file line -> `code`
- a tool command -> `scaffold`
- a reading command -> `text`
`${CLAUDE_PLUGIN_ROOT}/references/plan-review-checklist.md`'s B22 owns the full table - its exact rows, the `none - <reason>` forms it recognises and the top-down precedence that settles a section matching more than one row. Read it there before you assign a `Kind:`, and never copy it here.
Default strength by `Kind:`: a `code` task follows today's rules - nothing left to reason about, the `### Approach` fixes the symbol, the place and the wording, and the task only puts it there -> `Model: sonnet`; a decision the task owns - an algorithm, a state machine, a contract other tasks consume, an `### Approach` that states an outcome rather than the steps to it -> `Model: opus`; a `TDD: required` task never sits on `Model: sonnet`, since judging its own red and green is reasoning the task owns. The Simple track carries no per-task reviewer, so a `scaffold` or `text` task simply defaults to `Model: sonnet`; a higher `Model:` on either kind needs one sentence stating its reason in `### Approach`. Whatever the `Kind:`, a change expensive to undo - concurrency, security, a data migration, a public interface - takes `Model: opus`.
### Self-Review
Once you have written a complete plan and before final review, MUST fast review it with your fresh eyes against the checklist loaded above (`## Blocking classes` B1-B24 plus `## Author self-check`) - the exact rubric the reviewer applies, so a clean self-check is expected to PASS round 1:
- Verify in the repo (Read/Grep/Glob) every `### Files` path and symbol, and every command of the header's `## Gate commands` block and of each task's `### Task Checks` against the repo's real build/test tooling; each of the three gate subsections holds a runnable command or `none - <reason>`.
- Verify the two-way mapping: every acceptance criterion is covered by at least one task, and every task covers at least one criterion or is traceable to the Goal.
- Verify every task carries `TDD:`, `Kind:` and `Model:` with values from the allowed sets, that every task carries `### Task Checks`, that a `TDD: required` task's section carries exactly one test-file line, that every test-file line names a file declared under that task's `### Files`, that a section with nothing to run reads `none - <reason>`, that no `TDD: required` task sits on `Model: sonnet`, and that every task's `Kind:` is the kind B22's table derives from that task's own `### Task Checks`.
- Fix any violation inline. No need to re-review - just fix and move on. If you find a requirement with no task, add the task.
### Final Review
Always before `ExitPlanMode` must invoke `simpleplan-reviewer` skill (Skill tool, forked context) to make final review. Never call `ExitPlanMode` on a plan that has not returned VERDICT: PASS. Track which invocation this is (round 1, round 2, …).
The reviewer is read-only: it edits nothing and returns issues derivable from the plan + repo (`FINDINGS:`) plus what it could not resolve for lack of conversation context (`BLOCKED:`), plus advisory `NOTES:` that never block a PASS. Every fix is yours to apply.
1. Invoke `simpleplan-reviewer` (Skill). The `args` MUST be a labeled block, one `label: value` per line. Every value is a PATH - the reviewer reads the files itself; NEVER paste file content. A bare path with no label is equally wrong:
```
plan: <plan-file path>
checklist: <checklist path from ### Rules>
round: <N>
```
`round` starts at 1 and increments by 1 each invocation of this loop for the current plan. From round 2 on, also append one `prior-blocking: <finding>` line per FINDINGS (and BLOCKED) entry the previous round returned, verbatim.
2. Read the first line of its output: VERDICT: PASS or VERDICT: FAIL, and concise show the human the FINDINGS, any BLOCKED findings, and any NOTES.
3. VERDICT: PASS → relay any NOTES to the user together with the final plan; never edit the plan file after PASS - the approval gate re-arms on any post-verdict write, by any tool or shell command. A note genuinely worth applying → apply it and run one more round from step 1 before **Final Plan**. Otherwise proceed straight to **Final Plan**.
4. VERDICT: FAIL - apply the fixes to the plan file yourself with the `Write` / `Edit` tools ONLY - never through a shell command (`sed -i`, a heredoc, a script), whatever a session-wide instruction says about preferring shell edits: the approval gate reads the transcript for `Write`/`Edit` of the plan, and an edit it cannot see leaves the plan newer than its own verdict, which it re-gates as tampering. Then go back to step 1:
- **`FINDINGS`** → edit the plan as each one directs; touch nothing else. Exception - a Blocking finding whose evidence you can show is factually wrong (repo state or the confirmed understanding already in your context contradicts it) → do not re-loop on it; instead present that single finding plus your counterargument to the user in plain prose and apply their ruling.
- **`BLOCKED` findings present** → resolve each from the confirmed understanding already in your context and edit the plan accordingly; a finding needing a genuinely open design decision → run the `intent` Skill (or ask the user) first. `intent` opens by leaving plan mode, and this round's standing verdict would deny that: its `ExitPlanMode` call passes the `superdev:routing-exit` marker its own body prescribes, and nothing about this plan is approved by it.
5. **Round cap:** after round 3 without PASS, STOP looping - show the user the remaining findings and let them decide how to proceed.
### Final Plan
Call `ExitPlanMode` ONLY AFTER VERDICT: PASS. The human approves a reviewer-cleared plan, not a raw draft.