@gobing-ai/spur 0.3.40 → 0.3.42

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 (185) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/README.md +15 -1
  3. package/config/templates/AGENTS.md +5 -3
  4. package/config/workflows/task-pipeline.yaml +103 -12
  5. package/package.json +15 -12
  6. package/plugins/README.md +655 -0
  7. package/plugins/sp/README.md +621 -0
  8. package/plugins/sp/agents/expert-spur.md +109 -0
  9. package/plugins/sp/agents/super-coder.md +126 -0
  10. package/plugins/sp/agents/super-planner.md +283 -0
  11. package/plugins/sp/agents/super-reviewer.md +154 -0
  12. package/plugins/sp/commands/dev-arch.md +30 -0
  13. package/plugins/sp/commands/dev-brainstorm.md +40 -0
  14. package/plugins/sp/commands/dev-changelog.md +28 -0
  15. package/plugins/sp/commands/dev-daily.md +29 -0
  16. package/plugins/sp/commands/dev-debug.md +29 -0
  17. package/plugins/sp/commands/dev-dogfood.md +33 -0
  18. package/plugins/sp/commands/dev-featurechange.md +130 -0
  19. package/plugins/sp/commands/dev-find-conflict.md +51 -0
  20. package/plugins/sp/commands/dev-find-issue.md +76 -0
  21. package/plugins/sp/commands/dev-find-next.md +60 -0
  22. package/plugins/sp/commands/dev-fixall.md +33 -0
  23. package/plugins/sp/commands/dev-gitmsg.md +28 -0
  24. package/plugins/sp/commands/dev-gtd.md +97 -0
  25. package/plugins/sp/commands/dev-handover.md +26 -0
  26. package/plugins/sp/commands/dev-idea.md +50 -0
  27. package/plugins/sp/commands/dev-next.md +31 -0
  28. package/plugins/sp/commands/dev-parallel.md +30 -0
  29. package/plugins/sp/commands/dev-plan.md +46 -0
  30. package/plugins/sp/commands/dev-refine.md +48 -0
  31. package/plugins/sp/commands/dev-refineall.md +65 -0
  32. package/plugins/sp/commands/dev-refresh.md +32 -0
  33. package/plugins/sp/commands/dev-reverse.md +32 -0
  34. package/plugins/sp/commands/dev-review.md +31 -0
  35. package/plugins/sp/commands/dev-run.md +63 -0
  36. package/plugins/sp/commands/dev-runall.md +80 -0
  37. package/plugins/sp/commands/dev-simplify.md +39 -0
  38. package/plugins/sp/commands/dev-unit.md +29 -0
  39. package/plugins/sp/commands/dev-verify.md +48 -0
  40. package/plugins/sp/commands/dev-verifyall.md +72 -0
  41. package/plugins/sp/commands/dev-wrap.md +30 -0
  42. package/plugins/sp/commands/dev-wrapall.md +33 -0
  43. package/plugins/sp/commands/rule-add.md +18 -0
  44. package/plugins/sp/commands/rule-refine.md +18 -0
  45. package/plugins/sp/commands/rule-scan.md +18 -0
  46. package/plugins/sp/commands/spur-init.md +22 -0
  47. package/plugins/sp/commands/workflow-add.md +18 -0
  48. package/plugins/sp/commands/workflow-refine.md +18 -0
  49. package/plugins/sp/hooks/agent-hint.ts +60 -0
  50. package/plugins/sp/hooks/careful-guard.ts +147 -0
  51. package/plugins/sp/hooks/context-post-tool.ts +325 -0
  52. package/plugins/sp/hooks/context-session-start.ts +182 -0
  53. package/plugins/sp/hooks/context-session-stop.ts +95 -0
  54. package/plugins/sp/hooks/hooks.json +51 -0
  55. package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
  56. package/plugins/sp/hooks/task-write-guard.ts +84 -0
  57. package/plugins/sp/plugin.json +8 -0
  58. package/plugins/sp/scripts/batch-preflight.ts +204 -0
  59. package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
  60. package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
  61. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
  62. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
  63. package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
  64. package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
  65. package/plugins/sp/scripts/task-size-precheck.ts +202 -0
  66. package/plugins/sp/scripts/validate-commands.ts +651 -0
  67. package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
  68. package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
  69. package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
  70. package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
  71. package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
  72. package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
  73. package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
  74. package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
  75. package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
  76. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
  77. package/plugins/sp/skills/code-implementation/SKILL.md +176 -0
  78. package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
  79. package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
  80. package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
  81. package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
  82. package/plugins/sp/skills/code-review/SKILL.md +112 -0
  83. package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
  84. package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
  85. package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
  86. package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
  87. package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
  88. package/plugins/sp/skills/code-testing/SKILL.md +108 -0
  89. package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
  90. package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
  91. package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
  92. package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
  93. package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
  94. package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
  95. package/plugins/sp/skills/code-verification/SKILL.md +535 -0
  96. package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
  97. package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
  98. package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
  99. package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
  100. package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
  101. package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
  102. package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
  103. package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
  104. package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
  105. package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
  106. package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
  107. package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
  108. package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
  109. package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
  110. package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
  111. package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
  112. package/plugins/sp/skills/functional-review/SKILL.md +364 -0
  113. package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
  114. package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
  115. package/plugins/sp/skills/issue-finding/SKILL.md +424 -0
  116. package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
  117. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
  118. package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
  119. package/plugins/sp/skills/issue-finding/references/session-formats.md +121 -0
  120. package/plugins/sp/skills/next-feature/SKILL.md +125 -0
  121. package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
  122. package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
  123. package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
  124. package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
  125. package/plugins/sp/skills/next-router/SKILL.md +181 -0
  126. package/plugins/sp/skills/next-router/references/messages.md +90 -0
  127. package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
  128. package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
  129. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +100 -0
  130. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
  131. package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
  132. package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
  133. package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
  134. package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
  135. package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
  136. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
  137. package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
  138. package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
  139. package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
  140. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
  141. package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
  142. package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
  143. package/plugins/sp/skills/spur-cli/references/features.md +234 -0
  144. package/plugins/sp/skills/spur-cli/references/init.md +119 -0
  145. package/plugins/sp/skills/spur-cli/references/message.md +98 -0
  146. package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
  147. package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
  148. package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
  149. package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
  150. package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
  151. package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
  152. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
  153. package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
  154. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
  155. package/plugins/sp/skills/spur-cli/references/tasks.md +278 -0
  156. package/plugins/sp/skills/spur-cli/references/team.md +133 -0
  157. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
  158. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
  159. package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
  160. package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
  161. package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
  162. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
  163. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +664 -0
  164. package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
  165. package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
  166. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
  167. package/plugins/sp/skills/spur-dev/references/execution-batch.md +727 -0
  168. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +350 -0
  169. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
  170. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
  171. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
  172. package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
  173. package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
  174. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +88 -0
  175. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
  176. package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
  177. package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
  178. package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
  179. package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
  180. package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
  181. package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
  182. package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
  183. package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
  184. package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
  185. package/spur.js +6093 -5180
