@gobing-ai/spur 0.3.41 → 0.3.43
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.
- package/.claude-plugin/marketplace.json +15 -0
- package/README.md +15 -1
- package/config/templates/AGENTS.md +5 -3
- package/config/workflows/task-pipeline.yaml +113 -12
- package/package.json +15 -12
- package/plugins/README.md +655 -0
- package/plugins/sp/README.md +621 -0
- package/plugins/sp/agents/expert-spur.md +109 -0
- package/plugins/sp/agents/super-coder.md +126 -0
- package/plugins/sp/agents/super-planner.md +283 -0
- package/plugins/sp/agents/super-reviewer.md +154 -0
- package/plugins/sp/commands/dev-arch.md +30 -0
- package/plugins/sp/commands/dev-brainstorm.md +40 -0
- package/plugins/sp/commands/dev-changelog.md +28 -0
- package/plugins/sp/commands/dev-daily.md +29 -0
- package/plugins/sp/commands/dev-debug.md +29 -0
- package/plugins/sp/commands/dev-dogfood.md +33 -0
- package/plugins/sp/commands/dev-featurechange.md +130 -0
- package/plugins/sp/commands/dev-find-conflict.md +51 -0
- package/plugins/sp/commands/dev-find-issue.md +76 -0
- package/plugins/sp/commands/dev-find-next.md +60 -0
- package/plugins/sp/commands/dev-fixall.md +33 -0
- package/plugins/sp/commands/dev-gitmsg.md +28 -0
- package/plugins/sp/commands/dev-gtd.md +97 -0
- package/plugins/sp/commands/dev-handover.md +26 -0
- package/plugins/sp/commands/dev-idea.md +50 -0
- package/plugins/sp/commands/dev-next.md +31 -0
- package/plugins/sp/commands/dev-parallel.md +30 -0
- package/plugins/sp/commands/dev-plan.md +46 -0
- package/plugins/sp/commands/dev-refine.md +48 -0
- package/plugins/sp/commands/dev-refineall.md +65 -0
- package/plugins/sp/commands/dev-refresh.md +32 -0
- package/plugins/sp/commands/dev-reverse.md +32 -0
- package/plugins/sp/commands/dev-review.md +31 -0
- package/plugins/sp/commands/dev-run.md +63 -0
- package/plugins/sp/commands/dev-runall.md +83 -0
- package/plugins/sp/commands/dev-simplify.md +39 -0
- package/plugins/sp/commands/dev-unit.md +29 -0
- package/plugins/sp/commands/dev-verify.md +48 -0
- package/plugins/sp/commands/dev-verifyall.md +72 -0
- package/plugins/sp/commands/dev-wrap.md +48 -0
- package/plugins/sp/commands/dev-wrapall.md +51 -0
- package/plugins/sp/commands/rule-add.md +18 -0
- package/plugins/sp/commands/rule-refine.md +18 -0
- package/plugins/sp/commands/rule-scan.md +18 -0
- package/plugins/sp/commands/spur-init.md +22 -0
- package/plugins/sp/commands/workflow-add.md +18 -0
- package/plugins/sp/commands/workflow-refine.md +18 -0
- package/plugins/sp/hooks/agent-hint.ts +60 -0
- package/plugins/sp/hooks/careful-guard.ts +147 -0
- package/plugins/sp/hooks/context-post-tool.ts +325 -0
- package/plugins/sp/hooks/context-session-start.ts +182 -0
- package/plugins/sp/hooks/context-session-stop.ts +95 -0
- package/plugins/sp/hooks/hooks.json +51 -0
- package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
- package/plugins/sp/hooks/task-write-guard.ts +84 -0
- package/plugins/sp/plugin.json +8 -0
- package/plugins/sp/scripts/batch-preflight.ts +204 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
- package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
- package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
- package/plugins/sp/scripts/task-size-precheck.ts +202 -0
- package/plugins/sp/scripts/validate-commands.ts +651 -0
- package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
- package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
- package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
- package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
- package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
- package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
- package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +203 -0
- package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
- package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
- package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
- package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
- package/plugins/sp/skills/code-review/SKILL.md +112 -0
- package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
- package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
- package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
- package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
- package/plugins/sp/skills/code-testing/SKILL.md +108 -0
- package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
- package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
- package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
- package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
- package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
- package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
- package/plugins/sp/skills/code-verification/SKILL.md +535 -0
- package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
- package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
- package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
- package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
- package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
- package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
- package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
- package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
- package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
- package/plugins/sp/skills/functional-review/SKILL.md +364 -0
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
- package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
- package/plugins/sp/skills/issue-finding/SKILL.md +442 -0
- package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
- package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
- package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
- package/plugins/sp/skills/issue-finding/references/session-formats.md +151 -0
- package/plugins/sp/skills/next-feature/SKILL.md +125 -0
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
- package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
- package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
- package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
- package/plugins/sp/skills/next-router/SKILL.md +181 -0
- package/plugins/sp/skills/next-router/references/messages.md +90 -0
- package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
- package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +109 -0
- package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
- package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
- package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
- package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
- package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
- package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
- package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
- package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
- package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
- package/plugins/sp/skills/spur-cli/references/features.md +234 -0
- package/plugins/sp/skills/spur-cli/references/init.md +119 -0
- package/plugins/sp/skills/spur-cli/references/message.md +98 -0
- package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
- package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
- package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
- package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
- package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
- package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +280 -0
- package/plugins/sp/skills/spur-cli/references/team.md +133 -0
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
- package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
- package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +680 -0
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +790 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -0
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
- package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +120 -0
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
- package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
- package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
- package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
- package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
- package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
- package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
- package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
- package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
- package/spur.js +6035 -4963
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: next-router
|
|
3
|
+
description: "Status→command router backing /sp:dev-next — resolve a task WBS or feature frontier, load corpus signals, look up TABLE A/B/C, dispatch exactly one existing /sp:dev-* command or stop with an exact dev-next: message. Never a second pipeline FSM. Triggers: \"what's next\", \"advance this task\", \"which dev command\"."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
protocol: "sp:next-router@1.0"
|
|
9
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
10
|
+
interactions:
|
|
11
|
+
- router
|
|
12
|
+
modes:
|
|
13
|
+
- dry-run
|
|
14
|
+
- dispatch
|
|
15
|
+
openclaw:
|
|
16
|
+
emoji: "🧭"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Next Router — Status→Command Dispatcher
|
|
20
|
+
|
|
21
|
+
`sp:next-router` is the backing skill for `/sp:dev-next`. It inspects corpus status (plus light
|
|
22
|
+
gates when a row calls for them), selects the **single best existing** `/sp:dev-*` command (or
|
|
23
|
+
documented `spur` verb) for a task WBS or feature frontier, optionally executes it, and on clean
|
|
24
|
+
success lets that command's own `--next` chain continue — **without inventing a second pipeline
|
|
25
|
+
FSM**.
|
|
26
|
+
|
|
27
|
+
The routing tables (TABLE A task / TABLE B feature / TABLE C light gates), the frontier-selection
|
|
28
|
+
algorithm, the HITL stop matrix, chain semantics, and the explicit non-routes are the SSOT in
|
|
29
|
+
**[references/routing-table.md](references/routing-table.md)**. This file owns the driver protocol:
|
|
30
|
+
parse → resolve → signals → lookup → shape argv → dispatch or stop.
|
|
31
|
+
|
|
32
|
+
## When to use
|
|
33
|
+
|
|
34
|
+
- Unsure which `/sp:dev-*` command to run for a task or feature.
|
|
35
|
+
- Want to complete the current lifecycle step and advance when gates are clean.
|
|
36
|
+
- Hygiene forks (unit gap, lint red, rule findings) need a deterministic first hop.
|
|
37
|
+
|
|
38
|
+
Do **not** use this skill to: reimplement `task-pipeline.yaml`, bypass lifecycle guards, batch a
|
|
39
|
+
feature (that is `/sp:dev-runall` — a deliberate aperture), or pick among multi-candidate forks
|
|
40
|
+
silently (that is a HITL stop).
|
|
41
|
+
|
|
42
|
+
## Inputs
|
|
43
|
+
|
|
44
|
+
| Input | Semantics |
|
|
45
|
+
|-------|-----------|
|
|
46
|
+
| `target` | Task WBS (digits), task `.md` path, or feature id (`^[A-Z][1-9]*$`). Required for dispatch; omit → stop **U1** (usage). |
|
|
47
|
+
| `--dry-run` | Print the resolved plan (**P1**) and do not dispatch. |
|
|
48
|
+
| `--once` | Strip `--next` from the shaped child argv so only the current step runs; no router re-entry. |
|
|
49
|
+
| `--auto` | Forward into dispatched children that support it. **Never** breaks multi-candidate HITL ties. |
|
|
50
|
+
| `--agent <inline\|auto\|name>` | Execution-surface selector forwarded into the dispatched child when that child documents `--agent`. Router defaults inline; a named escalation trigger overrides `--agent inline`. Omit → forward nothing. |
|
|
51
|
+
| `--full` | When the primary route is `dev-run … --next`, substitute `dev-run <wbs> --mode full` (no `--next`). No effect on non-run routes → warning **W-FULL**. |
|
|
52
|
+
|
|
53
|
+
## Protocol (deterministic)
|
|
54
|
+
|
|
55
|
+
1. **Parse** — split `$ARGUMENTS` into target + flags. Unknown flags are not silently dropped:
|
|
56
|
+
note them in the plan line (P1) or stop U1 if no valid target remains.
|
|
57
|
+
2. **Resolve target** —
|
|
58
|
+
- digits / known WBS → task mode;
|
|
59
|
+
- task `.md` path → resolve WBS via `spur task resolve` / path handling;
|
|
60
|
+
- feature id → TABLE B: run the **frontier algorithm** (routing-table §2 B3) over
|
|
61
|
+
`spur task list --json` + per-dep `spur task show <dep> --json`; no frontier → feature-level
|
|
62
|
+
row (B4–B8), usually a stop.
|
|
63
|
+
- unresolvable → stop **U2**; omitted → stop **U1**.
|
|
64
|
+
3. **Load signals (corpus first)** — `spur task show <wbs> --json` (status, `dependencies[]`),
|
|
65
|
+
dep statuses, `spur feature show <id> --json` when invoked by feature. Light gates only when
|
|
66
|
+
the matched row sets `probe=yes`.
|
|
67
|
+
4. **Table lookup** — TABLE A (task) or TABLE B (feature-level). Apply TABLE C **sequential
|
|
68
|
+
short-circuit** probes in order C1→C5; first hit replaces the dispatch.
|
|
69
|
+
5. **Cardinality** — 0 candidates → stop **U3**; 1 → continue; >1 → HITL stop **U-HITL**
|
|
70
|
+
(decision-brief; `--auto` does not pick a winner).
|
|
71
|
+
6. **Shape child argv** — apply `--once` (strip `--next`), `--full` (run-chain rewrite only),
|
|
72
|
+
`--auto` / `--agent` / execution-surface forwarding per the Inputs table and
|
|
73
|
+
[cross-cutting.md](../spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
74
|
+
7. **`--dry-run`** → print plan block **P1**; exit success without dispatching.
|
|
75
|
+
8. **Dispatch** — print **P2**, invoke the child:
|
|
76
|
+
- **Claude Code:** `Skill(skill="sp:spur-dev", args="…")` (or the documented backing
|
|
77
|
+
skill/command protocol for refine/run/verify/unit/wrap/wrapall/handover/fixall) with the
|
|
78
|
+
shaped argv.
|
|
79
|
+
- On child guard failure / review-pending → stop **U-GUARD** (leave task status untouched).
|
|
80
|
+
- On success → print **P3**. The child's own `--next` chain (when left intact) continues on
|
|
81
|
+
its own; the router never double-chains.
|
|
82
|
+
|
|
83
|
+
**Step budget:** one router invocation performs **at most one primary dispatch** (+ whatever that
|
|
84
|
+
command's own `--next` chain does). Never self-loop `/sp:dev-next`.
|
|
85
|
+
|
|
86
|
+
## Chain progression contract (`--next`)
|
|
87
|
+
|
|
88
|
+
The router is the single owner of `--next` chain progression. The definition of [`--next`](../spur-dev/references/flag-glossary.md#flag-next)
|
|
89
|
+
and the full chain contract (stop conditions, hop bound, reporting) live in the glossary; this
|
|
90
|
+
section states the router's side: how a chain propagates, how it stops, and how it reports.
|
|
91
|
+
|
|
92
|
+
**Single dispatch per invocation.** One router invocation performs **at most one primary dispatch**
|
|
93
|
+
(already stated above as the step budget). Chain continuation is the child's `--next` re-entering
|
|
94
|
+
the router, not the router self-looping. The router never double-chains.
|
|
95
|
+
|
|
96
|
+
**Propagation.** When the dispatched child completes successfully and its argv carried `--next`
|
|
97
|
+
(i.e. `--once` was not applied), the child re-invokes `/sp:dev-next` with the same target and
|
|
98
|
+
`--next` still set. The router resolves the next dispatch from the **new** task status (which may
|
|
99
|
+
have advanced) and dispatches again. This is the chain: router → child → router → child, until a
|
|
100
|
+
stop condition.
|
|
101
|
+
|
|
102
|
+
**Hop bound: 8 primary dispatches per `--next` chain.** A chain running under `--next` performs at
|
|
103
|
+
most **8 primary dispatches**. Each router re-entry is one hop. When the bound is reached without a
|
|
104
|
+
terminal task status, the router stops and emits message **W-CHAIN-BOUND** (below): "chain halted —
|
|
105
|
+
hop bound (8) reached at `<step>` without terminal status; this indicates a routing cycle, not
|
|
106
|
+
completion." The bound is sized for the longest legitimate chain (refine → run → verify → wrap is
|
|
107
|
+
four hops; the remaining four absorb probe short-circuits like `dev-fixall`/`dev-unit`).
|
|
108
|
+
|
|
109
|
+
**Stop conditions.** A chain halts cleanly when a gate fails, the verify verdict is non-PASS, a
|
|
110
|
+
HITL pause fires (taste gate, irreversible gate, multi-candidate fork), dependencies are unmet, or
|
|
111
|
+
the task reaches terminal status. The stop is a normal outcome, not an error: the report names
|
|
112
|
+
which step halted and why ("chain halted at `<step>` — `<cause>`"), distinct from the completion
|
|
113
|
+
report ("chain complete — task `<wbs>` is `<status>`"). The per-row `Stop / notes` column in
|
|
114
|
+
[routing-table.md](references/routing-table.md) §5 names the stop condition for each route.
|
|
115
|
+
|
|
116
|
+
**Flag vs command.** `/sp:dev-next` (the command) runs the next step **once** and stops; `--next`
|
|
117
|
+
(the flag) makes any command it is passed to **keep going**. `/sp:dev-next <wbs> --next` is valid
|
|
118
|
+
but redundant. See the glossary entry for the disambiguation in full.
|
|
119
|
+
|
|
120
|
+
| Id | Fires when | Kind |
|
|
121
|
+
|----|-----------|------|
|
|
122
|
+
| W-CHAIN-BOUND | `--next` chain hit the 8-dispatch hop bound without terminal status | warning — stop (routing-cycle suspected) |
|
|
123
|
+
|
|
124
|
+
## Operator messages
|
|
125
|
+
|
|
126
|
+
**[references/messages.md](references/messages.md)** (exact templates, prefixed `dev-next:`). The router fires them by id:
|
|
127
|
+
|
|
128
|
+
| Id | Fires when | Kind |
|
|
129
|
+
|----|-----------|------|
|
|
130
|
+
| U1 | no target | stop — usage |
|
|
131
|
+
| U2 | target unresolvable | stop |
|
|
132
|
+
| U3 | no route (table miss / cancelled) | stop |
|
|
133
|
+
| U4 | todo with open dependencies (A2) | stop |
|
|
134
|
+
| U-HITL | multi-candidate fork | HITL stop — decision-brief, then dispatch only after answer |
|
|
135
|
+
| U-GUARD | child guard / review-pending failure | stop — recovery line |
|
|
136
|
+
| P1 | `--dry-run` | plan block |
|
|
137
|
+
| P2 | dispatch start | info |
|
|
138
|
+
| P3 | success | info — re-run hint |
|
|
139
|
+
| W-FULL | `--full` on a non-run route | warning — continue |
|
|
140
|
+
|
|
141
|
+
## Non-routes (summary — full table in routing-table §6)
|
|
142
|
+
|
|
143
|
+
Never: reimplement the pipeline inside the router; default `todo` to `--mode full`; infer targets
|
|
144
|
+
from git/chat; auto-`--merge` on wrap; auto-author rules; use `dev-runall` as the feature default;
|
|
145
|
+
bypass lifecycle guards (`--no-lifecycle`) to force progress.
|
|
146
|
+
|
|
147
|
+
## Common Rationalizations
|
|
148
|
+
|
|
149
|
+
| Rationalization | Reality |
|
|
150
|
+
|---|---|
|
|
151
|
+
| "Two candidates are both fine — pick the higher-priority one." | Multi-candidate is a HITL stop (routing-table §4). A silent pick hides a real fork from the operator; print the decision-brief. |
|
|
152
|
+
| "The task is todo, so run the full pipeline to be safe." | Full mode is not the v1 default (non-route). A3 dispatches the `--next` chain link; `--full` exists for the explicit override. |
|
|
153
|
+
| "I can loop dev-next until the task is done." | Step budget is one dispatch per invocation. Self-looping makes token cost unbounded; the operator re-invokes after non-chain dispatches. |
|
|
154
|
+
| "The guard failed but the fix is obvious — force it through." | Guards are the product (non-route: no lifecycle bypass). Stop U-GUARD, surface the finding, let the operator resolve. |
|
|
155
|
+
|
|
156
|
+
## Red Flags
|
|
157
|
+
|
|
158
|
+
- Dispatching more than one primary command in a single invocation.
|
|
159
|
+
- `--auto` used to choose among HITL candidates.
|
|
160
|
+
- A route that is not in TABLE A/B/C (invented dispatch targets).
|
|
161
|
+
- `--once` honored by merely skipping the re-invoke while leaving `--next` in the child argv.
|
|
162
|
+
- Omitting the `dev-next:` prefix on stop/plan messages.
|
|
163
|
+
|
|
164
|
+
## Platform Notes
|
|
165
|
+
|
|
166
|
+
- **Claude Code:** invoked via `/sp:dev-next` → `Skill(skill="sp:next-router", args="$ARGUMENTS")`;
|
|
167
|
+
dispatch children via `Skill()`; HITL via `AskUserQuestion` with the decision-brief options.
|
|
168
|
+
- **Codex / OpenClaw / OpenCode / Antigravity:** no `Skill()` — read this file +
|
|
169
|
+
`references/routing-table.md` as the procedure SSOT; corpus signals via
|
|
170
|
+
`spur task show|list --json`, `spur feature show|list --json`, `spur task check --json`;
|
|
171
|
+
dispatch by invoking the target command protocol (or its backing skill) with forwarded flags;
|
|
172
|
+
message literals in `plugins/sp/commands/dev-next.md`; HITL via the platform's decision-brief
|
|
173
|
+
equivalent (`spur-dev/references/decision-brief.md`). Never reimplement refine/run/verify inside
|
|
174
|
+
the router.
|
|
175
|
+
|
|
176
|
+
## See also
|
|
177
|
+
|
|
178
|
+
- **[references/routing-table.md](references/routing-table.md)** — TABLE A/B/C SSOT + algorithm.
|
|
179
|
+
- **`sp:spur-dev`** — the spine that owns the lifecycle the router dispatches into.
|
|
180
|
+
- **`sp:dogfood-testing`** — peer meta-tool (also outside the numbered dev-operations map).
|
|
181
|
+
- **`plugins/sp/skills/spur-dev/references/decision-brief.md`** — HITL brief format.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: messages
|
|
3
|
+
description: "Exact dev-next: operator-message literals for sp:next-router — U1, U2, U3, U4, U-HITL, U-GUARD, P1, P2, P3, W-FULL templates, verbatim (R3)."
|
|
4
|
+
see_also:
|
|
5
|
+
- next-router
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Operator Messages — Exact Templates (R3)
|
|
9
|
+
|
|
10
|
+
Use these literals (substitute angle-bracket tokens). Prefix every stop with `dev-next:`.
|
|
11
|
+
|
|
12
|
+
### U1 — no target
|
|
13
|
+
```
|
|
14
|
+
dev-next: no target
|
|
15
|
+
usage: /sp:dev-next <wbs|feature-id> [--dry-run] [--once] [--auto] [--agent <name|auto>] [--full]
|
|
16
|
+
hint: pass a task WBS (e.g. 0274) or feature id (e.g. N)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### U2 — unknown / unresolvable target
|
|
20
|
+
```
|
|
21
|
+
dev-next: cannot resolve target <raw>
|
|
22
|
+
spur task show / spur feature show failed
|
|
23
|
+
fix: check WBS/feature id, then re-run
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### U3 — no route (table miss / cancelled)
|
|
27
|
+
```
|
|
28
|
+
dev-next: no route for <wbs|feature> (status=<status>)
|
|
29
|
+
reason: <one-line from table stop notes>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### U4 — deps not satisfied (A2)
|
|
33
|
+
```
|
|
34
|
+
dev-next: blocked by open dependencies for <wbs>
|
|
35
|
+
unmet: <dep1>(status), <dep2>(status), …
|
|
36
|
+
fix: finish deps or re-order work; re-run /sp:dev-next <wbs>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### U-HITL — multi-candidate
|
|
40
|
+
```
|
|
41
|
+
dev-next: multiple candidates — choose one
|
|
42
|
+
task/feature: <id> status=<status>
|
|
43
|
+
recommended: <cmd-1>
|
|
44
|
+
alternatives:
|
|
45
|
+
- <cmd-2>
|
|
46
|
+
- <cmd-3>
|
|
47
|
+
stakes: <one line>
|
|
48
|
+
(re-run with an explicit /sp:dev-* if you prefer not to use the router)
|
|
49
|
+
```
|
|
50
|
+
Then invoke decision-brief / AskUserQuestion; do not dispatch until answered.
|
|
51
|
+
|
|
52
|
+
### U-GUARD — child guard / review-pending
|
|
53
|
+
```
|
|
54
|
+
dev-next: dispatch stopped (review-pending)
|
|
55
|
+
child: <exact invocation>
|
|
56
|
+
reason: <guard or verify verdict summary>
|
|
57
|
+
task left at status=<status>
|
|
58
|
+
fix: resolve the finding, then /sp:dev-next <wbs>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### P1 — dry-run plan
|
|
62
|
+
```
|
|
63
|
+
dev-next: plan (dry-run)
|
|
64
|
+
target: <wbs> (from <raw>) status=<status> feature=<id|—>
|
|
65
|
+
row: <A#|B#|C#> probe=<yes|no>
|
|
66
|
+
signals: <bullet or compact json keys>
|
|
67
|
+
dispatch: <exact child argv>
|
|
68
|
+
chain: <embedded --next|none> once=<bool> full=<bool> auto=<bool>
|
|
69
|
+
(no commands executed)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### P2 — dispatch start
|
|
73
|
+
```
|
|
74
|
+
dev-next: dispatch
|
|
75
|
+
row: <A#|B#|C#>
|
|
76
|
+
→ <exact child argv>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### P3 — success (no further router work)
|
|
80
|
+
```
|
|
81
|
+
dev-next: ok
|
|
82
|
+
child finished: <exact child argv>
|
|
83
|
+
task status now: <status>
|
|
84
|
+
next: re-run /sp:dev-next <wbs> if more steps remain (or rely on child --next chain if present)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### W-FULL — --full ignored
|
|
88
|
+
```
|
|
89
|
+
dev-next: warning — --full ignored (primary route is not dev-run --next); continuing with <dispatch>
|
|
90
|
+
```
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: routing-table
|
|
3
|
+
description: "SSOT routing tables for sp:next-router — resolution algorithm, TABLE A (task status), TABLE B (feature frontier), TABLE C (light-gate short-circuit), HITL stop matrix, chain semantics, and explicit non-routes. Seeded from task 0270 Solution."
|
|
4
|
+
see_also:
|
|
5
|
+
- next-router
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Routing Table — `/sp:dev-next` v1
|
|
9
|
+
|
|
10
|
+
The v1 routing table is the SSOT for `/sp:dev-next`. The router is a pure status→command
|
|
11
|
+
dispatcher: resolve target → load corpus → apply primary table → optional light-gate short-circuit
|
|
12
|
+
→ single dispatch or HITL stop → optional chain.
|
|
13
|
+
|
|
14
|
+
## Batch consumers (task 0279)
|
|
15
|
+
|
|
16
|
+
`sp:super-planner` (via `/sp:dev-runall`) **reads** TABLE A STOP preconditions for:
|
|
17
|
+
|
|
18
|
+
1. **Preflight** — skip pipeline launch when A2/A7/A8/A9 would stop `dev-next` (`batch-preflight.ts`).
|
|
19
|
+
2. **One-shot recovery** — after a failed pipeline, map status → primary hop (A1/A3/A5/A6/A7) at most once.
|
|
20
|
+
|
|
21
|
+
It does **not** reimplement TABLES or replace `task-pipeline.yaml` with a `dev-next` loop. Keep this
|
|
22
|
+
file as the only SSOT for row semantics; batch helpers must stay aligned with A2/A7/A8/A9 codes.
|
|
23
|
+
|
|
24
|
+
## 0. Algorithm (deterministic)
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
INPUT: positional target (WBS | feature-id | omit), flags (--dry-run, --once, --auto?, --agent?, --full?)
|
|
28
|
+
OUTPUT: printed plan; optionally invoke one /sp:dev-* or spur verb; optionally chain
|
|
29
|
+
|
|
30
|
+
1. Resolve target
|
|
31
|
+
a. Digits-only or known WBS → task mode
|
|
32
|
+
b. Feature-id regex ^[A-Z][1-9]*$ → feature mode (pick frontier task, else feature-level row)
|
|
33
|
+
c. Omitted → NOT v1 (see Non-routes); stop with usage
|
|
34
|
+
2. Load signals (corpus first)
|
|
35
|
+
- task: spur task show <wbs> --json
|
|
36
|
+
- feature (if any): spur feature show <id> --json
|
|
37
|
+
- deps: for each dependencies[] entry, spur task show <dep> --json → status
|
|
38
|
+
3. Primary route = TABLE A (task) or TABLE B (feature-level when no frontier task)
|
|
39
|
+
4. Light gates — ONLY if the matched row sets probe=yes
|
|
40
|
+
- Run TABLE C probes in listed short-circuit order; first hit replaces dispatch
|
|
41
|
+
5. Cardinality
|
|
42
|
+
- 0 candidates → stop (message: no route)
|
|
43
|
+
- 1 candidate → dispatch (or print if --dry-run)
|
|
44
|
+
- >1 candidates → HITL STOP (decision-brief; never silent pick)
|
|
45
|
+
6. On dispatch success and not --once and row.chain is set → invoke chain command
|
|
46
|
+
On guard/HITL/fail → stop; leave status; print recovery line
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Default flags forwarded into dispatched lifecycle commands:** `--auto` when the operator passed
|
|
50
|
+
it or when chaining (chain links already use `--auto` per existing refine→run→verify convention).
|
|
51
|
+
`--agent` forwarded only when the child command documents it. `--full` only rewrites a
|
|
52
|
+
`dev-run … --next` primary into `dev-run <wbs> --mode full` (without `--next`); ignored otherwise
|
|
53
|
+
(warning W-FULL).
|
|
54
|
+
|
|
55
|
+
## 1. TABLE A — Task primary routes (corpus status)
|
|
56
|
+
|
|
57
|
+
Statuses from `TASK_STATUSES`: backlog | todo | wip | testing | blocked | done | cancelled.
|
|
58
|
+
|
|
59
|
+
| # | Precondition | Primary signal | Dispatch | probe | Chain on success? | Stop / notes |
|
|
60
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
61
|
+
| A1 | `status == backlog` | `task.show.status` | `/sp:dev-refine <wbs> --auto --next` | yes (refine skip-gate sections) | **yes** — refine's own `--next` → run → verify | If refine fails guard → stop review-pending |
|
|
62
|
+
| A2 | `status == todo` AND any open dep `status != done` | `dependencies[]` + dep statuses | *(none)* | no | no | **STOP** — blocked by deps; print unmet dep WBS list. Do not invent parallel work. |
|
|
63
|
+
| A3 | `status == todo` AND deps satisfied | `task.show.status` + deps | `/sp:dev-run <wbs> --mode implement --auto --next` | yes | **yes** — implement → verify | Explicit mode prevents the pipeline step from recursively launching full mode (bug-742) |
|
|
64
|
+
| A4 | `status == wip` AND checkpoint exists under `.spur/memory/sessions/*-<wbs>-*` | checkpoint `next_action` | `/sp:dev-run <wbs> --continue` | no | no (continue owns resume) | If continue cannot resume → fall through A5 |
|
|
65
|
+
| A5 | `status == wip` (no usable checkpoint) | `task.show.status` | `/sp:dev-run <wbs> --mode implement --auto --next` | yes | **yes** → verify | Completes implement step then chain |
|
|
66
|
+
| A6 | `status == testing` | `task.show.status` | `/sp:dev-verify <wbs> --auto --next` | yes | **yes** — verify `--next` → done (FSM + provenance guards) | On PARTIAL/FAIL → stop review-pending (do not force done) |
|
|
67
|
+
| A7 | `status == blocked` | `task.show` + Notes/History for blocker text | `/sp:dev-handover "<blocker summary from Notes or status>"` | no | no | **STOP** after handover doc; human unblocks |
|
|
68
|
+
| A8 | `status == done` | `task.show.status` | `/sp:dev-wrap <wbs>` (`--agent <value>` preserved when the originating command supplied it; omission remains omission) | no | **no** (wrap's `--merge` is irreversible HITL; never auto) | Operator may re-invoke with `--merge` explicitly later |
|
|
69
|
+
| A9 | `status == cancelled` | `task.show.status` | *(none)* | no | no | **STOP** — no-op; print "cancelled — nothing to advance" |
|
|
70
|
+
|
|
71
|
+
**Priority when multiple TABLE A rows could match:** lowest row number wins (A1–A9 are mutually
|
|
72
|
+
exclusive by status except A2/A3 which split `todo`).
|
|
73
|
+
|
|
74
|
+
## 2. TABLE B — Feature-ID path (rollup)
|
|
75
|
+
|
|
76
|
+
When input is a feature id:
|
|
77
|
+
|
|
78
|
+
| # | Precondition | Primary signal | Dispatch | probe | Chain? | Stop / notes |
|
|
79
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
80
|
+
| B0 | Feature missing / invalid id | `feature show` exit ≠ 0 | *(none)* | no | no | **STOP** — unknown feature |
|
|
81
|
+
| B1 | `feature.status == cancelled` | feature status | *(none)* | no | no | **STOP** |
|
|
82
|
+
| B2 | `feature.status == done` | feature status | *(none)* | no | no | **STOP** — suggest archive/docs only; no auto wrapall |
|
|
83
|
+
| B3 | Feature has ≥1 frontier task | task list under feature | **Recurse TABLE A** on chosen task | per A | per A | Frontier = open (`backlog`\|`todo`\|`wip`\|`testing`\|`blocked`), unblocked (all `dependencies[]` done), prefer WBS-ascending among `todo` then `backlog` then `wip` then `testing` then `blocked` |
|
|
84
|
+
| B4 | No frontier tasks AND `feature.status == backlog` AND AC placeholder/invalid | `feature check` / AC body | `/sp:dev-plan` continuation is not WBS-shaped — **STOP** with: run `/sp:dev-plan --feature <id>` or fix AC then `spur feature check <id>` | no | no | Planning-half entry needs a description; do not invent idea text |
|
|
85
|
+
| B5 | No frontier tasks AND feature has valid AC but zero tasks | feature + empty task roster | **STOP** with: `/sp:dev-plan --feature <id>` (decompose/batch-create) | no | no | Avoid auto-running plan without operator description confirmation in v1 |
|
|
86
|
+
| B6 | No frontier tasks AND all child tasks `done` AND feature in `active`\|`verifying` | task list all done | `/sp:dev-wrapall --feature <id>` (`--agent <value>` preserved when the originating command supplied it; omission remains omission) | no | no | Advances feature via wrapall guards; `--merge` never auto |
|
|
87
|
+
| B7 | No frontier tasks AND mixed cancelled/done only | statuses | **STOP** — print summary; suggest feature status update manually | no | no | |
|
|
88
|
+
| B8 | `feature.status == blocked` | feature status | **STOP** — print feature blocked; do not pick tasks | no | no | |
|
|
89
|
+
|
|
90
|
+
**Frontier selection algorithm (B3) — precise:**
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
candidates = tasks where feature_id == ID
|
|
94
|
+
AND status ∈ {backlog, todo, wip, testing, blocked}
|
|
95
|
+
AND every dep in dependencies[] has status == done
|
|
96
|
+
order = stable sort by:
|
|
97
|
+
1. status rank: todo=0, backlog=1, wip=2, testing=3, blocked=4
|
|
98
|
+
2. WBS ascending (numeric)
|
|
99
|
+
pick = first(candidates)
|
|
100
|
+
if pick is null → TABLE B rows B4–B7
|
|
101
|
+
else → TABLE A(pick)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 3. TABLE C — Light-gate short-circuit (probe=yes rows only)
|
|
105
|
+
|
|
106
|
+
**Order is sequential short-circuit** (first match wins). Never parallel in v1 (simpler, lower
|
|
107
|
+
token, deterministic).
|
|
108
|
+
|
|
109
|
+
| Order | When evaluated | Probe | Signal | Redirect dispatch | Else |
|
|
110
|
+
| --- | --- | --- | --- | --- | --- |
|
|
111
|
+
| C1 | A1, A3, A5 (pre-implement / refine path) | `spur task check <wbs> --json` | Any **L3** finding on sections ∈ {Background, Requirements, Acceptance Criteria, Design, Plan} | Force `/sp:dev-refine <wbs> --auto` (**without** `--next` if already mid-refine; with `--next` only when status was backlog/todo and operator wants chain — default: keep `--next` for A1/A3) | continue |
|
|
112
|
+
| C2 | A3, A5 after C1 clean | Cheap workspace health: `bun run lint` (or project lint) exit ≠ 0 **and** scope inferable from task Solution/Plan paths or default repo | lint/type failures | `/sp:dev-fixall` (optional `--scope` if single package known) | continue |
|
|
113
|
+
| C3 | A5/A6 when Testing empty/N/A **and** verify would fail for missing tests — only if prior implement claims code exists | Coverage/test signal: `bun test` fail attributed to task paths OR explicit "insufficient tests" in prior verify verdict artifact `.spur/run/<wbs>-verdict.json` | test fail / coverage gap | `/sp:dev-unit <wbs> --auto` | continue |
|
|
114
|
+
| C4 | A3/A5/A6 when operator or task tags mention rules, OR `spur rule run` last report dirty in `.spur/` if present | `spur rule run` (default project preset) non-zero with findings | rule findings | **HITL STOP** — print rule summary; suggest `/sp:rule-scan` or `rule-add`/`rule-refine` (do not auto-author rules) | continue |
|
|
115
|
+
| C5 | A6 only | Existing `.spur/run/<wbs>-verdict.json` with FAIL and findings pointing at coverage | verdict artifact | `/sp:dev-unit <wbs>` then re-verify on next invocation (`--once` friendly) | `/sp:dev-verify …` |
|
|
116
|
+
|
|
117
|
+
**Explicit non-probes in v1:** no freeform chat history; no always-on full `bun run test` for every
|
|
118
|
+
call; no git dirtiness as a route (optional advisory print only).
|
|
119
|
+
|
|
120
|
+
## 4. Multi-candidate HITL STOP matrix
|
|
121
|
+
|
|
122
|
+
| Situation | Why not auto | Operator brief options (recommended first) |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| C2 and C3 both true | lint vs tests both red | (1) fixall (2) unit (3) abort |
|
|
125
|
+
| Feature B3 pick ambiguous because two `todo` same rank — **should not happen** after WBS sort | — | N/A — WBS tie-break is total |
|
|
126
|
+
| Task `todo` but also feature-level AC invalid when invoked via feature id | feature health vs task progress | (1) fix feature AC (2) proceed with task A3 |
|
|
127
|
+
| `testing` with open P1 in Review section | verify vs review-fix | (1) `/sp:dev-review <wbs> --fix blockers-first` (2) verify anyway |
|
|
128
|
+
| `wip` with both checkpoint and dirty Solution L3 | resume vs re-implement | (1) `--continue` (2) implement `--next` |
|
|
129
|
+
|
|
130
|
+
When HITL STOP fires: print decision-brief (question, stakes, recommended option, alternatives).
|
|
131
|
+
**Do not dispatch** until operator answers (or `--auto` is **not** allowed to break multi-candidate
|
|
132
|
+
ties in v1 — `--auto` only skips confirmations *inside* a single chosen command).
|
|
133
|
+
|
|
134
|
+
## 5. Chain semantics (success path)
|
|
135
|
+
|
|
136
|
+
**Canonical definition.** [`--next`](../../spur-dev/references/flag-glossary.md#flag-next) is
|
|
137
|
+
chain-to-completion with propagation: on success, hand the task back to `sp:next-router`, which
|
|
138
|
+
resolves the next dispatch and re-invokes with `--next` still set, until the work is done or a gate
|
|
139
|
+
stops it. The full chain contract (stop conditions, hop bound, reporting) lives in the glossary; this
|
|
140
|
+
section is the routing-table projection of it. Per-row `Stop / notes` columns below name the stop
|
|
141
|
+
condition for each route.
|
|
142
|
+
|
|
143
|
+
| After successful dispatch | If not `--once` | Stop condition | Notes |
|
|
144
|
+
| --- | --- | --- | --- |
|
|
145
|
+
| `dev-refine … --next` | chains to `dev-run` (status → todo+deps) | unmet deps (A2), guard fail, refine guard fail | Router does not double-chain |
|
|
146
|
+
| `dev-run … --next` | chains to `dev-verify` (status → testing) | non-PASS verify verdict, gate fail | Router does not double-chain |
|
|
147
|
+
| `dev-verify … --next` | attempts done (FSM + provenance guards) | PARTIAL/FAIL verdict → stop review-pending; done → chain complete | Router stops after return |
|
|
148
|
+
| `dev-unit` / `dev-fixall` / `dev-wrap` / `dev-handover` | **no auto re-entry** into router in v1 | operator re-invoke | Keeps token cost bounded; operator re-invokes `/sp:dev-next` |
|
|
149
|
+
| HITL / guard failure | no chain | named in `Stop / notes` | Print recovery one-liner with exact re-run command |
|
|
150
|
+
|
|
151
|
+
**Hop bound: 8.** A chain running under `--next` performs at most **8 primary dispatches** (router
|
|
152
|
+
re-entries). When the bound is hit without terminal task status, the router stops and emits
|
|
153
|
+
**W-CHAIN-BOUND** (routing-cycle suspected, not completion). The bound is sized for refine → run →
|
|
154
|
+
verify → wrap (4 hops) plus probe short-circuits (`dev-fixall`/`dev-unit`).
|
|
155
|
+
|
|
156
|
+
**Step budget:** one router invocation performs **at most one primary dispatch** (+ whatever that
|
|
157
|
+
command's own `--next` chain does). It does **not** loop `dev-next` on itself (prevents unbounded
|
|
158
|
+
auto).
|
|
159
|
+
|
|
160
|
+
### `--once` vs child-embedded `--next` (clarification)
|
|
161
|
+
|
|
162
|
+
TABLE A rows encode `--next` on refine/run/verify. Operator-facing `--once` on `/sp:dev-next`
|
|
163
|
+
means "only the current step":
|
|
164
|
+
|
|
165
|
+
1. Build child argv from table.
|
|
166
|
+
2. If `--once`: remove `--next` from child argv (and any router-level re-entry).
|
|
167
|
+
3. Dispatch single step; print P3 with hint to re-run `/sp:dev-next`.
|
|
168
|
+
|
|
169
|
+
Without `--once`, leave table `--next` intact so refine→run→verify chain runs as today.
|
|
170
|
+
|
|
171
|
+
> **Redefinition note (feature H8, task 0399, 2026-07-31).** Before the glossary, `--next` carried
|
|
172
|
+
> four incompatible meanings across seven commands; this table was one of the places they collided.
|
|
173
|
+
> Task 0401 reconciled every declaring command against the single definition above. `dev-run --next`
|
|
174
|
+
> as implement-only mode selector is the only genuinely breaking case — replacement is
|
|
175
|
+
> `--mode implement` (row A5 already dispatches that). See ADR-039.
|
|
176
|
+
|
|
177
|
+
## 6. Non-routes (explicit)
|
|
178
|
+
|
|
179
|
+
| Temptation | Why forbidden in v1 |
|
|
180
|
+
| --- | --- |
|
|
181
|
+
| Reimplement `task-pipeline.yaml` inside next | Spine owns full pipeline; use `dev-run` without `--next` only if we add a future row — **not default** |
|
|
182
|
+
| Default to `/sp:dev-run --mode full` for every `todo` | Heavier HITL surface; chain-link is the locked auto-advance style |
|
|
183
|
+
| Infer target from git dirty / chat | Locked out of v1 signals |
|
|
184
|
+
| Auto `--merge` on wrap | Irreversible |
|
|
185
|
+
| Auto `rule-add` | Authoring needs human judgment |
|
|
186
|
+
| `dev-runall` as default for feature | Batch is a deliberate aperture; feature path picks **one** frontier task |
|
|
187
|
+
| Lifecycle bypass (`--no-lifecycle`) to force progress | Guards are the product |
|
|
188
|
+
|
|
189
|
+
## 7. Worked scenarios (stress tests)
|
|
190
|
+
|
|
191
|
+
**S1 — New task, backlog, empty Plan L3**
|
|
192
|
+
Signals: status=backlog → A1 → C1 may still refine → `/sp:dev-refine 0042 --auto --next` → chains
|
|
193
|
+
to implement/verify.
|
|
194
|
+
|
|
195
|
+
**S2 — Mid implement, wip, no checkpoint**
|
|
196
|
+
A5 → C1 clean → C2 lint red → short-circuit `/sp:dev-fixall` → stop (no auto re-enter). Operator
|
|
197
|
+
runs `/sp:dev-next 0042` again → A5 → implement.
|
|
198
|
+
|
|
199
|
+
**S3 — Feature F, three todo tasks, one blocked by dep**
|
|
200
|
+
B3 frontier filter drops blocked-by-dep; WBS-ascending picks lowest ready todo → A3.
|
|
201
|
+
|
|
202
|
+
**S4 — All tasks done, feature active**
|
|
203
|
+
B6 → `/sp:dev-wrapall --feature F`.
|
|
204
|
+
|
|
205
|
+
**S5 — testing, verify would fail on tests**
|
|
206
|
+
A6 → C5/C3 → unit first if verdict says so; else verify.
|
|
207
|
+
|
|
208
|
+
## Source anchors (file:line)
|
|
209
|
+
|
|
210
|
+
- Task status enum: `packages/domain/src/planning/schema.ts:20`
|
|
211
|
+
- Feature status enum: `packages/domain/src/planning/schema.ts:23`
|
|
212
|
+
- Dev operations map: `plugins/sp/skills/spur-dev/references/dev-operations.md:37-56`
|
|
213
|
+
- `--next` chain on run: `plugins/sp/commands/dev-run.md:104-127`
|
|
214
|
+
- Refine skip-gate sections: `plugins/sp/skills/spur-dev/references/dev-operations.md:114-128`
|
|
215
|
+
- Task lifecycle wip→testing guard: `.spur/workflows/task-lifecycle.yaml:48-54`
|
|
216
|
+
- Decision-brief format: `plugins/sp/skills/spur-dev/references/decision-brief.md`
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: parallel-execution
|
|
3
|
+
description: "Decide when to fan out independent work across subagents, choose the fan-out pattern, synthesize parallel results. Triggers: \"fan out\", \"run in parallel\", \"parallelize\", \"concurrent execution\", \"multi-agent run\"."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: execution
|
|
10
|
+
interactions:
|
|
11
|
+
- technique
|
|
12
|
+
- pipeline
|
|
13
|
+
operations:
|
|
14
|
+
- fan-out
|
|
15
|
+
- review-panel
|
|
16
|
+
- investigation
|
|
17
|
+
- result-synthesis
|
|
18
|
+
see_also:
|
|
19
|
+
- sp:spur-dev
|
|
20
|
+
- sp:super-planner
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# sp:parallel-execution — Parallel Execution & Fan-Out
|
|
24
|
+
|
|
25
|
+
The parallel-execution competency — decide when to fan out independent work across subagents, choose the right fan-out pattern, and synthesize parallel results. This skill owns the **decision framework** (when to parallelize) and the **execution patterns** (how to structure fan-out); the spine (`sp:spur-dev`) and batch orchestrator (`sp:super-planner`) consult it when they encounter independent work.
|
|
26
|
+
|
|
27
|
+
This is a **competency skill** — it teaches the agent *how* to parallelize, not *what* to parallelize. The spine owns the lifecycle and task selection; this skill owns the fan-out mechanics.
|
|
28
|
+
|
|
29
|
+
## The decision framework
|
|
30
|
+
|
|
31
|
+
**The one question:** can these items run independently with no shared mutable state and no sequential dependency?
|
|
32
|
+
|
|
33
|
+
Ask these five questions before fanning out:
|
|
34
|
+
|
|
35
|
+
| Question | Yes → | No → |
|
|
36
|
+
|----------|-------|------|
|
|
37
|
+
| Do the items share mutable state (files, DB, global config)? | Serialize | Continue |
|
|
38
|
+
| Is there a hard sequential dependency (B needs A's output)? | Serialize A→B | Continue |
|
|
39
|
+
| Do the items target overlapping files (same file:line range)? | Serialize or merge-first | Continue |
|
|
40
|
+
| Is the remaining token budget ≥ (N × estimated cost per subagent)? | Continue | Reduce N or serialize |
|
|
41
|
+
| Are the items truly independent concerns (different skills/modules)? | Fan out | Question whether splitting is artificial |
|
|
42
|
+
|
|
43
|
+
**Hard rule:** if ANY question in rows 1-3 is Yes, serialize. Rows 4-5 are advisory — they guide N and pattern choice but don't block fan-out.
|
|
44
|
+
|
|
45
|
+
## Fan-out patterns
|
|
46
|
+
|
|
47
|
+
Four proven patterns, cataloged in [fan-out-patterns.md](references/fan-out-patterns.md):
|
|
48
|
+
|
|
49
|
+
| Pattern | Use when | Token cost | Result shape |
|
|
50
|
+
|---------|----------|------------|--------------|
|
|
51
|
+
| **N-way investigation** | One question, N independent search angles | ~N × 3k | Merged findings, deduped |
|
|
52
|
+
| **Competency-lens review** | One artifact, N review dimensions | ~N × 5k | Per-lens verdicts, unified report |
|
|
53
|
+
| **Independent-task batch** | M tasks, zero dependency edges | ~M × 8k | Per-task results, batch summary |
|
|
54
|
+
| **Adversarial verification panel** | One claim, N independent skeptics | ~N × 4k | Vote tally (survives if ≥2/3 affirm) |
|
|
55
|
+
|
|
56
|
+
**Pattern selection rule:** match the work shape to the pattern. Don't force a pattern onto mismatched work — N-way investigation on dependent tasks produces conflicting results; adversarial panel on a fact-check produces noise.
|
|
57
|
+
|
|
58
|
+
## Result synthesis
|
|
59
|
+
|
|
60
|
+
Parallel subagent outputs must be **synthesized**, not concatenated. The synthesis contract:
|
|
61
|
+
|
|
62
|
+
1. **Dedup** — merge findings with the same `file:line` anchor; keep the highest-severity version.
|
|
63
|
+
2. **Resolve conflicts** — when two subagents disagree on the same claim, surface the disagreement explicitly; don't silently pick one.
|
|
64
|
+
3. **Rank by confidence** — sort synthesized results by confidence (HIGH → MEDIUM → LOW); unresolved conflicts go last.
|
|
65
|
+
4. **Unified format** — emit one coherent output, not N raw dumps.
|
|
66
|
+
|
|
67
|
+
Full synthesis methodology: [result-synthesis.md](references/result-synthesis.md).
|
|
68
|
+
|
|
69
|
+
## Subagent execution disciplines
|
|
70
|
+
|
|
71
|
+
When you dispatch work to a subagent - a fan-out worker, an adversarial reviewer, a research angle -
|
|
72
|
+
four disciplines keep the dispatch reliable and cheap. They apply to every pattern above and are the
|
|
73
|
+
SSOT the batch orchestrator (`sp:super-planner`) and [execution-batch.md](../spur-dev/references/execution-batch.md) point back to. The choice of which **execution surface** carries the dispatch
|
|
74
|
+
(native subagent vs `spur agent run`) is decided by [dispatch-surface.md](references/dispatch-surface.md) - apply it before these disciplines.
|
|
75
|
+
|
|
76
|
+
### Hand artifacts as files, not pasted context
|
|
77
|
+
|
|
78
|
+
Never paste bulk context into a dispatch prompt. Write the artifact — the diff, the file set, the
|
|
79
|
+
spec excerpt, the data — to a file and hand the subagent the **path**. Pasting bulk text bloats the
|
|
80
|
+
prompt, truncates unpredictably, and cannot be re-read after compaction. A file handoff is durable,
|
|
81
|
+
re-readable, and keeps the dispatch prompt small enough to reason about.
|
|
82
|
+
|
|
83
|
+
### Keep a durable progress ledger
|
|
84
|
+
|
|
85
|
+
Maintain a progress ledger that survives compaction — a file (or the batch report table) recording,
|
|
86
|
+
per dispatched item, its status (pending / running / done / failed) and its result location. When the
|
|
87
|
+
session compacts or a run resumes, the ledger is the source of truth for what already ran; working
|
|
88
|
+
memory is not. Update it as each item terminates, not in one batch at the end.
|
|
89
|
+
|
|
90
|
+
### Select the cheapest model that fits each role
|
|
91
|
+
|
|
92
|
+
Match the model to the role. A mechanical extraction or a structural check runs on a cheap model; a
|
|
93
|
+
nuanced design review or a hard implementation wants a stronger one. Paying for the top model on every
|
|
94
|
+
subagent role is waste; using a weak model on a judgment role is a false economy. Choose per role.
|
|
95
|
+
|
|
96
|
+
### Never pre-judge the reviewer
|
|
97
|
+
|
|
98
|
+
A reviewer/skeptic subagent must receive the artifact and the contract and nothing that steers its
|
|
99
|
+
verdict. No "don't worry about X", no "this part is fine", no pre-rated severity, no "focus only on
|
|
100
|
+
Y". A pre-judged reviewer confirms your framing instead of testing it — the exact failure the fan-out
|
|
101
|
+
was meant to avoid. Let the reviewer reach its own conclusion.
|
|
102
|
+
|
|
103
|
+
## Integration with the spine
|
|
104
|
+
|
|
105
|
+
- **`sp:spur-dev`** owns task selection and lifecycle. When a batch contains independent tasks, the spine consults this skill for the fan-out pattern.
|
|
106
|
+
- **`sp:super-planner`** is the orchestrator that executes the fan-out. Its parallel mode (documented in its agent definition) applies the patterns from this skill.
|
|
107
|
+
- **`/sp:dev-parallel`** is the thin slash-command entry point that delegates to this skill.
|
|
108
|
+
|
|
109
|
+
## When to use
|
|
110
|
+
|
|
111
|
+
- Deciding whether a set of tasks can run in parallel.
|
|
112
|
+
- Choosing the right fan-out pattern for a batch.
|
|
113
|
+
- Synthesizing results from multiple subagent runs.
|
|
114
|
+
- The operator says "fan out", "run in parallel", or "parallelize this batch."
|
|
115
|
+
|
|
116
|
+
Do **not** use this skill for:
|
|
117
|
+
- Sequential pipeline execution — that is `sp:spur-dev`'s execution half.
|
|
118
|
+
- Single-task lifecycle — that is `sp:spur-dev` (`/sp:dev-run`).
|
|
119
|
+
- Batch orchestration logic — that is `sp:super-planner` (the orchestrator); this skill is the *decision support* it consults.
|
|
120
|
+
|
|
121
|
+
## Gotchas
|
|
122
|
+
|
|
123
|
+
1. **Silent truncation is a finding.** If you fan out 10 items but only report on 8, the 2 dropped items are a finding — document them explicitly.
|
|
124
|
+
2. **Token budget is real.** Fan-out multiplies token cost. The framework's row 4 is not optional — check `remaining budget` before spawning.
|
|
125
|
+
3. **Same-file overlap = serialize.** Two subagents editing the same file WILL conflict. The framework catches this at decision time; don't override it.
|
|
126
|
+
4. **Synthesis is work.** Merging N outputs is not free — budget ~2k tokens for synthesis per pattern. Plan for it.
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
| [fan-out-patterns.md](references/fan-out-patterns.md) | Four fan-out patterns, per-pattern token-cost estimates, when-to-use decision table |
|
|
131
|
+
| [result-synthesis.md](references/result-synthesis.md) | Merge/dedup/conflict-resolution strategies, anti-patterns, unified-report template |
|
|
132
|
+
| [dispatch-surface.md](references/dispatch-surface.md) | Native subagent vs `spur agent run` decision rule: default, four escalation triggers, naming requirement, ADR-033 composition, sandbox reliability tax |
|
|
133
|
+
|
|
134
|
+
## See also
|
|
135
|
+
|
|
136
|
+
- **`sp:spur-dev`** — the orchestration spine that consults this skill for fan-out decisions.
|
|
137
|
+
- **`sp:super-planner`** — the batch orchestrator that executes fan-out patterns.
|
|
138
|
+
- **`/sp:dev-parallel`** — the slash command entry point for parallel execution.
|
|
139
|
+
|
|
140
|
+
## Platform Notes
|
|
141
|
+
|
|
142
|
+
### Claude Code
|
|
143
|
+
|
|
144
|
+
Native - `Skill()`/`Task()` delegation for subagent spawns. The decision framework is consumed by the agent in-session; fan-out execution uses the **native subagent by default** and escalates to `spur agent run <prompt> --agent <name>` only when a named trigger in [dispatch-surface.md](references/dispatch-surface.md) applies.
|
|
145
|
+
|
|
146
|
+
### Codex / OpenClaw / OpenCode / Antigravity
|
|
147
|
+
|
|
148
|
+
Run the decision framework manually; spawn subagents via the platform's native multi-agent mechanism. Parse `--json` outputs for result synthesis.
|