From 95a6af8b2f6ea7613582898756aa1f973cc05cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Fri, 29 May 2026 17:41:24 +0200 Subject: [PATCH 1/5] chore(skills): unwrap markdown prose to one line per paragraph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These sources were hand-wrapped at ~80-100 columns (no formatter enforces it — the repo has none), which reads as ragged short lines in diffs and was never an intentional convention. Join soft-wrapped prose and list-item continuations into one line per paragraph; a genuine paragraph break stays a blank line. Tables, fenced code, headings, and frontmatter are byte-identical (verified). Covers every markdown file except the four SKILL.md being reworked in the naming-coherence PR (which carries their unwrap, to keep zero file overlap). Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 47 ++----- README.md | 78 +++------- skills/developing-a-feature/SKILL.md | 133 +++++------------- skills/opening-a-pull-request/SKILL.md | 62 +++----- .../templates/feature-state.md | 13 +- skills/testing-a-feature/SKILL.md | 51 +++---- templates/project-CLAUDE.md | 15 +- 7 files changed, 109 insertions(+), 290 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0ae296f..899faac 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,16 +4,12 @@ Read this before changing anything. -Skills are behavior-shaping code, not prose. A reworded Red Flags table or a loosened trigger changes how -every downstream agent acts. Treat an edit to a `SKILL.md` with the rigor you would give a code change, not -a docs tweak. +Skills are behavior-shaping code, not prose. A reworded Red Flags table or a loosened trigger changes how every downstream agent acts. Treat an edit to a `SKILL.md` with the rigor you would give a code change, not a docs tweak. Before you open a PR: -1. **Develop the change with `superpowers:writing-skills`** and follow its RED → GREEN → REFACTOR loop. - This is mandatory for creating or modifying any skill. -2. **Confirm the change belongs here.** This plugin is general-purpose feature-development choreography. If - an idea only helps a specific project, language, or product, it does not belong in a skill body. +1. **Develop the change with `superpowers:writing-skills`** and follow its RED → GREEN → REFACTOR loop. This is mandatory for creating or modifying any skill. +2. **Confirm the change belongs here.** This plugin is general-purpose feature-development choreography. If an idea only helps a specific project, language, or product, it does not belong in a skill body. 3. **Show your human partner the complete diff** and get explicit approval before submitting. 4. **One problem per PR.** Describe the problem you solved, not just what you changed. @@ -21,35 +17,22 @@ Before you open a PR: A single Claude Code plugin, packaged as its own single-plugin marketplace. -- `.claude-plugin/plugin.json` is the plugin manifest; `.claude-plugin/marketplace.json` makes the repo - installable as a marketplace. Skills are auto-discovered from `skills/`. -- The only runtime dependencies are the [superpowers](https://github.com/obra/superpowers) plugin and the - `gh` CLI. Keep it that way. Do not add a third-party dependency to make a skill work. +- `.claude-plugin/plugin.json` is the plugin manifest; `.claude-plugin/marketplace.json` makes the repo installable as a marketplace. Skills are auto-discovered from `skills/`. +- The only runtime dependencies are the [superpowers](https://github.com/obra/superpowers) plugin and the `gh` CLI. Keep it that way. Do not add a third-party dependency to make a skill work. ## Editing skills - **`superpowers:writing-skills` first.** Do not hand-edit a skill outside that loop. -- **A skill `description:` is "Use when..." trigger text only, never a workflow summary.** A summary - becomes a shortcut the agent takes instead of reading the body. -- **Keep skills project-agnostic.** No hardcoded repo slug, no project-specific build commands, no domain - examples. No language, framework, or product names in illustrations. A skill must read the same in a Go - repo, a Next.js app, or a Python service. The honest test: would this still be correct in a project built - on a completely different stack? -- **Reference templates with `${CLAUDE_PLUGIN_ROOT}/skills//templates/`.** Relative paths - break once the plugin is copied into the install cache. -- **Intra-plugin skill invocations are namespaced `feature-dev-workflow:`.** Leave `superpowers:*` - references and the external `review` skill alone. -- **The `**REQUIRED SUB-SKILL:**` markers are the control flow.** If you add, rename, or remove a skill, - fix every marker that points at it, in every skill, and update the diagram in `templates/project-CLAUDE.md` - and the table in `README.md`. -- **Do not churn carefully-tuned content** (Red Flags tables, rationalization lists, anti-pattern bullets) - without a concrete reason and a sense of how it changes agent behavior. The bar for editing - behavior-shaping prose is high. +- **A skill `description:` is "Use when..." trigger text only, never a workflow summary.** A summary becomes a shortcut the agent takes instead of reading the body. +- **Keep skills project-agnostic.** No hardcoded repo slug, no project-specific build commands, no domain examples. No language, framework, or product names in illustrations. A skill must read the same in a Go repo, a Next.js app, or a Python service. The honest test: would this still be correct in a project built on a completely different stack? +- **Reference templates with `${CLAUDE_PLUGIN_ROOT}/skills//templates/`.** Relative paths break once the plugin is copied into the install cache. +- **Intra-plugin skill invocations are namespaced `feature-dev-workflow:`.** Leave `superpowers:*` references and the external `review` skill alone. +- **The `**REQUIRED SUB-SKILL:**` markers are the control flow.** If you add, rename, or remove a skill, fix every marker that points at it, in every skill, and update the diagram in `templates/project-CLAUDE.md` and the table in `README.md`. +- **Do not churn carefully-tuned content** (Red Flags tables, rationalization lists, anti-pattern bullets) without a concrete reason and a sense of how it changes agent behavior. The bar for editing behavior-shaping prose is high. ## Conventions -- **Commit shape:** `feat(): ...`, `fix(): ...`, `refactor(): ...`, `docs(): ...`, - `chore(): ...`. Area mirrors the path: `skills/`, `templates`, `.claude-plugin`. +- **Commit shape:** `feat(): ...`, `fix(): ...`, `refactor(): ...`, `docs(): ...`, `chore(): ...`. Area mirrors the path: `skills/`, `templates`, `.claude-plugin`. - **One logical change per commit.** Do not bundle unrelated edits. - **Never `git add -A` or `git add .`.** Stage by name. - **No GitHub mutation without a fresh confirmation** against the specific body about to land. @@ -58,7 +41,5 @@ A single Claude Code plugin, packaged as its own single-plugin marketplace. ## Verify before done - The JSON in `.claude-plugin/` must parse. -- Before committing any genericization, grep the skills for leakage: no repo slug, no project-specific - build commands, no product or domain identifiers. -- Read the diff cold. If a sentence only makes sense knowing what just changed, it belongs in the commit - message, not the file. +- Before committing any genericization, grep the skills for leakage: no repo slug, no project-specific build commands, no product or domain identifiers. +- Read the diff cold. If a sentence only makes sense knowing what just changed, it belongs in the commit message, not the file. diff --git a/README.md b/README.md index 25c3295..648a765 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,25 @@ # feature-dev-workflow -A Claude Code plugin that turns feature development into a visible, reviewable process. It packages an -end-to-end workflow as a set of composable skills that an agent follows from a feature's conception -through to merge. +A Claude Code plugin that turns feature development into a visible, reviewable process. It packages an end-to-end workflow as a set of composable skills that an agent follows from a feature's conception through to merge. -You invoke one skill at feature conception (`feature-dev-workflow:planning-a-feature`), and the -`REQUIRED SUB-SKILL` markers inside each skill body walk the agent to the next step. The -[How it works](#how-it-works) diagram below shows the full flow. +You invoke one skill at feature conception (`feature-dev-workflow:planning-a-feature`), and the `REQUIRED SUB-SKILL` markers inside each skill body walk the agent to the next step. The [How it works](#how-it-works) diagram below shows the full flow. ## Why this exists -Real-world software development has a shape. You plan a feature, then break it into smaller tasks so the -work stays coherent and each piece is reviewable in a small batch. That discipline is what keeps a -codebase legible: every change has an intent, a reviewer, and a trail back to the decision that motivated -it. - -AI lets you skip all of that. You can hand a model the whole feature and have it one-shot the -implementation in a single sweep. It looks like the fast path, but you lose the visibility and the review -discipline, and you are left with one opaque diff that has no plan behind it and nothing a reviewer can -follow. Reviewability is the missing link in AI-driven development: teams have long treated review as a -discipline, but one-shotting discards it exactly when the volume of machine-written code makes it matter -most. It is not even the fast path: a single sweep is serial, so the whole feature -waits on one long session. - -This plugin keeps the engineering discipline while still using the agent to move fast. It makes -agent-driven development follow the same standard a senior team already uses: - -- **Design before code.** A brainstorm produces a spec, plus an ADR when the decision is cross-cutting, - that a human approves before any implementation starts. -- **Work is tracked.** Every change maps to a GitHub issue, or an epic with sub-issues, so the plan is - visible to the whole team and not just the agent. -- **Changes ship in reviewable batches.** A single self-contained change is one PR. A larger feature - becomes a set of PRs on a feature branch, each independently reviewable. -- **Quality gates are explicit.** Tests come first, verification runs before anything is called done, and - a human reviews the integration before it merges. - -The result is agent speed without the output becoming a black box: legible artifacts (specs, issues, -plans, PRs), incremental review, and a clear audit trail. - -It is also the faster path. Breaking the feature into independent PRs lets the multi-PR flow fan the work -out across parallel subagents, each in its own worktree, so independent pieces are built concurrently -rather than waiting in one serial sweep. That wins on wall-clock time and on tokens, because each subagent -holds only its own slice of context instead of the whole feature at once. +Real-world software development has a shape. You plan a feature, then break it into smaller tasks so the work stays coherent and each piece is reviewable in a small batch. That discipline is what keeps a codebase legible: every change has an intent, a reviewer, and a trail back to the decision that motivated it. + +AI lets you skip all of that. You can hand a model the whole feature and have it one-shot the implementation in a single sweep. It looks like the fast path, but you lose the visibility and the review discipline, and you are left with one opaque diff that has no plan behind it and nothing a reviewer can follow. Reviewability is the missing link in AI-driven development: teams have long treated review as a discipline, but one-shotting discards it exactly when the volume of machine-written code makes it matter most. It is not even the fast path: a single sweep is serial, so the whole feature waits on one long session. + +This plugin keeps the engineering discipline while still using the agent to move fast. It makes agent-driven development follow the same standard a senior team already uses: + +- **Design before code.** A brainstorm produces a spec, plus an ADR when the decision is cross-cutting, that a human approves before any implementation starts. +- **Work is tracked.** Every change maps to a GitHub issue, or an epic with sub-issues, so the plan is visible to the whole team and not just the agent. +- **Changes ship in reviewable batches.** A single self-contained change is one PR. A larger feature becomes a set of PRs on a feature branch, each independently reviewable. +- **Quality gates are explicit.** Tests come first, verification runs before anything is called done, and a human reviews the integration before it merges. + +The result is agent speed without the output becoming a black box: legible artifacts (specs, issues, plans, PRs), incremental review, and a clear audit trail. + +It is also the faster path. Breaking the feature into independent PRs lets the multi-PR flow fan the work out across parallel subagents, each in its own worktree, so independent pieces are built concurrently rather than waiting in one serial sweep. That wins on wall-clock time and on tokens, because each subagent holds only its own slice of context instead of the whole feature at once. ## Skills @@ -57,9 +35,7 @@ holds only its own slice of context instead of the whole feature at once. ## How it works -The flow forks once, on whether the work ships as **one PR** or **many**, and rejoins at the merge. A -single PR runs straight through. A multi-PR feature opens a long-lived feature branch and fans the sub-PRs -out across isolated worktrees, one wave at a time, with an alignment checkpoint between waves. +The flow forks once, on whether the work ships as **one PR** or **many**, and rejoins at the merge. A single PR runs straight through. A multi-PR feature opens a long-lived feature branch and fans the sub-PRs out across isolated worktrees, one wave at a time, with an alignment checkpoint between waves. ```mermaid flowchart TD @@ -89,19 +65,11 @@ flowchart TD PR2 --> Ship ``` -You invoke `feature-dev-workflow:planning-a-feature` at conception. It, and the `REQUIRED SUB-SKILL` -markers inside each skill body, walk the agent through the rest. The -[`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) paste-in maps each part of the flow to the -skill that owns it. +You invoke `feature-dev-workflow:planning-a-feature` at conception. It, and the `REQUIRED SUB-SKILL` markers inside each skill body, walk the agent through the rest. The [`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) paste-in maps each part of the flow to the skill that owns it. ## Prerequisites -This plugin depends on the [superpowers](https://github.com/obra/superpowers) plugin and references its -skills directly: `superpowers:brainstorming`, `superpowers:writing-plans`, -`superpowers:test-driven-development`, `superpowers:verification-before-completion`, and -`superpowers:dispatching-parallel-agents`. It also uses superpowers' `docs/superpowers/{specs,plans}/` -path convention, adding a sibling `docs/superpowers/states/` directory for orchestration state files. -Install superpowers first. +This plugin depends on the [superpowers](https://github.com/obra/superpowers) plugin and references its skills directly: `superpowers:brainstorming`, `superpowers:writing-plans`, `superpowers:test-driven-development`, `superpowers:verification-before-completion`, and `superpowers:dispatching-parallel-agents`. It also uses superpowers' `docs/superpowers/{specs,plans}/` path convention, adding a sibling `docs/superpowers/states/` directory for orchestration state files. Install superpowers first. The skills also assume the [`gh`](https://cli.github.com/) CLI is installed and authenticated. @@ -116,16 +84,12 @@ This repo is both a plugin and its own single-plugin marketplace: A local path also works for development: `/plugin marketplace add /path/to/feature-dev-workflow`. -No further setup is required; the skills derive your repo and build commands from context. Optionally, -paste [`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) into your project's `CLAUDE.md` to give -every session the workflow overview and the operational rules (TDD, commit conventions, GitHub-mutation -confirmation, and so on). +No further setup is required; the skills derive your repo and build commands from context. Optionally, paste [`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) into your project's `CLAUDE.md` to give every session the workflow overview and the operational rules (TDD, commit conventions, GitHub-mutation confirmation, and so on). ## Notes - Intra-plugin skill references are namespaced as `feature-dev-workflow:`. -- Skill bodies reference their own templates via `${CLAUDE_PLUGIN_ROOT}` so paths resolve after the plugin - is copied into the install cache. +- Skill bodies reference their own templates via `${CLAUDE_PLUGIN_ROOT}` so paths resolve after the plugin is copied into the install cache. ## License diff --git a/skills/developing-a-feature/SKILL.md b/skills/developing-a-feature/SKILL.md index bc74f35..6db3c21 100644 --- a/skills/developing-a-feature/SKILL.md +++ b/skills/developing-a-feature/SKILL.md @@ -10,17 +10,13 @@ description: ## 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`. +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/--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. +The orchestration state file (`docs/superpowers/states/--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: @@ -29,55 +25,30 @@ Then open the plan and spec it references. Note: - 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. +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 (feature-branch model) -- **Single PR** → one worktree on the `feature/` branch `feature-dev-workflow:planning-a-feature` created, one Claude session, one - PR from it targeting main. Skip the integration-PR step at the end. +- **Single PR** → one worktree on the `feature/` branch `feature-dev-workflow:planning-a-feature` created, one Claude session, one PR from it targeting main. Skip the integration-PR step at the end. - **Multi-PR** → feature-branch model: - - `feature-dev-workflow:planning-a-feature` already created `feature/` (off `origin/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/` (recorded as `feature_branch` + `feature_worktree` in the state file's - frontmatter). - - Every sub-PR is a real GitHub PR targeting `feature/`, not main. Each sub-worktree is created off the - feature branch with `git worktree add .claude/worktrees/-- -b feature/` - (raw git is the simplest path here; `EnterWorktree` defaults 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 - `feature/`. The dispatching agent owns this merge — sub-agents don't merge their own PRs. - - Sub-issue closure: `Fixes #` / `Closes #` only auto-fires on merge to the **default - branch**. Sub-PRs into the feature branch therefore use `Towards #` (the explicit "keep this issue - open" keyword); the orchestrator runs `gh issue close ` after each self-merge. - - When every sub-PR has been self-merged into the feature branch, the orchestrator opens the **integration PR** - `feature/` → `main`, with `Closes #` in its body, for external review and the final merge. - -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 `review` skill, self-merges it - into the feature branch, and closes its sub-issue automatically. Fastest fan-out; the user only sees the - integration PR at the end. 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 `review` skill on each sub-PR, but then pauses - to ask the user for explicit approval before `gh pr merge` runs. One round-trip per sub-PR, but the user - inspects every diff before it lands on the feature branch. - -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). + - `feature-dev-workflow:planning-a-feature` already created `feature/` (off `origin/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/` (recorded as `feature_branch` + `feature_worktree` in the state file's frontmatter). + - Every sub-PR is a real GitHub PR targeting `feature/`, not main. Each sub-worktree is created off the feature branch with `git worktree add .claude/worktrees/-- -b feature/` (raw git is the simplest path here; `EnterWorktree` defaults 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 `feature/`. The dispatching agent owns this merge — sub-agents don't merge their own PRs. + - Sub-issue closure: `Fixes #` / `Closes #` only auto-fires on merge to the **default branch**. Sub-PRs into the feature branch therefore use `Towards #` (the explicit "keep this issue open" keyword); the orchestrator runs `gh issue close ` after each self-merge. + - When every sub-PR has been self-merged into the feature branch, the orchestrator opens the **integration PR** `feature/` → `main`, with `Closes #` in its body, for external review and the final merge. + +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 `review` skill, self-merges it into the feature branch, and closes its sub-issue automatically. Fastest fan-out; the user only sees the integration PR at the end. 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 `review` skill on each sub-PR, but then pauses to ask the user for explicit approval before `gh pr merge` runs. One round-trip per sub-PR, but the user inspects every diff before it lands on the feature branch. + +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). ### 3. Set up the implementation environment -- **Multi-PR (feature-branch model)** — `feature/` already exists, created and pushed by `feature-dev-workflow:planning-a-feature` - and carrying the committed spec/plan/state. **Reuse it; never re-create it** off `origin/main` — that errors - (`fatal: a branch named 'feature/' already exists`) and would orphan the planning artifacts. If planning - already made the integration worktree at `.claude/worktrees/`, just `cd` into it. Otherwise attach one to the - existing branch: +- **Multi-PR (feature-branch model)** — `feature/` already exists, created and pushed by `feature-dev-workflow:planning-a-feature` and carrying the committed spec/plan/state. **Reuse it; never re-create it** off `origin/main` — that errors (`fatal: a branch named 'feature/' already exists`) and would orphan the planning artifacts. If planning already made the integration worktree at `.claude/worktrees/`, just `cd` into it. Otherwise attach one to the existing branch: ``` git fetch origin @@ -86,14 +57,9 @@ the field is missing in an older state file: `autonomous` (preserves the origina cd .claude/worktrees/ ``` - (Fallback only if planning was skipped and `feature/` exists nowhere: `git worktree add - .claude/worktrees/ -b feature/ origin/main && git -C .claude/worktrees/ push -u origin - feature/`.) 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`. +(Fallback only if planning was skipped and `feature/` exists nowhere: `git worktree add .claude/worktrees/ -b feature/ origin/main && git -C .claude/worktrees/ push -u origin feature/`.) 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-feature` created `feature/` 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, `cd` in; otherwise - attach one to the existing branch: +- **Single-PR** — `feature-dev-workflow:planning-a-feature` created `feature/` 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, `cd` in; otherwise attach one to the existing branch: ``` git fetch origin @@ -102,73 +68,44 @@ the field is missing in an older state file: `autonomous` (preserves the origina cd .claude/worktrees/ ``` - (Fallback if planning was skipped: `git worktree add .claude/worktrees/ -b feature/ origin/main`.) - Skip the integration-PR step at the end; this is the only PR. +(Fallback if planning was skipped: `git worktree add .claude/worktrees/ -b feature/ 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 the `review` skill, 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 is `locked`. +- **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 the `review` skill, 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 is `locked`. - **Single-PR** — the orchestrator implements directly in the worktree from Step 3: - **REQUIRED SUB-SKILL:** `superpowers:test-driven-development` for every code change. - - **REQUIRED SUB-SKILL:** `feature-dev-workflow:testing-a-feature` for the assertion shape — black-box against the contract, not - implementation. + - **REQUIRED SUB-SKILL:** `feature-dev-workflow:testing-a-feature` for the assertion shape — black-box against the contract, not implementation. - Commits follow CLAUDE.md conventions: `(): (#)`. - - 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.). + - 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.). ### 5. Checkpoint review before opening the final PR -- **Single-PR feature** → **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 main feature worktree (the feature branch as a whole, 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 through `feature-dev-workflow:developing-a-feature` Step 4 (follow-up sub-PR) or `feature-dev-workflow:planning-a-feature` - Steps 6/7 (plan/issue refinement) before continuing. +- **Single-PR feature** → **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 main feature worktree (the feature branch as a whole, 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 through `feature-dev-workflow:developing-a-feature` Step 4 (follow-up sub-PR) or `feature-dev-workflow:planning-a-feature` Steps 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 `main` from `feature/`. Body opens with `Fixes #` (bug) or - `Closes #` (feature/task) so the issue auto-closes on merge. -- **Multi-PR integration PR** → PR targets `main` from `feature/` (`gh pr create --base main --head - feature/`). Body opens with `Closes #` so the epic auto-closes on merge. This is the PR external - reviewers see; the diff is the whole feature. +- **Single-PR feature** → PR targets `main` from `feature/`. Body opens with `Fixes #` (bug) or `Closes #` (feature/task) so the issue auto-closes on merge. +- **Multi-PR integration PR** → PR targets `main` from `feature/` (`gh pr create --base main --head feature/`). Body opens with `Closes #` so the epic auto-closes on merge. This is the PR external reviewers see; the diff is the whole feature. Sub-PRs into the feature branch are owned by `feature-dev-workflow:fanning-out-with-worktrees`, not this step. ### 7. Tear down the planning artifacts -Delete the plan + state file once the work is genuinely done. The spec stays — it's the durable ADR. The plan and -state file are scratch; leaving them committed past readiness pollutes the repo with stale operational state that -future `grep`s have to wade through. +Delete the plan + state file once the work is genuinely done. The spec stays — it's the durable ADR. The plan and state file are scratch; leaving them committed past readiness pollutes the repo with stale operational state that future `grep`s have to wade through. -**Do NOT tear down until the integration PR's CI is green.** The state file is the resume contract for exactly the -case where the PR's 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. So the teardown is the **last commit on the feature branch, pushed -only after the integration PR's CI passes** — never as the commit *before opening* the PR, and never on "local green" -or "flipped ready" alone (those are not the CI gate). For single-PR features, same rule: fold the deletion in only -once the PR's CI is green. Until then, keep updating the state file as reality moves. +**Do NOT tear down until the integration PR's CI is green.** The state file is the resume contract for exactly the case where the PR's 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. So the teardown is the **last commit on the feature branch, pushed only after the integration PR's CI passes** — never as the commit *before opening* the PR, and never on "local green" or "flipped ready" alone (those are not the CI gate). For single-PR features, same rule: fold the deletion in only once the PR's CI is green. Until then, keep updating the state file as reality moves. ## Anti-patterns -- **Mixing single-PR and multi-PR flows mid-feature.** Once the plan declares multi-PR, the feature-branch model is - on. Don't quietly merge "just this small fix" directly to main while the feature branch is live — it skips - external review on the integration PR and forks the work. -- **Skipping `verification-before-completion` because "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). -- **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. +- **Mixing single-PR and multi-PR flows mid-feature.** Once the plan declares multi-PR, the feature-branch model is on. Don't quietly merge "just this small fix" directly to main while the feature branch is live — it skips external review on the integration PR and forks the work. +- **Skipping `verification-before-completion` because "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). +- **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. ## Red flags diff --git a/skills/opening-a-pull-request/SKILL.md b/skills/opening-a-pull-request/SKILL.md index e17edc8..80d0401 100644 --- a/skills/opening-a-pull-request/SKILL.md +++ b/skills/opening-a-pull-request/SKILL.md @@ -10,8 +10,7 @@ description: Two moments: -- **Opening a draft PR** when work is still in flight and you want an early surface for reviewers to flag direction - issues. Body follows the draft shape (below). +- **Opening a draft PR** when work is still in flight and you want an early surface for reviewers to flag direction issues. Body follows the draft shape (below). - **Flipping to ready, or opening a PR straight to ready**, when the work is done. Body follows the ready shape. ## Templates @@ -22,9 +21,7 @@ Two templates carry the shape and the per-section guidance: - `${CLAUDE_PLUGIN_ROOT}/skills/opening-a-pull-request/templates/pull-request-ready.md`: ready-for-review PR body. Copy the appropriate template, fill in each section per its `` guidance, then pass the body to -`gh pr create` (opening) or `gh pr edit` (flipping or editing) via a `--body "$(cat <<'EOF' ... EOF)"` heredoc. -GitHub doesn't render HTML comments, so leaving the template guidance in place is harmless — don't burn a step -removing it. +`gh pr create` (opening) or `gh pr edit` (flipping or editing) via a `--body "$(cat <<'EOF' ... EOF)"` heredoc. GitHub doesn't render HTML comments, so leaving the template guidance in place is harmless — don't burn a step removing it. ## PR title @@ -34,48 +31,32 @@ Set the title once when opening and don't rename it. Match the project's commit- (): ``` -Types: `feat`, `fix`, `refactor`, `test`, `chore`, `docs`. Area mirrors the module path (`api`, -`auth`, `ui`, `db`). When the PR bundles unrelated areas, lead with the headline change and -acknowledge the others in the body — don't try to encode both in the title. +Types: `feat`, `fix`, `refactor`, `test`, `chore`, `docs`. Area mirrors the module path (`api`, `auth`, `ui`, `db`). When the PR bundles unrelated areas, lead with the headline change and acknowledge the others in the body — don't try to encode both in the title. -**Do not suffix the title with lifecycle wording** (`wip`, `draft`, `plan`, `scaffolding`, etc.). GitHub's draft / ready -chip carries the lifecycle state. A single title that survives from open through merge avoids renames and avoids -shipping stale wording into the merged record. +**Do not suffix the title with lifecycle wording** (`wip`, `draft`, `plan`, `scaffolding`, etc.). GitHub's draft / ready chip carries the lifecycle state. A single title that survives from open through merge avoids renames and avoids shipping stale wording into the merged record. ## Linking the tracking issue -When the PR has a tracking issue, link it as the **first line of the body's opening section** — `## What lands here` -for draft, `## Description` for ready. The exact keyword depends on **whether the PR should close the issue on -merge**: +When the PR has a tracking issue, link it as the **first line of the body's opening section** — `## What lands here` for draft, `## Description` for ready. The exact keyword depends on **whether the PR should close the issue on merge**: - `Fixes #` — bug-fix issue; GitHub auto-closes the issue when the PR merges to the default branch. - `Closes #` — feature/task issue; same auto-close semantics, neutral phrasing. -- `Towards #` — the PR contributes to the issue but should NOT close it on merge. GitHub creates the back-link - but doesn't auto-close. Use when the issue will be closed by a sibling PR, by a later PR, or by the orchestrator - manually (see below). +- `Towards #` — the PR contributes to the issue but should NOT close it on merge. GitHub creates the back-link but doesn't auto-close. Use when the issue will be closed by a sibling PR, by a later PR, or by the orchestrator manually (see below). Which keyword belongs depends on **which branch the PR targets**: -- **PR targets `main` (the default branch)** — use `Fixes` / `Closes` if the merge should close the issue; - use `Towards` if the issue should stay open. -- **PR targets a feature branch** (`feature/` in the multi-PR feature-branch model — see `feature-dev-workflow:developing-a-feature`) - — use `Towards #`. `Fixes` / `Closes` keywords only auto-trigger on merges to the default branch, so - writing them on a feature-branch-bound PR creates a misleading promise that nothing will fulfill. The sub-issue is - closed manually by the orchestrator after the self-merge. The integration PR (feature → main) gets `Closes #` - because that PR does merge to main. +- **PR targets `main` (the default branch)** — use `Fixes` / `Closes` if the merge should close the issue; use `Towards` if the issue should stay open. +- **PR targets a feature branch** (`feature/` in the multi-PR feature-branch model — see `feature-dev-workflow:developing-a-feature`) — use `Towards #`. `Fixes` / `Closes` keywords only auto-trigger on merges to the default branch, so writing them on a feature-branch-bound PR creates a misleading promise that nothing will fulfill. The sub-issue is closed manually by the orchestrator after the self-merge. The integration PR (feature → main) gets `Closes #` because that PR does merge to main. If there is no tracking issue, drop the line entirely and open the section with prose. -Don't carry the issue link as a bold-line metadata header at the top of the body — the keyword form is what GitHub -uses to thread the cross-link and it reads as a natural opener to the implementation summary. +Don't carry the issue link as a bold-line metadata header at the top of the body — the keyword form is what GitHub uses to thread the cross-link and it reads as a natural opener to the implementation summary. -Other related PRs / issues (siblings, follow-ups, prior art) belong under `## Related` — that section is **only** for -links that aren't the tracking issue, since the tracking issue is already cross-linked via the keyword above. +Other related PRs / issues (siblings, follow-ups, prior art) belong under `## Related` — that section is **only** for links that aren't the tracking issue, since the tracking issue is already cross-linked via the keyword above. ## Core principle: user-in-the-loop for every GitHub mutation -Don't run `gh pr create` or `gh pr edit` without an explicit confirmation **for the specific body about to land**. -Generic intent earlier ("yes please open a PR") is not standing consent for the body now. +Don't run `gh pr create` or `gh pr edit` without an explicit confirmation **for the specific body about to land**. Generic intent earlier ("yes please open a PR") is not standing consent for the body now. Every confirmation shows the user: @@ -86,25 +67,16 @@ Wait for an explicit "yes" before any `gh pr` call. Treat absence of objection a ## Steps when flipping a draft to ready -1. **Rewrite the body from `${CLAUDE_PLUGIN_ROOT}/skills/opening-a-pull-request/templates/pull-request-ready.md`.** The shapes are different — the draft asks "review the - direction"; the ready asks "review the implementation." Don't ship the draft body forward unchanged. -2. **Confirm both mutations in one prompt, body inline.** Marking the PR ready is a separate GitHub mutation from - editing the body, and the user-in-the-loop rule applies to both. Phrase the confirmation as: "About to update - #'s body to the version below AND flip it from draft to ready. Confirm?" — then paste the body. Wait for - an explicit yes. Splitting confirmation across two prompts is fine; running `gh pr ready` on the strength of the - body confirmation is not. +1. **Rewrite the body from `${CLAUDE_PLUGIN_ROOT}/skills/opening-a-pull-request/templates/pull-request-ready.md`.** The shapes are different — the draft asks "review the direction"; the ready asks "review the implementation." Don't ship the draft body forward unchanged. +2. **Confirm both mutations in one prompt, body inline.** Marking the PR ready is a separate GitHub mutation from editing the body, and the user-in-the-loop rule applies to both. Phrase the confirmation as: "About to update #'s body to the version below AND flip it from draft to ready. Confirm?" — then paste the body. Wait for an explicit yes. Splitting confirmation across two prompts is fine; running `gh pr ready` on the strength of the body confirmation is not. 3. **Run `gh pr edit --body "$(cat <<'EOF' … EOF)"` then `gh pr ready `** once the user confirms. ## Anti-patterns -- **Lifecycle suffix in PR titles** (`... wip`, `... draft`, `... scaffolding`). The title outlives the state that - named it. The body and GitHub's chip carry lifecycle; the title doesn't need to. -- **Flipping ready with the draft body unchanged.** Different shape, different audience. Rewrite from the ready - template. -- **Marking ready before the Testing section is filled in.** That section is what gives the reviewer confidence the - PR is shippable; leaving it blank silently drops the claim. -- **Running `gh pr create` / `gh pr edit` on inferred consent.** Every body is a fresh confirmation. The cost of - pausing is low; the cost of an unwanted public mutation is high. +- **Lifecycle suffix in PR titles** (`... wip`, `... draft`, `... scaffolding`). The title outlives the state that named it. The body and GitHub's chip carry lifecycle; the title doesn't need to. +- **Flipping ready with the draft body unchanged.** Different shape, different audience. Rewrite from the ready template. +- **Marking ready before the Testing section is filled in.** That section is what gives the reviewer confidence the PR is shippable; leaving it blank silently drops the claim. +- **Running `gh pr create` / `gh pr edit` on inferred consent.** Every body is a fresh confirmation. The cost of pausing is low; the cost of an unwanted public mutation is high. ## Red flags: STOP before flipping ready or publishing diff --git a/skills/planning-a-feature/templates/feature-state.md b/skills/planning-a-feature/templates/feature-state.md index b10d393..764ec01 100644 --- a/skills/planning-a-feature/templates/feature-state.md +++ b/skills/planning-a-feature/templates/feature-state.md @@ -14,15 +14,7 @@ consumer-wave | review | merged. --> --- -feature: -spec: docs/superpowers/specs/YYYY-MM-DD--design.md -plan: docs/superpowers/plans/YYYY-MM-DD--plan.md -tracking_issue: # -feature_branch: feature/ # omit for single-PR features -feature_worktree: .claude/worktrees/ # the main integration worktree; omit for single-PR -sub_pr_approval: autonomous # autonomous | manual; omit for single-PR (see developing-a-feature Step 2) -integration_pr: # # filled in once the feature → main PR opens -status: planning +feature: spec: docs/superpowers/specs/YYYY-MM-DD--design.md plan: docs/superpowers/plans/YYYY-MM-DD--plan.md tracking_issue: # feature_branch: feature/ # omit for single-PR features feature_worktree: .claude/worktrees/ # the main integration worktree; omit for single-PR sub_pr_approval: autonomous # autonomous | manual; omit for single-PR (see developing-a-feature Step 2) integration_pr: # # filled in once the feature → main PR opens status: planning --- # — orchestration state @@ -94,5 +86,4 @@ For a fresh Claude session resuming this work: 3. Read the spec at the path in the `spec:` frontmatter. 4. Verify each open PR's actual state via `gh pr view `. 5. For each `in-progress` or `draft` row, `cd` to the worktree path and check `git status` + `git log --oneline main..HEAD`. -6. Re-dispatch subagents as needed per `feature-dev-workflow:developing-a-feature` (parallel waves still in flight; the orchestrator watch - loop continues). +6. Re-dispatch subagents as needed per `feature-dev-workflow:developing-a-feature` (parallel waves still in flight; the orchestrator watch loop continues). diff --git a/skills/testing-a-feature/SKILL.md b/skills/testing-a-feature/SKILL.md index 9538088..a279972 100644 --- a/skills/testing-a-feature/SKILL.md +++ b/skills/testing-a-feature/SKILL.md @@ -18,22 +18,17 @@ Skip for generated test scaffolds where the assertions come straight from a tool ## Core principle -**Tests assert intent, not implementation.** The intent lives in the docstring, the function comment, the spec, the -issue's acceptance criteria — the public contract of the surface under test. The implementation is the body of the -function. +**Tests assert intent, not implementation.** The intent lives in the docstring, the function comment, the spec, the issue's acceptance criteria — the public contract of the surface under test. The implementation is the body of the function. -When an implementation changes but the contract doesn't, the tests should not change. When the contract changes, the -tests change first (per TDD) and the implementation follows. +When an implementation changes but the contract doesn't, the tests should not change. When the contract changes, the tests change first (per TDD) and the implementation follows. -This is what makes a docstring valuable: it's the **black box** the tests verify against. Without an intentional -docstring, you have nothing but the code to test against, and tests degrade into change-detectors. +This is what makes a docstring valuable: it's the **black box** the tests verify against. Without an intentional docstring, you have nothing but the code to test against, and tests degrade into change-detectors. ## Workflow ### 1. Re-read the contract -Before adding any assertion, open the surface under test and read its docstring / contract. If the docstring is -absent or vague, that's the first bug to fix — a function without a contract can't be tested against intent. +Before adding any assertion, open the surface under test and read its docstring / contract. If the docstring is absent or vague, that's the first bug to fix — a function without a contract can't be tested against intent. For your project (customize this to your stack): - Public functions / methods: the doc comment is the contract. @@ -43,9 +38,7 @@ For your project (customize this to your stack): ### 2. Self-review the docstring against intent -A clean docstring should already enumerate the surface's promises. If reading it raises questions ("what happens when -N is zero?", "does this retry on failure?", "is the result sorted?"), the docstring is incomplete. **Fix the -docstring first**, then write the tests. Docstring-first surfaces the edge cases before any assertion is written. +A clean docstring should already enumerate the surface's promises. If reading it raises questions ("what happens when N is zero?", "does this retry on failure?", "is the result sorted?"), the docstring is incomplete. **Fix the docstring first**, then write the tests. Docstring-first surfaces the edge cases before any assertion is written. ### 3. List edge cases @@ -53,30 +46,24 @@ For each behavior the contract promises, ask: - **Happy path** — the documented success case. Always test. - **Boundary inputs** — zero, one, many; empty string, single char, max length; nil vs empty slice. -- **Error paths** — every error the contract names. Every error the contract _doesn't_ name but the code clearly - can return (then either name it in the docstring or make the code not return it). +- **Error paths** — every error the contract names. Every error the contract _doesn't_ name but the code clearly can return (then either name it in the docstring or make the code not return it). - **Invariants** — what should never happen, regardless of input. Concurrency safety, idempotency, atomicity. - **Failure recovery** — partial failure mid-call, retry semantics, what state survives. -Don't test for behavior the contract doesn't promise. If you're tempted to, the contract is incomplete — fix the -contract first. +Don't test for behavior the contract doesn't promise. If you're tempted to, the contract is incomplete — fix the contract first. ### 4. Write one test per edge case -Each test name reads as a contract statement: `TestStore_PersistsMultipleSessionsAcrossRestart`, -`TestGetChannelID_MissingScopeIsActionable`. The name describes the intent being verified, not the function being -called. Each test's assertion is what the contract promises, not what the implementation happens to do today. +Each test name reads as a contract statement: `TestStore_PersistsMultipleSessionsAcrossRestart`, `TestGetChannelID_MissingScopeIsActionable`. The name describes the intent being verified, not the function being called. Each test's assertion is what the contract promises, not what the implementation happens to do today. ### 5. When tempted to rewrite a test Stop. Ask: did the **contract** change, or just the implementation? - **Contract changed** → rewrite the test first, watch it fail for the right reason, then update the implementation. -- **Implementation changed** → the test should still pass. If it doesn't, either the test was coupled to - implementation details (bad test, fix it) or the implementation regressed the contract (bad change, revert it). +- **Implementation changed** → the test should still pass. If it doesn't, either the test was coupled to implementation details (bad test, fix it) or the implementation regressed the contract (bad change, revert it). -Rewriting a test "to match" a new implementation when the contract is unchanged decouples the test from intent and -silently weakens the suite. +Rewriting a test "to match" a new implementation when the contract is unchanged decouples the test from intent and silently weakens the suite. ## Edge-case discovery checklist @@ -93,18 +80,12 @@ Apply per surface, per change: ## Anti-patterns -- **Testing the implementation, not the intent.** A test that breaks when a private helper is renamed is testing - implementation, not contract. -- **Copy-pasting an assertion "to match the file's style"** without re-verifying that the asserted behavior is what - the contract under test actually promises. -- **One mega-test per function.** One assertion per intent. Mega-tests fail with one signal even when N intents are - broken. -- **Testing private functions directly.** If the contract is private, the test is testing implementation. Drive the - private code via the public surface. -- **Rewriting a test to make it pass against a changed implementation, without verifying the contract changed.** This - is how regressions slip through. -- **Skipping edge cases because "they're unlikely."** A reviewer asks "what happens when N=0?" — the test should - answer. +- **Testing the implementation, not the intent.** A test that breaks when a private helper is renamed is testing implementation, not contract. +- **Copy-pasting an assertion "to match the file's style"** without re-verifying that the asserted behavior is what the contract under test actually promises. +- **One mega-test per function.** One assertion per intent. Mega-tests fail with one signal even when N intents are broken. +- **Testing private functions directly.** If the contract is private, the test is testing implementation. Drive the private code via the public surface. +- **Rewriting a test to make it pass against a changed implementation, without verifying the contract changed.** This is how regressions slip through. +- **Skipping edge cases because "they're unlikely."** A reviewer asks "what happens when N=0?" — the test should answer. ## Red flags diff --git a/templates/project-CLAUDE.md b/templates/project-CLAUDE.md index 9520a14..6ebd3c5 100644 --- a/templates/project-CLAUDE.md +++ b/templates/project-CLAUDE.md @@ -7,8 +7,7 @@ and your test/lint/typecheck commands from context. Delete this comment after pa ## Feature-development workflow -This project uses the `feature-dev-workflow` plugin. Invoke `feature-dev-workflow:planning-a-feature` -at feature conception and let the cross-references fan out from there. +This project uses the `feature-dev-workflow` plugin. Invoke `feature-dev-workflow:planning-a-feature` at feature conception and let the cross-references fan out from there. ```mermaid flowchart TD @@ -38,9 +37,7 @@ flowchart TD PR2 --> Ship ``` -Invoke `feature-dev-workflow:planning-a-feature` at conception. It and the -`**REQUIRED SUB-SKILL:**` markers inside each skill body drive every box above. Which -skill owns which part of the flow: +Invoke `feature-dev-workflow:planning-a-feature` at conception. It and the `**REQUIRED SUB-SKILL:**` markers inside each skill body drive every box above. Which skill owns which part of the flow: | Part of the flow | Skill | | --- | --- | @@ -51,15 +48,11 @@ skill owns which part of the flow: | Verify-before-done | `superpowers:verification-before-completion` | | Open / flip pull requests | `feature-dev-workflow:opening-a-pull-request` | -`superpowers:*` skills come from the [superpowers](https://github.com/obra/superpowers) -plugin (a prerequisite, see below). +`superpowers:*` skills come from the [superpowers](https://github.com/obra/superpowers) plugin (a prerequisite, see below). ### Project commands (optional) -The skills run your project's checks before claiming work done, discovering the commands -from this file, the build config (Makefile, package.json, …), or `gh` (for the repo). If -your test / lint / typecheck commands aren't obvious from the build config, name them here -so sessions don't have to guess: +The skills run your project's checks before claiming work done, discovering the commands from this file, the build config (Makefile, package.json, …), or `gh` (for the repo). If your test / lint / typecheck commands aren't obvious from the build config, name them here so sessions don't have to guess: - **Test:** `` - **Lint:** `` From d259ba0ae27a8e9e6182b8dd8f3c14c39832511d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Fri, 29 May 2026 18:00:25 +0200 Subject: [PATCH 2/5] refactor(templates): stop restating skill-taught rules in project-CLAUDE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The template's operational-rules block duplicated discipline the skills already teach when invoked (TDD, verify-before-done, PR-title hygiene, the spec/plan/state lifecycle). A rule stated in both the template and a skill drifts — the state-dir move had to be edited in both places. Keep only what a skill reads from here (the commit convention) or can't enforce alone (the two git/GitHub safety rules); delete the rest and say why. Co-Authored-By: Claude Opus 4.8 (1M context) --- templates/project-CLAUDE.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/templates/project-CLAUDE.md b/templates/project-CLAUDE.md index 6ebd3c5..89333be 100644 --- a/templates/project-CLAUDE.md +++ b/templates/project-CLAUDE.md @@ -60,10 +60,8 @@ The skills run your project's checks before claiming work done, discovering the ### Operational rules -- **TDD is the standard.** Failing test → watch it fail for the right reason → implement. One commit per task. -- **Before claiming done:** run the project's test + lint (+ typecheck if it has one). These are the cheapest place to catch what CI gates. -- **Commit conventions:** `feat(): ...`, `fix(): ...`, `refactor(): ...`, `test(): ...`, `chore(): ...`, `docs(): ...`. Area mirrors the module path. +The skills teach the workflow discipline when invoked — TDD, verify-before-done, the issue/PR conventions, PR-title hygiene, and the spec/plan/state lifecycle. Don't restate those here; a rule duplicated between this file and a skill drifts. This block carries only what a skill must read from here or can't enforce on its own: + +- **Commit conventions:** `feat(): ...`, `fix(): ...`, `refactor(): ...`, `test(): ...`, `chore(): ...`, `docs(): ...`. Area mirrors the module path. (`feature-dev-workflow:opening-a-pull-request` reads this convention from here.) - **Never `--no-verify`, never `git add -A` / `git add .`.** Stage by name; pre-commit hooks exist for a reason. - **No GitHub mutation without a fresh confirmation against the specific body about to land.** Paste the body inline, name the target, wait for an explicit yes. -- **PR titles outlive lifecycle state.** No `wip` / `draft` / `plan` suffixes; GitHub's chip carries lifecycle. -- **Specs in `docs/superpowers/specs/` are durable; plans in `docs/superpowers/plans/` are scratch** (deleted once the plan ships). State files live in `docs/superpowers/states/` and share the plan's scratch lifecycle. From 69350d08e264941721068cd9a187c3bac9bb84fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Fri, 29 May 2026 18:12:53 +0200 Subject: [PATCH 3/5] fix(skills): join paragraph split by the reflow's false-trigger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prose reference to `` guidance tripped the unwrap's comment-skip, leaving the paragraph split across two physical lines. It renders as one paragraph (adjacent lines join), but it's an incomplete unwrap — join it. Same defect class the PR #3 review caught in writing-github-issues. --- skills/opening-a-pull-request/SKILL.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/skills/opening-a-pull-request/SKILL.md b/skills/opening-a-pull-request/SKILL.md index 80d0401..242be13 100644 --- a/skills/opening-a-pull-request/SKILL.md +++ b/skills/opening-a-pull-request/SKILL.md @@ -20,8 +20,7 @@ Two templates carry the shape and the per-section guidance: - `${CLAUDE_PLUGIN_ROOT}/skills/opening-a-pull-request/templates/pull-request-draft.md`: draft PR body. - `${CLAUDE_PLUGIN_ROOT}/skills/opening-a-pull-request/templates/pull-request-ready.md`: ready-for-review PR body. -Copy the appropriate template, fill in each section per its `` guidance, then pass the body to -`gh pr create` (opening) or `gh pr edit` (flipping or editing) via a `--body "$(cat <<'EOF' ... EOF)"` heredoc. GitHub doesn't render HTML comments, so leaving the template guidance in place is harmless — don't burn a step removing it. +Copy the appropriate template, fill in each section per its `` guidance, then pass the body to `gh pr create` (opening) or `gh pr edit` (flipping or editing) via a `--body "$(cat <<'EOF' ... EOF)"` heredoc. GitHub doesn't render HTML comments, so leaving the template guidance in place is harmless — don't burn a step removing it. ## PR title From 097ce10507f474b4d738391ed450b35892d5344f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Fri, 29 May 2026 18:32:58 +0200 Subject: [PATCH 4/5] fix(templates): restore feature-state.md YAML frontmatter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prose reflow only treated frontmatter as verbatim when it starts at line 1. feature-state.md opens with an HTML comment block before its `---` frontmatter, so the reflow joined the YAML fields onto one line — invalid, unparseable frontmatter. Restore the multi-line block; keep the one valid list-item unwrap the reflow also made. --- skills/planning-a-feature/templates/feature-state.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/skills/planning-a-feature/templates/feature-state.md b/skills/planning-a-feature/templates/feature-state.md index 764ec01..fb833ef 100644 --- a/skills/planning-a-feature/templates/feature-state.md +++ b/skills/planning-a-feature/templates/feature-state.md @@ -14,7 +14,15 @@ consumer-wave | review | merged. --> --- -feature: spec: docs/superpowers/specs/YYYY-MM-DD--design.md plan: docs/superpowers/plans/YYYY-MM-DD--plan.md tracking_issue: # feature_branch: feature/ # omit for single-PR features feature_worktree: .claude/worktrees/ # the main integration worktree; omit for single-PR sub_pr_approval: autonomous # autonomous | manual; omit for single-PR (see developing-a-feature Step 2) integration_pr: # # filled in once the feature → main PR opens status: planning +feature: +spec: docs/superpowers/specs/YYYY-MM-DD--design.md +plan: docs/superpowers/plans/YYYY-MM-DD--plan.md +tracking_issue: # +feature_branch: feature/ # omit for single-PR features +feature_worktree: .claude/worktrees/ # the main integration worktree; omit for single-PR +sub_pr_approval: autonomous # autonomous | manual; omit for single-PR (see developing-a-feature Step 2) +integration_pr: # # filled in once the feature → main PR opens +status: planning --- # — orchestration state From b3cafc4612951396fe40697904c8584dafb4be5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni?= <54936225+sourcehawk@users.noreply.github.com> Date: Fri, 29 May 2026 19:01:00 +0200 Subject: [PATCH 5/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 648a765..2b88100 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ This repo is both a plugin and its own single-plugin marketplace: A local path also works for development: `/plugin marketplace add /path/to/feature-dev-workflow`. -No further setup is required; the skills derive your repo and build commands from context. Optionally, paste [`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) into your project's `CLAUDE.md` to give every session the workflow overview and the operational rules (TDD, commit conventions, GitHub-mutation confirmation, and so on). +No further setup is required; the skills derive your repo and build commands from context. Optionally, paste [`templates/project-CLAUDE.md`](templates/project-CLAUDE.md) into your project's `CLAUDE.md` to give every session the workflow overview and the operational rules (commit conventions, safe git staging, GitHub-mutation confirmation). ## Notes