Help us improve
Share bugs, ideas, or general feedback.
From simiancraft-skills
Drafts tactical, hand-off-ready planning docs with atomic commit steps, verification gates, and before/after file trees. Includes interrogation protocol and self-destruct rule for completed work.
npx claudepluginhub simiancraft/simiancraft-skills --plugin simiancraft-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/simiancraft-skills:how-to-planThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A plan is the contract between the session that designs the work and the session that executes it. It only works if it is explicit enough to hand off cold to a fresh agent or a junior engineer who has none of your conversation context.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
A plan is the contract between the session that designs the work and the session that executes it. It only works if it is explicit enough to hand off cold to a fresh agent or a junior engineer who has none of your conversation context.
This skill encodes the methodology for producing such plans. Follow it in order.
model / subsystem / cross-stack / project-meta / cross-repo). Scope governs both what the body may reference and where the file lives.PLAN.md.Each step is detailed below. References in references/ carry the long-form templates and anti-patterns.
No code is authored until the plan is airtight. An airtight plan is one a weaker model could execute to a correct outcome without asking a follow-up question. Write for the dumbest plausible executor, not for the author.
Reaching that bar requires interrogation. Before drafting any plan prose, interview the developer about every branch of the design tree until shared understanding is reached.
Only when every branch has a settled answer; scope, domain model, file paths, data shapes, edge cases, out-of-scope items, ordering; begin drafting. Never paper over a gap with TBD; a plan with a TBD is a suggestion, not a plan.
A plan describes a single discrete feature or action. When work grows large enough to contain multiple heavy phases that could each stand alone, split it into multiple plans that reference each other. This is the most important structural choice while drafting.
Goal: keep each plan as detailed as possible but as bounded as possible. A plan covering five mixed phases loses detail at every phase to save space overall; two plans, each covering a tighter slice, stay dense where it matters.
Typical split patterns:
| Pattern | First plan | Second plan |
|---|---|---|
| Migration → features | Migrate the data/schema/structure | Build features that assume the new shape |
| Infrastructure → consumers | Scaffold the new infrastructure (registry, service, abstraction) | Migrate each consumer onto it |
| Deprecation → replacement | Remove the deprecated surface | Build the replacement (or vice versa, per ordering constraint) |
How to split:
Depends on: line in the front matter naming the prior plan and the state it must have reached. Example: "Depends on: migrate-resource-schema.md fully shipped and deployed; legacy_resources table dropped."Judgment, not a rule. Three tight phases that share context and edit the same files are fine in one plan. Three heavy phases that touch disjoint file sets, each with its own surface-area inventory, should split. When in doubt, split. A too-small plan is cheap; a too-big plan stays painful the whole time.
A plan's scope governs both what its body may reference and where the file lives. A plan checked into a repo is not automatically project-scoped just because the file is there; scope is determined by who will execute it and against what surface. Pick one scope before drafting; declare it as the Scope: front-matter value. The five canonical scopes are:
Scope: value | Lives at | Body may reference |
|---|---|---|
model | <models-or-db-dir>/<model>/<plan>.md | The model and its near-neighbors only. Don't reach across the data layer. |
subsystem (one folder, one concern; includes monorepo packages) | <feature-or-package>/<plan>.md | Real symbol names, domain nouns, internal helpers, real file paths. Anchor to the codebase: that's the value. |
cross-stack | Repo root | Project-internal identifiers freely. Default for anything spanning frontend + backend, or large enough to need persistent state across multiple agent sessions. |
project-meta | Repo root or docs/process/ | Repo-level configs, workflow files, CI/release tooling, durable convention docs. Avoid feature-domain nouns: the plan affects all features but is owned by none. |
cross-repo | Template repo or shared docs | Generic placeholder names; abstract patterns; no codebase-specific helpers. Same depth gate as a global skill. |
Rule of thumb: bigger than a breadbox and needs a planning doc to persist state across multiple agent sessions → cross-stack at repo root, unless it cleanly belongs to one folder (subsystem) or one model (model). A monorepo package counts as a subsystem; a plan touching one package lives inside that package; a plan touching many is cross-stack at the monorepo root.
Verification: before the draft is "ready," grep the body against the declared scope. cross-repo plan with project-specific paths → genericize. subsystem plan reading like a template → specialize. project-meta plan that names a feature's symbols → either move into a subsystem plan or abstract the noun. Mismatch = draft, not plan.
Never name a plan file PLAN.md. Generic names do not survive; six months later no one can tell what the plan was about without opening it, and greps for feature names miss it.
The filename must describe what the plan does. Use kebab-case, imperative-ish phrasing.
| Good | Bad |
|---|---|
deprecate-legacy-mocks.md | PLAN.md |
refactor-field-resolvers-pattern.md | plan.md |
migrate-image-uploads-to-s3-presign.md | notes.md |
onboarding-experience-flow.md | refactor.md |
File placement follows the Scope: chosen in Step 3; see the scope-table column "Lives at."
Every plan needs the same front matter and the same ordered sections.
# <Short, Descriptive Title>
**Status:** Draft | In progress | Descoped | Archived
**Scope:** model | subsystem | cross-stack | project-meta | cross-repo
**Date:** YYYY-MM-DD <!-- original authorship date -->
**Last reviewed:** YYYY-MM-DD <!-- bump on every non-trivial edit -->
**Context:** <one sentence naming the problem and why it matters now>
**Depends on:** `<other-plan-filename>.md` … <!-- optional; include only when this plan starts after another plan ships -->
The Status enum is closed; do not invent modifiers (Draft; blocked on X). If a plan is blocked, keep Status: Draft and put the blocker in the Context: line.
The Scope: field is set in Step 3 and governs what the body may reference.
Update Last reviewed on every non-trivial edit; a stale plan is a trap. If you read a plan without editing it and it still looks correct, bump Last reviewed anyway with a one-line # verified still accurate note in the front matter; that signal protects future readers from second-guessing.
Depends on: is included only when the plan needs another plan shipped and live before this one starts. Name the prior plan and the state it must have reached: "Depends on: migrate-resource-schema.md fully shipped and deployed; legacy_resources table dropped."
**Legend:** line directly above the tree, trimmed to operation symbols actually used; carry lineage in // from … notes. Canonical legend, mutex table, and combinable annotations live in references/file-tree-annotations.md: load it once and treat it as authoritative; the symbol set is not duplicated here to prevent drift. Same omission rule as the before-tree.Situational sections (include when relevant):
This is the single most important paragraph in the document; more than file trees, more than the commit list. Everything downstream derives meaning from the Goal.
The Goal must answer three questions, in order:
Cap the Goal at ~150 words. A Goal that runs longer is doing someone else's job.
The Goal is the reference point both author and executor consult to answer two recurring questions:
Non-negotiable when the plan creates, moves, renames, or deletes files. The before/after trees are the single most important transformation aid for the executing session; they let the executor reason about "this turns into that" without juggling prose.
Each step states:
grep returns zero matches, etc.Step template (use only the file-action subsections that apply; omit empty ones):
### Commit N: <imperative-tense summary>
**Goal:** <one sentence>
**Files created:**
- `path/to/new-file.ts`: <one-line purpose>
**Files rewritten:**
- `path/to/existing.tsx`: <what changes, in one sentence>
**Files moved/renamed:**
- `path/to/new.ts ← path/to/old.ts`: <one-line purpose if non-obvious>
**Files deleted:**
- `path/to/deadcode.ts`
**Gate:** <project validation command> passes. <Any additional verification.>
The Files moved/renamed: subsection mirrors the 🔀 new ← old notation from references/file-tree-annotations.md, so the commit text and the file tree describe the same operation in the same shape.
No Files split: subsection; splits decompose into existing subsections. The split source goes under Files rewritten: (if it survives the split) or Files deleted: (if it goes away); the targets go under Files created: with // from 🪓 <source-path> notes. The 🪓 symbol carries the split semantics in the file tree; the commit text uses the regular subsections. This is the same trade-off merge makes (no symbol; lineage via // from a + b).
When several commits share the same shape; same file-action subsections, same Gate, same template; and differ only by a single swap (which mutation, which model, which consumer), number them with sub-letters tied to one parent number:
### Commit 3a: <imperative for first variant>
…full step body…
### Commits 3b, 3c, 3d: <other variants> (same shape)
Each follows Commit 3a's template verbatim with the <swap> name swapped. Three separate commits, each with its own Gate; do not collapse into one.
Use sparingly: only when the commits are genuinely identical except for the swap. The first sub-letter (3a) is shown concretely with all subsections and a Gate; the rest get a one-line note. This keeps the parent number tied to the conceptual unit ("the per-action migration") instead of spraying eight sequential numbers across what is one step's worth of intent.
Between major sections (phase boundary, grouped commits), the gate is all checks pass: the project's full validation command at minimum; add scoped tests, Storybook smoke, or a grep assertion when the change touches those layers.
Use these to mark progress through the plan's commits or sections in long-running plans; not to mark file-operation outcomes (the file-tree legend covers that):
| Marker | Meaning |
|---|---|
| ✅ | Complete |
| 🔶 | Partial / In progress |
| ❌ | Not started |
| 🚫 | Descoped / will not do |
Hard rule; no cross-pollination between systems:
references/file-tree-annotations.md) never appear in commit checklists, status tables, or anywhere outside file trees.🔶 ✅) never appear inside file-tree nodes. (🔶 and ✅ exist in the file-tree legend only for the long-running-plan sub-case where the legend is doing double duty as a per-node progress indicator; in that case the tree IS a checklist. Never mix the two functions in one tree.)❌ and 🚫 is permitted because both senses converge on "gone / not happening," and the surrounding context (a tree node vs. a checklist row) disambiguates without ambiguity. When both appear in one tree, gloss them inline (see file-tree-annotations.md).Leaving the wrong things out is as important as putting the right ones in. Every paragraph spent on the wrong topic is a paragraph the executor skims past.
How the work ships; one PR vs many, which branch lands first, feature-flag staging, who reviews; is decided after planning, not during it. At plan-writing time the final packaging is unknown; guessing locks the executor into decisions that should stay flexible. Commit order within the plan is about technical correctness (nothing breaks between commits), not delivery logistics.
If the work has genuine deploy-order constraints, state them as technical dependencies inside the relevant commit's Gate, not as a separate rollout section.
| Good | Bad |
|---|---|
**Gate:** Resolver removal (Commit 6) must merge and deploy before table drop (Commit 7). Don't drop the table while old resolvers still query it. | ## Rollout notes: We'll ship Commits 1-5 as PR #1, then Commits 6-7 as PR #2 gated by product sign-off… |
Most repositories already have durable conventions that apply to every change (commit format, branching strategy, hook policy, atomic-commit discipline). A plan that repeats them adds noise and implies they are plan-specific (they are not). Assume them. Mention a workflow rule in a plan only when the plan deliberately deviates; and that deviation needs a justification.
Skip "this plan was discussed on 2026-04-20," "reviewed by X," "approved by Y." Git history records authorship; PR review records approval. The plan is the what-and-how, not the who-and-when.
Plans are tactical, disposable artifacts: like the self-destructing notes in Inspector Gadget. They exist to coordinate one piece of work. When the work is done, the plan is no longer truth; it is a snapshot of what was about to happen, which now rots in place and misleads future readers.
Delete the plan file as the final step of the work. Not "archive it." Not "move it to a done/ folder." Not "leave it with a Status: Archived header." Delete it.
The deletion is its own atomic commit, not folded into the feature's last code commit. Atomic-commit projects want the deletion as a separate, reviewable change so the diff is easy to read and easy to revert if needed. The "delete this plan" commit is the canonical Commit N+1 in every plan's commit list.
The agent deletes exactly the file at the path declared in the plan's front-matter filename, and no other paths. The plan's filename is the one the plan was created with (e.g. features/resources/split-resource-actions-hook.md); deletion of any other file; sibling docs, "stale" notes, related plans; is out of scope for this protocol and requires its own justification.
Deletion is a two-key event; both developer and agent must agree. Failure modes go both ways:
Protocol:
<exact path from front matter>, or do you want to hold off?""confirm delete", "yes, delete it", "go ahead and delete", "yep delete", "do it", "ship it", "yes" (only as a direct response to the agent's proposal turn). Ambiguous standalone responses ("sure", "looks good", "nice work", "great") do NOT count as confirmation: the agent must re-prompt with the explicit question..md, (b) is repo-relative (not absolute, not parent-of-repo), (c) currently exists in the working tree, and (d) matches the path declared in the plan's own front matter. If any check fails, the agent does not delete and surfaces the mismatch.If the developer says "this is totally done" without the agent having proposed deletion, the agent still confirms the checklist passes before acting; "done" is a signal to verify-then-propose-then-delete, not to delete blind. Same path check applies.
If the developer says "delete it" before the agent has proposed deletion (developer-ahead-of-protocol), the agent still runs the verification (every commit shipped, checklist passes, validation green, path checks pass). If verification passes, the developer's instruction counts as the confirmation; if any check fails, the agent surfaces what's not green and does not delete.
Dangling-handshake fallback. If the developer is not present to confirm (the agent is running in a long unattended session, or the user has stepped away without responding), the agent leaves the plan file in place and does not delete unilaterally. A plan rotting in the tree briefly is preferable to deleting in error. The agent may note in its session output that the plan is ready for deletion pending confirmation.
git log --diff-filter=D -- <plan-file> finds it. A file sitting in the tree is not.docs/ (or equivalent); describe how things work, not what to do next. If a plan produced a new convention worth keeping, extract it into the convention layer before deleting the plan.Add a Self-destruct step as the literal last item of the Commits section and the Verification checklist:
### Commit N+1: Delete this plan
- Delete `<this-plan-filename>.md`.
- If any convention is worth keeping, extract it to the project's convention docs first in a prior commit.
**Gate:** Project validation passes. Repo contains no references to the plan file.
## Verification checklist
- [ ] …
- [ ] Plan file deleted (Inspector Gadget Rule: no orphan plans).
A plan describing a never-completing process (a rolling migration that runs whenever a new model is added) belongs in the convention docs, not as a plan file. Convert it; do not leave it as PLAN.md.
Load on demand based on what the current draft needs:
| Need | Read |
|---|---|
| Minimum-viable plan skeleton + required front matter | references/plan-template.md |
| ASCII before/after tree conventions and a worked example | references/file-tree-annotations.md |
| Anti-patterns to avoid (Goal mistakes, scope mistakes, structure mistakes) | references/anti-patterns.md |
| End-to-end worked plan (placeholder names, complete shape) | references/example-plan.md |
A plan is complete when all of the following hold:
Scope: declared as one of model | subsystem | cross-stack | project-meta | cross-repo, and the body identifiers match it (subsystem/cross-stack plans cite real names; cross-repo plans use generic placeholders; project-meta plans avoid feature-domain nouns; model plans stay inside one model's surface).TBD markers, no rollout sections, no restatement of standing conventions, no meta-commentary.If any item fails, the plan is a draft, not a plan.