@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.
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 +113 -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 +83 -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 +48 -0
  42. package/plugins/sp/commands/dev-wrapall.md +51 -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 +203 -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 +442 -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 +151 -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 +109 -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 +280 -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 +680 -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 +790 -0
  168. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -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 +120 -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 +6035 -4963
@@ -0,0 +1,352 @@
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. The host is the controller; eligible `agent.run` stages may dispatch once to a native
56
+ subagent (task 0508), with host fallback and no post-dispatch replay — see the driver reference.
57
+ `--agent <name|auto>`, parallel batches, and headless workflow invocation select
58
+ the existing subprocess actions. Direct invocations of the same dev operations remain inline by
59
+ default. See the [inline-default execution-surface contract](cross-cutting.md#inline-default-execution-surface).
60
+
61
+ > **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.
62
+
63
+ ## Section ownership — `## Solution`
64
+
65
+ The implement step **owns** `## Solution` (the change-map). After writing code, before
66
+ yielding, the implement agent authors the `## Solution` section — a markdown table listing
67
+ each changed file with a `file:line` range and a one-line `what/why` summary — and writes it
68
+ via `spur task update <wbs> --section Solution --from-file <tmp>`. Write **only when the
69
+ section is bare** (absent, empty, or a known pipeline placeholder); never clobber a
70
+ hand-authored change-map. The `replaceSection` upsert guarantees missing→add,
71
+ present→replace, never duplicate. If the implement agent forgets, the pipeline's `record`
72
+ step backfills a minimal change-map from `git diff --name-only` as a safety net.
73
+
74
+ ## Step 1: Task selection
75
+
76
+ ```bash
77
+ spur task list --status backlog --json
78
+ spur task list --status wip --json
79
+ ```
80
+
81
+ Pick a task. Priority order: WIP tasks first (continue in-progress work), then highest-priority
82
+ backlog tasks. Use `--json` for machine consumption; sort client-side by priority/created_at.
83
+
84
+ **Reuse in-context task state.** Once a task's `show`/`check` output is in your context this
85
+ session, do not re-fetch it for data you already hold — reference the prior result. Re-fetch only
86
+ when the underlying state changed (e.g. you just wrote a section and need the new
87
+ `requiredSections`). When you must fetch, ask for the smallest shape (`--json`, one field), not the
88
+ full human dump. This keeps the programmatic drive's cache hit rate high; see the dogfood
89
+ cache-conservation discipline (`plugins/sp/skills/dogfood-testing/references/monitor-ledger.md`).
90
+
91
+ ## Step 2: Pipeline run
92
+
93
+ > **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:
94
+ > - Without `--auto`: warn the operator before calling `spur workflow run` and prompt for confirmation or a plan-item override via `--vars '{"maxImplementPlanItems":"<count>"}'`.
95
+ > - 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`).
96
+
97
+ **Choose the surface before execution.** In an interactive `/sp:dev-run --mode full` invocation,
98
+ omit/`--agent inline` selects the [inline pipeline driver](inline-pipeline-driver.md). Read the YAML
99
+ at invocation time, allocate the inline run id/session provenance, record `task run-link`, and walk
100
+ its actions/guards in declaration order. Do not call `spur workflow run` on this path. `--agent auto`,
101
+ a named executor, an explicit `vars.agent`/`vars.implementAgent`, or a headless caller selects the
102
+ workflow subprocess path below. Never fall back silently from inline to `agent.default`.
103
+
104
+ **Subprocess path: launch async, observe with a single `--follow` call.** A pipeline with `agent.run` stages runs
105
+ for many minutes (each stage can take the full `stepTimeoutMs`, default 10 min). Synchronous
106
+ invocation blocks the caller for the entire duration and risks an orphaned run if the caller is
107
+ interrupted (sync-orphan, see task 0127). Always launch with `--async`, then wait with
108
+ `spur workflow trace --follow`:
109
+
110
+ ```bash
111
+ # Async launch + single blocking --follow call (recommended).
112
+ # Full-mode `--auto` runs set profile=auto in the vars; pass --agent to merge the executor.
113
+ VARS=$(jq -nc --arg wbs "$WBS" --arg profile auto '{wbs:$wbs, profile:$profile}')
114
+ # optional, when --agent <name|auto> is set:
115
+ # VARS=$(jq -nc --arg wbs "$WBS" --arg profile auto --arg agent "$AGENT" \
116
+ # '{wbs:$wbs, profile:$profile, agent:$agent}')
117
+ RUN=$(spur workflow run .spur/workflows/task-pipeline.yaml --vars "$VARS" --async --json | jq -r '.runId')
118
+ spur workflow trace "$RUN" --follow --output # streams the run; --output shows the agent log surface
119
+ ```
120
+
121
+ **`--follow` is the default wait mechanism — never a manual sleep-poll loop, never `| tail`.** A
122
+ `sleep N && spur workflow trace` loop with escalating sleeps reimplements `--follow` badly, and
123
+ `trace --follow | tail` buffers through a pipe and hides the live surface (task 0421's sessions
124
+ burned ~110 min in 47 sleeps and 55 trace polls waiting on one run; ADR-047 mandates pipe-free
125
+ observation). `--follow` is a blocking human-streaming mode (no `--json`); run it in the session
126
+ background and let its exit report the terminal verdict. Use `spur workflow trace "$RUN" --follow
127
+ --output` to stream the non-interactive agent output to `.spur/run/<runId>.log` as it lands.
128
+
129
+ Synchronous invocation (`--json` without `--async`) is acceptable **only** for short pipelines
130
+ (< 2 min, e.g. precheck-only or a dry-run). Do not use it for the full task pipeline.
131
+
132
+ On the subprocess path, when `--agent <value>` is set (passed through from the thin wrapper), merge it into the vars as
133
+ **both** `agent` and `implementAgent` (task 0483 R2):
134
+ `--vars '{"wbs":"<wbs>","agent":"<value>","implementAgent":"<value>"}'`. The pipeline YAML reads
135
+ `${vars.agent}` for review/verify/test-fix and `${vars.implementAgent}` for implement — setting
136
+ both keys ensures the pinned executor reaches every hop. The full value-semantics contract (one
137
+ rule, value table, objective triggers, and headless `inline`→`agent.default` resolution per ADR-047)
138
+ lives in [cross-cutting.md](cross-cutting.md#inline-default-execution-surface) — the SSOT.
139
+ This file documents only the **workflow-pipeline mechanics**: how the selector reaches `agent.run`
140
+ steps. Precedence chain: `--agent` / explicit `--vars` → `agent.default` → YAML literal (see SSOT
141
+ § "Executor precedence chain").
142
+
143
+ **Mode is explicit before dispatch.** The full pipeline is selected by default or by `--mode full`;
144
+ the implement step is selected only by `--mode implement`. `--next` controls lifecycle chaining and
145
+ never changes this choice. In particular, every pipeline implement-stage prompt must contain the
146
+ literal `/sp:dev-run <wbs> --mode implement`; omitting the mode would recursively launch the full
147
+ pipeline (bug-742).
148
+
149
+ The pipeline (`kind: state-machine`) runs the work loop:
150
+
151
+ ```
152
+ precheck → implement → test [→ test-fix → test-recheck] → review → approve(HITL) → verify → record → done
153
+ ```
154
+
155
+ Agentic steps use the pure slash inputs declared by each YAML `agent.run` action (ADR-043). The
156
+ workflow engine dispatches them; the interactive driver invokes their backing skills in-session.
157
+ The `test` hop is primarily
158
+ **deterministic shell** (quality gate); only the optional `test-fix` hop is agentic
159
+ (`/sp:dev-fixall`). The skill monitors the run:
160
+
161
+ - **On HITL pause** (`approve` state): surface the review output to the operator. On the subprocess
162
+ path use `spur workflow continue <run-id> --yes`; on the inline path retain the current state and
163
+ resume the host driver with the operator's answer.
164
+ - **On guard failure** (`precheck`): the task's check findings block progress — fix the
165
+ task first.
166
+ - **On completion** (`done`): the pipeline's `record` step has already written results into
167
+ the task's `## Testing` and `## Review` sections via `spur task record <wbs>` (verdict →
168
+ matrix-compliant tables; never transitions to `done` — the gate stays in the workflow).
169
+
170
+ ## `--next` chain — advance to the next step
171
+
172
+ `--next` makes an explicit `/sp:dev-run <wbs> --mode implement` invocation one link in the linear
173
+ execution chain (`refine → run → verify → done`), not the whole-pipeline driver. It never selects
174
+ the implement step by itself. The headline chain link is therefore
175
+ `/sp:dev-run <wbs> --mode implement --auto --next`.
176
+
177
+ When `--next` is set and implementation succeeds:
178
+
179
+ 0. **Backlog promotion (chain step 0).** If the task's current status is `backlog`, the chain
180
+ first auto-promotes `backlog → todo` via `spur task update <wbs> todo`. The FSM permits this
181
+ transition unguarded (no section gate), so the promotion is pure ceremony — but the chain
182
+ performs it explicitly rather than surfacing a raw `GuardDeniedError: No transition from
183
+ "backlog" to "wip"`. `--auto --next` already expresses the operator's intent to drive the
184
+ task, so the mechanical two-hop (`backlog → todo → wip`) is correct behavior, not a bypass:
185
+ the lifecycle guard stays authoritative for every subsequent transition. If the promotion
186
+ itself fails, stop as review-pending and include both the FSM error and the concrete remediation
187
+ `spur task update <wbs> todo`; never surface a raw `GuardDeniedError` unaided.
188
+ 1. **Transition through the FSM (guards honored — no `--no-lifecycle`):**
189
+ - `spur task update <wbs> wip` — the `todo → wip` guard is `always`; passes.
190
+ - `spur task update <wbs> testing` — the `wip → testing` guard runs `spur task check <wbs>`.
191
+ 2. **Record provenance** — `spur task run-link <wbs> --source next-auto --json`. Writes a
192
+ `kind: pipeline` entry into `task_run_links` so the `testing → done` provenance guard
193
+ (lifecycle-adapter.ts L106-131) accepts the in-session implementation path. Idempotent:
194
+ safe to call even when a pipeline link already exists.
195
+ 3. **On a clean transition:** invoke `/sp:dev-verify <wbs> --auto --next` (`--auto` propagates
196
+ down the whole chain). The verify step's `--next` transition to `done` now passes the
197
+ provenance guard because step 2 recorded the link.
198
+ 4. **On a guard failure — stop as review-pending:** leave the task at its current status, surface
199
+ the blocking reason (e.g. a missing `## Solution` section that fails `spur task check`), and do
200
+ NOT invoke dev-verify. The chain halts here for the operator to resolve, exactly like the
201
+ pipeline's precheck/HITL gates.
202
+
203
+ ```
204
+ review pending — wip → testing guard failed for <wbs>
205
+ spur task check reported: <blocking finding, e.g. "## Solution section is empty">
206
+ task left at wip. Resolve the finding, then re-run: /sp:dev-run <wbs> --mode implement --auto --next
207
+ ```
208
+
209
+ **Status precondition (R2).** The chain assumes the task is at `todo` or later when step 0 is
210
+ absent — i.e. the operator has already moved it off `backlog` via `spur task update <wbs> todo`
211
+ during refinement. Step 0's auto-promote covers the case where they did not: a `backlog`-seeded
212
+ task with `--next` is promoted mechanically rather than denied (`--auto` only controls objective
213
+ confirmations). There is no refusal path for `backlog` when `--next` is present. To retain manual
214
+ status control, omit `--next` and promote explicitly with `spur task update <wbs> todo` before a
215
+ later chained run.
216
+
217
+ Honoring the guard is the point: the FSM is what stops a malformed task from sliding into `testing`
218
+ and then `done`. Keep chain transitions on the plain verb so the *lifecycle run* is recorded as
219
+ well — `--no-lifecycle` (which the pipeline uses for its own internal transitions, being a run
220
+ already) suppresses that record. Since 2026-08-07 it no longer suppresses the structural gate: the
221
+ CLI evaluates `spur task check` inline whenever the FSM guard will not, so the review-pending stop
222
+ survives the flag.
223
+
224
+ ## Mode resolution (deterministic — run before dispatch)
225
+
226
+ Mode is decided mechanically from `$ARGUMENTS`; `--next` is not part of mode resolution.
227
+
228
+ | `$ARGUMENTS` carries | Resolved mode | Dispatch |
229
+ | --- | --- | --- |
230
+ | `--mode full` (with or without `--next`) | `full` | `run $ARGUMENTS` |
231
+ | `--mode implement` (with or without `--next`) | `implement` | `implement $ARGUMENTS` |
232
+ | neither (default) | `full` | `run $ARGUMENTS` |
233
+
234
+ Pipeline stage **`agent.run` inputs** are pure slash commands (ADR-043) that always carry
235
+ `--mode implement` on implement; relying on `--next` to select the step is the recursive-pipeline
236
+ defect fixed by bug-742. Anti-recursion prose lives in `/sp:dev-run` + `sp:code-implementation`,
237
+ not in YAML `input:` essays.
238
+
239
+ ## Infrastructure failure recognition (mandatory)
240
+
241
+ On the subprocess path, an `agent.run` step timeout (default 600s) or non-zero exit is an **infrastructure signal**,
242
+ not a license to bypass the pipeline. The execution pipeline must not be abandoned because
243
+ an executor failed — the executor is swappable via config, the pipeline is not.
244
+
245
+ **When an `agent.run` step fails (timeout, non-zero exit, empty output):**
246
+
247
+ 1. **Diagnose, don't bypass.** Check `spur agent doctor <executor>` — is the agent
248
+ installed? Is auth present? Then check `.spur/config.yaml` → which executor does the
249
+ phase resolve to? Which model does that executor use? Could that model be out of tokens,
250
+ rate-limited, or deprecated?
251
+ 2. **Switch executors, don't abandon the pipeline.** Override the agent for the run:
252
+ `spur workflow run ... --vars '{"wbs":"<wbs>","agent":"<alt-executor>"}'` or re-run with
253
+ a different `default-by-phase` mapping. The operator can also update config in-flight.
254
+ 3. **Surface to the operator.** If you cannot determine the cause, ask. Do NOT silently
255
+ fall back to direct implementation. A pipeline step failure is a recoverable event; a
256
+ bypass is an irrecoverable provenance loss.
257
+ 4. **Never use ad-hoc direct implementation as a fallback.** The authorized interactive host
258
+ driver is not a bypass: it reads the YAML, records provenance, and executes `record → done`.
259
+ Manual section fills outside either driver are indistinguishable from pipeline output and bypass
260
+ the provenance contract silently.
261
+
262
+ **Known diagnostic gap:** `spur agent doctor` checks installation, version, and auth — it
263
+ cannot detect token quota exhaustion, model deprecation, or rate limits. An executor
264
+ configured with `agent: omp` + `model: <provider/model>` passes doctor if `omp` is
265
+ installed, even if the model is unavailable. If an `agent.run` times out with no useful
266
+ diagnostic, suspect the model, not the agent binary.
267
+
268
+ ## Large tasks and timed-out implement resume (task 0424)
269
+
270
+ Two obligations when driving a task that may not fit one implement pass.
271
+
272
+ **1. Split oversized tasks before pipeline execution.** A single `implement` `agent.run`
273
+ has a bounded budget (`implementTimeoutMs`); a task whose requirements cannot plausibly fit
274
+ that pass must be split into multiple tasks before `spur workflow run`, not found out at the
275
+ timeout wall. Heuristics: > 10 requirements, a change spanning > 8 files, or a multi-module
276
+ frontend/backend surface → decompose. The plan step owns this; if a task is already running
277
+ and oversized, stop and split rather than raise the budget (task 0398 R4: "stop and record
278
+ rather than raise again without sign-off").
279
+
280
+ **2. Timed-out implement — resume from the partial tree, don't restart.** A timeout kills the
281
+ implement `agent.run` (exit 3), the pipeline routes to `failed`, and the task stays `todo` with
282
+ the partial work still in the working tree. The failure output names the partial-work artifact
283
+ (`.spur/run/<runId>-implement-partial.md`) and this runbook. Recovery:
284
+
285
+ 1. **Recognise.** `.spur/run/<runId>-implement-partial.md` exists, the run reported `exited
286
+ with code 3`, the task is at `todo`. The artifact's `git diff --stat` section is the partial
287
+ work inventory.
288
+ 2. **Establish green from the partial files.** `bun run format` then `bun run lint` + `bun
289
+ test` (or the affected packages). Fix mechanical formatting/type fallout first; the partial
290
+ tree is the baseline, not a code review target.
291
+ 3. **Resume the remaining requirements against that tree.** Re-run the implement step with the
292
+ partial diff as explicit context — hand the continuation agent `git diff` (the partial
293
+ changes) and the remaining requirement list, and tell it to complete, not restart. The
294
+ task's `## Solution` is then backfilled from `git diff --name-only`.
295
+ 4. **Finish via the normal gate, or force-done.** If the resumed implement completes, run it
296
+ through the pipeline/verify gate normally. If the work is manually completed and the
297
+ pipeline is not worth re-driving, use the force-done recovery in
298
+ [`done-housekeeping.md`](done-housekeeping.md) F6 — it carries the provenance obligations
299
+ (honest `done_reason`, verdict regeneration).
300
+
301
+ **3. Match the executor to the size (task 0487 R3).** Size and executor capability are one
302
+ decision, not two. **≥ 6 requirements or ≥ 9 Plan items → a `capable-1`+ executor, or split the
303
+ task.** A `cheap`/`standard`-tier model handed a task that big does not fail fast: it consumes the
304
+ entire `implementTimeoutMs` and exits 3 with a partial tree (run `ca130182` — 7 reqs / 9 plan
305
+ items / 12+ files → 30 minutes, 6 of 12 files, no tests, no docs, no `## Solution`).
306
+
307
+ The precheck size gate enforces this: it resolves `$implementAgent`'s capability tier
308
+ (`spur agent doctor <exec> --json` → `capabilityTier`) and writes FAIL for a large task on a
309
+ sub-`capable-1` executor, naming the executor and its tier. An unknown or undeclared tier reads as
310
+ `standard`, so the block is the default. Clear it deliberately — `--agent <capable>` /
311
+ `--vars '{"implementAgent":"<capable>"}'`, or split — never by raising `maxImplementReqs`: the caps
312
+ accept a big task, they do not make a flash model able to finish one.
313
+
314
+ The empty-implement guard (`requireDiff` on the task-pipeline `implement` step, R3) fails the
315
+ run fast when an implement exits 0 with zero non-corpus changes — a no-op never drifts into
316
+ `test`/`review`. A no-op is an implement-input defect, not a resume case: fix the input and
317
+ re-run. The same gate checks diff *scope* (task 0487 R1): changes outside the files and explicit
318
+ directory/glob prefixes the task body backticks fail the step by name; new files beside a declared
319
+ file are allowed, and a pre-dispatch snapshot prevents pre-existing dirt from being charged to the
320
+ implementer. Bypass only with a deliberate
321
+ `--vars '{"implementScopeGuard":"off"}'`.
322
+
323
+ ## Checkpoint read on resume
324
+
325
+ When resuming a paused or interrupted pipeline run (`--continue`), read the latest checkpoint
326
+ from `.spur/memory/sessions/` before re-launching:
327
+
328
+ ```bash
329
+ ls -t .spur/memory/sessions/*-${wbs}-*.md 2>/dev/null | head -1
330
+ ```
331
+
332
+ The checkpoint's YAML frontmatter contains `session_id`, `workflow`, `task_wbs`, `phase`,
333
+ `last_gate`, `timestamp`, and `next_action`. Surface `next_action` to the operator so they
334
+ know where the run left off and what to do next. Checkpoints are written by the pipeline's
335
+ checkpoint actions after every HITL gate decision and every phase transition. See
336
+ [cross-cutting.md](cross-cutting.md) § "Session Checkpoint Convention" for the full format.
337
+
338
+ ## Step 3: Continue
339
+
340
+ After a completed task, decide next action:
341
+
342
+ - **More tasks in the feature?** Pick the next one, run again.
343
+ - **Feature complete?** Run `spur feature update <id> verifying` to mark it for
344
+ acceptance verification.
345
+ - **All done?** Run `spur task refresh` + `spur feature refresh` to regenerate the kanban
346
+ and index.
347
+
348
+ ## Skipping HITL
349
+
350
+ Passing `--vars '{"profile":"auto"}'` to `spur workflow run` (a var choice, not a YAML fork) skips
351
+ the `approve` HITL gate — use for low-risk, well-understood tasks where operator review adds no value.
352
+ (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 |