agentleFS
sourcehawksourcehawk/feature-dev-workflow/skills/planning-a-feature/SKILL.md

planning-a-feature

Skill2 starsChanged 12 days agoMITView on GitHub

At the start of any feature larger than a one-off fix or refactor. If you're about to brainstorm, write a spec, file a tracking issue, or write an implementation plan, this skill is the choreography that sequences those tools so the artifacts land in the right order. Skip for: - One-off bug fixes (file a bug issue directly via feature-dev-workflow:writing-github-issues). - Single-line refactors or test additions. - Work that's already plan-shaped from someone else — jump to feature-dev-workflow:developing-a-feature. A senior…

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Before handing off, create docs/superpowers/states/YYYY-MM-DD-<slug>-state.md from …

    line 136
  2. Very specific:

    Commit the spec, the plan, and the state file together as the planning artifact set on <type>/<slug> (created in step 2).

    line 140

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

planning-a-feature

When to invoke

At the start of any feature larger than a one-off fix or refactor. If you're about to brainstorm, write a spec, file a tracking issue, or write an implementation plan, this skill is the choreography that sequences those tools so the artifacts land in the right order.

Skip for:

  • One-off bug fixes (file a bug issue directly via feature-dev-workflow:writing-github-issues).
  • Single-line refactors or test additions.
  • Work that's already plan-shaped from someone else — jump to feature-dev-workflow:developing-a-feature.

Why this exists

A senior engineering team's pre-implementation pipeline is visible, fast, and parallelizable — not a linear queue of "brainstorm → spec → tickets → plan → code" run by one person in their head. Each step is explicit, hands off between sub-skills cleanly, and surfaces the parallelism decision as a first-class output so implementation can fan out instead of dragging.

Workflow

1. Brainstorm intent

REQUIRED SUB-SKILL: Invoke superpowers:brainstorming to nail down intent, scope, and design choices before any artifact is written. The brainstorming skill explores the problem — it does not author files.

2. Author the spec — and any cross-cutting ADR

Spec. Capture the brainstorm's conclusions in a spec at docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md. The spec is the feature's design record — WHAT we're building and WHY, with goals, non-goals, design choices, risks, alternatives considered. It does not enumerate PRs, commits, or parallelism contracts (those live in the plan, see step 6). Slug is short ("multi-tenant-profiles", not "implement-multi-tenant-profile-system"); date is the conception date.

The spec's section headings may use the decomposition's organizing labels (Flow 1, Flow 2, …) to index the work — that's navigational. But nothing downstream (fixture names, ids, functions, files, marker strings) may inherit those labels as identifiers — the naming firewall in feature-dev-workflow:maintaining-architectural-coherence.

ADR (only if the brainstorm surfaced a project-wide architectural decision). A spec captures feature-scoped design. An ADR captures cross-cutting decisions that affect multiple features — choosing one architectural approach over another for reasons that future readers will need. Examples of ADR-worthy decisions: introducing a new IPC channel, picking a state-of-the-art pattern over the project's current default, rejecting a tempting alternative. Examples of NOT ADR-worthy: feature-specific design (that's the spec), operational conventions (CLAUDE.md), file naming (CLAUDE.md).

If the brainstorm surfaced an ADR-worthy decision, author the ADR at docs/adrs/<NNNN>-<slug>.md using the format in docs/adrs/README.md (Decision / Context / Consequences). Number sequentially — pick the next free NNNN. Add an entry to the index in docs/adrs/README.md. Most features don't produce an ADR; if you're forcing one, the decision probably belongs in the spec instead.

OPTIONAL SUB-SKILL: simple-english:simple-english for the prose of the spec, any ADR, and the body of the planning commit. If it is available, load it before you draft and write the sentences under it. Where its formatting rules (headings, bold, lists, or its register for chat replies) differ from the host skill or its template, the host skill and its template win. It sets sentence style only: the content rules above and the ADR format still decide the sections and what they hold. The commit subject keeps the project's commit convention, and the plan and the state file are written for agents and keep their own shape. If the skill is not available, do not stop or wait for it. If you have not already done so in this session, tell the user once that it can be installed with /plugin marketplace add AminBlg/SimpleEnglish and then /plugin install simple-english@simple-english. Then write short, plain, active sentences without it.