@@ -0,0 +1,350 @@
1
+ ---
2
+ name: execution-workflow
3
+ description: "Extracted section: the execution half — task selection → pipeline run → HITL surfacing → continue. How operations SEQUENCE in the task pipeline; per-operation definitions live in dev-operations.md, not here."
4
+ see_also:
5
+ - spur-dev
6
+ - dev-operations
7
+ ---
8
+
9
+ # Execution Workflow
10
+
11
+ ```
12
+ pick task (spur task list --json)
13
+ → interactive omit/inline: host driver reads task-pipeline.yaml and walks it in-session
14
+ → explicit/headless executor: spur workflow run task-pipeline.yaml
15
+ → on HITL pause: surface to operator → resume the selected driver
16
+ ```
17
+
18
+ The execution half runs a single task through the `task-pipeline.yaml` FSM. In an interactive
19
+ omit/inline invocation, the skill's host driver interprets that YAML directly. Explicit executors
20
+ and headless invocations use the workflow engine. Both surfaces preserve the same actions, guards,
21
+ artifacts, HITL gates, and terminal states.
22
+
23
+ > **Single-task vs batch.** This file covers the **single-task** execution half — one task through
24
+ > `task-pipeline.yaml`. For **batch** execution (a set of tasks in dependency-correct order), see
25
+ > **[execution-batch.md](execution-batch.md)** — it layers set resolution, topological ordering, a
26
+ > failure policy, and a batch report on top of this same verbatim pipeline, driven by the
27
+ > `sp:super-planner` orchestrator via `/sp:dev-runall`.
28
+
29
+ This file owns **how operations sequence** in the pipeline. What each operation *does*
30
+ (`implement`, `unit`, `review`, `verify`) is defined once in
31
+ [dev-operations.md](dev-operations.md) — this file links to it rather than restating it.
32
+
33
+ > **`/sp:dev-run` drives the pipeline — it is NEVER a pipeline step.** The command
34
+ > `/sp:dev-run <wbs>` means "run this whole pipeline" (default `--mode full`). The pipeline's
35
+ > internal stages call `/sp:dev-run --mode implement`, shell quality gate + optional
36
+ > `/sp:dev-fixall`, `/sp:dev-review`, `/sp:dev-verify` — never `/sp:dev-run` in full mode.
37
+ > Calling `/sp:dev-run --mode full` from inside the `implement` step would recurse into another
38
+ > full pipeline run. The `implement` step is the **implement operation** (dev-operations.md §4);
39
+ > the verify step is `sp:code-verification`.
40
+
41
+ ## The pipeline's internal stages
42
+
43
+ Each stage maps to one operation. The pipeline calls the operation; the operation does exactly
44
+ one thing and yields, so the **pipeline (not the agent) owns the loop**.
45
+
46
+ | Stage | Operation | Defined in |
47
+ | ------- | ----------- | ------------ |
48
+ | `implement` | `/sp:dev-run --mode implement <wbs>` — write the code that satisfies the task; author `## Solution`. | [dev-operations.md §4 run](dev-operations.md) → `sp:code-implementation` |
49
+ | `test` → (`test-fix` ↔ `test-recheck`) → `review` \| `failed` | **Project quality gate** (not `/sp:dev-unit`). Soft shell probe of `${vars.qualityGateCmd}` (default `bun run autofix && bun run spur-check`) — green path pays **one** full gate run. On FAIL: bounded `/sp:dev-fixall` loop (`qualityGateMaxFixAttempts`, default 2) with soft recheck; exhausted attempts route to pipeline `failed`. `/sp:dev-unit` remains **coverage gap-fill** (router C3/C5 / standalone). | [dev-operations.md §10 fixall](dev-operations.md); unit op still §1 |
50
+ | `review` | `/sp:dev-review <wbs>` — SECUA-framework review of the diff. | [dev-operations.md §2 review](dev-operations.md) |
51
+ | `verify` | `sp:code-verification` — requirements traceability + verdict. | [dev-operations.md §3 verify](dev-operations.md) |
52
+
53
+ Interactive omit/`inline` executes these model stages through the
54
+ [inline pipeline driver](inline-pipeline-driver.md) in the host session and records stage/session
55
+ provenance. `--agent <name|auto>`, parallel batches, and headless workflow invocation select the
56
+ existing subprocess actions. Direct invocations of the same dev operations remain inline by
57
+ default. See the [inline-default execution-surface contract](cross-cutting.md#inline-default-execution-surface).
58
+
59
+ > **Single-run & parse discipline (suite run cost control).** Run full quality/test suites (`bun run check` / `spur-check`) at most ONCE per task iteration (task 0436 R2). Parse failure details from the single retained command output rather than re-running full suites repeatedly to inspect errors. Re-run targeted/narrow test files (e.g. `bun test <file> --test-name-pattern <pattern>`) while iterating on fixes, and re-run the full suite only when all targeted fixes pass.
60
+
61
+ ## Section ownership — `## Solution`
62
+
63
+ The implement step **owns** `## Solution` (the change-map). After writing code, before
64
+ yielding, the implement agent authors the `## Solution` section — a markdown table listing
65
+ each changed file with a `file:line` range and a one-line `what/why` summary — and writes it
66
+ via `spur task update <wbs> --section Solution --from-file <tmp>`. Write **only when the
67
+ section is bare** (absent, empty, or a known pipeline placeholder); never clobber a
68
+ hand-authored change-map. The `replaceSection` upsert guarantees missing→add,
69
+ present→replace, never duplicate. If the implement agent forgets, the pipeline's `record`
70
+ step backfills a minimal change-map from `git diff --name-only` as a safety net.
71
+
72
+ ## Step 1: Task selection
73
+
74
+ ```bash
75
+ spur task list --status backlog --json
76
+ spur task list --status wip --json
77
+ ```
78
+
79
+ Pick a task. Priority order: WIP tasks first (continue in-progress work), then highest-priority
80
+ backlog tasks. Use `--json` for machine consumption; sort client-side by priority/created_at.
81
+
82
+ **Reuse in-context task state.** Once a task's `show`/`check` output is in your context this
83
+ session, do not re-fetch it for data you already hold — reference the prior result. Re-fetch only
84
+ when the underlying state changed (e.g. you just wrote a section and need the new
85
+ `requiredSections`). When you must fetch, ask for the smallest shape (`--json`, one field), not the
86
+ full human dump. This keeps the programmatic drive's cache hit rate high; see the dogfood
87
+ cache-conservation discipline (`plugins/sp/skills/dogfood-testing/references/monitor-ledger.md`).
88
+
89
+ ## Step 2: Pipeline run
90
+
91
+ > **Pre-launch size-gate pre-check (R1 / 0478).** Before launching `spur workflow run task-pipeline.yaml`, probe the task's `## Plan` checklist item count (`spur task show <wbs> --json`). The default cap is 8 items (`maxImplementPlanItems: 8`). If the plan item count exceeds 8:
92
+ > - Without `--auto`: warn the operator before calling `spur workflow run` and prompt for confirmation or a plan-item override via `--vars '{"maxImplementPlanItems":"<count>"}'`.
93
+ > - With `--auto`: automatically append `"maxImplementPlanItems": "<count>"` to `--vars` and log a single-line notice (e.g. `Notice: task <wbs> has N plan items (>8 default cap); injecting maxImplementPlanItems override`).
94
+
95
+ **Choose the surface before execution.** In an interactive `/sp:dev-run --mode full` invocation,
96
+ omit/`--agent inline` selects the [inline pipeline driver](inline-pipeline-driver.md). Read the YAML
97
+ at invocation time, allocate the inline run id/session provenance, record `task run-link`, and walk
98
+ its actions/guards in declaration order. Do not call `spur workflow run` on this path. `--agent auto`,
99
+ a named executor, an explicit `vars.agent`/`vars.implementAgent`, or a headless caller selects the
100
+ workflow subprocess path below. Never fall back silently from inline to `agent.default`.
101
+
102
+ **Subprocess path: launch async, observe with a single `--follow` call.** A pipeline with `agent.run` stages runs
103
+ for many minutes (each stage can take the full `stepTimeoutMs`, default 10 min). Synchronous
104
+ invocation blocks the caller for the entire duration and risks an orphaned run if the caller is
105
+ interrupted (sync-orphan, see task 0127). Always launch with `--async`, then wait with
106
+ `spur workflow trace --follow`:
107
+
108
+ ```bash
109
+ # Async launch + single blocking --follow call (recommended).
110
+ # Full-mode `--auto` runs set profile=auto in the vars; pass --agent to merge the executor.
111
+ VARS=$(jq -nc --arg wbs "$WBS" --arg profile auto '{wbs:$wbs, profile:$profile}')
112
+ # optional, when --agent <name|auto> is set:
113
+ # VARS=$(jq -nc --arg wbs "$WBS" --arg profile auto --arg agent "$AGENT" \
114
+ # '{wbs:$wbs, profile:$profile, agent:$agent}')
115
+ RUN=$(spur workflow run .spur/workflows/task-pipeline.yaml --vars "$VARS" --async --json | jq -r '.runId')
116
+ spur workflow trace "$RUN" --follow --output # streams the run; --output shows the agent log surface
117
+ ```
118
+
119
+ **`--follow` is the default wait mechanism — never a manual sleep-poll loop, never `| tail`.** A
120
+ `sleep N && spur workflow trace` loop with escalating sleeps reimplements `--follow` badly, and
121
+ `trace --follow | tail` buffers through a pipe and hides the live surface (task 0421's sessions
122
+ burned ~110 min in 47 sleeps and 55 trace polls waiting on one run; ADR-047 mandates pipe-free
123
+ observation). `--follow` is a blocking human-streaming mode (no `--json`); run it in the session
124
+ background and let its exit report the terminal verdict. Use `spur workflow trace "$RUN" --follow
125
+ --output` to stream the non-interactive agent output to `.spur/run/<runId>.log` as it lands.
126
+
127
+ Synchronous invocation (`--json` without `--async`) is acceptable **only** for short pipelines
128
+ (< 2 min, e.g. precheck-only or a dry-run). Do not use it for the full task pipeline.
129
+
130
+ On the subprocess path, when `--agent <value>` is set (passed through from the thin wrapper), merge it into the vars as
131
+ **both** `agent` and `implementAgent` (task 0483 R2):
132
+ `--vars '{"wbs":"<wbs>","agent":"<value>","implementAgent":"<value>"}'`. The pipeline YAML reads
133
+ `${vars.agent}` for review/verify/test-fix and `${vars.implementAgent}` for implement — setting
134
+ both keys ensures the pinned executor reaches every hop. The full value-semantics contract (one
135
+ rule, value table, objective triggers, and headless `inline`→`agent.default` resolution per ADR-047)
136
+ lives in [cross-cutting.md](cross-cutting.md#inline-default-execution-surface) — the SSOT.
137
+ This file documents only the **workflow-pipeline mechanics**: how the selector reaches `agent.run`
138
+ steps. Precedence chain: `--agent` / explicit `--vars` → `agent.default` → YAML literal (see SSOT
139
+ § "Executor precedence chain").
140
+
141
+ **Mode is explicit before dispatch.** The full pipeline is selected by default or by `--mode full`;
142
+ the implement step is selected only by `--mode implement`. `--next` controls lifecycle chaining and
143
+ never changes this choice. In particular, every pipeline implement-stage prompt must contain the
144
+ literal `/sp:dev-run <wbs> --mode implement`; omitting the mode would recursively launch the full
145
+ pipeline (bug-742).
146
+
147
+ The pipeline (`kind: state-machine`) runs the work loop:
148
+
149
+ ```
150
+ precheck → implement → test [→ test-fix → test-recheck] → review → approve(HITL) → verify → record → done
151
+ ```
152
+
153
+ Agentic steps use the pure slash inputs declared by each YAML `agent.run` action (ADR-043). The
154
+ workflow engine dispatches them; the interactive driver invokes their backing skills in-session.
155
+ The `test` hop is primarily
156
+ **deterministic shell** (quality gate); only the optional `test-fix` hop is agentic
157
+ (`/sp:dev-fixall`). The skill monitors the run:
158
+
159
+ - **On HITL pause** (`approve` state): surface the review output to the operator. On the subprocess
160
+ path use `spur workflow continue <run-id> --yes`; on the inline path retain the current state and
161
+ resume the host driver with the operator's answer.
162
+ - **On guard failure** (`precheck`): the task's check findings block progress — fix the
163
+ task first.
164
+ - **On completion** (`done`): the pipeline's `record` step has already written results into
165
+ the task's `## Testing` and `## Review` sections via `spur task record <wbs>` (verdict →
166
+ matrix-compliant tables; never transitions to `done` — the gate stays in the workflow).
167
+
168
+ ## `--next` chain — advance to the next step
169
+
170
+ `--next` makes an explicit `/sp:dev-run <wbs> --mode implement` invocation one link in the linear
171
+ execution chain (`refine → run → verify → done`), not the whole-pipeline driver. It never selects
172
+ the implement step by itself. The headline chain link is therefore
173
+ `/sp:dev-run <wbs> --mode implement --auto --next`.
174
+
175
+ When `--next` is set and implementation succeeds:
176
+
177
+ 0. **Backlog promotion (chain step 0).** If the task's current status is `backlog`, the chain
178
+ first auto-promotes `backlog → todo` via `spur task update <wbs> todo`. The FSM permits this
179
+ transition unguarded (no section gate), so the promotion is pure ceremony — but the chain
180
+ performs it explicitly rather than surfacing a raw `GuardDeniedError: No transition from
181
+ "backlog" to "wip"`. `--auto --next` already expresses the operator's intent to drive the
182
+ task, so the mechanical two-hop (`backlog → todo → wip`) is correct behavior, not a bypass:
183
+ the lifecycle guard stays authoritative for every subsequent transition. If the promotion
184
+ itself fails, stop as review-pending and include both the FSM error and the concrete remediation
185
+ `spur task update <wbs> todo`; never surface a raw `GuardDeniedError` unaided.
186
+ 1. **Transition through the FSM (guards honored — no `--no-lifecycle`):**
187
+ - `spur task update <wbs> wip` — the `todo → wip` guard is `always`; passes.
188
+ - `spur task update <wbs> testing` — the `wip → testing` guard runs `spur task check <wbs>`.
189
+ 2. **Record provenance** — `spur task run-link <wbs> --source next-auto --json`. Writes a
190
+ `kind: pipeline` entry into `task_run_links` so the `testing → done` provenance guard
191
+ (lifecycle-adapter.ts L106-131) accepts the in-session implementation path. Idempotent:
192
+ safe to call even when a pipeline link already exists.
193
+ 3. **On a clean transition:** invoke `/sp:dev-verify <wbs> --auto --next` (`--auto` propagates
194
+ down the whole chain). The verify step's `--next` transition to `done` now passes the
195
+ provenance guard because step 2 recorded the link.
196
+ 4. **On a guard failure — stop as review-pending:** leave the task at its current status, surface
197
+ the blocking reason (e.g. a missing `## Solution` section that fails `spur task check`), and do
198
+ NOT invoke dev-verify. The chain halts here for the operator to resolve, exactly like the
199
+ pipeline's precheck/HITL gates.
200
+
201
+ ```
202
+ review pending — wip → testing guard failed for <wbs>
203
+ spur task check reported: <blocking finding, e.g. "## Solution section is empty">
204
+ task left at wip. Resolve the finding, then re-run: /sp:dev-run <wbs> --mode implement --auto --next
205
+ ```
206
+
207
+ **Status precondition (R2).** The chain assumes the task is at `todo` or later when step 0 is
208
+ absent — i.e. the operator has already moved it off `backlog` via `spur task update <wbs> todo`
209
+ during refinement. Step 0's auto-promote covers the case where they did not: a `backlog`-seeded
210
+ task with `--next` is promoted mechanically rather than denied (`--auto` only controls objective
211
+ confirmations). There is no refusal path for `backlog` when `--next` is present. To retain manual
212
+ status control, omit `--next` and promote explicitly with `spur task update <wbs> todo` before a
213
+ later chained run.
214
+
215
+ Honoring the guard is the point: the FSM is what stops a malformed task from sliding into `testing`
216
+ and then `done`. Keep chain transitions on the plain verb so the *lifecycle run* is recorded as
217
+ well — `--no-lifecycle` (which the pipeline uses for its own internal transitions, being a run
218
+ already) suppresses that record. Since 2026-08-07 it no longer suppresses the structural gate: the
219
+ CLI evaluates `spur task check` inline whenever the FSM guard will not, so the review-pending stop
220
+ survives the flag.
221
+
222
+ ## Mode resolution (deterministic — run before dispatch)
223
+
224
+ Mode is decided mechanically from `$ARGUMENTS`; `--next` is not part of mode resolution.
225
+
226
+ | `$ARGUMENTS` carries | Resolved mode | Dispatch |
227
+ | --- | --- | --- |
228
+ | `--mode full` (with or without `--next`) | `full` | `run $ARGUMENTS` |
229
+ | `--mode implement` (with or without `--next`) | `implement` | `implement $ARGUMENTS` |
230
+ | neither (default) | `full` | `run $ARGUMENTS` |
231
+
232
+ Pipeline stage **`agent.run` inputs** are pure slash commands (ADR-043) that always carry
233
+ `--mode implement` on implement; relying on `--next` to select the step is the recursive-pipeline
234
+ defect fixed by bug-742. Anti-recursion prose lives in `/sp:dev-run` + `sp:code-implementation`,
235
+ not in YAML `input:` essays.
236
+
237
+ ## Infrastructure failure recognition (mandatory)
238
+
239
+ On the subprocess path, an `agent.run` step timeout (default 600s) or non-zero exit is an **infrastructure signal**,
240
+ not a license to bypass the pipeline. The execution pipeline must not be abandoned because
241
+ an executor failed — the executor is swappable via config, the pipeline is not.
242
+
243
+ **When an `agent.run` step fails (timeout, non-zero exit, empty output):**
244
+
245
+ 1. **Diagnose, don't bypass.** Check `spur agent doctor <executor>` — is the agent
246
+ installed? Is auth present? Then check `.spur/config.yaml` → which executor does the
247
+ phase resolve to? Which model does that executor use? Could that model be out of tokens,
248
+ rate-limited, or deprecated?
249
+ 2. **Switch executors, don't abandon the pipeline.** Override the agent for the run:
250
+ `spur workflow run ... --vars '{"wbs":"<wbs>","agent":"<alt-executor>"}'` or re-run with
251
+ a different `default-by-phase` mapping. The operator can also update config in-flight.
252
+ 3. **Surface to the operator.** If you cannot determine the cause, ask. Do NOT silently
253
+ fall back to direct implementation. A pipeline step failure is a recoverable event; a
254
+ bypass is an irrecoverable provenance loss.
255
+ 4. **Never use ad-hoc direct implementation as a fallback.** The authorized interactive host
256
+ driver is not a bypass: it reads the YAML, records provenance, and executes `record → done`.
257
+ Manual section fills outside either driver are indistinguishable from pipeline output and bypass
258
+ the provenance contract silently.
259
+
260
+ **Known diagnostic gap:** `spur agent doctor` checks installation, version, and auth — it
261
+ cannot detect token quota exhaustion, model deprecation, or rate limits. An executor
262
+ configured with `agent: omp` + `model: <provider/model>` passes doctor if `omp` is
263
+ installed, even if the model is unavailable. If an `agent.run` times out with no useful
264
+ diagnostic, suspect the model, not the agent binary.
265
+
266
+ ## Large tasks and timed-out implement resume (task 0424)
267
+
268
+ Two obligations when driving a task that may not fit one implement pass.
269
+
270
+ **1. Split oversized tasks before pipeline execution.** A single `implement` `agent.run`
271
+ has a bounded budget (`implementTimeoutMs`); a task whose requirements cannot plausibly fit
272
+ that pass must be split into multiple tasks before `spur workflow run`, not found out at the
273
+ timeout wall. Heuristics: > 10 requirements, a change spanning > 8 files, or a multi-module
274
+ frontend/backend surface → decompose. The plan step owns this; if a task is already running
275
+ and oversized, stop and split rather than raise the budget (task 0398 R4: "stop and record
276
+ rather than raise again without sign-off").
277
+
278
+ **2. Timed-out implement — resume from the partial tree, don't restart.** A timeout kills the
279
+ implement `agent.run` (exit 3), the pipeline routes to `failed`, and the task stays `todo` with
280
+ the partial work still in the working tree. The failure output names the partial-work artifact
281
+ (`.spur/run/<runId>-implement-partial.md`) and this runbook. Recovery:
282
+
283
+ 1. **Recognise.** `.spur/run/<runId>-implement-partial.md` exists, the run reported `exited
284
+ with code 3`, the task is at `todo`. The artifact's `git diff --stat` section is the partial
285
+ work inventory.
286
+ 2. **Establish green from the partial files.** `bun run format` then `bun run lint` + `bun
287
+ test` (or the affected packages). Fix mechanical formatting/type fallout first; the partial
288
+ tree is the baseline, not a code review target.
289
+ 3. **Resume the remaining requirements against that tree.** Re-run the implement step with the
290
+ partial diff as explicit context — hand the continuation agent `git diff` (the partial
291
+ changes) and the remaining requirement list, and tell it to complete, not restart. The
292
+ task's `## Solution` is then backfilled from `git diff --name-only`.
293
+ 4. **Finish via the normal gate, or force-done.** If the resumed implement completes, run it
294
+ through the pipeline/verify gate normally. If the work is manually completed and the
295
+ pipeline is not worth re-driving, use the force-done recovery in
296
+ [`done-housekeeping.md`](done-housekeeping.md) F6 — it carries the provenance obligations
297
+ (honest `done_reason`, verdict regeneration).
298
+
299
+ **3. Match the executor to the size (task 0487 R3).** Size and executor capability are one
300
+ decision, not two. **≥ 6 requirements or ≥ 9 Plan items → a `capable-1`+ executor, or split the
301
+ task.** A `cheap`/`standard`-tier model handed a task that big does not fail fast: it consumes the
302
+ entire `implementTimeoutMs` and exits 3 with a partial tree (run `ca130182` — 7 reqs / 9 plan
303
+ items / 12+ files → 30 minutes, 6 of 12 files, no tests, no docs, no `## Solution`).
304
+
305
+ The precheck size gate enforces this: it resolves `$implementAgent`'s capability tier
306
+ (`spur agent doctor <exec> --json` → `capabilityTier`) and writes FAIL for a large task on a
307
+ sub-`capable-1` executor, naming the executor and its tier. An unknown or undeclared tier reads as
308
+ `standard`, so the block is the default. Clear it deliberately — `--agent <capable>` /
309
+ `--vars '{"implementAgent":"<capable>"}'`, or split — never by raising `maxImplementReqs`: the caps
310
+ accept a big task, they do not make a flash model able to finish one.
311
+
312
+ The empty-implement guard (`requireDiff` on the task-pipeline `implement` step, R3) fails the
313
+ run fast when an implement exits 0 with zero non-corpus changes — a no-op never drifts into
314
+ `test`/`review`. A no-op is an implement-input defect, not a resume case: fix the input and
315
+ re-run. The same gate checks diff *scope* (task 0487 R1): changes outside the files and explicit
316
+ directory/glob prefixes the task body backticks fail the step by name; new files beside a declared
317
+ file are allowed, and a pre-dispatch snapshot prevents pre-existing dirt from being charged to the
318
+ implementer. Bypass only with a deliberate
319
+ `--vars '{"implementScopeGuard":"off"}'`.
320
+
321
+ ## Checkpoint read on resume
322
+
323
+ When resuming a paused or interrupted pipeline run (`--continue`), read the latest checkpoint
324
+ from `.spur/memory/sessions/` before re-launching:
325
+
326
+ ```bash
327
+ ls -t .spur/memory/sessions/*-${wbs}-*.md 2>/dev/null | head -1
328
+ ```
329
+
330
+ The checkpoint's YAML frontmatter contains `session_id`, `workflow`, `task_wbs`, `phase`,
331
+ `last_gate`, `timestamp`, and `next_action`. Surface `next_action` to the operator so they
332
+ know where the run left off and what to do next. Checkpoints are written by the pipeline's
333
+ checkpoint actions after every HITL gate decision and every phase transition. See
334
+ [cross-cutting.md](cross-cutting.md) § "Session Checkpoint Convention" for the full format.
335
+
336
+ ## Step 3: Continue
337
+
338
+ After a completed task, decide next action:
339
+
340
+ - **More tasks in the feature?** Pick the next one, run again.
341
+ - **Feature complete?** Run `spur feature update <id> verifying` to mark it for
342
+ acceptance verification.
343
+ - **All done?** Run `spur task refresh` + `spur feature refresh` to regenerate the kanban
344
+ and index.
345
+
346
+ ## Skipping HITL
347
+
348
+ Passing `--vars '{"profile":"auto"}'` to `spur workflow run` (a var choice, not a YAML fork) skips
349
+ the `approve` HITL gate — use for low-risk, well-understood tasks where operator review adds no value.
350
+ (Combine with `wbs` in one object: `--vars '{"wbs":"0042","profile":"auto"}'`.)
@@ -0,0 +1,191 @@
1
+ ---
2
+ name: feature-link-helper
3
+ description: "Opt-in, strictness-triggered feature-link helper for sp:spur-dev. Resolves a deferred feature_id edge when the operator explicitly invokes --strict rigor or asks to link a task to a feature. Single-task mode (LLM-judge match + confirm) and batch-sweep mode (audit all orphan tasks). Never gate-time, never automatic, always confirm before applying."
4
+ see_also:
5
+ - spur-dev
6
+ - cross-cutting
7
+ ---
8
+
9
+ # Feature-Link Helper
10
+
11
+ **Scope:** opt-in, strictness-triggered — never gate-time, never automatic.
12
+
13
+ This helper resolves a deferred `feature_id` edge when the operator explicitly invokes or intends
14
+ `--strict` rigor, or asks to "link this task to a feature." It is **NOT** part of the `--strict-core`
15
+ done-gate, NOT in any `--next` chain, and NOT triggered automatically. Invoking it is always an
16
+ explicit operator choice.
17
+
18
+ **Design boundaries (enforced):**
19
+
20
+ - `feature_id: null` is a valid, supported state under the default done-gate (`--strict-core`). Deferral is legitimate.
21
+ - This helper fires only when the operator opts in — it does NOT change the L4 warning severity.
22
+ - It NEVER creates a new feature without operator confirmation.
23
+ - It ALWAYS prefers matching an **existing** feature before proposing creation.
24
+ - Declining leaves `feature_id` blank — deferral preserved.
25
+
26
+ ## When to use
27
+
28
+ - The operator runs (or intends to run) `spur task check <wbs> --strict` and the `feature_id` error surfaces.
29
+ - The operator explicitly asks to "link this task to a feature" or "assign a feature to this task."
30
+ - A deliberate traceability audit: `spur task check --strict` across the corpus reveals N orphan tasks.
31
+
32
+ **Do NOT invoke from:**
33
+ - The `--strict-core` done-gate (it must stay feature_id-agnostic)
34
+ - Any `--next` chain or automated pipeline step
35
+ - Any context where the operator has not explicitly requested strict rigor or linking
36
+
37
+ ## Post-PASS Verification Feature Sync & Deferral
38
+
39
+ When `/sp:dev-verify <wbs>` produces a `PASS` verdict:
40
+
41
+ 1. **Task has `feature_id`**:
42
+ - Run `spur feature sync <id> --dry-run --json` to generate the proposed status transition.
43
+ - Present the derivation proposal to the operator (showing current status, target status, and derivation reason).
44
+ - Confirm with the operator before executing `spur feature sync <id>` (in `--auto` mode, apply forward-only proposals).
45
+
46
+ 2. **Task missing `feature_id`**:
47
+ - Check if `feature_link_declined: true` is set on the task frontmatter (`spur task show <wbs> --json`).
48
+ - If `feature_link_declined: true`: skip linking prompt — explicit operator deferral is preserved.
49
+ - If unlinked and not declined: propose candidate existing features via single-task mode.
50
+ - If operator explicitly declines: record `feature_link_declined: true` via `spur task update <wbs> --field feature_link_declined --value true`.
51
+
52
+ ## Single-task mode
53
+
54
+ Use when the operator has a specific task in mind.
55
+
56
+ ### Step a — Read the task
57
+
58
+ ```bash
59
+ spur task show <wbs> --json
60
+ ```
61
+
62
+ Read the task's Background, Requirements, and Acceptance Criteria to understand what it does.
63
+
64
+ ### Step b — List existing features (candidate set)
65
+
66
+ ```bash
67
+ spur feature list --json
68
+ ```
69
+
70
+ Get the list of active/planning features (typically ~19 real features in this corpus). Read any
71
+ plausible candidate with `spur feature show <id> --json` to compare AC scope.
72
+
73
+ ### Step c — LLM-judge match (prefer existing)
74
+
75
+ Reason about which **existing** feature this task belongs to:
76
+
77
+ - Map the task's purpose to the feature set.
78
+ - Identify the best-fit existing feature with explicit reasoning.
79
+ - Rank alternatives if multiple are plausible.
80
+
81
+ If no existing feature is a reasonable fit, state that clearly — do not force a weak link.
82
+
83
+ ### Step d — Propose to the operator (ALWAYS show before mutating)
84
+
85
+ ```
86
+ Proposed link: task 0148 → feature F-TRACE ("Traceability hardening")
87
+ Reasoning: the task adds the feature-link helper, scoped to the traceability feature.
88
+ Alternatives: F-PLAN (planning workflow), F-OPS (operator tooling)
89
+
90
+ Apply this link? [y/n/override <id>]
91
+ ```
92
+
93
+ Wait for operator confirmation. If the operator says no or skips, **leave `feature_id` blank** —
94
+ deferral remains valid. Do not re-propose the same link.
95
+
96
+ ### Step e — Create only if necessary (and confirmed)
97
+
98
+ If no existing feature fits AND the operator confirms they want to create one:
99
+
100
+ ```bash
101
+ spur feature create "<feature name>" --json
102
+ ```
103
+
104
+ **This is a last resort.** The feature tree has ~19 real features; orphan creation pollutes it with
105
+ synthetic single-task nodes. Prefer linking to an existing feature.
106
+
107
+ ### Step f — Apply the confirmed link
108
+
109
+ ```bash
110
+ spur task update <wbs> --feature <id>
111
+ ```
112
+
113
+ Verify:
114
+
115
+ ```bash
116
+ spur task show <wbs> --json | grep feature_id
117
+ ```
118
+
119
+ ## Batch-sweep mode
120
+
121
+ Use when the operator wants to resolve `feature_id` edges across multiple orphan tasks in one pass —
122
+ typically a deliberate traceability audit.
123
+
124
+ ### Step 1 — Enumerate orphan tasks
125
+
126
+ ```bash
127
+ spur task list --json
128
+ ```
129
+
130
+ Filter to tasks where `feature_id` is null or empty. Or run `spur task check --strict` and collect
131
+ tasks with the L4 "Missing feature_id" error.
132
+
133
+ ### Step 2 — List existing features (once, cache for all proposals)
134
+
135
+ ```bash
136
+ spur feature list --json
137
+ ```
138
+
139
+ Do not re-query per orphan — use this result for all matching.
140
+
141
+ ### Step 3 — LLM-judge match per orphan
142
+
143
+ Apply Step c from single-task mode to each orphan. Build the full proposal list before presenting:
144
+
145
+ ```
146
+ Batch feature-link proposals (3 orphan tasks):
147
+ 0148 → F-TRACE ("Traceability hardening") [match: task implements the feature-link helper]
148
+ 0139 → F-PLAN ("Planning workflow") [match: task adds BDD AC generation step]
149
+ 0141 → (no good match found — skip)
150
+
151
+ Review each proposal:
152
+ 0148 → F-TRACE: [y/n/override <id>]
153
+ 0139 → F-PLAN: [y/n/override <id>]
154
+ 0141: [skip — no proposal]
155
+ ```
156
+
157
+ ### Step 4 — Per-orphan confirm/skip/override
158
+
159
+ For each orphan, the operator can:
160
+ - **`y`** — apply the proposed link
161
+ - **`n` / skip** — leave `feature_id` blank (deferral preserved, no mutation)
162
+ - **`override <id>`** — use a different feature id
163
+
164
+ ### Step 5 — Apply confirmed links (only the confirmed ones)
165
+
166
+ ```bash
167
+ spur task update <wbs> --feature <id>
168
+ ```
169
+
170
+ Skip declined/skipped orphans with no mutation. Do not re-prompt declined entries.
171
+
172
+ ### Step 6 — Report
173
+
174
+ ```
175
+ Batch sweep complete:
176
+ Applied: 0148 → F-TRACE, 0139 → F-PLAN
177
+ Skipped (deferred): 0141
178
+ Declined: (none)
179
+ ```
180
+
181
+ ## CLI primitives
182
+
183
+ | Verb | Purpose |
184
+ |------|---------|
185
+ | `spur feature list --json` | List all features (candidate set for matching) |
186
+ | `spur feature show <id> --json` | Read a specific feature's AC and description |
187
+ | `spur feature create "<name>" --json` | Create a new feature (last resort, confirm first) |
188
+ | `spur task list --json` | List all tasks (filter for `feature_id: null` orphans) |
189
+ | `spur task show <wbs> --json` | Read task context for LLM-judge matching |
190
+ | `spur task update <wbs> --feature <id>` | Apply the feature link |
191
+ | `spur task check <wbs> --strict` | Verify the link resolves the L4 error |