@gobing-ai/spur 0.4.15 → 0.4.17
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 +1 -1
- package/config/config.global.yaml +21 -8
- package/config/decisions/executor.yaml +53 -0
- package/config/decisions/task-pipeline.yaml +44 -28
- package/config/workflows/task-pipeline.yaml +66 -54
- package/package.json +11 -10
- package/plugins/sp/README.md +4 -4
- package/plugins/sp/agents/expert-spur.md +3 -0
- package/plugins/sp/agents/super-planner.md +5 -1
- package/plugins/sp/agents/super-reviewer.md +43 -12
- package/plugins/sp/commands/dev-find-conflict.md +18 -6
- package/plugins/sp/commands/dev-fixall.md +7 -2
- package/plugins/sp/commands/dev-idea.md +6 -1
- package/plugins/sp/commands/dev-run.md +3 -0
- package/plugins/sp/commands/dev-runall.md +6 -3
- package/plugins/sp/commands/dev-verify.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +8 -8
- package/plugins/sp/skills/code-improvement/SKILL.md +3 -3
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +5 -4
- package/plugins/sp/skills/code-verification/SKILL.md +4 -4
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +27 -11
- package/plugins/sp/skills/conflict-finding/SKILL.md +46 -16
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +4 -2
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +2 -2
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +22 -3
- package/plugins/sp/skills/fleet-join/SKILL.md +2 -0
- package/plugins/sp/skills/functional-review/SKILL.md +1 -1
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/spur-check/SKILL.md +1 -1
- package/plugins/sp/skills/spur-cli/SKILL.md +23 -2
- package/plugins/sp/skills/spur-cli/references/agent.md +12 -0
- package/plugins/sp/skills/spur-cli/references/decision/lifecycle.md +166 -0
- package/plugins/sp/skills/spur-cli/references/decision.md +146 -16
- package/plugins/sp/skills/spur-cli/references/features.md +12 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +2 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +13 -0
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +3 -2
- package/plugins/sp/skills/spur-cli/references/workflows.md +9 -0
- package/plugins/sp/skills/spur-composer/SKILL.md +20 -1
- package/plugins/sp/skills/spur-dev/SKILL.md +16 -16
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +5 -4
- package/plugins/sp/skills/spur-dev/references/decision-points.md +97 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +9 -9
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -3
- package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +41 -29
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +33 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +11 -10
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
- package/plugins/sp/skills/spur-dev/references/glossary.md +12 -3
- package/plugins/sp/skills/spur-doctor/SKILL.md +23 -0
- package/spur.js +7378 -6052
- package/web/_astro/{BoardApp.Bjdp3XWV.js → BoardApp.CC7Mwswv.js} +65 -65
- package/web/_astro/{BoardApp.DCDZxLlQ.js → BoardApp.mWyrWCAR.js} +1 -1
- package/web/_astro/{TaskDetail.B3vBxynO.js → TaskDetail.CtAXuiv8.js} +1 -1
- package/web/_astro/{arc.DcuHTB_T.js → arc.Duf4u60i.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.ClOFWBON.js → architectureDiagram-3BPJPVTR.JoymtqxN.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.otYyr7Zb.js → blockDiagram-GPEHLZMM.BvmhcioC.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BCjpc9LP.js → c4Diagram-AAUBKEIU.CfaWkgoQ.js} +1 -1
- package/web/_astro/channel.DtEPXXcH.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.D5Wpnpt_.js → chunk-2J33WTMH.B7uR02cD.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DkQGtWNz.js → chunk-4BX2VUAB.SwiEauYR.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.B7dqjAip.js → chunk-55IACEB6.6ZRCK8PO.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BDQvnKE2.js → chunk-727SXJPM.Cxra_G3N.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.D92doBX5.js → chunk-AQP2D5EJ.Cxd7gZeX.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.C968oI5G.js → chunk-FMBD7UC4.DCLhFkVc.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.AkkYC1bY.js → chunk-ND2GUHAM.B9AmKcv6.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.sCc-rKKo.js → chunk-QZHKN3VN.DOjCvl6S.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.pOQ9u0mY.js → classDiagram-4FO5ZUOK.BMiT_mNf.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js → classDiagram-v2-Q7XG4LA2.BMiT_mNf.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.CRaeD6FY.js → cose-bilkent-S5V4N54A.mLBCEGjI.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BiCPBu54.js → cynefin-OW5HDTMX.CjDAY0qn.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.C1-q3vkT.js → dagre-BM42HDAG._G_sP8fP.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.BSVOv30O.js → diagram-2AECGRRQ.39OcfSuz.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CHMkjJ-V.js → diagram-5GNKFQAL.D7v_eNC4.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CKY9M564.js → diagram-KO2AKTUF.Da1x-lhg.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.B9yNJiTP.js → diagram-LMA3HP47.C8EnzbEb.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Dk8AUGsk.js → diagram-OG6HWLK6.DPnBj69F.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BQHR89TZ.js → erDiagram-TEJ5UH35.CXMu2TIh.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.oNkWVgoK.js → flowDiagram-I6XJVG4X.ZklePVtQ.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.Kz2U2nu9.js → ganttDiagram-6RSMTGT7.BhYOkdqk.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DHIZ_wPq.js → gitGraphDiagram-PVQCEYII.CADyX8a1.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.D0NJLcv9.js → infoDiagram-5YYISTIA.BsdmwjHt.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CFEfTWRG.js → ishikawaDiagram-YF4QCWOH.CzjZ3Crd.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.Dc7IE7I4.js → journeyDiagram-JHISSGLW.Bxj-ZH_t.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.D5v0xO9k.js → kanban-definition-UN3LZRKU.Cbg3wVvX.js} +1 -1
- package/web/_astro/{linear.wR5KzXnE.js → linear.DJNUrBI9.js} +1 -1
- package/web/_astro/{mermaid.core.BDQ2FoPd.js → mermaid.core.DVHQV3SF.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.W6_INsia.js → mindmap-definition-RKZ34NQL.DyomosRU.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.61ihbgkK.js → pieDiagram-4H26LBE5.DajtFknN.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.B5lEpFLo.js → quadrantDiagram-W4KKPZXB.Bjq6SjGe.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CmhVBVX0.js → requirementDiagram-4Y6WPE33.ubBVqGLP.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js → sankeyDiagram-5OEKKPKP.I4q46xd-.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B1vPLixM.js → sequenceDiagram-3UESZ5HK.DsCgZIa8.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BnACmrGi.js → stateDiagram-AJRCARHV.DcYjYSqT.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CW4pnmc3.js → stateDiagram-v2-BHNVJYJU.Dt8yPqiS.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CkzMCPnC.js → timeline-definition-PNZ67QCA.0YTkoa5F.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CY4aNdAR.js → vennDiagram-CIIHVFJN.BNl0l1hs.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.BtoU9UFk.js → wardleyDiagram-YWT4CUSO.BYSX6cfn.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6._9ijUUAs.js → xychartDiagram-2RQKCTM6.DzxxpixK.js} +1 -1
- package/web/index.html +1 -1
- package/worker/laya_worker.py +219 -0
- package/web/_astro/channel.qgOLXjI_.js +0 -1
|
@@ -359,6 +359,19 @@ spur task path 0040 --json
|
|
|
359
359
|
basename-WBS fallback. Exit `1` when no task owns the path.
|
|
360
360
|
- `path <wbs>` is the inverse — absolute task file path for a WBS.
|
|
361
361
|
|
|
362
|
+
## Lifecycle playbook
|
|
363
|
+
|
|
364
|
+
| Stage | How | Gate / evidence |
|
|
365
|
+
| --- | --- | --- |
|
|
366
|
+
| **Create** | `spur task create <title> --feature <id>` ([Creating tasks](#creating-tasks)), then fill sections ([tasks/section-editing.md](tasks/section-editing.md)) | `spur task check <wbs> --json` exits 0 |
|
|
367
|
+
| **Evaluate** | Readiness matrix ([check --json](#the-readiness-matrix--check---json)); `--precheck` before a pipeline run | `sp:spur-doctor` report cites the check rows |
|
|
368
|
+
| **Triage** | Structural finding → `check --fix`; L3 refusal → [tasks/l3-guard-cheatsheet.md](tasks/l3-guard-cheatsheet.md); batch admission → `spur task preflight <wbs> --json` | Re-run `check` until clean |
|
|
369
|
+
| **Enhance** | Replace one section from a temp file; batch refinement through `/sp:dev-refineall --feature <id> --auto` | Same `check` passes; AC still traces to the feature |
|
|
370
|
+
|
|
371
|
+
- One deliverable per task; split rather than stack ACs from two features.
|
|
372
|
+
- Every AC is observable and verifiable by a named command or file, never by self-report.
|
|
373
|
+
- Status moves only through `update`/`record`; never hand-edit frontmatter.
|
|
374
|
+
|
|
362
375
|
## What this skill is NOT
|
|
363
376
|
|
|
364
377
|
- **Not the pipeline.** Driving a task through `task-pipeline.yaml`, HITL surfacing, and
|
|
@@ -138,7 +138,7 @@ Spur's host additionally registers (`registerSpurBuiltins`, `packages/app/src/wo
|
|
|
138
138
|
|
|
139
139
|
| Kind | Capability |
|
|
140
140
|
| ---- | ---------- |
|
|
141
|
-
| Action | `agent.run` (model call via `spur agent run`; `executor: 'fleet'` dispatches into the agent fleet), `decide` (
|
|
141
|
+
| Action | `agent.run` (model call via `spur agent run`; `executor: 'fleet'` dispatches into the agent fleet), `decide` (catalog reference `{id, decision, params?, evidence? \| instructions?, resultFile}` → a schemaVersion-1 row; gated by `workflows.decideDecisionMaker`, fallback row when off; the inline `question`/`method`/`default` form is deprecated, and a shell `spur decision run` bypasses the switch — see [decision lifecycle](../decision/lifecycle.md)), `command.gate`, `rule.check`, `doctor.probe`, `proof.fingerprint`, `run.artifact`, `file.exists`, `file.read`, `file.read.into-var`, `http.request`, `hitl.confirm`, `hitl.select`, `hitl.input`, `shell` (streaming) |
|
|
142
142
|
| Guard | `shell` (env-aware), `contract-violation` |
|
|
143
143
|
|
|
144
144
|
Order matters for both guards and conditions: **the first that passes wins.** Put the discriminating
|
|
@@ -53,8 +53,9 @@ when the run count justifies it. One or zero → **descriptive procedure**; say
|
|
|
53
53
|
| "Retry until the gate passes", "loop until clean" | workflow — bounded loop is the engine's job |
|
|
54
54
|
| "Pause for approval, continue later / in another session" | workflow — HITL resume needs a run record |
|
|
55
55
|
| "Every night", "for each task in the batch", unattended | workflow — replay + record |
|
|
56
|
-
| "Then check whether it looks right and decide" | prose — the
|
|
57
|
-
| "It depends what the diff says" | prose —
|
|
56
|
+
| "Then check whether it looks right and decide" | prose — unless the answer is a closed set with a safe default; then a catalog `decide` step |
|
|
57
|
+
| "It depends what the diff says" | prose — unless a deterministic floor routes first and a catalog decision refines it (task-triage pattern) |
|
|
58
|
+
| "Classify the failure, then fix or stop" | workflow — a `decide` row the guard reads ([decision points](../../../spur-dev/references/decision-points.md)) |
|
|
58
59
|
| Runs once, then the situation has changed | prose — a checklist, not a definition |
|
|
59
60
|
| One operator, in-session, watching each step | prose — the trace has no second reader |
|
|
60
61
|
|
|
@@ -422,6 +422,15 @@ a **pipeline** (validate → dry-run → read trace → refine). It also covers
|
|
|
422
422
|
extending the engine with custom actions/guards. It does not execute the orchestrated *work* itself —
|
|
423
423
|
the workflow's actions (`shell`, custom runners) do that; this skill builds and operates the workflow.
|
|
424
424
|
|
|
425
|
+
## Lifecycle playbook
|
|
426
|
+
|
|
427
|
+
| Stage | How | Gate / evidence |
|
|
428
|
+
| --- | --- | --- |
|
|
429
|
+
| **Create** | [Fit gate](#decide-it-is-a-workflow-at-all--before-the-mode), then the composer ladder (ephemeral → `.spur/workflows/` → shared); author per [workflows/authoring-workflows.md](workflows/authoring-workflows.md) | `spur workflow validate <file> --json` clean |
|
|
430
|
+
| **Evaluate** | Dry-run, then a real run; `spur workflow profile <workflow> --json` and `cost` for measured spend | [Composition measures](#composition-measures-and-the-advisory-0615) within budget |
|
|
431
|
+
| **Triage** | `spur workflow trace <run-id> --json` → the failing node; [workflows/operations.md](workflows/operations.md) for HITL/continue/cancel | Re-run reaches the node and passes |
|
|
432
|
+
| **Enhance** | Tune from measured evidence ([workflows/workflow-fit-and-tuning.md](workflows/workflow-fit-and-tuning.md)); judgement steps adopt a catalog `decide` ([decision/lifecycle.md](decision/lifecycle.md) §3) | Before/after `profile` pair |
|
|
433
|
+
|
|
425
434
|
## Gotchas
|
|
426
435
|
|
|
427
436
|
1. **`kind` is required for transition-flow, optional for state-machine.** A missing `kind` silently
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-composer
|
|
3
|
-
description: "Select, compose and tune spur artifacts — tasks, features, rules, workflows, agent specs and project Board modules. Owns workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning and applying accepted sp:spur-doctor proposals. Triggers: compose a workflow, tune a rule, add a Board module."
|
|
3
|
+
description: "Select, compose and tune spur artifacts — tasks, features, rules, workflows, decisions, agent specs and project Board modules. Owns workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning and applying accepted sp:spur-doctor proposals. Triggers: compose a workflow, tune a rule, add a Board module."
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
metadata:
|
|
@@ -49,6 +49,7 @@ its own output and never runs a recurring loop — evaluation is the doctor's jo
|
|
|
49
49
|
| feature | Apply accepted rows through `spur feature update --section --from-file`; keep acceptance criteria in Gherkin | [../spur-cli/references/features.md](../spur-cli/references/features.md) |
|
|
50
50
|
| rule | The trace-driven tuning loop (§ Rule tuning loop) | [../spur-cli/references/rules.md](../spur-cli/references/rules.md) · [fine-tuning](../spur-cli/references/rules/fine-tuning.md) |
|
|
51
51
|
| workflow | Catalog selection, the composition ladder, and the ADR-115 budgets (§ below) | [../spur-cli/references/workflows.md](../spur-cli/references/workflows.md) · [operations](../spur-cli/references/workflows/operations.md) |
|
|
52
|
+
| decision | Select an existing id, place new entries up the layer ladder, tune maker/criteria from reliability evidence, adopt in workflows by class (§ Decision composition) | [../spur-cli/references/decision.md](../spur-cli/references/decision.md) · [lifecycle](../spur-cli/references/decision/lifecycle.md) |
|
|
52
53
|
| agent spec | Read through `spur agent list --specs`; fleet member specs are derived in memory from `agent.fleet` (never written to `.spur/agents/`) | [../spur-cli/references/agent.md](../spur-cli/references/agent.md) |
|
|
53
54
|
| board module | Declare under `bootstrap.modules`, gated by the serve preflight (§ Board module composition) | [../spur-cli/references/serve.md](../spur-cli/references/serve.md) |
|
|
54
55
|
|
|
@@ -144,6 +145,24 @@ Start from trace evidence, never from a guess:
|
|
|
144
145
|
5. `spur rule run` on the affected inputs (constitution T11 — affected inputs, not a corpus sweep).
|
|
145
146
|
6. Trace again and compare. A tuning with no trace pair behind it is a preference.
|
|
146
147
|
|
|
148
|
+
## Decision composition
|
|
149
|
+
|
|
150
|
+
Same select → compose → tune shape, applied to the decision catalog
|
|
151
|
+
([lifecycle](../spur-cli/references/decision/lifecycle.md)):
|
|
152
|
+
|
|
153
|
+
1. **Classify first.** keep-deterministic, rescue-only, adopt or keep-human (lifecycle §1). Only
|
|
154
|
+
adopt and rescue-only become a catalog entry.
|
|
155
|
+
2. **Select.** `spur decision list --json`; reuse an id whose criteria fit.
|
|
156
|
+
3. **Compose up the ladder.** `.spur/decisions/<file>.yaml` (project) → `config/decisions/` (shared,
|
|
157
|
+
recorded operator consent + `build:bundle`). A project file shadows the shipped file of the same
|
|
158
|
+
basename whole.
|
|
159
|
+
4. **Tune from evidence.** Labelled `spur decision run --maker <name>` fixtures, then
|
|
160
|
+
`spur decision status --reliability --json`; one lever per pass (lifecycle §6). The maker
|
|
161
|
+
override goes in operator config, never the shipped catalog.
|
|
162
|
+
5. **Adopt in a workflow.** One catalog-reference `decide` step per change, validated with
|
|
163
|
+
`spur workflow validate` and `spur workflow run --dry-run`; the fallback must stay safe with
|
|
164
|
+
`workflows.decideDecisionMaker` off.
|
|
165
|
+
|
|
147
166
|
## Applying doctor proposals
|
|
148
167
|
|
|
149
168
|
`sp:spur-doctor` ([../spur-doctor/SKILL.md](../spur-doctor/SKILL.md)) returns a proposal table;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-dev
|
|
3
|
-
description: 'The thin orchestration spine for the planning→execution lifecycle: intake, feature-check/batch-create gates, the execution pipeline (precheck→implement→
|
|
3
|
+
description: 'The thin orchestration spine for the planning→execution lifecycle: intake, feature-check/batch-create gates, the execution pipeline (precheck→implement→gate⇄remediate→review→done), catalog decision points, HITL gating. Dispatches competency skills; never inlines them. Triggers: "run the pipeline", "drive this task", "plan a feature end to end", "continue the pipeline run", or operating the full lifecycle.'
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
author: spur
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.2"
|
|
8
8
|
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
9
|
interactions:
|
|
10
10
|
- pipeline
|
|
@@ -23,11 +23,9 @@ metadata:
|
|
|
23
23
|
execution_steps:
|
|
24
24
|
- precheck
|
|
25
25
|
- implement
|
|
26
|
-
-
|
|
26
|
+
- gate
|
|
27
|
+
- remediate
|
|
27
28
|
- review
|
|
28
|
-
- approve
|
|
29
|
-
- verify
|
|
30
|
-
- record
|
|
31
29
|
- done
|
|
32
30
|
openclaw:
|
|
33
31
|
emoji: "🔄"
|
|
@@ -80,7 +78,7 @@ Full procedure: **[references/planning-workflow.md](references/planning-workflow
|
|
|
80
78
|
|
|
81
79
|
```
|
|
82
80
|
pick task (spur task list --json)
|
|
83
|
-
→ interactive omit/inline:
|
|
81
|
+
→ interactive omit/inline: spur workflow run … executor=host → perform each returned work item
|
|
84
82
|
→ explicit/headless executor: spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>"}'
|
|
85
83
|
→ on HITL pause: surface to operator; resume the selected driver from the paused state
|
|
86
84
|
```
|
|
@@ -88,7 +86,7 @@ pick task (spur task list --json)
|
|
|
88
86
|
The pipeline (`kind: state-machine`) runs the work loop:
|
|
89
87
|
|
|
90
88
|
```
|
|
91
|
-
precheck → implement[
|
|
89
|
+
precheck → implement[⇄escalate(HITL)] → gate[⇄remediate] → review → done | failed
|
|
92
90
|
```
|
|
93
91
|
|
|
94
92
|
**Escalation contract (0933).** The implement agent may pause on an operator question: it writes
|
|
@@ -97,6 +95,10 @@ run. Resume with `spur workflow continue --answer-text <answer>` — the guard a
|
|
|
97
95
|
`.spur/run/<wbs>-escalation.md` and re-enters implement (transcript via `--escalation-file`).
|
|
98
96
|
`maxEscalations` (default 2) bounds the loop; exhausted or empty answer → `failed`. Implement only.
|
|
99
97
|
|
|
98
|
+
**Decision points.** Lane, failure class, review failure class and approval are recorded
|
|
99
|
+
`spur decision` answers with deterministic fallbacks, read by the next guard. Report the row; never
|
|
100
|
+
re-judge it: **[references/decision-points.md](references/decision-points.md)**.
|
|
101
|
+
|
|
100
102
|
Full procedure: **[references/execution-workflow.md](references/execution-workflow.md)**.
|
|
101
103
|
Host executor: `spur workflow run` with `executor=host` → work item → `spur workflow continue`.
|
|
102
104
|
|
|
@@ -112,9 +114,6 @@ Read this `SKILL.md` plus your mode's files below before the first dispatch; eve
|
|
|
112
114
|
|
|
113
115
|
`--mode auto` reads as sequential-inline until § 2.4a resolves it.
|
|
114
116
|
|
|
115
|
-
Byte budgets for these sums live in `plugins/sp/tests/bootstrap-budget.test.ts`
|
|
116
|
-
(`BOOTSTRAP_BUDGETS_BYTES`, task 1128); the test fails the build when a mode's bootstrap grows.
|
|
117
|
-
|
|
118
117
|
## Step routing
|
|
119
118
|
|
|
120
119
|
Each step delegates to a CLI verb and is documented in exactly one reference file. Read the
|
|
@@ -133,8 +132,9 @@ reference for the half you're operating; do not duplicate its content here.
|
|
|
133
132
|
| Task selection | execution | `spur task list` | [execution-workflow.md](references/execution-workflow.md) |
|
|
134
133
|
| Pipeline run | execution | `spur workflow run` / `spur workflow continue` | [execution-workflow.md](references/execution-workflow.md) |
|
|
135
134
|
| Implement (dispatch) | execution | `sp:code-implementation` | competency skill — the spine dispatches, does not inline |
|
|
136
|
-
|
|
|
137
|
-
| Review
|
|
135
|
+
| Gate / remediate | execution | `spur task gate` + `sp:dev-fixall` | [execution-workflow.md](references/execution-workflow.md) |
|
|
136
|
+
| Review (dispatch) | execution | `sp:dev-review` → `sp:code-verification` + `sp:functional-review` + `sp:code-improvement` | competency skills — the spine dispatches, does not inline |
|
|
137
|
+
| Decision points | execution | `spur decision status` (+ `show`, `run`) | [decision-points.md](references/decision-points.md) |
|
|
138
138
|
| Operation catalog | execution | `sp:dev-*` operations | [dev-operations.md](references/dev-operations.md) (spine dispatch table) |
|
|
139
139
|
| Continue | execution | `spur feature update` / `refresh` | [execution-workflow.md](references/execution-workflow.md) |
|
|
140
140
|
| Batch run | execution | `sp:super-planner` + `spur workflow run` | [execution-batch.md](references/execution-batch.md) |
|
|
@@ -193,8 +193,8 @@ CLI does.
|
|
|
193
193
|
you ship corrupted corpus.
|
|
194
194
|
2. **One writer per evidence section (F92 0593 R1).** `## Solution` is authored by the
|
|
195
195
|
implement step; `## Review` by the review coordinator (`/sp:dev-review`); `## Testing` by the
|
|
196
|
-
deterministic `record`
|
|
197
|
-
bare — fallback-only, never an overwrite). During execution, do not hand-edit another stage's
|
|
196
|
+
deterministic `spur task record` close in `done` from the verdict artifact (it backfills
|
|
197
|
+
`## Review` only when bare — fallback-only, never an overwrite). During execution, do not hand-edit another stage's
|
|
198
198
|
section.
|
|
199
199
|
3. **Resolve task IDs through the CLI.** Read a known WBS with `spur task show <wbs> --json`; it
|
|
200
200
|
returns metadata, full content, and `filePath` across configured task folders. Use `spur task
|
|
@@ -226,7 +226,7 @@ section adds per-file content summaries and items with no single step (glossary,
|
|
|
226
226
|
five gates (feature-check, batch-create, precheck, review, verify).
|
|
227
227
|
- [references/section-batching.md](references/section-batching.md) — the evidence-section
|
|
228
228
|
**one-writer protocol** (F92 0593 R1/R2): implement owns `Solution`, the review coordinator owns
|
|
229
|
-
`Review`, deterministic `record` owns `Testing`; skills query `spur task sections` /
|
|
229
|
+
`Review`, the deterministic `spur task record` close owns `Testing`; skills query `spur task sections` /
|
|
230
230
|
`spur task check` instead of static section tables.
|
|
231
231
|
- [references/ac-style-guide.md](references/ac-style-guide.md) — BDD scenario authoring:
|
|
232
232
|
R-numbering, the two AC tiers, scenario-title stability, Gherkin template usage.
|
|
@@ -131,8 +131,9 @@ surface instead of spawning a subprocess; a subprocess fallback happens only whe
|
|
|
131
131
|
|
|
132
132
|
**Interactive task pipelines invert control into the host session (ADR-047 amendment).**
|
|
133
133
|
`dev-run --mode full` and sequential `dev-runall` with omitted `--agent` or explicit `--agent
|
|
134
|
-
inline`
|
|
135
|
-
workflow run`
|
|
134
|
+
inline` run the existing `task-pipeline.yaml` on the host executor — the engine loop above
|
|
135
|
+
(`spur workflow run … executor=host` → work item → `spur workflow continue`), with no subprocess —
|
|
136
|
+
and never redirect silently to `agent.default`. Interactive **omit** is
|
|
136
137
|
**host-controlled and non-subprocess**, but no longer guarantees host-context execution for every
|
|
137
138
|
model stage (task 0508): an eligible `agent.run` stage — pure-slash input, non-interactive state,
|
|
138
139
|
native subagent with shared-worktree read/write/shell capability, and a task above the
|
|
@@ -181,14 +182,14 @@ spawned step resolves to `agent.default` (step 2) or the YAML literal (step 3).
|
|
|
181
182
|
|
|
182
183
|
`task-pipeline.yaml` declares a separate `implementAgent` var. The `implement` state's `agent.run`
|
|
183
184
|
step reads `${vars.implementAgent}` instead of `${vars.agent}`, so an operator can pin the
|
|
184
|
-
implement hop to one executor while review
|
|
185
|
+
implement hop to one executor while the remediate and review hops keep the default agent:
|
|
185
186
|
|
|
186
187
|
```bash
|
|
187
188
|
# Pin implement to a specific executor; other hops keep agent.default / YAML literal
|
|
188
189
|
--vars '{"implementAgent":"omp-zai"}'
|
|
189
190
|
```
|
|
190
191
|
|
|
191
|
-
All other `agent.run` steps (
|
|
192
|
+
All other `agent.run` steps (remediate, review) read `${vars.agent}`. `implementAgent`
|
|
192
193
|
applies **only** to the implement hop. **The `--agent` flag forwards into BOTH `agent` and
|
|
193
194
|
`implementAgent`** at the execution-batch boundary (§3.2), so a pinned `--agent X` reaches every
|
|
194
195
|
hop including implement. To pin ONLY implement to a different executor while other hops keep the
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision-points
|
|
3
|
+
description: "The lifecycle's catalog decision points: which workflow state asks which `spur decision` id, its fallback, the row it writes and the guard that reads it — plus the rules for consuming, diagnosing and adding one."
|
|
4
|
+
see_also:
|
|
5
|
+
- spur-dev
|
|
6
|
+
- execution-workflow
|
|
7
|
+
- spur-cli
|
|
8
|
+
- spur-composer
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Decision points
|
|
12
|
+
|
|
13
|
+
A **decision point** is a closed-vocabulary judgment the workflow asks through `spur decision`
|
|
14
|
+
instead of through an agent's prose. It names a catalog id, carries a deterministic fallback, and
|
|
15
|
+
writes a schemaVersion-1 row (`value`, `source: model|default`, `degraded`, `confidence`,
|
|
16
|
+
`confidenceLevel`, `reason`) that the next guard or projection reads. The verb catalog, maker
|
|
17
|
+
resolution and the authoring lifecycle live in `sp:spur-cli`
|
|
18
|
+
([decision.md](../../spur-cli/references/decision.md),
|
|
19
|
+
[decision/lifecycle.md](../../spur-cli/references/decision/lifecycle.md)); this file is the
|
|
20
|
+
lifecycle's map of where each one sits.
|
|
21
|
+
|
|
22
|
+
## Inventory
|
|
23
|
+
|
|
24
|
+
| Workflow · state | Decision id | Values (fallback) | Row | Consumer |
|
|
25
|
+
| --- | --- | --- | --- | --- |
|
|
26
|
+
| task-pipeline · `gate` | `task-triage` | low · standard · high (`standard`) | `.spur/run/<wbs>-triage.decision` | lane projection → `<wbs>-mode.txt` → review focus. Runs only after the deterministic floor (caller `mode`, sensitive path, > 400 lines) has not already pinned the lane |
|
|
27
|
+
| task-pipeline · `gate` | `failure-class` | fix · stop (`fix`) | `.spur/run/<wbs>-failure-class.decision` | red gate: `stop` → `failed`, `fix` → `remediate` (under the attempt cap) |
|
|
28
|
+
| task-pipeline · `review` | `review-failure-class` | fix · stop (`fix`) | `.spur/run/<wbs>-review-failure-class.decision` | non-PASS review: `stop` → `failed`, `fix` → `remediate` (same cap) |
|
|
29
|
+
| task-pipeline · `review` | `gate-evidence` (approval `hitl.confirm`) | yes · no · defer (`defer`) | `.spur/run/<wbs>-approval.status` (APPROVED · DENIED) | `done` requires APPROVED; DENIED → `failed` (`cancelled`) |
|
|
30
|
+
| idea-pipeline · discovery | `idea-recommendation` | proceed · reshape · drop · unknown (`unknown`) | `.spur/run/<runId>-idea-recommendation.decision` | rescue only: consulted when the awk parse says `unknown`; only a `source: model` answer is projected |
|
|
31
|
+
| idea-pipeline · discovery | `needs-design` | design · skip (`design`) | `.spur/run/<runId>-idea-needs-design.decision` | rescue only: used when the report's boolean is missing; anything but a model `skip` keeps `design` |
|
|
32
|
+
| idea-pipeline · `idea-eval`, `design-approval` | `gate-evidence` | yes · no · defer (`defer`) | `__hitlAnswer` → `<runId>-idea-eval-answer.txt` etc. | a deferred answer is a denial there |
|
|
33
|
+
| wrapup-pipeline · `branch-cleanup` | `gate-evidence` | yes · no · defer (`defer`) | `branchCleanupStatus` | consent record only; wrap-up performs no git operation |
|
|
34
|
+
| history-anatomy · validate | `anatomy-validation-verdict` | PASS · FAIL (`FAIL`) | shell `spur decision run` (not a `decide` row) | rescue for an unparseable validation verdict; a deterministic FAIL is never overturned |
|
|
35
|
+
|
|
36
|
+
`maker-liveness` is served only by `spur decision status --probe`. `spur decision list --json` is
|
|
37
|
+
the live inventory; when it and this table disagree, the CLI wins and this table is stale.
|
|
38
|
+
|
|
39
|
+
## Switches
|
|
40
|
+
|
|
41
|
+
- **`workflows.decideDecisionMaker`** (default off) gates every `decide` action. Off, the action
|
|
42
|
+
makes no model call and writes the fallback row (`source: default`). The pipeline still routes:
|
|
43
|
+
a red gate is `fix` and goes to the bounded repair, the lane is `standard`.
|
|
44
|
+
- **`workflows.hitlDecisionMaker`** (default off) gates the evidence-mode HITL gates. Off,
|
|
45
|
+
interactive gates ask the operator; under `profile=auto` the gate's answer is deferred, which
|
|
46
|
+
task-pipeline treats as no objection and idea-pipeline treats as a denial.
|
|
47
|
+
- **`spur decision run` ignores both switches.** A workflow that shells out to it calls a model
|
|
48
|
+
even with the switches off. That is why the typed `decide` action is the preferred form.
|
|
49
|
+
|
|
50
|
+
## Rules for the lifecycle
|
|
51
|
+
|
|
52
|
+
1. **Read the row; never re-judge it.** When a run reports `failed`, `remediate` or a lane, the
|
|
53
|
+
reason is the recorded `.decision` row or the approval token. Quote its `value`, `source` and
|
|
54
|
+
`reason`. Do not overrule a `stop` by hand-driving `remediate`, and do not treat a `source:
|
|
55
|
+
default` row as a model verdict.
|
|
56
|
+
2. **A fallback row is a real outcome.** `source: default` (switch off, `no-backend`, low
|
|
57
|
+
confidence, invalid answer) is what the run acted on. Report it as degraded, not as an error.
|
|
58
|
+
3. **Outside a pipeline, ask the catalog.** For a question a catalog id already owns (is this
|
|
59
|
+
red gate fixable? which lane does this diff need?), run `spur decision show <id>` and then
|
|
60
|
+
`spur decision run <id> --param … --evidence … --json` instead of improvising an answer. Never
|
|
61
|
+
let a `spur decision run` answer substitute for a gate the workflow owns.
|
|
62
|
+
4. **Recurring judgment → a decision point, not prose.** A judgment that has a closed set of
|
|
63
|
+
answers and a safe default, recurs across runs, and currently lives in an agent prompt or a
|
|
64
|
+
`case` over free text belongs in a catalog entry plus a `decide` step. Author it through the
|
|
65
|
+
decision lifecycle (decision/lifecycle.md) and `sp:spur-composer`. A new shared catalog id
|
|
66
|
+
needs recorded operator consent (composition ladder §7) and `build:bundle`.
|
|
67
|
+
5. **Keep deterministic floors first.** A decision point rescues or refines a deterministic
|
|
68
|
+
check; it never replaces one. task-triage runs after the sensitive-path/size floor, and the
|
|
69
|
+
idea-pipeline decides run after the parse they rescue.
|
|
70
|
+
|
|
71
|
+
## Reporting a run
|
|
72
|
+
|
|
73
|
+
After a task-pipeline run settles, `/sp:dev-run`, `/sp:dev-runall` and `sp:super-planner` report
|
|
74
|
+
its decision points under the execution summary, one line per row, plus the approval token:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
for f in .spur/run/<wbs>-{triage,failure-class,review-failure-class}.decision; do
|
|
78
|
+
[ -f "$f" ] && jq -r --arg f "${f##*/}" '"\($f): \(.value) — \(.source // (if .degraded then "default" else "model" end)) \(.backend // "-") \(.reason)"' "$f"
|
|
79
|
+
done
|
|
80
|
+
printf 'approval: %s\n' "$(cat .spur/run/<wbs>-approval.status 2>/dev/null || echo none)"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Rows outlive their run: a row's presence does not prove this run reached that state (the run's
|
|
84
|
+
trace does). Rows written before `source` existed carry only `degraded`; the fallback above reads it.
|
|
85
|
+
|
|
86
|
+
## Diagnosis
|
|
87
|
+
|
|
88
|
+
| Question | Evidence |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| Why did this run take that route? | The row file in the table above; `spur workflow trace <run-id> --json` |
|
|
91
|
+
| Is a maker serving at all? | `spur decision status --probe` |
|
|
92
|
+
| How reliable is a decision in practice? | `spur decision status --reliability [--since <date>] --json` — per decision × maker: samples, acceptedRate, fallbacks by reason, median confidence, p50/p95 latency |
|
|
93
|
+
| Which runs asked it? | Board → Decisions tab (`decision_logs`) |
|
|
94
|
+
| Is the catalog healthy? | `spur decision status --json` → `loadErrors`, `makers[]` |
|
|
95
|
+
|
|
96
|
+
A decision whose rows are almost all `source: default` while its switch is on has a maker
|
|
97
|
+
problem, not a workflow problem. Hand it to `sp:spur-doctor`, which owns the proposal.
|
|
@@ -147,7 +147,7 @@ must not be changed without updating the backing skill.
|
|
|
147
147
|
- **Purpose:** Batch verification of a set of tasks (or all tasks under a feature) against their requirements and AC. Produces per-task verdicts + a summary report with aggregate statistics (counts, table, overall batch verdict). With `--fix all`, also evaluates **feature shippable readiness** once for the set.
|
|
148
148
|
- **Inputs:** `--tasks <selector>` (required unless `--feature`). `--feature <id>` (convenience for `--tasks feature:<id>`). Shared verify flags from `dev-verify` (`--agent <inline|auto|name>`, `--fix`, `--focus`, `--bdd`, `--auto`, `--force`, **`--skip-shippable`**). `--next` (per-task lifecycle chaining: on a PASS verdict transition `testing → done` through the FSM with the target-aware `--as done` guard honored; PARTIAL/FAIL does not transition; transitions run **before** the shippable gate so `spur feature check` sees final statuses). `--json` for machine-readable summary report.
|
|
149
149
|
- **Backing:** `sp:spur-dev` skill, `verifyall` operation (resolves the set using the shared selector grammar, dispatches per-task verify via `sp:code-verification` verify mode, writes per-task artifacts, aggregates and emits the batch summary report, then optional shippable gate).
|
|
150
|
-
- **Behavior:** Resolve + freeze the set (supports `--feature` sugar). For each task: apply status guard, requirements traceability + AC + SECUA review, emit the verdict artifact (per-task fix pass under `--fix`). `## Testing` is written by the deterministic `record`
|
|
150
|
+
- **Behavior:** Resolve + freeze the set (supports `--feature` sugar). For each task: apply status guard, requirements traceability + AC + SECUA review, emit the verdict artifact (per-task fix pass under `--fix`). `## Testing` is written by the deterministic `spur task record` close from the artifact (F92 0593 R1). After the batch: **shippable gate once** when active (see below). Emit a structured summary report (markdown or `--json`). Per-task behavior matches single `dev-verify` (except shippable is batch-once). **Batch verdict rollup is deterministic** — computed by `spur task verifyall-aggregate --from-file <batch-input.json> --json` (a tested service module, not agent discretion). **Per-task outcome grammar:** `PASS` / `PARTIAL` / `FAIL` for implemented tasks; `NOT-STARTED` for tasks that have not entered implementation (status `backlog`/`todo`/`blocked` — reachable only via `--force`). **Rollup rule:** all-NOT-STARTED → `UNKNOWN`; any `FAIL` → `FAIL`; any `PARTIAL` or `UNKNOWN` → `PARTIAL`; all `PASS` → `PASS`. NOT-STARTED rows are _excluded_ from the FAIL/PARTIAL rollup (they cannot manufacture a batch failure) but are _reported explicitly_ in the summary ("N NOT-STARTED, excluded from rollup"). This closes the 0341 dogfood gap where a healthy feature with 5 PASS + 2 unstarted tasks read as FAIL. **Shippable FAIL:** treat the batch as not clean — force rollup to at least **PARTIAL** and set `"shippable": false` under `--json` even if every task outcome is PASS.
|
|
151
151
|
- **Shippable readiness (default on with `--fix all`):** Active when `--fix all` and feature context exists (`--feature` or unique shared `feature_id`) and not `--skip-shippable`. Procedure: `sp:code-verification` Step 13 once after all per-task legs. Without `--fix all`, do not run the hard gate (optional note: use `--fix all` for ship evaluation).
|
|
152
152
|
- **Cache discipline (batch):** freeze the `spur task list --feature <id> --json` (or selector) capture once at resolve; reuse that snapshot for every per-task verify leg. Do not re-list the set mid-batch. Re-read a task body only when that task's sections changed (e.g. after a `--fix` write). Prefer re-reading only cited `file:line` anchors over re-tokenizing full Solution sections when prior Testing is already present.
|
|
153
153
|
- **Dogfood / mutation composition:** prefer step-split when dogfooding verifyall with `--fix all` and/or `--next` — first observe-only verifyall, then a separate fix pass, then `--next` only if status transitions are still needed. See `sp:dogfood-testing` §step-splitting.
|
|
@@ -156,10 +156,10 @@ must not be changed without updating the backing skill.
|
|
|
156
156
|
### 4. run
|
|
157
157
|
|
|
158
158
|
- **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
|
|
159
|
-
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode
|
|
159
|
+
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode runs `task-pipeline.yaml` on the host executor (`spur workflow run … executor=host` → work item → `spur workflow continue`) — host-controlled and non-subprocess, with 0508 eligibility applying to the resolved-inline selector (eligible `agent.run` stages dispatch once to a native subagent, host fallback)). `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--worktree [<name>]` runs the full pipeline inside an isolated git worktree (create or reuse; FF-merge on success, retain on failure) — the batch lifecycle in [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) applied to a batch of one; rejected with `--mode implement`. `--no-summary` skips the [execution summary](#execution-summary) printed after a full-mode run. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
|
|
160
160
|
- **Backing:** `sp:spur-dev` skill — `run` operation for the full pipeline (the spine drives it); `sp:code-implementation` competency skill for the implement step (the spine dispatches to it).
|
|
161
161
|
- **Modes:**
|
|
162
|
-
- **`full`** (default): Drive the full pipeline — precheck → implement →
|
|
162
|
+
- **`full`** (default): Drive the full pipeline — precheck → implement → gate ⇄ remediate → review → done, with the repair, stop and approval routes taken from decision rows ([decision-points.md](decision-points.md)). Interactive omit/inline runs `spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>","executor":"host"}'` and performs each returned work item (eligible stages may use a native subagent); explicit/headless executor selection runs the same definition without the `executor` var (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
163
163
|
- **`implement`** (explicit `--mode implement` only): Execute only the implement step. Read the task's `## Requirements` / `## Design` / `## Plan`, write the code that satisfies them, author the `## Solution` change-map section (file:line + what/why per changed file) via `spur task update <wbs> --section Solution --from-file`. This is the implement step the pipeline calls — it is NOT the pipeline driver. With `--next`: on success, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`; on a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` and `## Review` sections MUST carry a `⚠️ PARTIAL` marker naming the deferred part and the follow-up WBS — see `plugins/sp/commands/dev-run.md` → "Section ownership".
|
|
164
164
|
- **Delegation:** `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")` for both full-mode paths (the `executor` var picks host session vs child process); `Skill(skill="sp:code-implementation", args="$ARGUMENTS")` for implement mode.
|
|
165
165
|
|
|
@@ -569,7 +569,7 @@ These define their procedure directly in the command file. No `Skill()` delegati
|
|
|
569
569
|
is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent reasoning.
|
|
570
570
|
|
|
571
571
|
**Gate ownership.** A project quality gate (`spur self exec autofix|check|lint`, typecheck, tests,
|
|
572
|
-
rule runs) runs only where an operation's own contract names it: the pipeline `
|
|
572
|
+
rule runs) runs only where an operation's own contract names it: the pipeline `gate` state
|
|
573
573
|
(`run`/`runall`), `fixall`, `gtd`, `fixgha`, `unit`, and the `--check <cmd>` loops. The scribe
|
|
574
574
|
operations — `changelog`, `gitmsg`, `handover`, `job-dump` — produce text or a commit, not code, so
|
|
575
575
|
they run **no gate by default**, and a generic "verify before you finish" rule from `AGENTS.md` or
|
|
@@ -683,7 +683,7 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
683
683
|
### 10. fixall
|
|
684
684
|
|
|
685
685
|
- **Purpose:** Fix all lint, type, and test errors systematically across the working tree.
|
|
686
|
-
- **Inputs:** `--scope <path>` (default: entire working tree) — limits fixes to a file or directory. `--gate-log <path>` (R3, task 0482) — before fixing, read this captured validation-run log and start at the `file:line` anchors its findings name, rather than re-deriving the failure from a fresh gate run. `--findings <anchors>` (R3, task 0482) — space-separated `file:line` anchors already extracted from that log by the `
|
|
686
|
+
- **Inputs:** `--scope <path>` (default: entire working tree) — limits fixes to a file or directory. `--gate-log <path>` (R3, task 0482) — before fixing, read this captured validation-run log and start at the `file:line` anchors its findings name, rather than re-deriving the failure from a fresh gate run. `--findings <anchors>` (R3, task 0482) — space-separated `file:line` anchors already extracted from that log by the `gate` state; when present these ARE the failing set, so fix them in order and do not run the gate to discover what broke.
|
|
687
687
|
- **Backing:** `inline` — lint + test fix loop.
|
|
688
688
|
- **Behavior:** 0. **Start at the anchors, never at a discovery run.** If `--findings <anchors>` is given, that space-separated `file:line` list IS the failing set — open those locations first, in order, and fix them; do not run the gate to find out what broke. If only `--gate-log <path>` is given, read that log first and identify the failing findings (lint/test errors with their `file:line` anchors) before running the loop — the captured log is the authoritative source. Either way the first action of this hop is a read, not a gate run (R3, task 0482).
|
|
689
689
|
1. Inspect the project's formatter command, then settle formatter-only diffs. Without `--scope`, use the project formatter (here `spur self exec format`). With `--scope`, use a formatter invocation whose only path operands are inside the selected scope — for Biome, `bunx biome check --write "$SCOPE"`. Never append a path to a script already containing `.`: `biome check . --write <path>` still writes across the repository. Preserve quoted paths and apply the same scope to every later formatting pass. If no scoped formatter is available, report that limitation and leave out-of-scope files untouched. Here `spur self exec lint` checks formatting without rewriting it and also runs typecheck; formatting errors fail that check.
|
|
@@ -695,9 +695,9 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
695
695
|
7. If tests are green, proceed to the applicable standalone confirmation or pipeline handoff below.
|
|
696
696
|
8. **Test fix loop:** for each in-scope failure, diagnose (test bug vs implementation bug), apply the fix, re-run the **failing test only** (`bun test <file> --test-name-pattern "<test>"`). Report outside-scope blockers without editing them. Do NOT re-run the full suite per fix — it is the dominant loop cost (task 0436 R2).
|
|
697
697
|
9. **Confirming run — standalone invocation only (at most once).** After all fixes, repeat the scope-safe formatting invocation from step 1, then run the selected validation command **at most once** to confirm (here the default project gate is `spur self exec check`). If it passes, the hop is done. **Skip this step entirely when `--gate-log` is set** (see step 10) — under the pipeline nothing consumes its verdict.
|
|
698
|
-
10. **Pipeline-awareness (R4, task 0483; confirming run dropped 2026-08-31).** `--gate-log` is set only by the pipeline's `
|
|
698
|
+
10. **Pipeline-awareness (R4, task 0483; confirming run dropped 2026-08-31).** `--gate-log` is set only by the pipeline's `remediate` hop, so treat it as the pipeline signal. There, the `gate` state's recheck visit runs the full `${vars.qualityGateCmd}` gate immediately after this hop returns — that is the **deciding** run, the only one that writes PASS to `.spur/run/<wbs>-test-gate.status`. A confirming run inside this hop decides nothing and costs a second full gate (~105 s here) to answer a question the gate recheck is about to answer anyway. So under `--gate-log`: **run no full gate at all.** Your self-check is what step 8 already gives you — the failing tests you re-ran individually — plus **one `spur self exec lint`** (~7 s: Biome + typecheck) to catch type or lint breakage your fixes introduced. Then return and let the gate recheck judge. It opens with the same cheap `${vars.gateProbeCmd}` probe, so a still-red tree is caught in seconds rather than by a full suite. Historical anti-pattern this replaces: 0482 ran the gate 3× plus a standalone `bun run test`, and the recheck then ran it a 5th time.
|
|
699
699
|
11. Report: list what was fixed (file + one-line summary per fix). If any error could not be resolved, report it explicitly — do not suppress.
|
|
700
|
-
- **Invariants:** Never bypass with `--no-verify`, `--force`, or new `biome-ignore`/`eslint-disable` suppressions. Never skip or `.skip` a test to make the suite green. Fix the root cause, not the symptom. Here lint checks formatting and types; it does not prove that the full test gate passed. Keep every write inside `--scope`. **Never re-run the full gate more than once per confirming pass** (R4) — use targeted probes during the fix loops and let the pipeline's `
|
|
700
|
+
- **Invariants:** Never bypass with `--no-verify`, `--force`, or new `biome-ignore`/`eslint-disable` suppressions. Never skip or `.skip` a test to make the suite green. Fix the root cause, not the symptom. Here lint checks formatting and types; it does not prove that the full test gate passed. Keep every write inside `--scope`. **Never re-run the full gate more than once per confirming pass** (R4) — use targeted probes during the fix loops and let the pipeline's `gate` recheck be the deciding run.
|
|
701
701
|
- **MANDATORY Exit Condition — standalone only.** At step 9, execute the following once; do not add another confirming run:
|
|
702
702
|
1. Run validation command: `eval "$VALIDATION_CMD"`
|
|
703
703
|
2. Capture exit code: `EXIT_CODE=$?`
|
|
@@ -706,7 +706,7 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
706
706
|
|
|
707
707
|
If EXIT_CODE != 0: NOT completed. Continue the bounded fix loop for in-scope failures; report outside-scope blockers.
|
|
708
708
|
|
|
709
|
-
**Pipeline exit condition (`--gate-log` set):** return the fixes and the targeted-test/lint evidence from step 10 to `
|
|
709
|
+
**Pipeline exit condition (`--gate-log` set):** return the fixes and the targeted-test/lint evidence from step 10 to the `gate` recheck. Do not run the standalone validation command or claim a full-gate PASS; the recheck owns that verdict.
|
|
710
710
|
|
|
711
711
|
**Hallucination Red Flags — STOP if you think:**
|
|
712
712
|
- "The errors look fixed" — check exit code, not appearance
|
|
@@ -735,7 +735,7 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
735
735
|
└─────────────────────────────────────────────────┘
|
|
736
736
|
```
|
|
737
737
|
|
|
738
|
-
The 7 phases describe standalone execution: Phases 1–2 capture the gate, Phase 3 settles auto-fixable formatting within scope, Phases 4–6 are the per-group root-cause fix loops, Phase 7 is the final verification run. With `--gate-log`, use the supplied evidence instead of capturing the gate again, and hand off to `
|
|
738
|
+
The 7 phases describe standalone execution: Phases 1–2 capture the gate, Phase 3 settles auto-fixable formatting within scope, Phases 4–6 are the per-group root-cause fix loops, Phase 7 is the final verification run. With `--gate-log`, use the supplied evidence instead of capturing the gate again, and hand off to the `gate` recheck instead of running Phase 7's full validation.
|
|
739
739
|
|
|
740
740
|
- **Fix Priority:**
|
|
741
741
|
|
|
@@ -15,7 +15,7 @@ Read at Step 5 and once at batch end (task 1128 R1).
|
|
|
15
15
|
When the batch finishes — clean (all `done`), halted (default failure policy), parked (`paused`:
|
|
16
16
|
one or more tasks sit on an operator question (escalate, 0933) or an approval gate), or aborted
|
|
17
17
|
(cycle / unknown selector) — emit a structured report. The report is the orchestrator's sole
|
|
18
|
-
output; it does not mutate the corpus (the pipeline's `
|
|
18
|
+
output; it does not mutate the corpus (the pipeline's `done` state already recorded per-task
|
|
19
19
|
results). A `paused` task is non-terminal — the report marks it `paused` (never `done`) and names
|
|
20
20
|
the resume command. Unless `--no-summary`, follow it with the measured
|
|
21
21
|
[execution summary](dev-operations.md#execution-summary), one `--progress <wbs>=<file>` per attempted run.
|
|
@@ -462,11 +462,11 @@ in next-router; this only maps status → primary TABLE A hop for recovery.
|
|
|
462
462
|
|
|
463
463
|
### 3.3c Feature-sync retry suppression (task 0411; 1004 R3)
|
|
464
464
|
|
|
465
|
-
During a batch, the per-task `
|
|
465
|
+
During a batch, the per-task `done` state invokes feature status sync. When a feature is
|
|
466
466
|
L4-gate-blocked (e.g. not all linked tasks are `done`), the identical blocked proposal repeats on
|
|
467
467
|
every call with no intervening input change. The service fixes this, not the engine.
|
|
468
468
|
|
|
469
|
-
`task-pipeline.yaml`'s `
|
|
469
|
+
`task-pipeline.yaml`'s `done` state invokes `spur feature sync <feature-id> --json` directly —
|
|
470
470
|
retry suppression lives inside the `FeatureService.syncFeature` implementation:
|
|
471
471
|
|
|
472
472
|
1. On a **blocked** result (`gateBlocked` checked first — a partial hop can have `applied: true`
|
|
@@ -482,7 +482,7 @@ retry suppression lives inside the `FeatureService.syncFeature` implementation:
|
|
|
482
482
|
never reads or writes the state.
|
|
483
483
|
|
|
484
484
|
**Batch driver contract:** the orchestrator does **nothing extra** — the suppression lives inside
|
|
485
|
-
the pipeline's `
|
|
485
|
+
the pipeline's `done` state. The driver still
|
|
486
486
|
launches `task-pipeline.yaml` verbatim (R4.1). Suppression is transparent: the sync emits the same
|
|
487
487
|
`FeatureSyncResult` JSON shape (`suppressed: true` added on replay), so downstream report logic is
|
|
488
488
|
unchanged. The only observable difference is fewer redundant `feature sync` derivations.
|
|
@@ -530,6 +530,16 @@ belongs to a subagent or the operator, not to the batch controller's report loop
|
|
|
530
530
|
By default, the **first** pipeline failure halts the batch. Remaining tasks in the plan are reported
|
|
531
531
|
as `not-attempted`. The report lists succeeded, failed, and not-attempted tasks.
|
|
532
532
|
|
|
533
|
+
**Run-failed / task-done (observed 2026-10-19, feature P1).** A run can fail *after* the task is
|
|
534
|
+
already finished: the `done` state's close commands run last, and a lint or anchor rule can refuse
|
|
535
|
+
the transition on an otherwise green task. Resolve it the honest way — fix the finding through the
|
|
536
|
+
owning surface, re-run the same close command, and confirm the task reads `done` with a PASS verdict
|
|
537
|
+
— then record the task as `done (run-failed-recovered)` with the failing command in the report.
|
|
538
|
+
That is **not** a `failed` outcome: the failure policy applies to a task that did not reach its
|
|
539
|
+
contract, not to a run whose last recorded state was superseded. Surface it in the report either
|
|
540
|
+
way (never silently continue), and never re-run the pipeline just to flip a run row from `failed` to
|
|
541
|
+
`done` — a second run re-executes model stages for a task that is already closed.
|
|
542
|
+
|
|
533
543
|
### 4.2 `--keep-going` (R3.2)
|
|
534
544
|
|
|
535
545
|
With `--keep-going`, a failed task does **not** halt the batch. Instead:
|
|
@@ -29,7 +29,7 @@ while ready or running:
|
|
|
29
29
|
RUN[t] = (cd "$WT" && spur workflow run task-pipeline.yaml \
|
|
30
30
|
--vars '{"wbs":"<wbs>","deferFeatureSync":"true"[,"deferQualityGate":"true"],...}' --async --json)
|
|
31
31
|
# deferQualityGate is added ONLY under the opt-in --defer-gate flag (1111 R3):
|
|
32
|
-
# the task's `
|
|
32
|
+
# the task's `gate` state then runs the light tier and writes DEFERRED.
|
|
33
33
|
wait for any RUN terminal # trace poll --follow --timeout 600000; stale-evidence rule applies
|
|
34
34
|
on done: WT-3b commit on $BRANCH → integrate(t)
|
|
35
35
|
on failed: WT-5 retain (marker retained); failure policy — stop-the-batch default / --keep-going subtree skip
|
|
@@ -92,9 +92,9 @@ per-task with `/sp:dev-run <wbs> --worktree <branch>`.
|
|
|
92
92
|
|
|
93
93
|
### Generated regions — defer the sync, regenerate once (R5)
|
|
94
94
|
|
|
95
|
-
The only per-task writer of feature files is the `
|
|
95
|
+
The only per-task writer of feature files is the `done` state's post-record feature sync
|
|
96
96
|
(`task-pipeline.yaml`). Parallel launches set
|
|
97
|
-
the pipeline var `deferFeatureSync: "true"` (default `"false"`): the
|
|
97
|
+
the pipeline var `deferFeatureSync: "true"` (default `"false"`): the done state appends
|
|
98
98
|
`feature sync deferred to batch integration` to the task report and skips the sync, so task
|
|
99
99
|
branches never touch feature files or `docs/features/INDEX.md`. After the last integration, on the
|
|
100
100
|
base ref, the orchestrator runs `spur feature sync <f> --json` (service-level suppression) plus `spur feature refresh --feature <f>`
|
|
@@ -103,7 +103,7 @@ inline runs keep the default `"false"` and are unchanged. Any rebase conflict
|
|
|
103
103
|
path or any other — is an R4 `integration-conflict`; there is no path-based exception.
|
|
104
104
|
|
|
105
105
|
**Deferred gate (`--defer-gate`, task 1111 R3/R4).** The opt-in flag adds
|
|
106
|
-
`deferQualityGate: "true"` to the same per-task `--vars`, so each task's `
|
|
106
|
+
`deferQualityGate: "true"` to the same per-task `--vars`, so each task's `gate` state runs the light
|
|
107
107
|
tier and writes `DEFERRED` instead of a full-gate `PASS` (see
|
|
108
108
|
[flag-glossary](flag-glossary.md#flag-defer-gate)). The orchestrator then runs the project
|
|
109
109
|
`qualityGateCmd` **once** on the integrated `BASE_REF` **before** the deferred feature sync:
|