@drunkcoding/agents-and-skills 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.claude-plugin/marketplace.json +9 -6
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/plugins/html-effectiveness/.claude-plugin/plugin.json +1 -1
  5. package/plugins/html-effectiveness/README.md +9 -4
  6. package/plugins/html-effectiveness/agents/report-builder.md +4 -0
  7. package/plugins/html-effectiveness/assets/base.css +40 -20
  8. package/plugins/html-effectiveness/docs/template-gallery.md +28 -0
  9. package/plugins/html-effectiveness/scripts/_tmp.js +37 -0
  10. package/plugins/html-effectiveness/scripts/catalog.js +47 -0
  11. package/plugins/html-effectiveness/scripts/extract.js +104 -0
  12. package/plugins/html-effectiveness/scripts/render.js +2 -2
  13. package/plugins/html-effectiveness/skills/html-effectiveness/SKILL.md +4 -4
  14. package/plugins/html-effectiveness/templates/01-exploration-code-approaches.html.tmpl +400 -0
  15. package/plugins/html-effectiveness/templates/02-exploration-visual-designs.html.tmpl +456 -0
  16. package/plugins/html-effectiveness/templates/03-code-review-pr.html.tmpl +581 -0
  17. package/plugins/html-effectiveness/templates/04-code-understanding.html.tmpl +443 -0
  18. package/plugins/html-effectiveness/templates/05-design-system.html.tmpl +578 -0
  19. package/plugins/html-effectiveness/templates/06-component-variants.html.tmpl +557 -0
  20. package/plugins/html-effectiveness/templates/07-prototype-animation.html.tmpl +417 -0
  21. package/plugins/html-effectiveness/templates/08-prototype-interaction.html.tmpl +363 -0
  22. package/plugins/html-effectiveness/templates/09-slide-deck.html.tmpl +535 -0
  23. package/plugins/html-effectiveness/templates/10-svg-illustrations.html.tmpl +444 -0
  24. package/plugins/html-effectiveness/templates/11-status-report.html.tmpl +152 -0
  25. package/plugins/html-effectiveness/templates/12-incident-report.html.tmpl +547 -0
  26. package/plugins/html-effectiveness/templates/13-flowchart-diagram.html.tmpl +361 -0
  27. package/plugins/html-effectiveness/templates/14-research-feature-explainer.html.tmpl +348 -0
  28. package/plugins/html-effectiveness/templates/15-research-concept-explainer.html.tmpl +334 -0
  29. package/plugins/html-effectiveness/templates/16-implementation-plan.html.tmpl +657 -0
  30. package/plugins/html-effectiveness/templates/17-pr-writeup.html.tmpl +553 -0
  31. package/plugins/html-effectiveness/templates/18-editor-triage-board.html.tmpl +541 -0
  32. package/plugins/html-effectiveness/templates/19-editor-feature-flags.html.tmpl +627 -0
  33. package/plugins/html-effectiveness/templates/20-editor-prompt-tuner.html.tmpl +687 -0
  34. package/plugins/html-effectiveness/templates/manifest.json +436 -2
  35. package/plugins/html-effectiveness/tests/_tmp.test.js +58 -0
  36. package/plugins/html-effectiveness/tests/fixtures/01-exploration-code-approaches.data.json +3 -0
  37. package/plugins/html-effectiveness/tests/fixtures/02-exploration-visual-designs.data.json +3 -0
  38. package/plugins/html-effectiveness/tests/fixtures/03-code-review-pr.data.json +3 -0
  39. package/plugins/html-effectiveness/tests/fixtures/04-code-understanding.data.json +3 -0
  40. package/plugins/html-effectiveness/tests/fixtures/05-design-system.data.json +3 -0
  41. package/plugins/html-effectiveness/tests/fixtures/06-component-variants.data.json +3 -0
  42. package/plugins/html-effectiveness/tests/fixtures/07-prototype-animation.data.json +3 -0
  43. package/plugins/html-effectiveness/tests/fixtures/08-prototype-interaction.data.json +3 -0
  44. package/plugins/html-effectiveness/tests/fixtures/09-slide-deck.data.json +3 -0
  45. package/plugins/html-effectiveness/tests/fixtures/10-svg-illustrations.data.json +3 -0
  46. package/plugins/html-effectiveness/tests/fixtures/11-status-report.data.json +37 -0
  47. package/plugins/html-effectiveness/tests/fixtures/12-incident-report.data.json +3 -0
  48. package/plugins/html-effectiveness/tests/fixtures/13-flowchart-diagram.data.json +3 -0
  49. package/plugins/html-effectiveness/tests/fixtures/14-research-feature-explainer.data.json +3 -0
  50. package/plugins/html-effectiveness/tests/fixtures/15-research-concept-explainer.data.json +3 -0
  51. package/plugins/html-effectiveness/tests/fixtures/16-implementation-plan.data.json +3 -0
  52. package/plugins/html-effectiveness/tests/fixtures/17-pr-writeup.data.json +3 -0
  53. package/plugins/html-effectiveness/tests/fixtures/18-editor-triage-board.data.json +3 -0
  54. package/plugins/html-effectiveness/tests/fixtures/19-editor-feature-flags.data.json +3 -0
  55. package/plugins/html-effectiveness/tests/fixtures/20-editor-prompt-tuner.data.json +3 -0
  56. package/plugins/html-effectiveness/tests/manifest.test.js +61 -0
  57. package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
  58. package/plugins/plugin-validator/skills/validate-agents/SKILL.md +2 -2
  59. package/plugins/plugin-validator/skills/validate-commands/SKILL.md +2 -2
  60. package/plugins/plugin-validator/skills/validate-hooks/SKILL.md +57 -18
  61. package/plugins/team-superpower/.claude-plugin/plugin.json +7 -39
  62. package/plugins/team-superpower/README.md +85 -24
  63. package/plugins/team-superpower/agents/backend-developer.md +82 -0
  64. package/plugins/team-superpower/agents/designer.md +5 -1
  65. package/plugins/team-superpower/agents/frontend-developer.md +96 -0
  66. package/plugins/team-superpower/agents/planner.md +144 -16
  67. package/plugins/team-superpower/agents/qa-engineer.md +30 -0
  68. package/plugins/team-superpower/agents/reviewer.md +68 -22
  69. package/plugins/team-superpower/agents/security-engineer.md +110 -0
  70. package/plugins/team-superpower/agents/software-architect.md +30 -0
  71. package/plugins/team-superpower/assets/CLAUDE.md.template +96 -0
  72. package/plugins/team-superpower/assets/ESCALATION.md +19 -5
  73. package/plugins/team-superpower/assets/SESSION_README.md +119 -11
  74. package/plugins/team-superpower/commands/team-feature-resume.md +72 -6
  75. package/plugins/team-superpower/commands/team-feature.md +329 -28
  76. package/plugins/team-superpower/hooks/hooks.json +0 -3
  77. package/plugins/team-superpower/hooks/task-completed.sh +54 -5
  78. package/plugins/team-superpower/hooks/task-created.sh +79 -4
  79. package/plugins/team-superpower/scripts/detect-stack.sh +434 -0
  80. package/plugins/team-superpower/scripts/parse-claudemd.sh +194 -0
  81. package/plugins/tech-graph/.claude-plugin/plugin.json +1 -1
  82. package/plugins/tech-graph/agents/tech-graph.md +8 -0
  83. package/plugins/team-superpower/agents/implementer.md +0 -46
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Launch a Superpowers-compliant agent team to deliver a feature end-to-end with at most 4 owner touchpoints, with automatic team cleanup after the finish phase.
2
+ description: Launch a Superpowers-compliant agent team to deliver a feature end-to-end with at most 3 owner touchpoints, with automatic team cleanup after the finish phase.
3
3
  argument-hint: <one-line feature idea>