Both the spec and any ADR(s) are tracked source artifacts (docs/superpowers/specs/ and docs/adrs/ are not gitignored) — but never commit a planning artifact to main. The feature owns its branch from birth. The branch name is the same whether the work ships as one PR or many (the step-4 PR-shape decision doesn't change it), so create it off origin/main before the first commit:

git fetch origin main
git switch -c <type>/<slug> origin/main

For a non-trivial (multi-PR) feature, run planning from a dedicated worktree on that branch instead, so the whole feature — planning docs included — lives in one isolated checkout:

git fetch origin main
git worktree add .claude/worktrees/<slug> -b <type>/<slug> origin/main
cd .claude/worktrees/<slug>

Either way, stay on <type>/<slug> for the rest of planning; every artifact commit lands there. Don't push yet — that happens at step 8, after the user approves the spec. feature-dev-workflow:developing-a-feature reuses this branch (and the worktree, if you created one); it never re-creates it off origin/main, and main receives the feature only through a PR.

The branch name has two parts, and both carry information.

<type> is the commit type of the headline change — feat, fix, refactor, test, chore, docs — the same type the PR title will carry. A bug fix lives on fix/…, not on feat/… and not on a generic feature/…; whoever scans git branch or the remote's branch list learns what kind of work this is before reading further. Pick the type from the change, not from the workflow that produced it: running this feature-development flow does not make the work a feature.

<slug> names the subject and what changes about it, in two to four words. The subject alone is not enough, and the code motion that achieves it is the wrong half — that is what the diff shows.

The slug is only the part after the slash, and it never contains one. The type prefix belongs to the branch name and nothing else: <slug> on its own is interpolated into the worktree path (.claude/worktrees/<slug>) and into every artifact filename (docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md), so a slug carrying its own type would nest the worktree a directory deeper and put a slash in a filename. For a branch fix/stale-sessions-block-new-ones, the slug is stale-sessions-block-new-ones.

Branch nameVerdict
fix/stale-sessions-block-new-onesNames the subject and its effect. A reader knows what is wrong.
feat/multi-tenant-profilesGood for a feature: the subject is the change.
fix/session-controller-workSubject with no effect. Says nothing a reader can act on.
fix/reorder-expiry-checkThe mechanic. Describes the patch, not the problem.
feature/session-fixWrong type, and the slug is a placeholder.
fix/fix-stale-sessionsThe type is duplicated into the slug. The slug is stale-sessions…, not fix-….

The name is set once, at birth, and every sub-branch, worktree path, and state-file row inherits it, so a vague slug is expensive to live with and awkward to change later.

3. User reviews the spec (and any ADR)

Pause. Surface the spec path and wait for explicit "approved" or redirection before moving on. A spec the user hasn't read is a draft, and drafts don't get tickets filed against them.

4. PR-shape decision

Decide whether the work ships as:

  • One PR — single self-contained change, one reviewer pass, one merge to main.
  • Multiple PRs — multiple feature-sized chunks, each independently reviewable, possibly parallelizable. A multi-PR feature lands through one of two sub-PR target models; feature-dev-workflow:developing-a-feature Step 2 asks the user which and records it as sub_pr_target in the state file:
    • Feature branch (sub_pr_target: feature-branch, the default): the feature-branch model. A long-lived <type>/<slug> branch off main; every sub-PR is a real GitHub PR targeting <type>/<slug> (not main); when every sub-PR has been self-merged into the feature branch, a final integration PR from <type>/<slug> to main collects the whole feature for external review. Main stays shippable throughout the work; each sub-PR retains full GitHub visibility (comments, reviews, history).
    • Directly to main (sub_pr_target: main): every sub-PR is reviewed on its own and merges into main; there is no integration PR. It fits sub-PRs that are truly independent and individually deliverable.

The PR-shape judgment is grounded in reviewer cost: a 2000-line PR is unreviewable even if the work is "one thing". If you can name two independent surfaces that ship value separately, that's two PRs, and the work is a multi-PR feature.

The decision is noted in chat (or as a one-line ## Implementation breakdown paragraph in the spec naming the PRs — NOT the contracts between them). The spec stays a clean ADR otherwise.

5. File the tracking issue(s)

REQUIRED SUB-SKILL: Invoke feature-dev-workflow:writing-github-issues with the PR-shape decision in hand.

  • Single PR → file one feature (or bug) issue.
  • Multiple PRs → file an epic with one sub-issue per PR.

Sub-issues reference only the parent epic in their ## Context section — GitHub's sub-issue linkage threads them and the epic is the design hub. Don't link the spec or plan from any issue: issues are durable, those files move and get deleted, and the spec is referenced from the plan, not the ticket.

6. Write the plan (and discover contracts)

REQUIRED SUB-SKILL: Invoke superpowers:writing-plans to produce docs/superpowers/plans/YYYY-MM-DD-<slug>-plan.md. The plan is HOW: ordered tasks, dependencies, review checkpoints, PR-by-PR breakdown.

The sub-skill ends at its self-review. Use superpowers:writing-plans for the plan and its self-review, then return here and continue with step 7. Step 9 of this workflow replaces its closing "Execution Handoff" section: when the plan is saved, do not ask the user to choose an execution method (subagent-driven or native), and do not start execution from that section. feature-dev-workflow:developing-a-feature decides how the work runs and which execution skill it uses, and it asks its own setup questions.

During plan-writing, identify parallelism and define contracts. For every pair of PRs that could run in parallel, ask: what does each side need to know about the other's wire shape, API surface, or data layout to start work without blocking? That's a contract. Document each in a ## Contracts section of the plan:

NameProducer (issue)Consumer (issue)ShapeRealization
cache-storage-layout#22#24, #25path ~/.config/<app>/<env>/sessions/<id>/...data-only
config-loader-signature#22#24, #25config.Resolve(name string) (*Config, error)pre-merge stub PR (#21)

Each contract names the wire / signature / layout the consumer can write code against today, without waiting for the producer's implementation. "TBD" is not a contract — block on it until it's concrete.

Realization strategy. A contract row is conceptual; for parallel work to actually compile, the interface has to exist as code or as data before either side starts. Pick one per row and put it in the Realization column:

  • Pre-merge stub PR — file a tiny scaffold PR that exports the symbol the consumers need: the type or function signature with a not-yet-implemented body, the shared type declaration, the route/path constant. It targets the feature branch (in the feature-branch model) or main (in single-PR features, or with sub_pr_target: main) and merges BEFORE the implementation PRs branch off. Producer and consumers then all branch from the post-stub state and import the real symbol. Best default for code-shaped contracts; costs one trivial extra PR; payoff is both sides compile from day one. Reference the stub PR's number in the Realization column once it's open.
  • Stub-on-producer-branch — the producer's own PR opens with just the signature + not-yet-implemented bodies; consumers branch from the producer's branch (not main) and rebase as the producer fills in the body. Avoids the extra PR but couples consumers to the producer's branch lifetime — rebase pain when the interface evolves. Use only when the interface and one implementation are inherently coupled (a shared private/internal module, sibling files in one package).
  • Data-only — when the contract is a path layout, file format, wire protocol, or env-var name, no code stub is needed. Consumers write against the contract row directly — strings and paths are just strings and paths. Mark the row data-only.

Sequential work doesn't need contracts. Only document them where two workers genuinely run in parallel.

Then pin the conventions. Contracts keep parallel work compiling; conventions keep it coherent. Add a ## Conventions section to the plan capturing the decisions every sub-PR inherits — the dimensions feature-dev-workflow:maintaining-architectural-coherence names (layout, naming, interfaces, vocabulary, idiom) for the surfaces this work touches. You're not inventing conventions; you're writing down the ones the brainstorm and the existing codebase already imply, so parallel workers reach the same answer instead of guessing. A convention you can't state in one line isn't agreed yet — agree it now, not after merge. Single-PR features can keep this terse; multi-PR fan-out depends on it.

7. Refine issues if planning surfaced changes

Planning often surfaces scope changes. If the issues from step 5 no longer match the plan's breakdown, update them now, before implementation starts.

REQUIRED SUB-SKILL: Re-invoke feature-dev-workflow:writing-github-issues Step 2B (update) for any issue whose acceptance criteria, scope, or dependencies shifted. Present and confirm each affected issue one at a time — one issue's gap list + proposed body per confirmation prompt, then its gh issue edit, then the next. Don't batch several issues into a single "yes to all": a wall of bodies gets rubber-stamped instead of read.

8. Initialize the orchestration state file

Before handing off, create docs/superpowers/states/YYYY-MM-DD-<slug>-state.md from ${CLAUDE_PLUGIN_ROOT}/skills/planning-a-feature/templates/feature-state.md. This is the orchestration state — phases, PRs, worktrees, contract realization, bubble-up log, pending snapshot. It's what a future Claude session resumes from via feature-dev-workflow:resuming-a-feature, without a massive user prompt.

The state file is scratch (same lifecycle as the plan): tracked in git so it survives sessions / worktrees / machines, and deleted in the orchestrator's last commit once every sub-issue is closed and the feature has shipped. Update it as the work progresses — see feature-dev-workflow:developing-a-feature for the update choreography.

Commit the spec, the plan, and the state file together as the planning artifact set on <type>/<slug> (created in step 2). Confirm you're not on main, then publish the branch so feature-dev-workflow:developing-a-feature can attach its integration worktree to it:

git branch --show-current        # must be <type>/<slug>, never main
git push -u origin <type>/<slug>

9. Hand off to implementation

Spec + plan + state file committed and pushed on <type>/<slug>, issues aligned, contracts written → invoke feature-dev-workflow:developing-a-feature to start the work. The state file is the entry-point artifact for every session that touches this feature afterward.

Anti-patterns

  • Putting PR breakdown or parallelism contracts in the spec. Spec is a durable ADR. PR breakdown is short-lived scaffolding; contracts are implementation coordination. Both belong in the plan.
  • Filing issues before the spec is reviewed. Wastes time when scope shifts during review.
  • Writing a plan before deciding PR shape. The plan's structure depends on whether you're shipping one PR or many.
  • Declaring "we'll parallelize this" without writing the contract. "Two workers in parallel" turns into "two workers blocked on each other after day one" without explicit shapes.
  • Treating "no parallelism possible" as a defeat. Sequential work is fine. The cost of inventing fake parallelism exceeds the wall-clock saved.
  • Pinning wire contracts but not conventions. Contracts make parallel work compile; without a ## Conventions block, each subagent invents its own layout and naming and the merged feature reads as written by a committee.
  • Letting an organizing label become an identifier. Flow 2 belongs in titles and spec headings, not in flow2-fixture, TestFlow2…, or …_FLOW2_…. The label is navigational; the code names the thing.

Red flags

ThoughtReality
"The spec already covers ordering, we don't need a plan"Spec is WHAT/WHY. Plan is HOW. Different artifacts, different lifecycles.
"I'll just write the plan and figure out parallelism later"Parallelism not in the plan never happens. Identify it during plan-writing.
"Filing issues is busywork, I'll just start coding"Without issues, the work isn't reviewable in chunks; the PR will be one giant blob.
"The contract is obvious, no need to write it down"Two parallel workers reading the same "obvious" thing produce divergent implementations. Write.
"I'll skip user review on the spec, it's just an internal doc"An unreviewed spec is a draft. Drafts don't get tickets filed against them.
"The feature branch is created later in feature-dev-workflow:developing-a-feature, so the spec/plan/state commit to main first"Planning owns the branch's birth. Create <type>/<slug> in step 2 before the first commit; feature-dev-workflow:developing-a-feature reuses it. Nothing about the feature reaches main except through a PR.
"This is running the feature-development flow, so the branch is feature/…"The type comes from the change, not from the workflow. A bug fix planned through this flow is still fix/….
"The plan is saved, so I ask the user: subagent-driven or native?"That question is the handoff of superpowers:writing-plans, and step 9 replaces it. Continue with steps 7 and 8, then invoke feature-dev-workflow:developing-a-feature, which asks its own setup questions.
"The slug can be refined once I see how the work lands"Every sub-branch, worktree path, and state-file row derives from it. Name the subject and its effect now (step 2); renaming later touches all of them.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.