@gobing-ai/spur 0.3.41 → 0.3.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +15 -0
- package/README.md +15 -1
- package/config/templates/AGENTS.md +5 -3
- package/config/workflows/task-pipeline.yaml +113 -12
- package/package.json +15 -12
- package/plugins/README.md +655 -0
- package/plugins/sp/README.md +621 -0
- package/plugins/sp/agents/expert-spur.md +109 -0
- package/plugins/sp/agents/super-coder.md +126 -0
- package/plugins/sp/agents/super-planner.md +283 -0
- package/plugins/sp/agents/super-reviewer.md +154 -0
- package/plugins/sp/commands/dev-arch.md +30 -0
- package/plugins/sp/commands/dev-brainstorm.md +40 -0
- package/plugins/sp/commands/dev-changelog.md +28 -0
- package/plugins/sp/commands/dev-daily.md +29 -0
- package/plugins/sp/commands/dev-debug.md +29 -0
- package/plugins/sp/commands/dev-dogfood.md +33 -0
- package/plugins/sp/commands/dev-featurechange.md +130 -0
- package/plugins/sp/commands/dev-find-conflict.md +51 -0
- package/plugins/sp/commands/dev-find-issue.md +76 -0
- package/plugins/sp/commands/dev-find-next.md +60 -0
- package/plugins/sp/commands/dev-fixall.md +33 -0
- package/plugins/sp/commands/dev-gitmsg.md +28 -0
- package/plugins/sp/commands/dev-gtd.md +97 -0
- package/plugins/sp/commands/dev-handover.md +26 -0
- package/plugins/sp/commands/dev-idea.md +50 -0
- package/plugins/sp/commands/dev-next.md +31 -0
- package/plugins/sp/commands/dev-parallel.md +30 -0
- package/plugins/sp/commands/dev-plan.md +46 -0
- package/plugins/sp/commands/dev-refine.md +48 -0
- package/plugins/sp/commands/dev-refineall.md +65 -0
- package/plugins/sp/commands/dev-refresh.md +32 -0
- package/plugins/sp/commands/dev-reverse.md +32 -0
- package/plugins/sp/commands/dev-review.md +31 -0
- package/plugins/sp/commands/dev-run.md +63 -0
- package/plugins/sp/commands/dev-runall.md +83 -0
- package/plugins/sp/commands/dev-simplify.md +39 -0
- package/plugins/sp/commands/dev-unit.md +29 -0
- package/plugins/sp/commands/dev-verify.md +48 -0
- package/plugins/sp/commands/dev-verifyall.md +72 -0
- package/plugins/sp/commands/dev-wrap.md +48 -0
- package/plugins/sp/commands/dev-wrapall.md +51 -0
- package/plugins/sp/commands/rule-add.md +18 -0
- package/plugins/sp/commands/rule-refine.md +18 -0
- package/plugins/sp/commands/rule-scan.md +18 -0
- package/plugins/sp/commands/spur-init.md +22 -0
- package/plugins/sp/commands/workflow-add.md +18 -0
- package/plugins/sp/commands/workflow-refine.md +18 -0
- package/plugins/sp/hooks/agent-hint.ts +60 -0
- package/plugins/sp/hooks/careful-guard.ts +147 -0
- package/plugins/sp/hooks/context-post-tool.ts +325 -0
- package/plugins/sp/hooks/context-session-start.ts +182 -0
- package/plugins/sp/hooks/context-session-stop.ts +95 -0
- package/plugins/sp/hooks/hooks.json +51 -0
- package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
- package/plugins/sp/hooks/task-write-guard.ts +84 -0
- package/plugins/sp/plugin.json +8 -0
- package/plugins/sp/scripts/batch-preflight.ts +204 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
- package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
- package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
- package/plugins/sp/scripts/task-size-precheck.ts +202 -0
- package/plugins/sp/scripts/validate-commands.ts +651 -0
- package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
- package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
- package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
- package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
- package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
- package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
- package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +203 -0
- package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
- package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
- package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
- package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
- package/plugins/sp/skills/code-review/SKILL.md +112 -0
- package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
- package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
- package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
- package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
- package/plugins/sp/skills/code-testing/SKILL.md +108 -0
- package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
- package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
- package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
- package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
- package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
- package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
- package/plugins/sp/skills/code-verification/SKILL.md +535 -0
- package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
- package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
- package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
- package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
- package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
- package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
- package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
- package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
- package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
- package/plugins/sp/skills/functional-review/SKILL.md +364 -0
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
- package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
- package/plugins/sp/skills/issue-finding/SKILL.md +442 -0
- package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
- package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
- package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
- package/plugins/sp/skills/issue-finding/references/session-formats.md +151 -0
- package/plugins/sp/skills/next-feature/SKILL.md +125 -0
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
- package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
- package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
- package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
- package/plugins/sp/skills/next-router/SKILL.md +181 -0
- package/plugins/sp/skills/next-router/references/messages.md +90 -0
- package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
- package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +109 -0
- package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
- package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
- package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
- package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
- package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
- package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
- package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
- package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
- package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
- package/plugins/sp/skills/spur-cli/references/features.md +234 -0
- package/plugins/sp/skills/spur-cli/references/init.md +119 -0
- package/plugins/sp/skills/spur-cli/references/message.md +98 -0
- package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
- package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
- package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
- package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
- package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
- package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +280 -0
- package/plugins/sp/skills/spur-cli/references/team.md +133 -0
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
- package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
- package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +680 -0
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +790 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -0
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
- package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +120 -0
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
- package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
- package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
- package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
- package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
- package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
- package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
- package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
- package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
- package/spur.js +6035 -4963
|
@@ -0,0 +1,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 |
|