4
4
  ---
5
5
 
@@ -11,17 +11,96 @@ $ARGUMENTS
11
11
 
12
12
  ## Your job
13
13
 
14
- You are a **conductor**, not an implementer. Spawn teammates and coordinate them through the canonical Superpowers skill chain. Do not run skills yourself — delegate every skill to the correct teammate. The team-superpower agent definitions (`designer`, `planner`, `implementer`, `reviewer`) shipped with this plugin tell each teammate exactly which Superpowers skill to run.
14
+ You are a **conductor**, not an implementer. Spawn teammates and coordinate them through the canonical Superpowers skill chain. Do not run skills yourself — delegate every skill to the correct teammate. The team-superpower agent definitions (`designer`, `planner`, `software-architect`, `security-engineer`, `backend-developer`, `frontend-developer`, `qa-engineer`, `reviewer`) shipped with this plugin tell each teammate exactly which Superpowers skill to run.
15
15
 
16
16
  ## Required prechecks (run these first, in order)
17
17
 
18
- 1. Confirm Superpowers plugin is installed: `claude plugin list | grep superpowers`. If missing, **halt** and instruct the owner: `/plugin install superpowers@claude-plugins-official`.
18
+ 1. Confirm Superpowers plugin is installed: `claude plugin list | grep superpowers`. If missing, **halt** and instruct the owner: `/plugin install superpowers@claude-plugins-official`. Capture the version string from `claude plugin list --json` (e.g. `5.0.7`) — you'll write it to the checkpoint in phase 0 step 5 below.
19
19
  2. Confirm Claude Code version is `2.1.32` or later: `claude --version`. If older, halt.
20
20
  3. Confirm `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set in the environment. If not, halt and instruct the owner to add it to `~/.claude/settings.json` under `env`.
21
21
  4. Generate a kebab-case `<slug>` from the owner's request. Use it in every artifact filename for the rest of the run. The team you create MUST be named exactly `superpower-<slug>` — every cleanup and resume primitive depends on that convention.
22
22
  5. Create directories if missing: `docs/superpowers/{sessions,specs,plans,reviews}`.
23
23
  6. Seed `docs/superpowers/ESCALATION.md` from `${CLAUDE_PLUGIN_ROOT}/assets/ESCALATION.md` if it does not already exist. Seed `docs/superpowers/README.md` from `${CLAUDE_PLUGIN_ROOT}/assets/SESSION_README.md` if missing. Commit any seeded files.
24
24
 
25
+ ## Phase 0 — Stack detection, version pinning, shape decision
26
+
27
+ This phase runs **after** preflight clears (see the next section) and **before** spawning any teammate. It decides which teammates to spawn and pins the Superpowers version so a mid-feature skill update can't corrupt recovery.
28
+
29
+ ### 0.1 — Read CLAUDE.md, or detect
30
+
31
+ 1. Check whether `CLAUDE.md` exists at the repo root AND contains a fenced `team-superpower` block:
32
+ ```bash
33
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/parse-claudemd.sh extract CLAUDE.md
34
+ ```
35
+ - Exit 0: a block was extracted. Parse it. Skip to 0.2.
36
+ - Exit 1 (file missing or no block): run detection.
37
+
38
+ 2. Run detection:
39
+ ```bash
40
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/detect-stack.sh "$PWD" > /tmp/team-superpower-detected.yaml
41
+ ```
42
+ - Exit 0 (confident): write the detected YAML (plus a one-line header) to `docs/superpowers/stack.detected.md` and commit. Halt with this message to the owner (via §7 escalation): "I detected this stack — `docs/superpowers/stack.detected.md`. Review the `# CONFIRM:` lines, paste the corrected block into a `team-superpower` fenced section of your CLAUDE.md (or create CLAUDE.md from `${CLAUDE_PLUGIN_ROOT}/assets/CLAUDE.md.template`), then re-run `/team-feature`." **Do NOT auto-edit CLAUDE.md — the spec forbids it.**
43
+ - Exit 1 (no signal): halt. Escalate to the owner: "No backend or frontend signal found in the repo. Create a CLAUDE.md from `${CLAUDE_PLUGIN_ROOT}/assets/CLAUDE.md.template` and re-run."
44
+ - Exit 2 (ambiguous): write the detected YAML to `docs/superpowers/stack.detected.md` with both candidate BE languages marked; halt and escalate so the owner picks one.
45
+
46
+ ### 0.2 — Determine stack shape
47
+
48
+ Use the parser:
49
+
50
+ ```bash
51
+ shape="$(bash ${CLAUDE_PLUGIN_ROOT}/scripts/parse-claudemd.sh shape CLAUDE.md)"
52
+ ```
53
+
54
+ `$shape` is one of `full-stack` | `be-only` | `fe-only` | `none`. If `none` (the block has `backend: none` AND `frontend: none`), halt and escalate — that combination is non-sensical.
55
+
56
+ ### 0.3 — Cross-validate: claimed stack vs. filesystem
57
+
58
+ For every claimed component, verify at least one corresponding source file exists. Example checks:
59
+
60
+ - `backend.language: csharp` → at least one `*.csproj` or `*.sln` exists.
61
+ - `backend.language: node-ts` → `package.json` exists and declares a server dep (`express`, `fastify`, `koa`, `@nestjs/core`, etc.).
62
+ - `frontend.framework: react` → `package.json` declares `react`.
63
+ - `contracts.source_of_truth: openapi` → an OpenAPI file exists at `contracts.openapi_path` if specified.
64
+
65
+ If any claimed component has no file evidence, halt and escalate. CLAUDE.md is the contract, but a contract that contradicts the filesystem is a bug to flag, not a configuration to act on.
66
+
67
+ ### 0.4 — Write the shape marker
68
+
69
+ Write the resolved shape to a marker file the hooks read:
70
+
71
+ ```bash
72
+ mkdir -p docs/superpowers/sessions
73
+ echo "$shape" > docs/superpowers/sessions/<slug>.shape
74
+ git add docs/superpowers/sessions/<slug>.shape
75
+ ```
76
+
77
+ The `TaskCreated` hook reads this marker to enforce shape-appropriate `impl:` sub-prefixes.
78
+
79
+ ### 0.5 — Decide team composition (shape-adaptive spawn)
80
+
81
+ | Shape | Teammates to spawn |
82
+ |---------------|--------------------|
83
+ | `full-stack` | designer, planner, software-architect, security-engineer, backend-developer, frontend-developer, qa-engineer, reviewer (**8 total**) |
84
+ | `be-only` | designer, planner, software-architect, security-engineer, backend-developer, qa-engineer, reviewer (**7 total**) |
85
+ | `fe-only` | designer, planner, software-architect, security-engineer, frontend-developer, qa-engineer, reviewer (**7 total**) |
86
+
87
+ `software-architect`, `security-engineer`, `qa-engineer`, and `reviewer` are stack-agnostic and ALWAYS spawn. Designer, planner, and the implementers adapt.
88
+
89
+ Spawning happens at phase boundaries (you don't spawn implementers until phase 4 starts; you don't spawn the reviewer until phase 6) — this section just decides which teammates the team will EVER spawn for this feature. Record the list in the checkpoint.
90
+
91
+ ### 0.6 — Pin the Superpowers version
92
+
93
+ Read the installed Superpowers version (from precheck step 1) and write it to the checkpoint frontmatter. This pins the skill-set for this feature. `/team-feature-resume` reads it back and refuses to continue if the installed version has drifted.
94
+
95
+ The frontmatter format is in the **Checkpointing** section below; the relevant added fields are:
96
+
97
+ ```yaml
98
+ superpowers_version: <e.g. 5.0.7>
99
+ plugin_version: <team-superpower plugin version>
100
+ claude_code_version: <e.g. 2.1.32>
101
+ stack_shape: full-stack | be-only | fe-only
102
+ ```
103
+
25
104
  ## Preflight — detect stale or orphaned state
