Skip to content

Commit 984f605

Browse files
committed
feat(plugin): add opt-in subagent model routing, commit strategy, and bounded parallel dispatch
1 parent bd000c6 commit 984f605

19 files changed

Lines changed: 2230 additions & 11 deletions

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
{
1010
"name": "superpowers-extended-cc",
1111
"description": "Claude Code-specific fork of Superpowers with native task management and CC-specific enhancements",
12-
"version": "5.5.1-dev",
12+
"version": "6.0.0",
1313
"source": "./",
1414
"author": {
1515
"name": "pcvelz",

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "superpowers-extended-cc",
33
"description": "Claude Code-specific fork of Superpowers with native task management and CC-specific enhancements",
4-
"version": "5.5.1-dev",
4+
"version": "6.0.0",
55
"author": {
66
"name": "pcvelz",
77
"email": "pcvelz@users.noreply.github.com"

.cursor-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "superpowers-extended-cc",
33
"displayName": "Superpowers Extended CC",
44
"description": "Claude Code-specific fork of Superpowers with native task management and CC-specific enhancements",
5-
"version": "5.5.1-dev",
5+
"version": "6.0.0",
66
"author": {
77
"name": "Jesse Vincent",
88
"email": "jesse@fsck.com"

README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ This fork integrates Claude Code-native features into the Superpowers workflow.
2222
| Structured Task Metadata | v2.1.16+ | Goal/Files/AC/Verify structure with embedded `json:metadata` |
2323
| Pre-commit Task Gate | v2.1.16+ | Plugin hook blocks `git commit` when tasks are incomplete |
2424
| User-Thrown Gate Enforcement | v2.1.16+ | `userGate` / `user-gate` tag + opt-in hooks force re-validation when Claude closes a user-ordered verification task (see [Recommended Configuration](#recommended-configuration)) |
25+
| Subagent Model Routing | v2.1.170+ | Opt-in per-task model tiers (`mechanical`/`standard`/`frontier`) route plan-execution subagents to cheaper models (see [Subagent Model Routing](#subagent-model-routing--optional-flow)) |
26+
| Configurable Commit Strategy | v2.1.16+ | Opt-in `workflow.json` switches plan execution from per-task commits to a single commit at plan end (see [Commit Strategy](#commit-strategy)) |
2527

2628
## Visual Comparison
2729

@@ -200,6 +202,89 @@ Tail the hook trace log while a tagged gate task is closing: `tail -F /tmp/claud
200202

201203
---
202204

205+
## Subagent Model Routing — Optional Flow
206+
207+
*Canonical design doc: [`docs/model-routing-flow.md`](docs/model-routing-flow.md). The section below is a reader-facing summary.*
208+
209+
This flow addresses a cost problem that frontier-priced models (Opus, Fable) made acute: plan execution via `subagent-driven-development` spawns an implementer plus two reviewers per task — plus re-dispatches for fixes and escalations — and every one of them inherits the session model by default. On a top-tier session, a ten-task plan means thirty-plus top-tier subagent dispatches, most doing work a cheaper model handles fine when the plan is well-specified. Prompt caching does not help here: caching discounts input tokens, while fan-out cost is dominated by freshly generated output. Routing lowers the per-token rate of dispatches; it does not impose token budgets or spend ceilings (see the design doc for boundaries).
210+
211+
**The whole flow is opt-in, with a single switch: `docs/superpowers/model-routing.json` in your project.** The enforcement gates ship with the plugin but are dormant — without that file every check no-ops and behavior is byte-identical to vanilla. No settings to edit, no hooks to register.
212+
213+
### How it works — four harness-enforced layers
214+
215+
Skills prose is not enforcement; agents skip instructions under load. So every layer here is executed by the harness, not volunteered by the model:
216+
217+
| Layer | When | What it does |
218+
|-------|------|--------------|
219+
| **Session notice** (`session-start` hook) | Session start | Routing file detected → the tier rules and your mapping are injected into context. The agent starts the session already knowing the rules. |
220+
| **Plan gate** (`pre-taskcreate-model-tier` hook) | Every `TaskCreate` | A plan task (one carrying a `json:metadata` fence) without a valid `"modelTier"` is blocked; the block message contains the full tier table, so the agent fixes and re-issues without reading anything. |
221+
| **Dispatch gate** (`pre-agent-model-routing` hook) | Every `Agent` dispatch | While a tiered task is in progress, allows the task tier's model plus the `standard` reviewer model; blocks anything else and names the correct dispatch per role. A concrete `"model"` pin in task metadata overrides the tier (pin enforcement: see [Recommended Configuration](#recommended-configuration)). |
222+
| **Handoff guard** (`pre-askuser-handoff-guard` hook) | After `writing-plans` creates tasks | When armed, allows `AskUserQuestion` only if it carries exactly the two mandated options ("Subagent-Driven (this session)" / "Parallel Session (separate)"). Blocks custom menus that bypass the execution-method choice and skip the subagent pipeline. |
223+
224+
Both gates fail open (parse errors never brick a session) and share a kill switch: `SUPERPOWERS_ROUTING_GUARD=0`.
225+
226+
### The tiers
227+
228+
| Tier | Meaning |
229+
|------|---------|
230+
| `"mechanical"` | Touches 1-2 files, complete spec with code in the steps, no design judgment. Most tasks in a well-specified plan. |
231+
| `"standard"` | Multi-file coordination, integration concerns, pattern matching, debugging. |
232+
| `"frontier"` | Design judgment, architecture decisions, broad codebase understanding. |
233+
234+
Tiers are abstract on purpose — plans survive model generations; the routing file decides what they mean today.
235+
236+
### Setup
237+
238+
Prefer a guided setup? Run `/superpowers-extended-cc:onboard` — it asks one multiple-choice question per optional feature and writes the files for you. Manual setup below achieves exactly the same.
239+
240+
Create `docs/superpowers/model-routing.json` in your project:
241+
242+
```json
243+
{"mechanical": "haiku", "standard": "sonnet", "frontier": "inherit"}
244+
```
245+
246+
- Keys are the three tiers; values are Agent `model` values (`haiku`, `sonnet`, `opus`, `fable`).
247+
- `"inherit"` means: omit the model parameter — that tier runs on the session model.
248+
- Mapping all tiers to one model gives a flat cost cap with no per-task gradation.
249+
- Delete the file to switch routing off — the gates go dormant instantly; existing tier annotations become inert metadata.
250+
- **User-level default:** the file may instead live at `~/.claude/superpowers/model-routing.json`, applying to every project that has no project-level file. Lookup is project first, then user — the first file found wins entirely (no merging). A project file of all-`"inherit"` values switches routing off for that project while a user-level default exists.
251+
252+
### Role assignments when routing is on
253+
254+
Implementers (and fix re-dispatches) run at their task's tier. Spec and code-quality reviewers run at `standard` — reviewing against explicit criteria is mid-tier work, and review output is the expensive direction at frontier prices. The final whole-plan reviewer runs after all tasks complete (no task in progress, so the dispatch gate does not constrain it) and should stay at session level — one frontier judgment pass per plan. When an implementer reports BLOCKED and needs more reasoning, escalate one tier up by updating the task's metadata transparently — never silently down.
255+
256+
---
257+
258+
## Workflow Configuration — Optional Flow
259+
260+
*Canonical design doc: [`docs/workflow-config-flow.md`](docs/workflow-config-flow.md). The section below is a reader-facing summary.*
261+
262+
### Commit Strategy
263+
264+
By default, plan execution commits per task: every plan task ends with its own Commit step, and implementer subagents commit their work before review. That default is unchanged and recommended — frequent commits give fine-grained history and per-task rollback. Projects that prefer a single reviewable commit per plan can opt in to an at-end strategy.
265+
266+
**The whole flow is opt-in, with a single switch: `docs/superpowers/workflow.json` in your project.** Without that file (or without the key), behavior is byte-identical to the default.
267+
268+
```json
269+
{"commitStrategy": "at-end"}
270+
```
271+
272+
When `at-end` is set, a notice injected at session start instructs the agent to:
273+
274+
- write plans without per-task Commit steps;
275+
- end every plan with one final task — "Commit the full implementation" — blocked by all implementation tasks;
276+
- tell implementer subagents not to commit (the coordinator runs that final task, making the single commit), with reviewers reading the uncommitted working-tree diff.
277+
278+
Setup notes:
279+
280+
- Prefer a guided setup? Run `/superpowers-extended-cc:onboard` — it covers this feature alongside the other optional flows.
281+
- Valid values are `"per-task"` (the default) and `"at-end"`; anything else falls back to per-task.
282+
- **User-level default:** the file may instead live at `~/.claude/superpowers/workflow.json`, applying to every project that has no project-level file. Lookup is project first, then user — the first file found wins entirely (no merging). A project file of `{"commitStrategy": "per-task"}` restores per-task commits for that project while a user-level default exists.
283+
- Unlike model routing, this flow has no enforcement gates — the session-start notice is the only delivery mechanism, so it takes effect from the next session on and relies on plan-time compliance (see the design doc for this boundary).
284+
- Undo: delete the file or remove the `commitStrategy` key — per-task commits resume at the next session start.
285+
286+
---
287+
203288
## What's Inside
204289

205290
### Skills Library

commands/onboard.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
description: "Guided setup for superpowers' optional features. Asks short multiple-choice questions and writes the chosen configuration files in place. Everything it configures can also be set up manually — see README.md."
3+
---
4+
5+
# Superpowers Onboarding
6+
7+
Walk the user through superpowers' optional features one at a time. For each feature: ask, then immediately write the chosen configuration — no deferred "now apply this yourself" summary.
8+
9+
## Ground rules
10+
11+
- **Assume a clean slate.** Do NOT scan for existing configuration before asking — go straight to the questions. The user runs this command to set settings, not to audit them.
12+
- **Discrepancy handling (the only state handling you do):** if a file you are about to write already exists with different content, stop and show the difference, then let the user decide free-form (keep / overwrite / adjust). "Different" means: for `docs/superpowers/model-routing.json` and `docs/superpowers/workflow.json`, any existing content that differs from what you are about to write; for `.claude/settings.json`, an existing hook entry whose `command` references the same script filename you are adding.
13+
- Each feature is optional. "No" means write nothing and move to the next feature.
14+
- **NEVER commit anything.** Files are written to the working tree only; committing is the user's call.
15+
- After the last feature, summarize: what was written and where, what was skipped, and how to undo each (see Closing).
16+
17+
## Scope — ask ONCE, before Feature 1
18+
19+
One scope answer governs every write in this run: config files AND hook registrations.
20+
21+
```yaml
22+
AskUserQuestion:
23+
question: "Where should superpowers configuration live?"
24+
header: "Scope"
25+
multiSelect: false
26+
options:
27+
- label: "This project (recommended)"
28+
description: "Config files in docs/superpowers/ of this repo; hook registrations in this project's .claude/settings.json. Applies only here. Create missing directories; that is intentional."
29+
- label: "User-level (all projects)"
30+
description: "Config files in ~/.claude/superpowers/; hook registrations in ~/.claude/settings.json. Applies to every project without its own project-level config; a project file always overrides entirely."
31+
```
32+
33+
The scope fixes these targets for the rest of the run:
34+
35+
| Scope | Config files (Features 1 & 3) | Hook registrations (Feature 2) |
36+
|-------|-------------------------------|--------------------------------|
37+
| This project | `docs/superpowers/<file>.json` | `<cwd>/.claude/settings.json` |
38+
| User-level | `~/.claude/superpowers/<file>.json` | `~/.claude/settings.json` |
39+
40+
State the two chosen targets back to the user in one line, then proceed to Feature 1. Never re-ask scope per feature.
41+
42+
## Feature 1: Subagent Model Routing
43+
44+
One-line intro for the user before asking: plan execution dispatches an implementer plus reviewers per task, and by default they all inherit the session model — on frontier-priced sessions (Opus, Fable) that multiplies the most expensive model across routine tasks. Full explanation: README.md → "Subagent Model Routing — Optional Flow".
45+
46+
```yaml
47+
AskUserQuestion:
48+
question: "Enable model routing for plan-execution subagents?"
49+
header: "Routing"
50+
multiSelect: false
51+
options:
52+
- label: "Guided tiers (recommended)"
53+
description: "mechanical→haiku, standard→sonnet, frontier→session model. Cheap models for routine implementation, mid-tier for integration and reviews, full power only where judgment lives."
54+
- label: "One fixed model"
55+
description: "Every subagent uses one model you pick next — flat cost cap, no per-task gradation."
56+
- label: "No"
57+
description: "Keep the default: every subagent inherits the session model. Nothing is written."
58+
```
59+
60+
- **Guided tiers** → write `model-routing.json` to the scope's config target with this content:
61+
62+
```json
63+
{"mechanical": "haiku", "standard": "sonnet", "frontier": "inherit"}
64+
```
65+
66+
- **One fixed model** → ask the model follow-up below first (do NOT write before both answers), then write the same structure with all three tiers set to the chosen value.
67+
68+
```yaml
69+
AskUserQuestion:
70+
question: "Which model should every subagent use?"
71+
header: "Model"
72+
multiSelect: false
73+
options:
74+
- label: "haiku"
75+
description: "Cheapest and fastest. Fine when plans are well-specified."
76+
- label: "sonnet"
77+
description: "Mid-tier reasoning at mid-tier price. The balanced cap."
78+
- label: "opus"
79+
description: "Frontier reasoning. Caps cost only on Fable-class sessions."
80+
- label: "fable"
81+
description: "Highest capability and price. Only useful as a cap if your session model is above it."
82+
```
83+
84+
- **No** → write nothing.
85+
86+
After writing the file, tell the user: the plugin's routing gates activate immediately (they check for this file on every relevant tool call), and from the next session on a routing notice is injected at session start. No restart, no settings edits, no hook registration needed. Off-switch: delete the file.
87+
88+
## Feature 2: User-Thrown Gate Enforcement Hooks
89+
90+
One-line intro: when the user asks for a verification gate ("make sure X works before proceeding"), opt-in hooks force re-validation with captured evidence when such a task is closed — without them, gate tags are inert metadata. Full explanation: README.md → "User-Thrown Gate Enforcement — Optional Flow".
91+
92+
```yaml
93+
AskUserQuestion:
94+
question: "Enable enforcement hooks for user-thrown verification gates?"
95+
header: "Gates"
96+
multiSelect: false
97+
options:
98+
- label: "Yes, both hooks (recommended)"
99+
description: "Per-task close enforcement + end-of-plan stop enforcement. They compose."
100+
- label: "Per-task hook only"
101+
description: "Only re-validate when an individual gate task is closed."
102+
- label: "No"
103+
description: "Gate tagging stays inert metadata. Nothing is written."
104+
```
105+
106+
On yes, write the hook registration(s) into the scope's settings target — `<cwd>/.claude/settings.json` for this-project scope, `~/.claude/settings.json` for user-level:
107+
108+
1. Take the JSON block(s) from README.md → "Recommended Configuration": "Force Re-Validation on User-Thrown Gate Close" (per-task) and "Re-Validate Gates on 'Plan Complete' Claims" (end-of-plan).
109+
2. **Verify the script path before writing.** The README blocks reference scripts under `~/.claude/plugins/marketplaces/superpowers-extended-cc-marketplace/hooks/examples/`. Check that path exists (`ls` the directory); if the plugin lives elsewhere on this machine, substitute the real path in the `command` values.
110+
3. **Merge, never overwrite.** Read the scope's settings file first (resolve a symlink and edit the real target). If it exists: parse it, append each new hook entry into the matching array (`hooks.PostToolUse` / `hooks.Stop`), creating only the missing keys, and write the full merged result back. If it does not exist: create it containing only the chosen hooks structure. Never drop existing entries.
111+
4. **Duplicate check spans both scopes:** if the same hook script is already registered in EITHER the project file or the user file, do not add it again — report where it already lives and which scope it covers.
112+
5. **Confirm the write.** Re-read the target file, verify the new entries parse and are present, and report the confirmed absolute path back to the user. Output of this feature MUST name the file that was actually written.
113+
114+
## Feature 3: Commit Strategy
115+
116+
One-line intro: plan execution commits after every task by default — each plan task ends with its own Commit step and implementer subagents commit their own work; switching to a single commit at the end of the plan gives one reviewable commit per feature. Full explanation: README.md → "Commit Strategy".
117+
118+
```yaml
119+
AskUserQuestion:
120+
question: "How should plan execution commit its work?"
121+
header: "Commits"
122+
multiSelect: false
123+
options:
124+
- label: "Per-task commits (recommended)"
125+
description: "The default: every task ends with its own commit — fine-grained history, per-task rollback. Nothing is written."
126+
- label: "Single commit at plan end"
127+
description: "Tasks leave changes uncommitted; one final plan task commits the full implementation as a single commit."
128+
```
129+
130+
- **Per-task commits** → write nothing (an absent file already means per-task).
131+
- **Single commit at plan end** → write `workflow.json` to the scope's config target with this content:
132+
133+
```json
134+
{"commitStrategy": "at-end"}
135+
```
136+
137+
After writing the file, tell the user: this feature has no enforcement gates — it is delivered by a notice injected at session start, so it takes effect from the next session on (the current session keeps per-task behavior). Off-switch: delete the file, or remove the `commitStrategy` key.
138+
139+
## Closing
140+
141+
Report in one short block: the chosen scope, files written (confirmed absolute paths), features skipped, and how to undo each — delete the scope's `model-routing.json` (routing); remove the hook objects you added from the arrays in the scope's settings file, `<cwd>/.claude/settings.json` or `~/.claude/settings.json` (gate hooks); delete the scope's `workflow.json` or remove its `commitStrategy` key (commit strategy). Do not commit. Do not re-ask any question.

0 commit comments

Comments
 (0)