developing-a-feature
Skill2 starsChanged 12 days agoMITView on GitHub
When the plan from feature-dev-workflow:planning-a-feature (or equivalent) is committed and you're about to start writing code. Skip for ad-hoc fixes — those go directly through superpowers:test-driven-development and feature-dev-workflow:opening-a-pull-request. The orchestration state file (docs/superpowers/states/<date>-<slug>-state.md, created by feature-dev-workflow:planning-a-feature Step 8) is the entry point — it points at the plan, the spec, the tracking issue, the open PRs, the worktrees, and any bubble-up concerns logged so far. Read it in full before anything else; follow the file's "Resume checklist" section to verify…
- Commits and pushes
In this repository19 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- addressing-review-feedbackSkill
- bounding-heavy-commandsSkill
- copilot-review-loopSkill
- drafting-a-releaseSkill
- fanning-out-with-worktreesSkill
- maintaining-architectural-coherenceSkill
- opening-a-pull-requestSkill
- planning-a-featureSkill
- product-epicSkill
- reporting-a-skill-gapSkill
- resuming-a-featureSkill
- reviewing-feature-progressSkill
- stacking-dependent-prsSkill
- testing-a-featureSkill
- testing-end-to-endSkill
- writing-code-commentsSkill
- writing-docsSkill
- writing-github-issuesSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 0 are distinctive, and 6 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.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 13
When the plan from feature-dev-workflow:planning-a-feature (or equivalent) is committed and you're about to start writing code.
- Very specific: line 35
Every sub-PR is a real GitHub PR targeting <type>/<slug>, not main.
- Very specific: line 36
When a sub-PR is ready, the orchestrator runs a self-review pass, then self-merges the sub-PR into <type>/<slug>.
- Very specific: line 38
When every sub-PR has been self-merged into the feature branch, the orchestrator opens the integration PR <type>/<slug> → main, with Closes …
- Very specific: line 43
Sub-PR approval mode (multi-PR only): Before any sub-worktree work starts, the orchestrator presents the user with a two-option choice via …
- Very specific: line 154
Delete the plan + state file once the work is genuinely done.
≈ “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.
Files
developing-a-feature
When to invoke
When the plan from feature-dev-workflow:planning-a-feature (or equivalent) is committed and you're about to start writing code. Skip for ad-hoc fixes — those go directly through superpowers:test-driven-development and feature-dev-workflow:opening-a-pull-request.
Workflow
1. Read the state file first, then plan + spec
The orchestration state file (docs/superpowers/states/<date>-<slug>-state.md, created by feature-dev-workflow:planning-a-feature Step 8) is the entry point — it points at the plan, the spec, the tracking issue, the open PRs, the worktrees, and any bubble-up concerns logged so far. Read it in full before anything else; follow the file's "Resume checklist" section to verify reality against the recorded state.
Then open the plan and spec it references. Note:
- The PR breakdown (one PR or multiple).
- The contract table in the plan's
## Contractssection (if any). - The dependency ordering — what must land first.
- Each contract's Realization strategy (pre-merge stub PR / stub-on-producer-branch / data-only).
If the plan is missing, stale, or the state file's recorded state doesn't match reality (a PR's actual status has drifted from the row), STOP and reconcile — re-invoke feature-dev-workflow:planning-a-feature Step 7 if the plan needs to change, or update the state file's rows to match reality before continuing.
2. Decide: single-PR or multi-PR
- Single PR → one worktree on the
<type>/<slug>branchfeature-dev-workflow:planning-a-featurecreated, one Claude session, one PR from it targeting main. Skip the integration-PR step at the end. - Multi-PR → two sub-models, selected by the Sub-PR target model question below. The default is the feature-branch model:
feature-dev-workflow:planning-a-featurealready created<type>/<slug>(offorigin/main) and committed the spec + plan + state file onto it. The orchestrator reuses that branch — it does not re-create it — attaching the integration worktree at.claude/worktrees/<slug>(recorded asfeature_branch+feature_worktreein the state file's frontmatter).- Every sub-PR is a real GitHub PR targeting
<type>/<slug>, not main. Each sub-worktree is created off the feature branch withgit worktree add .claude/worktrees/<slug>--<sub-name> -b <sub-type>/<slug>--<sub-name> <type>/<slug>(raw git is the simplest path here;EnterWorktreedefaults to branching from origin/main). - When a sub-PR is ready, the orchestrator runs a self-review pass, then self-merges the sub-PR into
<type>/<slug>. The dispatching agent owns this merge — sub-agents don't merge their own PRs. - Sub-issue closure:
Fixes #<sub-issue>/Closes #<sub-issue>only auto-fires on merge to the default branch. Sub-PRs into the feature branch therefore useTowards #<sub-issue>(the explicit "keep this issue open" keyword); the orchestrator runsgh issue close <sub-issue>after each self-merge. - When every sub-PR has been self-merged into the feature branch, the orchestrator opens the integration PR
<type>/<slug>→main, withCloses #<epic>in its body, for external review and the final merge. The alternative sub-model — sub-PRs targeting main directly, no integration PR — is configured by the Sub-PR target model question below.
For sequential single-PR work, skip to Step 4. For multi-PR work, dispatch parallel subagents in Step 3 — but first, ask the user how sub-PR approval should work.
Sub-PR approval mode (multi-PR only). Before any sub-worktree work starts, the orchestrator presents the user with a two-option choice via AskUserQuestion:
- Autonomous sub-worktree approval — the orchestrator reviews each sub-PR with the
reviewskill, flips it from draft to ready, self-merges it into its target (the feature branch, ormainunder the directly-to-main target model below), and closes its sub-issue automatically. Fastest fan-out; the user only sees the integration PR at the end, or, with sub-PRs targetingmain, the merged sub-PRs. Suitable when the integration PR's external-review pass is the user's intended inspection point. - Manual sub-worktree approval — the orchestrator still runs the
reviewskill on each sub-PR, but then pauses to ask the user for explicit approval beforegh pr mergeruns. One round-trip per sub-PR, but the user inspects every diff before it lands on its target (the feature branch, ormainwith sub-PRs targeting it).
Record the choice in the state file's frontmatter as sub_pr_approval: autonomous or sub_pr_approval: manual. The fan-out skill reads this field at every sub-PR ripening to decide whether to gate on user approval. Default if the field is missing in an older state file: autonomous (preserves the original behaviour).
Sub-PR review-loop (multi-PR only). Immediately after the approval-mode choice, ask a second AskUserQuestion: should each sub-PR run an automated review-loop and come back clean before it is self-merged? This is opt-in and independent of the approval mode.
- On — at each sub-PR's ripening, the orchestrator runs
feature-dev-workflow:copilot-review-loopagainst the open sub-PR before the existingreview-skill pass and self-merge. A comment the loop wants to push back on does not pause the fan-out; it is logged as a bubble-up concern and surfaced at the wave checkpoint. - Off (default) — ripening is unchanged.
Record the choice as sub_pr_review_loop: on or sub_pr_review_loop: off. The fan-out skill reads it at every ripening. Default if the field is missing in an older state file: off (preserves the original behaviour).
Sub-PR target model (multi-PR only). Immediately after the review-loop choice, ask a third AskUserQuestion: should sub-PRs target the feature branch (with one integration PR to main at the end) or main directly (with each sub-PR reviewed and merged independently)?
- Feature branch (default) — sub-PRs target
<type>/<slug>; the orchestrator self-merges each one into the feature branch; the feature culminates in a single integration PR (<type>/<slug>→main) withCloses #<epic>that closes the epic and gives external reviewers a combined diff. Choose this when sub-PRs are coupled by shared contracts and a unified review surface matters. - Directly to main — sub-PRs target
maindirectly; each is reviewed and merged on its own timeline; no integration PR at the end. Choose this when sub-PRs are truly independent and individually deliverable, and a combined review surface isn't needed.
Record the choice as sub_pr_target: feature-branch or sub_pr_target: main. The fan-out skill reads this field to set the base ref for sub-worktrees and the --base flag for each PR. Default if the field is missing in an older state file: feature-branch (preserves the original behaviour).
3. Set up the implementation environment
Multi-PR (feature-branch model) —
<type>/<slug>already exists, created and pushed byfeature-dev-workflow:planning-a-featureand carrying the committed spec/plan/state. Reuse it; never re-create it offorigin/main— that errors (fatal: a branch named '<type>/<slug>' already exists) and would orphan the planning artifacts. If planning already made the integration worktree at.claude/worktrees/<slug>, justcdinto it. Otherwise attach one to the existing branch:git fetch origin git switch main # vacate <type>/<slug> if planning left you on it git worktree add .claude/worktrees/<slug> <type>/<slug> cd .claude/worktrees/<slug>
(Fallback only if planning was skipped and <type>/<slug> exists nowhere: git worktree add .claude/worktrees/<slug> -b <type>/<slug> origin/main && git -C .claude/worktrees/<slug> push -u origin <type>/<slug>.) Update the state file's feature_branch + feature_worktree frontmatter fields to point here. Sub-worktrees off this branch are created later by feature-dev-workflow:fanning-out-with-worktrees.
Single-PR —
feature-dev-workflow:planning-a-featurecreated<type>/<slug>and committed the planning artifacts onto it; this is the only branch, and the PR opens from it. Reuse it the same way — if planning made a worktree,cdin; otherwise attach one to the existing branch:git fetch origin git switch main # vacate <type>/<slug> if planning left you on it git worktree add .claude/worktrees/<slug> <type>/<slug> cd .claude/worktrees/<slug>
(Fallback if planning was skipped: git worktree add .claude/worktrees/<slug> -b <type>/<slug> origin/main.) Skip the integration-PR step at the end; this is the only PR.
4. Implement
- Multi-PR — REQUIRED SUB-SKILL:
feature-dev-workflow:fanning-out-with-worktrees. The skill owns parallel dispatch, multi-wave ordering, the orchestrator watch loop, per-sub-PR review (via thereviewskill, orchestrator-driven — the worktree subagent does not review its own PR), self-merge into the feature branch, manual sub-issue close, and state-file maintenance. Returns control here when every sub-PR is self-merged and every contract islocked. Single-PR — the build mode depends on the plan's task shape. Read the committed plan's task list and count the tasks that are independent (no task depends on another's output — they could, in principle, be built in any order). The integration task that ties them together does not count toward independence; it consumes the others.
2+ independent tasks → drive the build task-by-task with review between tasks. REQUIRED SUB-SKILL:
superpowers:subagent-driven-development. The orchestrator (this session — the main loop, which can dispatch subagents) runs that skill's loop engine: a fresh implementer subagent per task with full task text handed in, then review, fix-loop, and continuous execution across all tasks. Two adaptations keep it consistent with the rest of this plugin:- Per-task review is the
reviewskill (the same mechanismfeature-dev-workflow:fanning-out-with-worktreesuses for sub-PRs), run by the orchestrator — not the implementer subagent that wrote the task. Run it as two scoped passes, spec-compliance first as a gate, then code quality; route findings back to the implementer and re-run until clean. - Each implementer subagent uses
superpowers:test-driven-development+feature-dev-workflow:testing-a-featurefor its task, andfeature-dev-workflow:writing-code-commentsfor every comment the change adds, edits, or deletes, exactly as the direct path below. - Each implementer subagent's prompt carries the bounded command line for every heavy command it will run, and the rule to use no other form. A subagent does not see the orchestrator's project memory. REQUIRED SUB-SKILL:
feature-dev-workflow:bounding-heavy-commands(§Dispatching subagents).
Why conditional: SDD's premise is independent tasks. Below that threshold the dispatch overhead and context hand-off cost more than they return, so the direct path is correct. This is the in-session analogue of the multi-PR fan-out — same "author and reviewer are different contexts" discipline, one PR instead of many.
- Per-task review is the
- Fewer than 2 independent tasks (one cohesive change, or a strictly sequential chain) → the orchestrator implements directly in the worktree from Step 3:
- REQUIRED SUB-SKILL:
superpowers:test-driven-developmentfor every code change. - REQUIRED SUB-SKILL:
feature-dev-workflow:testing-a-featurefor the assertion shape — black-box against the contract, not implementation.
- REQUIRED SUB-SKILL:
Either way: commits follow CLAUDE.md conventions (
<type>(<area>): <imperative summary> (#<feature-issue>)), and you run the project's test and lint commands (and typecheck, if it has one) before claiming work is done. Discover them from the project's CLAUDE.md / AGENTS.md or its build config (Makefile, package.json, etc.).REQUIRED SUB-SKILL:
feature-dev-workflow:bounding-heavy-commandsbefore you run any of them. Every test, lint, build, and typecheck command goes through its wrapper, whether or not this session looks alone: other sessions and other projects share the machine, and none of them can see the others.REQUIRED SUB-SKILL:
feature-dev-workflow:writing-code-commentsfor every comment the change adds, edits, or deletes, on both single-PR build modes. It decides whether the comment exists and what it holds.OPTIONAL SUB-SKILL:
simple-english:simple-englishfor the prose of every commit body and every code or doc comment you write, here and in the Step 7 teardown 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 subject line keeps the project's commit convention (format, prefix, length), the body still carries the why and what the diff cannot show, and the project's comment rules still decide whether a comment exists and what it may say (no narration of the code, no change history). Identifiers, strings, and log messages are code and keep the project's rules. 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/SimpleEnglishand then/plugin install simple-english@simple-english. Then write short, plain, active sentences without it.
Keep the tracking issue true as you build. When an implementation decision diverges from what the tracking issue (or sub-issue / epic) currently states — a changed acceptance criterion, a stated approach that no longer matches, a scope shift, a contract that shipped in a different shape — the issue must be reconciled and the decision recorded, not left to go stale until the merge. REQUIRED SUB-SKILL: feature-dev-workflow:writing-github-issues Step 2D — it records the decision as a comment (what the issue said before, what it is now, why, with a link to the commit) and reconciles the body, both under one confirmation. Do it at the decision, while the before-state and the commit are fresh, not deferred to PR-open where the delta and its reason are lost. The PR description still carries the line-level design; the issue carries the decision trail. Applies to all three build modes: in fan-out the orchestrator owns it for the epic/sub-issue divergences a sub-PR surfaces.
5. Checkpoint review before opening the final PR
- Single-PR feature → the implementation is now structurally complete, so this is the point to add whole-flow coverage. If the change introduced a new user- or consumer-visible flow, write the end-to-end coverage now — REQUIRED SUB-SKILL:
feature-dev-workflow:testing-end-to-endfor which flows earn one and what each asserts. The behavior is settled now, so this is also the point to write or update the public-facing docs the change touches — REQUIRED SUB-SKILL:feature-dev-workflow:writing-docsfor what earns a doc and how to verify a reader can actually use it. Then REQUIRED SUB-SKILL:superpowers:verification-before-completion. Run the project's test, lint, and (if it has one) typecheck commands. Paste the output. Forbids claiming "done" without evidence. - Multi-PR feature → REQUIRED SUB-SKILL:
feature-dev-workflow:reviewing-feature-progress. The orchestrator's checkpoint skill re-reads spec + plan + state, walks every self-merged sub-PR against acceptance criteria, checks state-file integrity, and runs end-to-end verification on the integrated code (the feature branch as a whole, ormainwhen sub-PRs target it; not just per-sub-PR CI). Catches drift and integration-only failures before the external-review surface opens. If the checkpoint finds gaps, route back throughfeature-dev-workflow:developing-a-featureStep 4 (follow-up sub-PR) orfeature-dev-workflow:planning-a-featureSteps 6/7 (plan/issue refinement) before continuing.
6. Open the PR
REQUIRED SUB-SKILL: feature-dev-workflow:opening-a-pull-request. Base + body keyword depend on which model is in play:
- Single-PR feature → PR targets
mainfrom<type>/<slug>. Body opens withFixes #<feature-issue>(bug) orCloses #<feature-issue>(feature/task) so the issue auto-closes on merge. - Multi-PR (feature-branch) integration PR → PR targets
mainfrom<type>/<slug>(gh pr create --base main --head <type>/<slug>). Body opens withCloses #<epic>so the epic auto-closes on merge. This is the PR external reviewers see; the diff is the whole feature. - Multi-PR (directly to main) → there is no integration PR and nothing to open here. The epic stays open: sub-PR keywords only close sub-issues, and closing the epic is the user's decision (see
feature-dev-workflow:fanning-out-with-worktreesStep 7). Proceed to Step 7.
Sub-PRs into the feature branch are owned by feature-dev-workflow:fanning-out-with-worktrees, not this step.
Once the PR to main is open — the single-PR PR, or the multi-PR integration PR — ask the user (via AskUserQuestion) whether to run an automated review-loop on it before handing off for external human review. If yes, OPTIONAL SUB-SKILL: feature-dev-workflow:copilot-review-loop against this PR; it drives the PR's automated (Copilot) review to clean. This is the interactive context, so a comment the loop wants to push back on pauses for the user. If no, hand off as-is.
Run the loop on the final PR diff. The Step 7 teardown is the last commit on the branch, so a review run before it goes stale against what external reviewers actually see. If the teardown will land after a clean review, defer the loop until after the teardown commit (or re-run it afterward) — and when CI gates the teardown, that means running the loop once the teardown commit is pushed and green, not at PR-open.
The merge to main is the user's — always. This step's terminal state is ready-to-merge: PR open, review loop clean (if run), teardown landed per Step 7. The orchestrator never runs gh pr merge on the single-PR feature PR or the integration PR. The only merges this workflow executes itself are the sub-PR merges governed by the state file's explicit sub_pr_approval/sub_pr_target configuration (feature-dev-workflow:fanning-out-with-worktrees Step 5) — configuration the user answered as specific questions, not inferred consent. A blanket autonomy grant — "do this all autonomously", "I'm going AFK" — authorizes everything up to and including the review loop and the teardown, and ends there. Merge-ish phrasing in passing ("merge it when you're done", "merge to the main worktree") is not the merge button either: it usually means "bring the result into the local checkout and verify it", and even when it doesn't, merging the feature to main is a fresh decision the user takes looking at the specific, final PR. Finish everything else, report the PR ready-to-merge, and stop — an open clean PR waiting for the user costs nothing; an unwanted merge to main costs a revert on the default branch.
Linear stacks of dependent PRs go through gh stack
A stack is a linear chain of open PRs where each PR's branch is based on the branch of the PR below it. A consumer branched from its producer's branch (stub-on-producer-branch) is a stack, and so is a strictly sequential run of sub-PRs opened before their parents merge. Parallel, independent sub-PRs in a fan-out wave are not a stack.
REQUIRED SUB-SKILL: feature-dev-workflow:stacking-dependent-prs for every operation on a stack: creating or adopting it, opening and linking its PRs, propagating a fix through it, syncing after a parent merges, and merging its layers. Never propagate a stack by hand (manual gh pr edit --base retargets, per-layer merge-forward, gh pr merge on a layer).
Review-driven changes while several open PRs share history
Multi-PR features put several open PRs on branches that contain each other's commits — sub-PRs stacked on a parent branch, feature-branch sub-PRs open concurrently, wave N+1 branched off what wave N merged. When a human reviews those PRs and streams findings, three rules govern every change:
- Fix where the code lives, not where the comment sits. A reviewer flags code on whichever PR they happen to be reading; the branch whose PR introduced the code is where the fix commits. Establish ownership before editing (
git log -S '<snippet>' --format='%h %D %s' -- <file>, then find the earliest stack branch containing that commit): a file being visible in a descendant's worktree is history inheritance, not ownership. Fixing at the point of visibility pollutes the descendant's diff with a change to code it didn't introduce, and lets the ancestor PR merge with the defect intact. If the owning PR has already merged, the code now lives on the trunk it merged into (main, or<type>/<slug>in the feature-branch model), so the fix is its own small PR against that trunk, built in its own worktree off the trunk (never the stack's worktree or the main checkout). It references a new bug issue that links the owning sub-issue, since that sub-issue usually closed with its merge. It is not a commit added to whichever open layer the reviewer happened to be reading. One exception: when an open layer cannot pass its gates or behave correctly without the fix, commit the fix in the lowest open layer that needs it, and say so in that PR's body. In agh stackstack, the open layers pick up the merged fix withgh stack synconce it lands. - Propagate through
gh stackin a stack; merge forward everywhere else. In a linear stack, REQUIRED SUB-SKILL:feature-dev-workflow:stacking-dependent-prs§Propagation is a rebase: it commits the fix on the owning layer and rebases the layers above withgh stack, adopting a link-only stack first. Outside a stack, never rebase: once the origin branch is fixed and pushed, each descendant merges its updated parent in order and pushes, because rebasing rewrites SHAs under live review and orphans the reviewer's comment anchors. - Propagate the decision, not just the code. A review decision that changes approach, scope, or a contract touches more than the diff. Walk the full list at each decision, while the why is fresh: the spec and plan (amend), the state file (bubble-up entry + the head SHAs of every branch the propagation moved), affected issue bodies (
feature-dev-workflow:writing-github-issuesStep 2D), and every open PR body the change makes stale (feature-dev-workflow:opening-a-pull-request's reconciliation). A wrap-up sweep is a backstop, not the mechanism.
Scripted state-file edits assert, then write. Long review sessions update the state file's dense PR-table rows many times, so the edits get scripted. A guarded substitution ("replace the SHA if this pattern matches") fails silently: the no-op produces no diff hunk, and an eyeball pass can't see an absence. A scripted state-file edit is keyed on the row's stable cell (branch name or PR number), asserts that every targeted row matched and that exactly one token was replaced per row, aborts without writing when any assertion fails, and prints old → new per row after writing. The head SHAs it records come from the remote at write time (git ls-remote origin <branch> or gh pr view <num> --json headRefOid), never from memory of the push: the table describes what a resumed session will find on GitHub.
7. Tear down the planning artifacts
Delete the plan + state file once the work is genuinely done. They are scratch; leaving them committed past readiness pollutes the repo with stale operational state that future greps have to wade through.
The spec's fate depends on where the repo keeps its durable decision records. Check for an established convention: a docs/adrs/ (or equivalent) directory, an ADR-authoring skill, an architecture log.
- The repo has one → the spec does not merge as-is. Distill its lasting architectural decisions into that format — one record per coherent decision bundle, following the house format and any authoring skill the repo provides — present the drafts for user review, and land the approved records with the teardown; the spec is deleted alongside the plan and state file. A year out, engineers read the repo's canonical decision record, not a feature-scoped design doc in a scratch path; a spec that "stays" outside that record is durable in letter, not in function. The distilled records carry the decisions, alternatives, and consequences; the operational detail they leave behind lives on in the merged code, its tests, and the docs written at Step 5.
- The repo has none → the spec stays as the feature's durable design record.
OPTIONAL SUB-SKILL: simple-english:simple-english for the prose of the distilled decision records. 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 house format still decides the sections and what they hold. 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.
The teardown is the last commit on the feature branch; what gates it depends on whether the repo runs CI on the integration PR. Settle that first by inspecting the repo's CI configuration — is a pipeline wired to run on this PR's branch? Decide from the configuration, not from a momentary gh pr checks reading: zero checks reported can mean either "no CI exists" or "CI hasn't registered yet," and you can't tell those apart by polling.
CI is configured to run on the PR → do NOT tear down until its checks are green. The state file is the resume contract for exactly the case where CI comes back red and you have to fix forward — tear it down before CI confirms and a failed run leaves you fixing forward with no recorded state. Push the teardown only after the checks pass — never as the commit before opening the PR, and never on "local green" or "flipped ready" alone (those are not the CI gate).
No CI is configured to run on the PR → the full local suite you already pasted via superpowers:verification-before-completion is the gate, so proceed. Nothing async can come back red, so there is no resume contract to protect and nothing to wait for — polling for checks the configuration shows will never appear only stalls the workflow.
Single-PR features follow the same two branches. Until you tear down, keep updating the state file as reality moves.
The teardown does not change where the flow ends. In the models that end in a final PR (single-PR; feature-branch integration PR), the terminal state is still ready-to-merge — report and stop; the user merges (see the merge guard in Step 6). In the sub_pr_target: main model there is no final PR — the deliverables already merged as sub-PRs — so report that every sub-PR merged and every sub-issue closed, leave the epic open for the user, and stop.
Anti-patterns
- Mixing single-PR and multi-PR flows mid-feature. Once the plan declares multi-PR, every change lands through the chosen sub-PR flow. Don't quietly merge "just this small fix" directly to main outside it — it skips the sub-PR review the feature relies on and, in the feature-branch model, forks the work from the feature branch.
- Skipping
verification-before-completionbecause "tests passed in my package". The full test suite runs the whole project because cross-package wiring breaks on edits that look local. - Letting the state file drift from reality. A resumed session reads the state file as ground truth. Update it on every transition (worktree assigned, PR opened, sub-PR self-merged, phase changed, feature shipped).
- Fixing a review finding on the branch where it was reported. The reviewer's comment sits on whichever PR they were reading; the fix belongs on the branch whose PR introduced the code, propagated to the descendants by
gh stackin a stack and by merging forward otherwise (see §Review-driven changes while several open PRs share history). - Re-implementing fan-out logic inline. Parallel dispatch, multi-wave ordering, the watch loop, per-sub-PR self-review and self-merge — all of that is in
feature-dev-workflow:fanning-out-with-worktrees. Don't paste it into the dispatch prompt or the developing-a-feature flow; reference the sub-skill instead. - Merging the final PR to main yourself. The single-PR feature PR and the integration PR are external-review surfaces; the user holds that merge button. No blanket autonomy grant covers it — the workflow's terminal state is ready-to-merge, not merged (see the merge guard in Step 6).
Red flags
| Thought | Reality |
| "I'll just open one big PR, the plan is overcomplicating this" | The PR-shape decision happened during planning. Reopening it here means re-running feature-dev-workflow:planning-a-feature Step 4, not skipping the model. |
| "Tests pass, I'll skip lint" | Lint is a CI gate. Running it locally is the cheapest place to catch the failure. |
| "The state file is for the planner, I don't need to update it during dev" | The state file is the resume contract. Every transition is your responsibility while dev is in flight. |
| "The user said 'do this all autonomously', so merging to main is covered" | Blanket autonomy ends at ready-to-merge (review loop clean, teardown landed). The merge to main is the user's fresh decision on the specific final PR. Report and stop. |
| "They wrote 'merge it / merge to the main worktree' earlier — that's authorization" | Merge-ish phrasing in passing isn't the merge button; it usually means "bring the result into the local checkout and verify it". Stop at ready-to-merge; if they want you to merge, they'll say so against the open PR. |
"Closes #<epic> is in the body — merging just completes the design" | The keyword describes what happens when the user merges. It is not an instruction to merge. |
| "I'll open the integration PR before the last sub-PR is self-merged" | The integration PR's diff is supposed to be the whole feature. An in-flight sub-PR means the integration PR will be re-pushed mid-review. Wait. |
"I'll create <type>/<slug> off origin/main in step 3" | Planning already created it and committed the spec/plan/state onto it. -b <type>/<slug> errors ("already exists") and re-creating off origin/main orphans the planning artifacts. Reuse the existing branch; attach a worktree to it. |
| "Tests pass locally and the PR is ready, so I'll tear down plan/state now" | When CI runs on the PR, local green and "ready" aren't the gate — if it comes back red you fix forward, with no state file if you deleted it. Tear down on the PR's checks going green. (Repo has no CI configured for this branch? Then the local suite is the gate — proceed.) |
| "The spec stays — it's the durable record" | Only in repos with no decision-record convention of their own. Where docs/adrs/ (or equivalent) exists, distill the lasting decisions into it — with user review — and delete the spec with the other scratch artifacts. The canonical record is what future engineers actually read. |
"gh pr checks reports no checks, so I'll keep polling until CI shows up" | Zero checks reported isn't the same as CI pending. Inspect the repo's CI configuration: if no pipeline runs on this branch, none will ever appear and polling just stalls the workflow. Proceed on the local suite you already pasted. |
| "It's one PR, I'll just implement all the tasks myself in this session" | If the plan has 2+ independent tasks, that skips per-task review — the author and reviewer are the same context, so the bug that slipped into task 1 survives into the PR. Count the independent tasks; at 2+ drive it through superpowers:subagent-driven-development. |
| "The tasks are independent, so I'll knock them out back-to-back myself" | Independence is the signal for task-by-task dispatch with review between, not against it — it's exactly when SDD pays off. Direct implementation is for one cohesive change or a strictly sequential chain. |
| "The redesign is in the PR description, the issue can stay as-is" | The PR carries the design; the issue's thread is the decision trail — what its stated approach/criteria were and why they changed. A divergence from the issue gets recorded on it while it's fresh (feature-dev-workflow:writing-github-issues Step 2D). |
| "It auto-closes on merge, so a stale issue body doesn't matter" | A closed issue and its comments are the durable record people read later. A stale body misleads and the 'why' is gone. Reconcile and record the decision before the merge (feature-dev-workflow:writing-github-issues Step 2D). |
| "Design belongs in the PR, so I leave the issue's Approach alone" | That bars dumping new line-level design into the issue — not keeping its stated content true. A now-false Approach is reconciled and the decision recorded (feature-dev-workflow:writing-github-issues Step 2D). |
| "The function is right here in this worktree, I'll fix it here" | Visibility is history inheritance, not ownership. Trace which PR introduced the code and fix there, then propagate (gh stack rebase --upstack in a stack, merge forward otherwise), or the ancestor merges with the defect intact. If that PR already merged, the fix is its own PR against the trunk, unless an open layer cannot pass without it; then it goes in the lowest open layer that needs it, noted in that PR's body. |
| "My replace script is guarded, and I'll eyeball the diff after" | A guarded substitution that doesn't match no-ops silently: no hunk appears, and an eyeball pass can't see an absence. Assert every row matched before writing; abort on any anomaly. |
| "I just pushed these branches, I know what the heads are" | Record what the remote actually has (git ls-remote / gh pr view --json headRefOid), not what you remember pushing. The state file describes what a resumed session will find on GitHub. |
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
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.