26
105
 
27
106
  Before writing any checkpoint or spawning any teammate, run the helper:
@@ -49,43 +128,155 @@ Same-session check: if the current Claude Code session already manages an agent
49
128
 
50
129
  ## Initial checkpoint and heartbeat
51
130
 
52
- After preflight clears:
131
+ After preflight clears AND phase 0 has decided the shape:
53
132
 
54
- 1. Write the initial checkpoint `docs/superpowers/sessions/YYYY-MM-DD-<slug>.md` per the format in the **Checkpointing** section and commit it.
133
+ 1. Write the initial checkpoint `docs/superpowers/sessions/YYYY-MM-DD-<slug>.md` per the format in the **Checkpointing** section — including the v2 frontmatter fields (`superpowers_version`, `plugin_version`, `claude_code_version`, `stack_shape`) — and commit it.
55
134
  2. `touch docs/superpowers/sessions/<slug>.heartbeat` and commit (or leave uncommitted — the file is intentionally ephemeral; either is fine). **Touch this heartbeat at every phase boundary** and any time you remain active for more than ~10 minutes inside a phase. The cleanup script uses its mtime to decide whether a future session is allowed to wipe state.
56
- 3. Write checkpoint updates atomically: write to `<file>.tmp` then `mv -f <file>.tmp <file>`. Half-written checkpoints corrupt recovery.
135
+ 3. Ensure `docs/superpowers/sessions/<slug>.shape` was written in phase 0.4 and is committed.
136
+ 4. Write checkpoint updates atomically: write to `<file>.tmp` then `mv -f <file>.tmp <file>`. Half-written checkpoints corrupt recovery.
137
+
138
+ ## Spawn prompt template (use verbatim — do NOT improvise per role)
139
+
140
+ Every teammate spawn MUST hand over the same minimum context. A teammate inherits project context (`CLAUDE.md`, MCP servers, skills) automatically but does NOT inherit your conversation history — anything implicit on your side is invisible on theirs. Use this template:
141
+
142
+ ```
143
+ You are the <role> teammate for feature `<slug>`.
144
+
145
+ Stack shape: <full-stack | be-only | fe-only> (read docs/superpowers/sessions/<slug>.shape if you need to confirm)
146
+ Worktree: <absolute path> (planner records this in WORKTREE_READY)
147
+ Resume: <yes | no> (yes when spawned by /team-feature-resume; pick up at the next pending task)
148
+
149
+ Read first:
150
+ - CLAUDE.md (free-form prose AND the `team-superpower` block)
151
+ - Your role brief: <relative path to plugins/team-superpower/agents/<role>.md>
152
+ - <role-relevant artefact paths — list them all; e.g. design doc, plan, ARCH/SEC reports, QA report>
153
+
154
+ Open escalations:
155
+ <one-line summary per open escalation in the checkpoint, or "(none)">
156
+
157
+ Your task: <one sentence describing the specific phase work the role is being spawned for>
158
+ Mailbox signal expected back: <e.g. DESIGN_APPROVED <path>, PLAN_READY <path>, ARCH_PASSED <path>, BE_DONE <task-id>, etc.>
159
+ ```
160
+
161
+ Fill every field. If a field is genuinely N/A for a role (e.g. there is no QA report when spawning the designer), write `n/a` rather than omitting the line — the template's stability is what keeps respawns deterministic.
57
162
 
58
163
  ## Phase chain (strict order — no skipping, no inlining)
59
164
 
