From 1b5ac48f2e7d99c09a1f8aaba3ed2c435ea9ccd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86gir=20M=C3=A1ni=20Hauksson?= <54936225+sourcehawk@users.noreply.github.com> Date: Sat, 4 Jul 2026 05:42:32 +0200 Subject: [PATCH 1/6] feat(skills/resuming-a-feature): add cold-resume skill and pending-snapshot convention --- skills/planning-a-feature/SKILL.md | 2 +- .../templates/feature-state.md | 12 +++- skills/resuming-a-feature/SKILL.md | 71 +++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 skills/resuming-a-feature/SKILL.md diff --git a/skills/planning-a-feature/SKILL.md b/skills/planning-a-feature/SKILL.md index b68e488..d944693 100644 --- a/skills/planning-a-feature/SKILL.md +++ b/skills/planning-a-feature/SKILL.md @@ -108,7 +108,7 @@ Planning often surfaces scope changes. If the issues from step 5 no longer match ### 8. Initialize the orchestration state file -Before handing off, create `docs/superpowers/states/YYYY-MM-DD--state.md` from `${CLAUDE_PLUGIN_ROOT}/skills/planning-a-feature/templates/feature-state.md`. This is the **orchestration state** — phases, PRs, worktrees, contract realization, bubble-up log. It's what a future Claude session reads first to resume the work without a massive user prompt. +Before handing off, create `docs/superpowers/states/YYYY-MM-DD--state.md` from `${CLAUDE_PLUGIN_ROOT}/skills/planning-a-feature/templates/feature-state.md`. This is the **orchestration state** — phases, PRs, worktrees, contract realization, bubble-up log, pending snapshot. It's what a future Claude session resumes from via `feature-dev-workflow:resuming-a-feature`, without a massive user prompt. The state file is scratch (same lifecycle as the plan): tracked in git so it survives sessions / worktrees / machines, and deleted in the orchestrator's last commit once every sub-issue is closed and the feature has shipped. Update it as the work progresses — see `feature-dev-workflow:developing-a-feature` for the update choreography. diff --git a/skills/planning-a-feature/templates/feature-state.md b/skills/planning-a-feature/templates/feature-state.md index 2ea6773..28d60ca 100644 --- a/skills/planning-a-feature/templates/feature-state.md +++ b/skills/planning-a-feature/templates/feature-state.md @@ -61,13 +61,21 @@ Concerns raised by any subagent during fan-out, the resolution, and how it was p - _No concerns yet._ +## Pending snapshot + + + +- _Nothing pending._ + ## Resume checklist -For a fresh Claude session resuming this work: +For a fresh Claude session resuming this work: invoke `feature-dev-workflow:resuming-a-feature` — it executes the steps below, routes by the `status:` frontmatter, and works the `## Pending snapshot`. Fallback if that skill is unavailable: 1. Read this state file in full. 2. Read the plan at the path in the `plan:` frontmatter. 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), or work the `## Pending snapshot` when development is past. diff --git a/skills/resuming-a-feature/SKILL.md b/skills/resuming-a-feature/SKILL.md new file mode 100644 index 0000000..22a5e33 --- /dev/null +++ b/skills/resuming-a-feature/SKILL.md @@ -0,0 +1,71 @@ +--- +name: resuming-a-feature +description: + Use when a session starts with a request to resume, continue, or + pick up in-flight feature work recorded in an orchestration state + file (docs/superpowers/states/), or when handed a state-file path. +--- + +# resuming-a-feature + +## When to invoke + +First action of a fresh session when the user asks to resume, continue, or pick up a planned feature — at any phase: mid-development, mid-review, merge staging, or wrap-up. Skip when no state file exists; there is nothing to resume, so ask what the work is or enter `feature-dev-workflow:planning-a-feature`. + +## Why this exists + +The state file is the resume contract, but a cold session that only knows "read the state file" still has to derive the rest: which recorded facts to trust versus re-verify, which skill owns each remaining action, and how to re-enter at a phase the development skills' triggers don't name (a feature past active development matches no skill description). Left underivable, the user compensates with a hand-written resume prompt reconstructing what the state file already records. This skill is the protocol; the state file's `## Pending snapshot` section is its input. + +## Workflow + +### 1. Locate the state file + +A user-provided path wins. Otherwise search every checkout — state files live on feature branches, so the main checkout usually has none: `ls docs/superpowers/states/` in the current directory, then in each worktree listed by `git worktree list`. Multiple candidates → ask which feature. + +### 2. Read it in full, then the plan and spec + +Everything: frontmatter (`status`, the `sub_pr_*` configuration, branch/worktree/artifact paths), `## Phases`, the `## PRs / worktrees` table, `## Contracts`, `## Bubble-up log`, `## Pending snapshot`, the resume checklist. Then the plan and spec at the recorded paths (they may already be torn down late in the lifecycle; that is normal, not drift). + +### 3. Verify before trusting + +The state file is authoritative for intent, decisions, pointers, and recorded user configuration; live git/GitHub/filesystem are authoritative for every mutable fact. On disagreement, reality wins — reconcile the state file first (commit and push it) before proposing any mutation. + +| Trust from the file | Verify against live sources | +| ------------------- | --------------------------- | +| Plan/spec paths, slug, issue and PR numbers, branch names, worktree paths | Each PR's actual state: `gh pr view --json state,isDraft,baseRefName,headRefOid,mergedAt` vs the recorded row | +| `sub_pr_approval` / `sub_pr_review_loop` / `sub_pr_target` — explicit user answers; don't re-ask | Each issue's open/closed state (`gh issue view --json state`) | +| Bubble-up resolutions and their propagation records | Each worktree: exists, clean, no unpushed commits (`git -C status --porcelain`; `git -C log --oneline @{u}..`) | +| The `## Pending snapshot`'s intent and ordering | Branch existence (`git rev-parse --verify`), CI state (`gh pr checks`) | + +### 4. Treat the bubble-up log as settled + +Its entries record adjudicated decisions with their why. A fresh session's fresh eyes are not new evidence — don't reopen or silently redo them. If one looks genuinely wrong, raise it with the user; never relitigate it unprompted. + +### 5. Route by recorded phase + +| `status:` | Re-enter | +| --------- | -------- | +| `planning` | `feature-dev-workflow:planning-a-feature`, at the step the snapshot names | +| `foundational-wave` / `consumer-wave` | `feature-dev-workflow:developing-a-feature` Step 4 → `feature-dev-workflow:fanning-out-with-worktrees`, continuing the recorded wave | +| `review` | The `## Pending snapshot`'s actions, each through the skill that owns it: retargets, body reconciliation, and ready-flips via `feature-dev-workflow:opening-a-pull-request`; pre-flip checkpoints via `feature-dev-workflow:reviewing-feature-progress`; issue closure and reconciliation via `feature-dev-workflow:writing-github-issues`; teardown via `feature-dev-workflow:developing-a-feature` Step 7 | +| `merged` | Remaining wrap-up items from the snapshot only (epic closure verification, worktree deletion after the unpushed-commit check, teardown) | + +Resuming changes who is at the keyboard, not who holds the merge button: `feature-dev-workflow:developing-a-feature`'s merge guard still governs, and no `gh pr merge` runs beyond what `sub_pr_approval` / `sub_pr_target` already configured. + +### 6. Report before mutating + +One reconciled summary to the user: the feature, the phase, per-PR reality against the recorded rows, every divergence found and fixed, and the next actions from the snapshot. Then confirm the first mutation — resuming is not standing consent for the backlog. + +## The Pending snapshot contract (producing side) + +Resume quality is determined before a session ends, not after the next one starts. At the end of every work burst — and always when the user signals a pause or a session end — refresh the state file's `## Pending snapshot`: the ordered next actions, each carrying what, where, which skill owns it, and what gates it, with enough context that a cold session could execute from the file alone. If the user has to hand-write a resume prompt reconstructing the state, the snapshot failed its job. + +## Red flags + +| Thought | Reality | +| ------- | ------- | +| "The row says draft, so it's a draft" | Rows record the past; `gh pr view` is the present. Verify every mutable fact before acting on it. | +| "The user's resume prompt describes the state, that's enough" | Prompts go stale exactly like rows. Read the file, verify live, reconcile — then act. | +| "This bubble-up decision looks wrong, I'll redo it properly" | It records an adjudication with its why. Raise it with the user if genuinely suspect; don't silently reopen it. | +| "Development is done, so developing-a-feature doesn't apply anymore" | Its merge guard, state-file contract, and Step 7 teardown still govern. Route each remaining atom through the skill that owns it. | +| "I'll work through the snapshot, no need to check GitHub first" | The snapshot was true when written. A human may have merged, retargeted, or commented since. Verify, reconcile, then execute. | From deb420f26fb0928d716333acd43cecbce90471c2 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, 10 Jul 2026 10:01:09 +0200 Subject: [PATCH 2/6] fix(skills/resuming-a-feature): make the verify-table commands executable with placeholders git rev-parse --verify and gh pr checks were missing their required arguments; a cold session can't run them as written. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J1vgUwZZpzavETACT3fXPM --- skills/resuming-a-feature/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/resuming-a-feature/SKILL.md b/skills/resuming-a-feature/SKILL.md index 22a5e33..af88e14 100644 --- a/skills/resuming-a-feature/SKILL.md +++ b/skills/resuming-a-feature/SKILL.md @@ -35,7 +35,7 @@ The state file is authoritative for intent, decisions, pointers, and recorded us | Plan/spec paths, slug, issue and PR numbers, branch names, worktree paths | Each PR's actual state: `gh pr view --json state,isDraft,baseRefName,headRefOid,mergedAt` vs the recorded row | | `sub_pr_approval` / `sub_pr_review_loop` / `sub_pr_target` — explicit user answers; don't re-ask | Each issue's open/closed state (`gh issue view --json state`) | | Bubble-up resolutions and their propagation records | Each worktree: exists, clean, no unpushed commits (`git -C status --porcelain`; `git -C log --oneline @{u}..`) | -| The `## Pending snapshot`'s intent and ordering | Branch existence (`git rev-parse --verify`), CI state (`gh pr checks`) | +| The `## Pending snapshot`'s intent and ordering | Branch existence (`git rev-parse --verify `), CI state (`gh pr checks `) | ### 4. Treat the bubble-up log as settled From a1397a85c387890cddee63442bba5cff88e9911f 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, 10 Jul 2026 10:01:33 +0200 Subject: [PATCH 3/6] fix(templates): check unpushed commits, not main..HEAD, in the fallback resume checklist Sub-PR branches are based on the feature branch, so main..HEAD includes inherited commits; the upstream check matches what resuming-a-feature verifies. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J1vgUwZZpzavETACT3fXPM --- skills/planning-a-feature/templates/feature-state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/planning-a-feature/templates/feature-state.md b/skills/planning-a-feature/templates/feature-state.md index 28d60ca..ac5b1e0 100644 --- a/skills/planning-a-feature/templates/feature-state.md +++ b/skills/planning-a-feature/templates/feature-state.md @@ -77,5 +77,5 @@ For a fresh Claude session resuming this work: invoke `feature-dev-workflow:resu 2. Read the plan at the path in the `plan:` frontmatter. 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`. +5. For each `in-progress` or `draft` row, `cd` to the worktree path and check `git status` + `git log --oneline @{u}..` (unpushed commits; sub-branches are based on the feature branch, so `main..HEAD` would show inherited commits too). 6. Re-dispatch subagents as needed per `feature-dev-workflow:developing-a-feature` (parallel waves still in flight; the orchestrator watch loop continues), or work the `## Pending snapshot` when development is past. From eb4be38d726713f61566e0bf02baa709ad40b9a3 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, 10 Jul 2026 10:02:14 +0200 Subject: [PATCH 4/6] docs(templates): register resuming-a-feature in the README skills table and the project-CLAUDE.md ownership table A router skill nobody can discover fails its purpose; CLAUDE.md requires the discovery docs to track skill additions. The mermaid diagram is unchanged: it depicts the conception-to-ship path, which resume re-enters rather than extends. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J1vgUwZZpzavETACT3fXPM --- README.md | 1 + templates/project-CLAUDE.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 317ab12..7eaf49e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ It is also the faster path. Breaking the feature into independent PRs lets the m | `planning-a-feature` | At feature conception, before any code, issue, or plan. Sequences brainstorm, spec, issues, and plan. | | `writing-github-issues` | About to `gh issue create`/`edit`, or right after a brainstorm that needs an issue. Templates for bug, feature, and epic. | | `developing-a-feature` | Starting implementation against a committed plan. Routes single-PR vs multi-PR. | +| `resuming-a-feature` | A fresh session picking up in-flight feature work recorded in an orchestration state file — at any phase. Verifies the file against live git/GitHub, then routes to the skill that owns each remaining action. | | `fanning-out-with-worktrees` | An orchestrator dispatching parallel subagents into per-PR worktrees off a feature branch. | | `reviewing-feature-progress` | Orchestration checkpoints: between fan-out waves, and before the integration PR. | | `testing-a-feature` | Writing tests for any non-trivial change. Decides the assertion shape (black-box against the contract). | diff --git a/templates/project-CLAUDE.md b/templates/project-CLAUDE.md index a7d88bf..e7c40f8 100644 --- a/templates/project-CLAUDE.md +++ b/templates/project-CLAUDE.md @@ -41,6 +41,7 @@ Invoke `feature-dev-workflow:planning-a-feature` at conception. It and the `**RE | Brainstorm → spec → issues → plan → state file | `feature-dev-workflow:planning-a-feature` (calls `superpowers:brainstorming`, `feature-dev-workflow:writing-github-issues`, `superpowers:writing-plans`) | | Implement (single or multi-PR) | `feature-dev-workflow:developing-a-feature` (with `superpowers:test-driven-development` + `feature-dev-workflow:testing-a-feature`) | | The worktree fan-out loop + wave merges | `feature-dev-workflow:fanning-out-with-worktrees` | +| Cold-session resume of in-flight work (state file → verify → route by phase) | `feature-dev-workflow:resuming-a-feature` | | Checkpoints between waves & before the integration PR | `feature-dev-workflow:reviewing-feature-progress` | | End-to-end tests for a new user/consumer-visible flow (once structurally complete) | `feature-dev-workflow:testing-end-to-end` | | Public-facing docs for what the feature changed (once structurally complete) | `feature-dev-workflow:writing-docs` | From 6122570c26982fdb650e4e0a90f938ebb2425daa 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, 10 Jul 2026 10:07:48 +0200 Subject: [PATCH 5/6] fix(skills/resuming-a-feature): verify unpushed commits with status --branch instead of @{u} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @{u} errors on a branch with no upstream — exactly the state of an in-progress worktree that hasn't pushed yet, which a cold resume must handle. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J1vgUwZZpzavETACT3fXPM --- skills/resuming-a-feature/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/resuming-a-feature/SKILL.md b/skills/resuming-a-feature/SKILL.md index af88e14..ce40ac7 100644 --- a/skills/resuming-a-feature/SKILL.md +++ b/skills/resuming-a-feature/SKILL.md @@ -34,7 +34,7 @@ The state file is authoritative for intent, decisions, pointers, and recorded us | ------------------- | --------------------------- | | Plan/spec paths, slug, issue and PR numbers, branch names, worktree paths | Each PR's actual state: `gh pr view --json state,isDraft,baseRefName,headRefOid,mergedAt` vs the recorded row | | `sub_pr_approval` / `sub_pr_review_loop` / `sub_pr_target` — explicit user answers; don't re-ask | Each issue's open/closed state (`gh issue view --json state`) | -| Bubble-up resolutions and their propagation records | Each worktree: exists, clean, no unpushed commits (`git -C status --porcelain`; `git -C log --oneline @{u}..`) | +| Bubble-up resolutions and their propagation records | Each worktree: exists, clean, no unpushed commits (`git -C status --porcelain --branch` — an `ahead` count in the header means unpushed commits; no upstream in the header means the branch was never pushed, so everything on it is unpushed) | | The `## Pending snapshot`'s intent and ordering | Branch existence (`git rev-parse --verify `), CI state (`gh pr checks `) | ### 4. Treat the bubble-up log as settled From 498af89b86aeebdc18a9dbaa922192d93e39e747 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, 10 Jul 2026 10:07:48 +0200 Subject: [PATCH 6/6] fix(templates): use git status -sb in the fallback resume checklist so it runs without an upstream Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J1vgUwZZpzavETACT3fXPM --- skills/planning-a-feature/templates/feature-state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/planning-a-feature/templates/feature-state.md b/skills/planning-a-feature/templates/feature-state.md index ac5b1e0..f4f1057 100644 --- a/skills/planning-a-feature/templates/feature-state.md +++ b/skills/planning-a-feature/templates/feature-state.md @@ -77,5 +77,5 @@ For a fresh Claude session resuming this work: invoke `feature-dev-workflow:resu 2. Read the plan at the path in the `plan:` frontmatter. 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 @{u}..` (unpushed commits; sub-branches are based on the feature branch, so `main..HEAD` would show inherited commits too). +5. For each `in-progress` or `draft` row, `cd` to the worktree path and check `git status -sb` — an `ahead` count in the header means unpushed commits, and no upstream in the header means the branch was never pushed at all. 6. Re-dispatch subagents as needed per `feature-dev-workflow:developing-a-feature` (parallel waves still in flight; the orchestrator watch loop continues), or work the `## Pending snapshot` when development is past.