60
- 1. **Brainstorming (designer).** Spawn the `designer` teammate. Hand it `<slug>` and the owner's request. Wait for `DESIGN_APPROVED <path>` in your mailbox. If the designer asks a clarifying question, answer from project context if unambiguous; otherwise batch with any open questions and use the §7 escalation template to the owner. Checkpoint: `phase: brainstorming, status: complete`. Touch heartbeat.
61
- 2. **Worktree + plan (planner).** Spawn the `planner` teammate. Hand it `<slug>` and the design doc path. Wait for `WORKTREE_READY` then `PLAN_READY <path>`. Route the plan to the owner for approval (third owner touchpoint). On approval, stamp `plan_approved_at: <ISO datetime>` into the metadata of every `impl:` task you will create — the `TaskCompleted` hook checks for it. Checkpoint: `phase: plan, status: approved`. Touch heartbeat.
62
- 3. **Implementation (implementers, 1–3 in parallel).** Read the approved plan. Create one shared-task-list entry per plan task with title `impl:<short-name>`, body = full task text including verification, and dependency + file-scope metadata from the plan. Spawn one `implementer` teammate. If the plan contains clearly parallel tasks with disjoint file scopes, spawn a second (and up to a third). Implementers self-claim. **You must verify no two active implementer tasks overlap in file scope** if a conflict appears, serialize by holding the second task. Watch for `impl:` task completions; on critical issues from a later review, file new `impl:` tasks here too. Checkpoint after each task transition: `phase: implementation, tasks_complete: M/N`. Touch heartbeat at every transition.
63
- 4. **Review (reviewer).** Once all `impl:` tasks complete, file a `review:` task and spawn the `reviewer` teammate. Wait for `REVIEW_PASSED <path>`. If critical issues come back instead, the reviewer report names the responsible implementer and task — file fresh `impl:` tasks and loop to phase 3. Checkpoint: `phase: review, status: pass | critical_issues_returned`. Touch heartbeat.
64
- 5. **Finish (reviewer).** Same reviewer runs `finishing-a-development-branch`. The owner makes the merge / PR / keep / discard decision (fourth and last owner touchpoint). On `FINISH_DONE <decision> <ref>`, checkpoint: `phase: finish, status: <merged|pr_opened|kept|discarded>`. Touch heartbeat.
165
+ 1. **Design (designer).** Spawn the `designer` teammate. Hand it `<slug>` and the owner's request. Wait for `DESIGN_APPROVED <path>` in your mailbox. If the designer asks a clarifying question, answer from project context if unambiguous; otherwise batch with any open questions and use the §7 escalation template to the owner. Checkpoint: `phase: design, status: complete`. Touch heartbeat.
166
+
167
+ 2. **Plan (planner).** Spawn the `planner` teammate. Hand it `<slug>` and the design doc path. Wait for `WORKTREE_READY <path> <branch> <origin>` (`<origin>` {`reused`, `created`} if the planner posts the legacy 2-arg form, treat as `created` for backward compatibility) then `PLAN_READY <path>`. Record both `**Worktree:** <path>` and `**Worktree origin:** <origin>` in the checkpoint. Route the plan to the owner for approval (second owner touchpoint). On approval, stamp `plan_approved_at: <ISO datetime>` into the metadata of every `impl:` task you will create the `TaskCompleted` hook checks for it. Checkpoint: `phase: plan, status: approved`. Touch heartbeat.
168
+
169
+ 3. **Pre-impl review gate (software-architect + security-engineer, parallel).** Spawn both. Hand each the design doc path AND the plan path. Wait for `ARCH_PASSED <path>` AND `SEC_PASSED <path>`. If either posts `ARCH_BLOCKED` / `SEC_BLOCKED`, route the findings to `planner` for a plan revision, then re-route to whichever gate is still blocking. Cap at three plan-revision rounds — escalate to owner via §7 if it does not converge. Checkpoint: `phase: pre_impl_review, status: passed | blocked`. Touch heartbeat.
170
+
171
+ 4. **Implementation (shape-adaptive, parallel where allowed).** Read the approved plan. Create one shared-task-list entry per plan task with the planner's assigned title (`impl:be-*`, `impl:fe-*`, `impl:be-migration-*`, `impl:be-contract-publish-*`), body = full task text including verification, and `depends_on` + `files` + `tests` + `estimated_minutes` + `plan_approved_at` metadata from the plan.
172
+
173
+ **Spawn rule (shape-adaptive):**
174
+ - `full-stack`: spawn one `backend-developer` AND one `frontend-developer`.
175
+ - `be-only`: spawn one `backend-developer` only. Do NOT spawn `frontend-developer`.
176
+ - `fe-only`: spawn one `frontend-developer` only. Do NOT spawn `backend-developer`.
177
+
178
+ **Contract publish (full-stack only).** If the planner emitted `impl:be-contract-publish-<slug>` as the first task, the backend-developer claims it first. Do NOT release any `impl:fe-*` task to the frontend-developer until you see `CONTRACT_PUBLISHED <task-id>` in your mailbox. The plan tasks already encode `depends_on: [impl:be-contract-publish-<slug>]` on every FE task, but you enforce the gate at the assignment level too.
179
+
180
+ **Mid-implementation contract drift.** If you receive `CONTRACT_DRIFT_DETECTED` from frontend-developer, or backend-developer files an `impl:contract-update-*` task on its own, pause all `impl:fe-*` in-flight work (post a "pause" message to frontend-developer's mailbox; it will idle on its current task). Wait for `CONTRACT_UPDATED <task-id>` from backend-developer, then unpause FE. Frontend-developer re-pulls the contract hash on resume.
181
+
182
+ **Migration serialization.** `impl:be-migration-*` tasks must run one at a time. The planner chains them via `depends_on`, the `TaskCompleted` hook is a backstop with `MIGRATION_RACE`, and you enforce it at assignment: do not release a second migration task while one is `in_progress`.
183
+
184
+ **File-scope conflict check.** Verify no two active implementer tasks overlap in file scope — if a conflict appears, serialize by holding the second task. Watch for `BE_DONE` / `FE_DONE`.
185
+
186
+ Checkpoint after each task transition: `phase: implementation, tasks_complete: M/N`. Touch heartbeat at every transition.
187
+
188
+ 5. **QA gate (qa-engineer).** Once every `impl:` task is complete, spawn `qa-engineer`. Wait for `QA_PASSED <path>` or `QA_BLOCKED <path>`. If blocked, the QA report contains `impl:qa-fix-be-` / `impl:qa-fix-fe-` tasks — file them in the shared task list and loop to phase 4. Checkpoint: `phase: qa, status: passed | blocked`. Touch heartbeat.
189
+
190
+ 6. **Code review (reviewer).** Once `QA_PASSED`, file a `review:` task and spawn the `reviewer` teammate. Wait for `REVIEW_PASSED <path>`. If critical issues come back instead, the reviewer report names the responsible implementer (`backend-developer` or `frontend-developer`) and the failing task — file `impl:review-fix-be-` / `impl:review-fix-fe-` tasks and loop to phase 4. Checkpoint: `phase: review, status: pass | critical_issues_returned`. Touch heartbeat.
191
+
192
+ 7. **Finish (reviewer, with CI gate).** Same reviewer runs `finishing-a-development-branch`. Before presenting the finish menu, the reviewer pushes the branch and (if `ci.provider != none`) polls CI per the `ci` block in CLAUDE.md until all `required_checks` go green, time out, or fail. On CI red, the reviewer posts `FINISH_BLOCKED ci-red <failed-checks>` and you surface the merge-failure menu with an added option F **"Show CI logs"**. On CI timeout, the reviewer posts `FINISH_BLOCKED ci-timeout` and you surface a 3-option menu (re-poll / switch to `pr_opened` / escalate). The CI gate is the **same finish-branch touchpoint** — no new touchpoint.
193
+
194
+ The owner makes the merge / PR / keep / discard decision (third and last owner touchpoint). On `FINISH_DONE <decision> <ref>`, checkpoint: `phase: finish, status: <merged|pr_opened|kept|discarded>`. Touch heartbeat. If the reviewer posts `FINISH_BLOCKED <reason>` (any reason — merge or CI), follow **Phase 7 merge-failure handling** below.
195
+
196
+ ## Phase 7 merge-failure handling
197
+
198
+ When the reviewer posts `FINISH_BLOCKED <reason>` (instead of `FINISH_DONE`), the merge step or the CI gate failed. Handle it inline — this is the same owner touchpoint as the finish-branch decision continued, NOT a new touchpoint.
199
+
200
+ `<reason>` is one of `conflict` / `non-ff` / `dirty-worktree` / `push-rejected` / `ci-red <failed-checks>` / `ci-timeout` / `other:<short-string>` (see `agents/reviewer.md` § Hat 2 for the full enum and what each reason means).
201
+
202
+ ### CI-specific menus
203
+
204
+ For `ci-red <failed-checks>` use the standard 5-option merge-failure menu **plus an option F: Show CI logs**, which runs `gh run view --log-failed` (or the provider equivalent the reviewer is using) and pipes the output into the conversation, then re-presents the menu.
205
+
206
+ For `ci-timeout` use a 3-option menu:
207
+
208
+ > **CI did not finish within the poll window.** Pick one:
209
+ > - **A. Re-poll** — wait another `ci.poll_timeout_minutes` for CI to finish.
210
+ > - **B. Switch to pr_opened** — open a PR; the owner deals with CI on the PR side.
211
+ > - **E. Escalate** — §7 escalation, full reviewer status appended.
212
+
213
+ Re-poll is the same finish-branch touchpoint continued. The `merge_retries` counter does NOT apply to CI re-polls (it tracks merge attempts, not CI polls); cap re-polls at 3 instead, recorded as `ci_repolls: K/3` in the checkpoint.
214
+
215
+ 1. Read the mailbox message. Stash `<reason>` and the verbatim git stderr.
216
+ 2. Update the checkpoint: `phase: finish, status: merge_blocked, reason: <reason>, merge_retries: K/3` where `K` is the count of prior retry attempts in this run (start at 0).
217
+ 3. Touch the heartbeat.
218
+ 4. Present the 5-option menu below to the owner.
219
+ 5. Translate the owner's choice into the next instruction to the reviewer per the table.
220
+
221
+ ### 5-option merge-failure menu
222
+
223
+ Present verbatim:
224
+
225
+ > **Merge failed:** `<reason>`. Pick one:
226
+ > - **A. Retry merge** — re-attempt the merge now (you've resolved conflicts externally or upstream has stabilised).
227
+ > - **B. Switch to pr_opened** — open a PR for human merge instead.
228
+ > - **C. Switch to kept** — keep the worktree as-is, you'll handle the merge later.
229
+ > - **D. Switch to discarded** — drop the branch entirely.
230
+ > - **E. Escalate** — pause and surface a §7 escalation with full git output.
231
+
232
+ Translation:
233
+
234
+ | Choice | Reviewer instruction | Expected next signal |
235
+ |---|---|---|
236
+ | **A** | "Retry the merge step only. Do not re-do design/plan/etc." Increment `merge_retries`. | `FINISH_DONE merged <ref>` OR a new `FINISH_BLOCKED <reason>` |
237
+ | **B** | "Re-run `finishing-a-development-branch` with `decision=pr_opened`." | `FINISH_DONE pr_opened <ref>` |
238
+ | **C** | "Post `FINISH_DONE kept <branch>` directly. Do not attempt another merge." | `FINISH_DONE kept <ref>` |
239
+ | **D** | "Run the discard path of `finishing-a-development-branch`." | `FINISH_DONE discarded <ref>` |
240
+ | **E** | Lead posts §7 template to owner with verbatim git stderr; halts until owner responds. | Owner directs manually |
241
+
242
+ ### Retry cap
243
+
244
+ `merge_retries` is bounded at 3. Before presenting the menu, check the current value:
245
+
246
+ - `merge_retries < 3` → present all five options.
247
+ - `merge_retries == 3` → drop option A. The menu shows B/C/D/E only.
248
+
249
+ The counter is persisted in the checkpoint so `/team-feature-resume` honours it across sessions.
250
+
251
+ ### Flow rejoin
252
+
253
+ On any `FINISH_DONE <decision>` (any decision), flow rejoins normal phase 7: checkpoint `phase: finish, status: <decision>`, then run **Automatic cleanup** below. Auto-cleanup Step D.5 (worktree removal) runs only when `decision == merged`.
65
254
 
66
255
  ## Automatic cleanup (runs after `FINISH_DONE`)
67
256
 
68
- The instant phase 5 records `FINISH_DONE`, run cleanup **before idling**. Do this in order, halting and escalating to the owner if any step fails:
257
+ The instant phase 7 records `FINISH_DONE`, run cleanup **before idling**. Do this in order, halting and escalating to the owner if any step fails:
69
258
 
70
259
  ### Step A — Verify safety preconditions
71
260
 
72
261
  Confirm all of the following from the checkpoint and the task list:
73
262
 
74
- - Every phase from `brainstorming` through `finish` is checked complete.
263
+ - Every phase from `design` through `finish` is checked complete.
75
264
  - The shared task list has zero `in_progress` tasks. Every `impl:` and `review:` task is `completed`.
76
- - Phase 5 returned a recognised decision: `merged`, `pr_opened`, `kept`, or `discarded`.
77
- - The expected git commits exist on the worktree branch. Run `git log --oneline -20` and confirm:
265
+ - Phase 7 returned a recognised decision: `merged`, `pr_opened`, `kept`, or `discarded`.
266
+ - The expected git commits exist on the worktree branch. Run `git log --oneline -30` and confirm:
78
267
  - A design doc commit under `docs/superpowers/specs/`
79
268
  - A plan commit under `docs/superpowers/plans/`
269
+ - An ARCH report commit AND a SEC report commit under `docs/superpowers/reviews/` (phase-3 gate)
80
270
  - One or more implementation commits (TDD pairs of test + code on the same files; the test commit precedes the code commit per the `test-driven-development` skill)
81
- - A review report commit under `docs/superpowers/reviews/`
271
+ - A QA report commit under `docs/superpowers/reviews/` (phase-5 gate)
272
+ - A code-review report commit under `docs/superpowers/reviews/`
82
273
  - If the finish decision is `merged` or `pr_opened`, the corresponding merge / PR-prep commit
83
274
 
84
275
  If any of these is missing, **halt cleanup**, escalate with the §7 template, and instruct the owner to inspect manually. **Do not run cleanup on a half-finished feature.**
85
276
 
86
277
  ### Step B — Shut down teammates gracefully
87
278
 
88
- For each live teammate (`designer`, `planner`, every `implementer`, `reviewer`):
279
+ For each live teammate (`designer`, `planner`, `software-architect`, `security-engineer`, every `backend-developer`, every `frontend-developer`, `qa-engineer`, `reviewer`):
89
280
 
90
281
  1. Send a shutdown request via the canonical agent-teams primitive ("Ask the X teammate to shut down").
91
282
  2. Wait for graceful exit.
@@ -117,6 +308,61 @@ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug> --force
117
308
 
118
309
  The heartbeat refusal check applies. If it fires, you are still touching the heartbeat (or another lead is alive) — investigate before forcing. If the only reason is your own fresh heartbeat from this session, pass `--ignore-heartbeat` (you know the lead is you and you are about to exit).
119
310
 
311
+ ### Step D.5 — Worktree removal (on successful merge only)
312
+
313
+ Runs only after Step C / D have brought platform state to absent. Removes the planner's git worktree when, and only when, the feature was actually merged.
314
+
315
+ **Trigger conditions** (ALL must be true; any miss → skip and record the reason in the Closing block):
316
+
317
+ 1. `FINISH_DONE merged <ref>` is recorded in the checkpoint.
318
+ 2. Step A precondition check passed.
319
+ 3. Step B teammate shutdown was clean.
320
+ 4. The post-Step-C (or post-Step-D) scan shows `team_config_state: absent`, `task_list_state: absent`, `tmux_state: absent`.
321
+ 5. The checkpoint has a non-empty `**Worktree:**` field.
322
+ 6. The checkpoint records `**Worktree origin:** created`. A `reused` origin means the worktree existed before this run — it is the owner's, not ours to remove.
323
+
324
+ If any condition fails, record `worktree: removal-skipped:<reason>` in the Closing block (Step E) where `<reason>` is one of:
325
+
326
+ - `not-merged-decision` — finish decision was `pr_opened`, `kept`, or `discarded`.
327
+ - `team-cleanup-incomplete` — Step C/D left platform state present.
328
+ - `no-worktree-recorded` — checkpoint has no `**Worktree:**` line.
329
+ - `reused-existing-worktree` — `**Worktree origin:** reused`; the owner pre-existed the worktree and keeps it.
330
+
331
+ **Procedure** (only when all trigger conditions pass):
332
+
333
+ 1. Read the worktree path from the checkpoint's `**Worktree:**` line. Call it `WT_PATH`.
334
+ 2. `cd` to the repo root (the **main** worktree, NOT `WT_PATH`). `git worktree remove` refuses when the current directory is inside the target.
335
+ 3. Run `git worktree list --porcelain`. If `WT_PATH` is not listed (already pruned, manual removal, etc.), record `worktree: already-absent` in the Closing block and skip to Step E.
336
+ 4. Touch the heartbeat.
337
+ 5. Run `git worktree remove "$WT_PATH"` (non-forced).
338
+ 6. On success → record `worktree: removed` in the Closing block. Touch heartbeat. Proceed to Step E.
339
+ 7. On non-zero exit → enter the **4-option remove-failure menu** below.
340
+
341
+ **Branch handling:** `git worktree remove` does NOT delete the branch. The feature branch survives this step. Branch deletion is left to the owner.
342
+
343
+ ### 4-option remove-failure menu
344
+
345
+ Triggered when `git worktree remove "$WT_PATH"` exits non-zero. Common causes: untracked files, locked worktree, in-progress git operation, owner pre-seeded files.
346
+
347
+ Present verbatim:
348
+
349
+ > **Could not remove worktree** `<WT_PATH>`. Git said: `<stderr>`. Pick one:
350
+ > - **A. Show files + retry** — list what's blocking, then retry the remove.
351
+ > - **B. Force remove** — discard uncommitted work in `<WT_PATH>` and remove. (Confirmation required.)
352
+ > - **C. Keep worktree** — leave it on disk; you'll remove it manually later.
353
+ > - **D. Escalate** — pause and surface a §7 escalation with the verbatim stderr.
354
+
355
+ Translation:
356
+
357
+ | Choice | Action | Closing-block record |
358
+ |---|---|---|
359
+ | **A** | Run `git -C "$WT_PATH" status --short` and `git -C "$WT_PATH" diff --stat`. Surface output to owner. Retry `git worktree remove "$WT_PATH"`. Cap: 3 retries per Step D.5. On success: record `worktree: removed (after manual fix)` and proceed to Step E. On 3rd retry still failing: drop option A from the next menu and force B/C/D. | See action column. |
360
+ | **B** | Lead prompts: `"This will discard uncommitted work in <WT_PATH>. Confirm force-remove? (type 'yes' to confirm)"`. On `yes`: snapshot the file list from the pre-remove `git -C "$WT_PATH" status --short` (or take a snapshot now if option A hasn't run), then run `git worktree remove --force "$WT_PATH"`. On any other input: abort B, re-present the menu. | `worktree: force-removed`, `dropped_files: [<path>, ...]` |
361
+ | **C** | Log `WT_PATH` in the Closing block. Tell the owner: `"Worktree retained at <WT_PATH>. Remove manually with 'git worktree remove <WT_PATH>' once you've handled it."` Proceed to Step E. | `worktree: kept-by-owner`, `worktree_path: <WT_PATH>` |
362
+ | **D** | Halt Step D.5. Post the §7 template to the owner with the verbatim stderr from the failed remove. Wait for direction. | `worktree: escalated`, `worktree_path: <WT_PATH>` |
363
+
364
+ In all four cases, Step E still runs after Step D.5 closes (whether by success or by the owner's menu choice). Step E records the outcome in the Closing block.
365
+
120
366
  ### Step E — Final checkpoint commit
121
367
 
122
368
  Append a closing block to the checkpoint:
@@ -126,20 +372,39 @@ Append a closing block to the checkpoint:
126
372
  - finished at: <ISO datetime>
127
373
  - decision: <merged|pr_opened|kept|discarded>
128
374
  - cleanup: complete
375
+ - worktree: <removed | already-absent | removal-skipped:<reason> | removed (after manual fix) | force-removed | kept-by-owner | escalated>
376
+ - worktree_path: <path> # present whenever the worktree directory still exists on disk after cleanup (states: kept-by-owner, escalated, or removal-skipped where the path exists)
377
+ - merge_retries: K # only when K > 0; matches the final value of the mid-phase counter
378
+ - dropped_files: [<path>, ...] # only when state == force-removed
129
379
  ```
130
380
 
381
+ `removal-skipped` reasons: `not-merged-decision` | `team-cleanup-incomplete` | `no-worktree-recorded` | `reused-existing-worktree`.
382
+
131
383
  Remove the `<slug>.heartbeat` file. Commit the checkpoint. Confirm to the owner: "Team cleaned up. Feature complete."
132
384
 
133
385
  ### Step F — If anything failed
134
386
 
135
387
  Tell the owner exactly which step failed, include the script output verbatim, and instruct them to run `/team-cleanup <slug>` once they have confirmed nothing else is running. Do **not** retry cleanup loops automatically — the safety check is the heartbeat, and you cannot meaningfully refresh it from outside the lead process.
136
388
 
389
+ ## Within-phase stall watchdog
390
+
391
+ Heartbeat at phase boundaries is not enough — a teammate can hang silently mid-phase and you'd never notice. Run a watchdog:
392
+
393
+ 1. Read `limits.phase_stall_minutes` from CLAUDE.md (`bash ${CLAUDE_PLUGIN_ROOT}/scripts/parse-claudemd.sh get limits.phase_stall_minutes CLAUDE.md`). Default to **30** if unset.
394
+ 2. Inside any phase, if the watchdog window elapses with **no mailbox message AND no shared-task-list state transition** from the active teammate(s):
395
+ - Send a ping to the teammate's mailbox: `STATUS_CHECK <slug> — no activity for <N> minutes; reply with current status or progress note.`
396
+ - Start a second watchdog window of the same length.
397
+ 3. If a second watchdog window also elapses with no reply: surface a §7 escalation to the owner with the teammate's last-known status, the elapsed wall time, and the current phase. Halt — do NOT silently respawn or force-cancel; the owner decides.
398
+
399
+ The watchdog is **not** an owner touchpoint by itself — pinging the teammate is internal. Escalation step 3 is what reaches the owner, and only via the §7 template (so it doesn't count against the 3 allowed touchpoints either).
400
+
401
+ Reset the watchdog on every received mailbox message and every task transition. Touch the heartbeat each time you reset.
402
+
137
403
  ## Owner touchpoints (the ONLY allowed pings to the owner)
138
404
 
139
- 1. Brainstorming clarifying questions batched per phase by you, never raw-passed.
140
- 2. Design sign-off (the brainstorming skill's built-in step).
141
- 3. Plan approval before phase 3 starts.
142
- 4. Finish-branch decision in phase 6.
405
+ 1. Design sign-off (phase 1, the brainstorming skill's built-in step).
406
+ 2. Plan approval before phase 3 starts.
407
+ 3. Finish-branch decision in phase 7.
143
408
 
144
409
  **Anything else requires the §7 escalation template** from `docs/superpowers/ESCALATION.md`. Refuse to ping the owner without it. Cleanup runs without owner involvement when Step A passes.
145
410
 
@@ -148,24 +413,41 @@ Tell the owner exactly which step failed, include the script output verbatim, an
148
413
  After every phase boundary, write `docs/superpowers/sessions/YYYY-MM-DD-<slug>.md` atomically (tmp + rename) per this format and commit it. This is the only way the workflow survives a `/resume` failure:
149
414
 
150
415
  ```markdown
416
+ ---
417
+ slug: <slug>
418
+ started: <ISO datetime>
419
+ superpowers_version: <e.g. 5.0.7>
420
+ plugin_version: <team-superpower plugin version>
421
+ claude_code_version: <e.g. 2.1.32>
422
+ stack_shape: full-stack | be-only | fe-only
423
+ ---
424
+
151
425
  # Session: <slug>
152
426
  **Started:** <ISO datetime>
153
427
  **Last update:** <ISO datetime>
154
428
  **Team:** superpower-<slug>
155
429
  **Worktree:** <path>
430
+ **Worktree origin:** created | reused # `reused` means the owner launched `/team-feature` from inside a linked worktree; Step D.5 skips removal in that case
156
431
 
157
432
  ## Phases
158
- - [x] brainstorming → docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md
433
+ - [x] design → docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md
159
434
  - [x] worktree → <branch>
160
435
  - [x] plan → docs/superpowers/plans/YYYY-MM-DD-<slug>-plan.md (approved <datetime>)
436
+ - [x] pre_impl_review → arch + sec PASSED
161
437
  - [ ] implementation (M/N tasks complete)
438
+ - [ ] qa
162
439
  - [ ] review
163
- - [ ] finish
440
+ - [ ] finish — when `FINISH_BLOCKED <reason>` is in flight, this line reads `- [ ] finish (blocked: <reason>, merge_retries: K/3)` instead, and stays unchecked until `FINISH_DONE` arrives.
164
441
 
165
442
  ## Teammates
443
+ (list reflects stack_shape — omit the implementer that doesn't exist for be-only / fe-only)
166
444
  - designer (agent-id: ...) — idle
167
445
  - planner (agent-id: ...) — idle
168
- - implementer-1 (agent-id: ...) — active on task impl:<name>
446
+ - software-architect (agent-id: ...) — idle
447
+ - security-engineer (agent-id: ...) — idle
448
+ - backend-developer (agent-id: ...) — active on task impl:be-<name> # full-stack | be-only
449
+ - frontend-developer (agent-id: ...) — idle # full-stack | fe-only
450
+ - qa-engineer (agent-id: ...) — idle
169
451
  - reviewer (agent-id: ...) — idle
170
452
 
171
453
  ## Open escalations
@@ -181,10 +463,29 @@ After every phase boundary, write `docs/superpowers/sessions/YYYY-MM-DD-<slug>.m
181
463
 
182
464
  - **Never** run a Superpowers skill yourself. Always delegate to the correct teammate.
183
465
  - **Never** modify, replace, or skip a Superpowers skill. Consume them as-installed.
184
- - **Never** let an implementer write code before the plan is approved. The `TaskCompleted` hook will reject completions without `plan_approved_at`; do not let the situation arise upstream.
466
+ - **Never** start phase 4 before both `ARCH_PASSED` and `SEC_PASSED` are recorded. The phase-3 gate is non-optional.
467
+ - **Never** start phase 6 before `QA_PASSED` is recorded. The phase-5 gate is non-optional.
468
+ - **Never** let an implementer write code before the plan is approved AND the phase-3 gate has passed. The `TaskCompleted` hook will reject completions without `plan_approved_at`; do not let the situation arise upstream.
185
469
  - **Never** let an `impl:` task be marked complete without TDD and the two-stage review from `subagent-driven-development`. The hook is a backstop, not a primary control.
186
- - **Never** ping the owner without the §7 template, except for the four allowed touchpoints listed above.
470
+ - **Never** ping the owner without the §7 template, except for the three allowed touchpoints listed above.
187
471
  - **Never** skip the automatic cleanup block after `FINISH_DONE`. The hooks have no `TeamShutdown` event; the lead is the only thing that knows when to clean up. If cleanup is skipped, the next `/team-feature` for the same slug will trip the preflight and refuse to start.
188
472
  - **Never** force cleanup while the heartbeat is fresh and you didn't write it. That's the signal that another lead is alive.
189
-
190
- Begin with the prechecks, then preflight, then spawn `designer`.
473
+ - **Never** run Step D.5 worktree removal unless the finish decision is `merged` AND the platform-cleanup scan (Step C, or Step D fallback) shows every state `absent`. Other decisions or partial cleanups must record `worktree: removal-skipped:<reason>` and leave the worktree on disk.
474
+ - **Never** force-remove a worktree (`--force`) without explicit owner confirmation in the 4-option menu. The default remove is non-forced; force only on option B with a typed `yes`.
475
+ - **Never** retry merge more than 3 times. After the 3rd `FINISH_BLOCKED`, drop option A from the 5-option menu and require B/C/D/E.
476
+ - **Never** treat the `FINISH_BLOCKED` menu as a new owner touchpoint. It is the same finish-branch touchpoint continued — the 3-touchpoint cap stays at 3.
477
+
478
+ ## Hard rules (v2 additions)
479
+
480
+ - **Never** spawn `frontend-developer` in a `be-only` shape, or `backend-developer` in a `fe-only` shape. The shape was decided in phase 0.5 from CLAUDE.md (or the auto-detection fallback the owner has confirmed); deviating means a different team than the owner agreed to.
481
+ - **Never** auto-edit the user's `CLAUDE.md`. Phase 0 writes to `docs/superpowers/stack.detected.md` only and asks the owner to paste/edit. The user's CLAUDE.md is theirs.
482
+ - **Never** release an `impl:fe-*` task before `CONTRACT_PUBLISHED` arrives (full-stack with `contracts.source_of_truth != none`).
483
+ - **Never** release a second `impl:be-migration-*` task while one is `in_progress`. The hook is a backstop; you are the primary control.
484
+ - **Never** present the finish-branch menu before the CI gate either passes or is explicitly bypassed (CI red → menu with "Show CI logs"; CI timeout → 3-option menu; `ci.provider: none` → skip the gate entirely but still push).
485
+ - **Never** wait passively on a teammate for longer than `limits.phase_stall_minutes` (default 30) without running the within-phase stall watchdog above. Two consecutive stall windows with no teammate activity must escalate via §7.
486
+ - **Never** improvise a spawn prompt. Use the **Spawn prompt template** verbatim — leave fields as `n/a` rather than omitting them.
487
+ - **Never** spawn more than 5 teammates concurrently. The plugin defines up to 8 lifetime roles but phase-gating must keep ≤ 5 active at any moment. If a future change would break this, halt and escalate.
488
+ - **Never** run Step D.5 worktree removal when `**Worktree origin:** reused`. The worktree existed before `/team-feature` started; the owner owns it. Record `worktree: removal-skipped:reused-existing-worktree` and leave the worktree on disk.
489
+ - **Never** let the planner run inside a linked worktree on a protected branch (`main`, `master`, `develop`, `dev`, `release/*`, `releases/*`). The planner halts and escalates; the owner switches to a feature branch and re-runs.
490
+
491
+ Begin with the prechecks, then preflight, then run phase 0 (stack detection / shape decision / version pin / shape marker), then spawn `designer`.
@@ -2,7 +2,6 @@
2
2
  "hooks": {
3
3
  "TeammateIdle": [
4
4
  {
5
- "matcher": "*",
6
5
  "hooks": [
7
6
  { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/teammate-idle.sh" }
8
7
  ]
@@ -10,7 +9,6 @@
10
9
  ],
11
10
  "TaskCreated": [
12
11
  {
13
- "matcher": "*",
14
12
  "hooks": [
15
13
  { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/task-created.sh" }
16
14
  ]
@@ -18,7 +16,6 @@
18
16
  ],
19
17
  "TaskCompleted": [
20
18
  {
21
- "matcher": "*",
22
19
  "hooks": [
23
20
  { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/task-completed.sh" }
24
21
  ]
@@ -6,12 +6,15 @@
6
6
  # - task.title: string
7
7
  # - task.metadata.plan_approved_at: string (ISO datetime), required for impl: tasks
8
8
  # - task.metadata.blocked_questions: array of strings (optional)
9
+ # - task.metadata.commits: array of git SHAs (optional, used by v2 checks)
10
+ # - task.metadata.contract_files: array of paths (optional, for contract-publish)
9
11
  #
10
- # Rules:
11
- # - impl: task -> plan_approved_at MUST be present (exit 2 NO_PLAN_APPROVAL)
12
- # - any blocked_questions entry -> must mention every escalation field
13
- # (Phase, Context, Options, Recommendation, Need from you)
14
- # otherwise exit 2 BAD_ESCALATION: missing field(s) <list>
12
+ # v2 rules added on top of v1:
13
+ # - impl:be-migration-* completions: refuse if another in-progress migration
14
+ # exists in the shared task list payload (anti-race).
15
+ # - impl:be-contract-publish-* completions: at least one commit on this task
16
+ # must touch a contracts file (default `contracts/` directory, or paths
17
+ # listed in metadata.contract_files). Verified via `git show --name-only`.
15
18
 
16
19
  set -euo pipefail
17
20
 
@@ -51,6 +54,52 @@ case "$title" in
51
54
  ;;
52
55
  esac
53
56
 
57
+ # v2: migration serialization. If this is a migration task, verify no other
58
+ # `impl:be-migration-*` task is currently in_progress in the shared task list
59
+ # (payload.tasks[]). The lead also enforces this; the hook is a backstop.
60
+ case "$title" in
61
+ impl:be-migration-*)
62
+ other_in_progress="$(printf '%s' "$payload" | jq -r --arg me "$title" '
63
+ [ .tasks[]?
64
+ | select((.title // "") != $me)
65
+ | select(((.title // "") | startswith("impl:be-migration-")))
66
+ | select((.status // "") == "in_progress")
67
+ ] | length' 2>/dev/null || echo 0)"
68
+ if [ "${other_in_progress:-0}" -gt 0 ]; then
69
+ echo "MIGRATION_RACE: another impl:be-migration-* task is in_progress; migrations must serialize. (title: $title)" >&2
70
+ exit 2
71
+ fi
72
+ ;;
73
+ esac
74
+
75
+ # v2: contract-publish must actually touch a contracts file in at least one
76
+ # of its commits. Best-effort: skip if git unavailable or no commits recorded.
77
+ case "$title" in
78
+ impl:be-contract-publish-*)
79
+ if command -v git >/dev/null 2>&1; then
80
+ commits="$(printf '%s' "$payload" | jq -r '(.task.metadata.commits // .metadata.commits // [])[]?' 2>/dev/null || true)"
81
+ patterns="$(printf '%s' "$payload" | jq -r '(.task.metadata.contract_files // .metadata.contract_files // ["contracts/"])[]?' 2>/dev/null || echo "contracts/")"
82
+ if [ -n "$commits" ]; then
83
+ touched=0
84
+ while IFS= read -r sha; do
85
+ [ -z "$sha" ] && continue
86
+ files="$(git show --no-color --name-only --pretty=format: "$sha" 2>/dev/null || true)"
87
+ while IFS= read -r pat; do
88
+ [ -z "$pat" ] && continue
89
+ if printf '%s\n' "$files" | grep -qE "(^|/)${pat//./\\.}"; then
90
+ touched=1; break 2
91
+ fi
92
+ done <<< "$patterns"
93
+ done <<< "$commits"
94
+ if [ "$touched" -ne 1 ]; then
95
+ echo "EMPTY_CONTRACT_PUBLISH: $title claims to publish a contract but no commit touches a contract file (looked for: $(echo "$patterns" | tr '\n' ' '))" >&2
96
+ exit 2
97
+ fi
98
+ fi
99
+ fi
100
+ ;;
101
+ esac
102
+
54
103
  # Validate escalation entries if present.
55
104
  required_fields=("Phase" "Context" "Options" "Recommendation" "Need from you")
56
105
  missing_any=""