@gobing-ai/spur 0.4.15 → 0.4.16
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 +1 -1
- 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-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/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 +2 -2
- package/plugins/sp/skills/spur-dev/references/decision-points.md +97 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +8 -8
- 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 +3 -3
- 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
|
@@ -27,12 +27,17 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
27
27
|
|
|
28
28
|
## Implementation
|
|
29
29
|
|
|
30
|
-
Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#10-fixall) (fixall). Pipeline signal: when `--gate-log` is set (the `
|
|
30
|
+
Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#10-fixall) (fixall). Pipeline signal: when `--gate-log` is set (the `remediate` hop), run no full gate — the `gate` state's recheck immediately after is the deciding run (R4, task 0483).
|
|
31
31
|
|
|
32
|
-
When dispatched from the pipeline's
|
|
32
|
+
When dispatched from the pipeline's `remediate` hop (F96, task 0950), the gate log carries a
|
|
33
33
|
`residual artifact` block (`<wbs>-residuals.json`) and the findings file already
|
|
34
34
|
contains the merged residual anchors: treat those items as fix targets, in order,
|
|
35
35
|
alongside gate anchors. The fixer may write `.spur/run/<wbs>-residual-deferrals.json`
|
|
36
36
|
— one `{id, reason}` entry per item — but only for P3 findings or diff markers it
|
|
37
37
|
cannot fix inside the task; the done stage settles deferrals into follow-up tasks.
|
|
38
38
|
|
|
39
|
+
The `remediate` hop is entered only after a `fix` decision (`failure-class` on a red gate,
|
|
40
|
+
`review-failure-class` on a non-PASS review). A `stop` decision ends the run before this command
|
|
41
|
+
runs, so do not invoke it by hand to overrule a `stop`
|
|
42
|
+
([decision points](../skills/spur-dev/references/decision-points.md)).
|
|
43
|
+
|
|
@@ -44,7 +44,7 @@ trace records the answering source. `--auto` takes the recommended option at eac
|
|
|
44
44
|
|
|
45
45
|
| Gate | Pauses when | Recommendation comes from | `--auto` takes |
|
|
46
46
|
| --- | --- | --- | --- |
|
|
47
|
-
| idea-eval | after discovery | eval report `## Recommendation` (`proceed` / `reshape` / `drop`) | `proceed`/`reshape` → continue; `drop` → cancel;
|
|
47
|
+
| idea-eval | after discovery | eval report `## Recommendation` (`proceed` / `reshape` / `drop`); when unparseable, a model answer from the `idea-recommendation` decision | `proceed`/`reshape` → continue; `drop` → cancel; neither → the gate asks, and under `--auto` its `gate-evidence` decision answers (a deferred answer denies) |
|
|
48
48
|
| design-approval | after system-design (skipped by `--skip-design`) | recorded design check | PASS → approve; FAIL → still asks |
|
|
49
49
|
|
|
50
50
|
The AC check and the batch create are deterministic pipeline steps, not gates: `ac-generate`
|
|
@@ -52,6 +52,11 @@ runs `spur feature check` and routes on the recorded result (a FAIL retries the
|
|
|
52
52
|
and `batch-create-run` runs `spur task batch-create` and routes on its own recorded result.
|
|
53
53
|
Neither ever pauses, under any profile.
|
|
54
54
|
|
|
55
|
+
The rescue decisions and the gate answers are catalog decision points; their rows and switches
|
|
56
|
+
are in [decision points](../skills/spur-dev/references/decision-points.md). With both switches off
|
|
57
|
+
(the default) no model is called and a `--auto` run with no parseable recommendation stops at
|
|
58
|
+
idea-eval as a denial rather than creating a feature.
|
|
59
|
+
|
|
55
60
|
Flag → vars: `--auto` sets `profile=auto`, `idea_approved=true`, `design_approved=true`;
|
|
56
61
|
`--skip-design` sets `design=skip`.
|
|
57
62
|
|
|
@@ -50,6 +50,9 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
50
50
|
- Implement step only (`--mode implement`): `Skill(skill="sp:code-implementation", args="$ARGUMENTS")`
|
|
51
51
|
- After a full-mode run settles (done, failed or paused), print the
|
|
52
52
|
[execution summary](../skills/spur-dev/references/dev-operations.md#execution-summary) unless `--no-summary`.
|
|
53
|
+
- Then report the run's decision points (triage lane, failure classes, approval) from their rows
|
|
54
|
+
([reporting a run](../skills/spur-dev/references/decision-points.md#reporting-a-run)). A `failed` or `remediate` route is explained by the row
|
|
55
|
+
that chose it; quote its value, source and reason, never a fresh judgment.
|
|
53
56
|
|
|
54
57
|
**Flags:**
|
|
55
58
|
|
|
@@ -26,7 +26,7 @@ Wraps the **sp:spur-dev** skill.
|
|
|
26
26
|
| `--worktree` `[<name>]` | Run the batch in an isolated git worktree; FF-merge on success, retain on failure. Bare `--worktree` creates a fresh tree; `--worktree <name>` adopts an existing worktree by name/path/branch. | off |
|
|
27
27
|
| `--no-summary` | Skip the measured execution summary (one row per task run: time, wait, tool calls, total / non-cached tokens) printed after the batch report. | off (summary printed) |
|
|
28
28
|
| `--concurrency` `<n>` | Parallel-mode worker bound: at most `<n>` task pipelines run at once (task 0931); a dependent starts only after its in-set dependencies are integrated onto the base ref. No-op in sequential mode (ignored). | 2 |
|
|
29
|
-
| `--defer-gate` | Opt-in parallel-batch gate policy (task 1111): each task's `
|
|
29
|
+
| `--defer-gate` | Opt-in parallel-batch gate policy (task 1111): each task's `gate` state runs the light tier and writes `DEFERRED`; the batch runs one integrated full gate on the base ref before the feature sync. Requires `--mode parallel`, or `--mode auto` resolved to parallel (dropped with a note otherwise); default off. | off |
|
|
30
30
|
|
|
31
31
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
32
32
|
|
|
@@ -82,8 +82,8 @@ FF-merge on success. This is expected, not a bug.
|
|
|
82
82
|
|
|
83
83
|
**`--next` (batch-once wrap).** `--next`
|
|
84
84
|
is chain-to-completion with propagation. On `dev-runall`, each task in the batch runs its
|
|
85
|
-
`task-pipeline.yaml` to terminal status (the pipeline already drives precheck → implement →
|
|
86
|
-
review →
|
|
85
|
+
`task-pipeline.yaml` to terminal status (the pipeline already drives precheck → implement → gate ⇄ remediate →
|
|
86
|
+
review → done); when the batch is complete, the wrap hop runs **once
|
|
87
87
|
for the batch** — mirroring the batch-once shippable gate `dev-verifyall` uses — rather than once
|
|
88
88
|
per task. Without `--next`, `--wrap` is wrap-without-chaining (the single batch wraps without
|
|
89
89
|
advancing the feature lifecycle). **was: `--next` deliberately omitted; the old no-`--next` rationale argued against the old per-task-transition meaning and does not carry.**
|
|
@@ -111,3 +111,6 @@ full distinction.
|
|
|
111
111
|
- Explicit executor (any mode, including `auto`) or parallel mode: `Skill(skill="sp:spur-dev", args="runall $ARGUMENTS")` → `sp:super-planner` agent.
|
|
112
112
|
- After the batch report, print the [execution summary](../skills/spur-dev/references/dev-operations.md#execution-summary) over every attempted run unless
|
|
113
113
|
`--no-summary`.
|
|
114
|
+
- A failed task's report row names the decision row that ended it (`failure-class` or
|
|
115
|
+
`review-failure-class` = `stop`, or approval `DENIED`) per
|
|
116
|
+
[reporting a run](../skills/spur-dev/references/decision-points.md#reporting-a-run); the batch failure policy then applies unchanged.
|
|
@@ -45,7 +45,7 @@ See `sp:code-verification` § Shippable readiness gate.
|
|
|
45
45
|
run `spur task residual <wbs> scan` + `fold` (observe-only; folds the verdict's `residual-sweep` check,
|
|
46
46
|
PASS → PARTIAL when a blocking residual exists) — under every `--fix` mode — then, only on a
|
|
47
47
|
downgrade, re-run `spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json` so Testing
|
|
48
|
-
carries the final verdict. Same order as the pipeline `
|
|
48
|
+
carries the final verdict. Same order as the pipeline `done` state's record close (0983): scanning before
|
|
49
49
|
record reads unticked-but-proven boxes and folds a clean PASS to PARTIAL. When the task reaches
|
|
50
50
|
`done` through `--next`, run `spur task residual <wbs> settle` (best-effort). On a folded PARTIAL: the bounded remediation loop has
|
|
51
51
|
already run — a residual-failed task is routed to router C6 (HITL STOP), never another
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -103,7 +103,7 @@ surfaces is what keeps that gate quiet.
|
|
|
103
103
|
|
|
104
104
|
## Implement scope: do not run the project quality gate
|
|
105
105
|
|
|
106
|
-
During implement, the pipeline's `
|
|
106
|
+
During implement, the pipeline's `gate` state runs `${vars.qualityGateCmd}` (the full project gate:
|
|
107
107
|
`spur self exec check`) immediately after this step and is the gate that actually
|
|
108
108
|
decides pass/fail. Running it inside implement is pure redundancy — it cannot change the outcome and
|
|
109
109
|
only burns wall clock and context budget.
|
|
@@ -118,9 +118,9 @@ only burns wall clock and context budget.
|
|
|
118
118
|
re-select the execution tree inside the call (`cd -- "$TREE"` plus the identity check) instead of
|
|
119
119
|
relying on a `cd` a previous call left behind.
|
|
120
120
|
- **NEVER run** `spur self exec test`, `spur self exec check`, `bun run check`, or any other full-suite /
|
|
121
|
-
project-gate command from inside implement. These belong to the pipeline's `
|
|
121
|
+
project-gate command from inside implement. These belong to the pipeline's `gate` state.
|
|
122
122
|
- **Full-suite budget: at most 2 per task** (task 0436 R2) — counted across the whole task run
|
|
123
|
-
(implement probes + the pipeline `
|
|
123
|
+
(implement probes + the pipeline `gate` state and its rechecks), not per step. When a check fails,
|
|
124
124
|
run the narrow target (`bun test <file> --test-name-pattern <test>`) to green before any full
|
|
125
125
|
suite; reach for the second full run only when the narrow target cannot reproduce the failure.
|
|
126
126
|
- **Consolidate dogfood runs**: one combined real-data execution that exercises all scenarios,
|
|
@@ -128,7 +128,7 @@ only burns wall clock and context budget.
|
|
|
128
128
|
rerunning the same dogfood command with one flag changed, stop and fold the variants into a
|
|
129
129
|
single run — repeated identical commands are loop-detector findings and pure cost.
|
|
130
130
|
- If a targeted probe reveals a failure you cannot fix within implement scope, note it in
|
|
131
|
-
`## Solution` and let the `
|
|
131
|
+
`## Solution` and let the `gate` state's `remediate` hop handle it — do not pre-empt the gate.
|
|
132
132
|
|
|
133
133
|
### Public-surface probe (task 1135 R1/R6/R8)
|
|
134
134
|
|
|
@@ -155,7 +155,7 @@ changed no public surface, report the single line
|
|
|
155
155
|
- the paired-script parity test when `package.json` changed (a half-updated `spur-check` /
|
|
156
156
|
`spur-check:full` chain).
|
|
157
157
|
|
|
158
|
-
The single full project check stays the pipeline `
|
|
158
|
+
The single full project check stays the pipeline `gate` state's job (see the section above); these are
|
|
159
159
|
changed-path checks, not that gate.
|
|
160
160
|
|
|
161
161
|
## Changed-path targeted checks (dependency-aware verification, task 0510 R3 / task 1142 R3)
|
|
@@ -164,14 +164,14 @@ changed-path checks, not that gate.
|
|
|
164
164
|
surface can break a downstream consumer. The matrix below is dependency-aware — domain → app →
|
|
165
165
|
CLI — so a shared change verifies its consumers without recreating the full project check inside
|
|
166
166
|
implement. **It augments narrow behavior tests; it never authorizes `spur self exec check`,
|
|
167
|
-
`spur self exec test`, or another full project check inside implement** — the pipeline's `
|
|
167
|
+
`spur self exec test`, or another full project check inside implement** — the pipeline's `gate` state owns
|
|
168
168
|
that single full gate.
|
|
169
169
|
|
|
170
170
|
**Worker iteration check order (task 1142 R3):**
|
|
171
171
|
1. The **changed-path matrix** below (narrow behavior tests + affected consumers);
|
|
172
172
|
2. `spur task gate <wbs> light` (biome on changed files, per-workspace typecheck, rule presets `rules:pre`/`rules:post`, related tests).
|
|
173
173
|
|
|
174
|
-
Neither step takes the full project gate. The full gate is named only for the pipeline's `
|
|
174
|
+
Neither step takes the full project gate. The full gate is named only for the pipeline's `gate` state (first visit and rechecks).
|
|
175
175
|
|
|
176
176
|
| Changed surface | Required targeted tests | Required typechecks |
|
|
177
177
|
| --- | --- | --- |
|
|
@@ -189,7 +189,7 @@ Neither step takes the full project gate. The full gate is named only for the pi
|
|
|
189
189
|
(a flag the plugin layer consumes) actually changes, so an unconditional parity suite does not
|
|
190
190
|
creep into every plugin edit.
|
|
191
191
|
- Run the applicable rows, then stop: the single full project check belongs to the pipeline's
|
|
192
|
-
`
|
|
192
|
+
`gate` state (`task-pipeline.yaml` `${vars.qualityGateCmd}`).
|
|
193
193
|
- **Mirrored surfaces: an edit lands on all of them.** When the change is one instance of a repeated
|
|
194
194
|
pattern — the same wiring rule on two runbooks, a signature in both a generator and its generated
|
|
195
195
|
`.d.mts`, a command chain in both `spur-check` and `spur-check:full` — grep for the siblings and
|
|
@@ -89,8 +89,8 @@ and the deepening direction. Full definitions and examples in
|
|
|
89
89
|
| **minor** | advisory | Local friction: a module slightly too shallow, coupling that's awkward but not coordinated. |
|
|
90
90
|
| **advisory** | advisory | Deepening opportunity: the code works and is testable, but would be cleaner with a deeper module. Always non-blocking. |
|
|
91
91
|
|
|
92
|
-
**Under the pipeline** (`/sp:dev-review` in a task run), `blocker` and `major` block
|
|
93
|
-
|
|
92
|
+
**Under the pipeline** (`/sp:dev-review` in a task run), `blocker` and `major` block review
|
|
93
|
+
certification (a non-PASS review goes to the `review-failure-class` decision). `minor` and `advisory` are recorded but do not block. **Standalone** reviews
|
|
94
94
|
are advisory-only — the operator decides what to act on.
|
|
95
95
|
|
|
96
96
|
---
|
|
@@ -185,7 +185,7 @@ Each candidate is a structured finding:
|
|
|
185
185
|
When invoked as the `--focus architecture` dimension of `/sp:dev-review`:
|
|
186
186
|
|
|
187
187
|
- The scope is the task's diff (pipeline) or the `path` arg (standalone).
|
|
188
|
-
- `blocker`/`major` candidates block
|
|
188
|
+
- `blocker`/`major` candidates block review certification alongside any SECUA blockers from
|
|
189
189
|
`sp:code-verification`.
|
|
190
190
|
- The candidate list is returned as a **review fragment**; the review coordinator
|
|
191
191
|
(`sp:super-reviewer` — the invoking session under `/sp:dev-review`) merges it into the combined
|
|
@@ -42,10 +42,11 @@ Before reporting a task as complete, a test as passing, a bug as fixed, or a fea
|
|
|
42
42
|
|
|
43
43
|
## Under the pipeline
|
|
44
44
|
|
|
45
|
-
`task-pipeline.yaml`
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
PASS
|
|
45
|
+
`task-pipeline.yaml` enforces this gate deterministically. The `gate` state runs `spur task gate`
|
|
46
|
+
and a red result goes through the `failure-class` decision to `remediate`; the `review` state
|
|
47
|
+
certifies the review answer with `spur task verdict`, which writes the `VerifyVerdict` artifact.
|
|
48
|
+
`review → done` requires that PASS plus the approval decision point, and `done`'s `spur task record`
|
|
49
|
+
close transcribes the verdict to the task's `## Testing` section.
|
|
49
50
|
|
|
50
51
|
Under manual execution (no pipeline), the agent must still run the gates and paste the evidence.
|
|
51
52
|
"Manual" is not an exemption — it just means the agent, not the pipeline, runs the commands.
|
|
@@ -29,7 +29,7 @@ The **verifier** in the Spur execution loop. A coding agent reports "done" with
|
|
|
29
29
|
this skill is the deterministic counterweight that proves — or disproves — the claim against the
|
|
30
30
|
task's own requirements and Acceptance Criteria, then emits the canonical verdict artifact
|
|
31
31
|
through CLI verbs (section writes are owned by the review coordinator and the deterministic
|
|
32
|
-
`record`
|
|
32
|
+
`spur task record` close in `done` — F92 0593 R1).
|
|
33
33
|
|
|
34
34
|
It backs two commands:
|
|
35
35
|
|
|
@@ -321,7 +321,7 @@ spur task residual <wbs> fold
|
|
|
321
321
|
> **Do not write `## Review` directly, ever.** The `## Review` section is owned by the
|
|
322
322
|
> `review` coordinator (`/sp:dev-review` → `sp:super-reviewer`), which merges
|
|
323
323
|
> `functional-review` + `code-verification` review mode + `code-improvement` fragments. The
|
|
324
|
-
> `record`
|
|
324
|
+
> `spur task record` close backfills `## Review` from the verdict artifact **only** if the section is bare
|
|
325
325
|
> (`sectionIsBare` guard, `task-section-bodies.ts`) — a standalone compatibility fallback, never an
|
|
326
326
|
> overwrite of authored Review. Writing `## Review` here destroys the review step's
|
|
327
327
|
> three-dimensional findings.
|
|
@@ -546,7 +546,7 @@ Flags: `--agent <inline|auto|name>` (execution surface — inline default, with
|
|
|
546
546
|
|
|
547
547
|
## When to use
|
|
548
548
|
|
|
549
|
-
- **Verify a task before `done`** — the pipeline's `
|
|
549
|
+
- **Verify a task before `done`** — the pipeline's `review` state certifies it (`spur task verdict`), or a manual `/sp:dev-verify`.
|
|
550
550
|
- **Audit completed work** — `--force` re-verifies a `done` task (compliance, post-merge).
|
|
551
551
|
- **Focused code review** — `/sp:dev-review` for SECUA findings on a diff.
|
|
552
552
|
|
|
@@ -581,7 +581,7 @@ Do **not** use this skill for:
|
|
|
581
581
|
rubric.
|
|
582
582
|
- `plugins/sp/references/roles.md` — the Layer-1 role→tier table; this skill's verify/review modes
|
|
583
583
|
run under the `reviewer` role (0538 R4: this file points at roles.md, it does not restate tiers).
|
|
584
|
-
- `task-pipeline.yaml` — the `
|
|
584
|
+
- `task-pipeline.yaml` — the `review → done` gate that consumes the verdict.
|
|
585
585
|
- **`sp:spur-dev`** — the execution-half umbrella that drives the pipeline this skill gates.
|
|
586
586
|
- [references/code-improvement.md](references/code-improvement.md) — architecture-improvement lens
|
|
587
587
|
for module depth, seam placement, locality, coupling, and testability.
|
|
@@ -64,6 +64,14 @@ no level (ADR-131, 1196), no operator `ackLowConfidence`-style var exists, and h
|
|
|
64
64
|
findings carry no per-finding grade. A verifier that can write a PASS can still write a wrong
|
|
65
65
|
`HIGH` — which is exactly why the gate derives the level instead of trusting it.
|
|
66
66
|
|
|
67
|
+
**A review run carries two answer artifacts, one `Confidence:` line each (1254).** The `## Review`
|
|
68
|
+
section states the disposition-derived level (`deriveReviewConfidence`); the captured answer handed
|
|
69
|
+
to `spur task verdict --from-answer` states the evidence-derived level (`deriveVerifyConfidence`)
|
|
70
|
+
under the table above and carries exactly one `Confidence:` line. The two legitimately disagree — a
|
|
71
|
+
PASS with executable AC and one carried P4 is section `MEDIUM`, answer `HIGH` — so the captured
|
|
72
|
+
answer must not repeat the section's line (`confidence-duplicate` rejects the whole answer). The
|
|
73
|
+
review stage's prompt owns that instruction; this schema owns the shape it must produce.
|
|
74
|
+
|
|
67
75
|
## Compatibility alias: `scenario` row key
|
|
68
76
|
|
|
69
77
|
Task 0410 hardened the verdict reader. Producers SHOULD use the canonical `id` field for every
|
|
@@ -241,25 +249,33 @@ Wave C verification can emit the following additive `checks[]` rows:
|
|
|
241
249
|
|
|
242
250
|
## How the gate reads it
|
|
243
251
|
|
|
244
|
-
`task-pipeline.yaml
|
|
252
|
+
In `task-pipeline.yaml` the `review` state writes this artifact: `spur task verdict <wbs>
|
|
253
|
+
--from-answer` lints the review answer and derives `.spur/run/<wbs>-verdict.json`. A fold step then
|
|
254
|
+
writes `.spur/run/<wbs>-review.status` = PASS only when the typed verdict is PASS, the artifact's own
|
|
255
|
+
`verdict` is PASS (`jq -r '.verdict // empty'`) and `spur task residual <wbs> review-gate` is clean.
|
|
256
|
+
The `review → done` guard reads that status **and** the approval decision point's token:
|
|
245
257
|
|
|
246
258
|
```yaml
|
|
247
259
|
guard:
|
|
248
260
|
kind: shell
|
|
249
261
|
options:
|
|
250
|
-
command:
|
|
262
|
+
command: >-
|
|
263
|
+
test "$(cat ".spur/run/$wbs-review.status" 2>/dev/null)" = PASS &&
|
|
264
|
+
test "$(cat ".spur/run/$wbs-approval.status" 2>/dev/null)" = APPROVED
|
|
251
265
|
```
|
|
252
266
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
completion without an explicit PASS artifact.
|
|
267
|
+
A missing file, malformed JSON or any non-`PASS` verdict leaves the status FAIL, which the
|
|
268
|
+
`review-failure-class` decision routes to `remediate` (`fix`) or `failed` (`stop`). The pipeline
|
|
269
|
+
cannot certify completion without an explicit PASS artifact.
|
|
256
270
|
|
|
257
271
|
## Lifecycle
|
|
258
272
|
|
|
259
|
-
- **Written:**
|
|
260
|
-
|
|
261
|
-
- **
|
|
262
|
-
|
|
273
|
+
- **Written:** by `spur task verdict` in the pipeline's `review` state, or by Step 9 of standalone
|
|
274
|
+
verify mode, *after* the verdict is final (never partially).
|
|
275
|
+
- **Read:** by the review fold and the `review → done` guard, then by `done`'s `spur task record`
|
|
276
|
+
close, which transcribes it.
|
|
277
|
+
- **Location:** `.spur/run/`.
|
|
278
|
+
- **Lifetime:** per execution attempt; overwritten on the next certification of the same WBS.
|
|
263
279
|
|
|
264
280
|
## Optional check severity (task 0592, feature F92)
|
|
265
281
|
|
|
@@ -304,6 +320,6 @@ The prose shape above is executed by a single runtime-validated contract:
|
|
|
304
320
|
failure can never yield PASS.
|
|
305
321
|
- A row-less artifact aggregates to UNKNOWN — a stored PASS that does not recompute to PASS
|
|
306
322
|
(including a row-less PASS) is treated as non-PASS at the done gate. The done-transition choke
|
|
307
|
-
point (`done-transition-guard.ts` `evaluateDoneTransition`) is the final authority; workflow
|
|
308
|
-
routing may select `
|
|
323
|
+
point (`done-transition-guard.ts` `evaluateDoneTransition`) is the final authority; workflow
|
|
324
|
+
routing may select `review → done/failed` but cannot weaken the final transition.
|
|
309
325
|
- `--force-done --reason` on `spur task update <wbs> done` remains the sole auditable override.
|
|
@@ -295,7 +295,7 @@ Include the per-requirement traceability table in the report:
|
|
|
295
295
|
**Under the pipeline**, `sp:functional-review` is a component of `/sp:dev-review`: it returns its
|
|
296
296
|
fragment to the coordinator (`sp:super-reviewer` — the invoking session under `/sp:dev-review`),
|
|
297
297
|
which writes the combined `## Review`. The
|
|
298
|
-
`record`
|
|
298
|
+
`done` state's `spur task record` close transcribes only `## Testing` from the verdict artifact and backfills `## Review`
|
|
299
299
|
only when the section is bare (`sectionIsBare` guard, `task-section-bodies.ts`); it never overwrites the
|
|
300
300
|
coordinator's authored Review. Keep the priority-table lead stable in the fragment so the L3 gate
|
|
301
301
|
stays satisfied through `record` → `done`.
|
|
@@ -130,4 +130,4 @@ all core requirements MET → PASS
|
|
|
130
130
|
| `VerifyVerdict` | `sp:code-verification` | Is the code SECUA-correct and AC-complete? | any core req/AC UNMET → FAIL; any blocker correctness/security → FAIL; any PARTIAL → PARTIAL; else PASS |
|
|
131
131
|
|
|
132
132
|
A complete `/sp:dev-review --focus all` pipeline may produce both artifacts; they are consumed by
|
|
133
|
-
the
|
|
133
|
+
the `done` state's `spur task record` close and written to the task's `## Testing` section.
|
|
@@ -125,7 +125,7 @@ token, deterministic).
|
|
|
125
125
|
means the workspace holds unfinished task residue, so fixall/unit reruns would either clean it
|
|
126
126
|
unintentionally or re-certify a folded verdict. C6 fires before any fix/unit dispatch; recovery is
|
|
127
127
|
the operator re-running the pipeline (`/sp:dev-run <wbs>`), which re-enters the normal
|
|
128
|
-
|
|
128
|
+
gate ⇄ remediate budget.
|
|
129
129
|
|
|
130
130
|
**Explicit non-probes in v1:** no freeform chat history; no always-on full `bun run test` for every
|
|
131
131
|
call; no git dirtiness as a route (optional advisory print only).
|
|
@@ -92,7 +92,7 @@ preserved by construction. `recheck` stays the no-progress probe path for fix lo
|
|
|
92
92
|
|
|
93
93
|
## Composition
|
|
94
94
|
|
|
95
|
-
- **Pipeline:** `sp:spur-dev` runs `run`
|
|
95
|
+
- **Pipeline:** `sp:spur-dev` runs `run` on the `gate` state's first visit and `recheck` on later visits (after `remediate`); light mode
|
|
96
96
|
belongs to implement/fix edits, not to the gate state.
|
|
97
97
|
- **Fix loops:** `/sp:dev-fixall --gate-log` consumes `<wbs>-test-gate.log` (and the bounded
|
|
98
98
|
`<wbs>-test-gate.findings` anchors) after a red gate; it never writes receipts. A green fixall
|
|
@@ -50,7 +50,7 @@ Pick the noun, read its reference. Each Tier A and Tier B reference owns that no
|
|
|
50
50
|
| **Tier B** | **self** | Self-management verbs: scaffold (`init`), project SDLC actions (`exec`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), status overview (`status`); `self init` runs post-scaffold validation probes & layout classification | [references/self.md](references/self.md) |
|
|
51
51
|
| **Tier B** | **history** | Import agent histories, aggregate forensic artifacts, render reports, and run the checkpoint-resumed daily pipeline | [references/history.md](references/history.md) |
|
|
52
52
|
| **Tier B** | **projects** | Manage the local multi-project registry and start/stop project servers | [references/projects.md](references/projects.md) |
|
|
53
|
-
| **Tier B** | **decision** | Decision
|
|
53
|
+
| **Tier B** | **decision** | Decision catalog: list visible decisions, show a served contract, run a decision to a served outcome, audit catalog health and maker reliability; author and tune catalog entries | [references/decision.md](references/decision.md) |
|
|
54
54
|
| **Tier C** | **help** | Commander-generated help command; not a Spur noun | Generated `--help` |
|
|
55
55
|
|
|
56
56
|
**Execute-First Contract:** Load the noun reference first and execute Tier A or Tier B commands
|
|
@@ -69,6 +69,26 @@ Each noun's per-topic detail lives one level deeper under `references/<noun>/` (
|
|
|
69
69
|
`references/tasks/verbs.md`, `references/tasks/section-editing.md`, `references/features/acceptance-criteria.md`,
|
|
70
70
|
`references/rules/operations.md`, `references/workflows/authoring-workflows.md`).
|
|
71
71
|
|
|
72
|
+
## Lifecycle playbooks
|
|
73
|
+
|
|
74
|
+
Authorable nouns carry a `## Lifecycle playbook` (rules: `## Lifecycle map`) in one shared stage
|
|
75
|
+
vocabulary — **Create → Evaluate → Triage → Enhance** — each row naming the command and the gate
|
|
76
|
+
that proves the stage, plus best practices. The playbook links the noun's subfiles; it never
|
|
77
|
+
restates them.
|
|
78
|
+
|
|
79
|
+
| Noun | Playbook |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| task | [references/tasks.md](references/tasks.md#lifecycle-playbook) |
|
|
82
|
+
| feature | [references/features.md](references/features.md#lifecycle-playbook) |
|
|
83
|
+
| rule | [references/rules.md](references/rules.md#lifecycle-map) |
|
|
84
|
+
| workflow | [references/workflows.md](references/workflows.md#lifecycle-playbook) |
|
|
85
|
+
| agent spec | [references/agent.md](references/agent.md#lifecycle-playbook-agent-specs) |
|
|
86
|
+
| decision | [references/decision/lifecycle.md](references/decision/lifecycle.md) |
|
|
87
|
+
|
|
88
|
+
Operational nouns (builder, message, self, history, projects) run verbs rather than author
|
|
89
|
+
artifacts, so they have no playbook. Cross-noun selection and composition live in
|
|
90
|
+
`sp:spur-composer`; read-only evaluation reports in `sp:spur-doctor`.
|
|
91
|
+
|
|
72
92
|
## When to use
|
|
73
93
|
|
|
74
94
|
Use this skill to:
|
|
@@ -144,7 +164,8 @@ and spreading it; full contract in `docs/04_DESIGN.md` §1.0.1.
|
|
|
144
164
|
- **[references/message.md](references/message.md)** - durable inter-agent messaging (`send`,
|
|
145
165
|
`inbox`, `reply`, `watch`).
|
|
146
166
|
- **[references/decision.md](references/decision.md)** - decision catalog (`list`, `show`, `run`,
|
|
147
|
-
`status`);
|
|
167
|
+
`status`); with no reachable backend each decision serves its declared fallback. Authoring and
|
|
168
|
+
tuning: [references/decision/lifecycle.md](references/decision/lifecycle.md).
|
|
148
169
|
- **[references/self.md](references/self.md)** - `spur self init|exec|maintain|migrate|serve|status` CLI verbs
|
|
149
170
|
(the five legacy top-level nouns remain hidden aliases). `self init` runs post-scaffold init
|
|
150
171
|
validation (Phase 1.5/1.6 probes).
|
|
@@ -400,6 +400,18 @@ failed drains marked the session poisoned. The next drain opens a fresh session.
|
|
|
400
400
|
only. A settled (delivered) inbox message is never redelivered — resuming a session or resetting
|
|
401
401
|
one never re-sends settled work; only never-started deliveries release and redeliver (0831/0834).
|
|
402
402
|
|
|
403
|
+
## Lifecycle playbook (agent specs)
|
|
404
|
+
|
|
405
|
+
| Stage | How | Gate / evidence |
|
|
406
|
+
| --- | --- | --- |
|
|
407
|
+
| **Create** | Prefer an `agent.fleet.members` entry; hand-author `.spur/agents/<id>.yaml` only for a spec the fleet cannot express | `spur agent list --specs --json` shows the row with the intended `source` |
|
|
408
|
+
| **Evaluate** | `spur agent doctor [agent] --json` for the executor; `spur agent status --json` for the live process and member session | Executor ready; spec resolves |
|
|
409
|
+
| **Triage** | Run failed → `spur agent trace <runId> --json`; stuck occupant → `spur agent wait <specId> --until <state> --timeout <ms>`; supervisor unreachable → `spur self serve` | Lineage names the failing dispatch |
|
|
410
|
+
| **Enhance** | Change one field (executor, model, role) and re-run the same prompt | Compare the two `trace` records |
|
|
411
|
+
|
|
412
|
+
- The fleet declaration wins on an id clash; do not keep a same-id file "as a backup".
|
|
413
|
+
- Coordinate through `spur message` / `spur agent wait`, never terminal scraping.
|
|
414
|
+
|
|
403
415
|
## What this skill is NOT
|
|
404
416
|
|
|
405
417
|
- **Not the dispatch decision.** *When* to use `spur agent run` vs a native subagent is the
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spur-cli-decision-lifecycle
|
|
3
|
+
description: "spur decision lifecycle: author a catalog entry, wire it into a workflow, evaluate a maker with recorded evidence, triage fallbacks and catalog errors, and tune criteria, floors and makers."
|
|
4
|
+
see_also:
|
|
5
|
+
- spur-cli
|
|
6
|
+
- spur-composer
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Decision lifecycle — create, evaluate, triage, enhance
|
|
10
|
+
|
|
11
|
+
The verb catalog is [../decision.md](../decision.md). This file is the per-noun procedure: how a
|
|
12
|
+
decision point is born, proven, diagnosed and improved. Contracts it links rather than restates:
|
|
13
|
+
[decision catalog design](../../../../../../docs/design/decision-catalog.md) (§3.1 SSOT, §3.2 layers,
|
|
14
|
+
§3.6 maker precedence) and
|
|
15
|
+
[decision observability](../../../../../../docs/design/decision-observability-and-adoption.md) (§3.4
|
|
16
|
+
reliability, §4 workflow audit, §5 staged adoption). The upstream format authority is the
|
|
17
|
+
`@gobing-ai/ts-ai-decision` README and its `schemas/decision-catalog.schema.json`.
|
|
18
|
+
|
|
19
|
+
## 1. Decide it is a decision at all
|
|
20
|
+
|
|
21
|
+
A catalog decision is a **total classification**: a closed vocabulary, a declared fallback, and a
|
|
22
|
+
recorded outcome. Use the §4 audit classes before authoring anything:
|
|
23
|
+
|
|
24
|
+
| Class | Use when | Shape |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| **keep-deterministic** | An exact check answers it (status file, exit code, count, regex) | No decision; a shell guard or rule |
|
|
27
|
+
| **rescue-only** | A deterministic parse answers most inputs; free-form output sometimes defeats it | Parse first, call the decision only on what the parse cannot classify |
|
|
28
|
+
| **adopt** | The input is judgement over prose/diff evidence and a safe default exists | Catalog-reference `decide` step |
|
|
29
|
+
| **keep-human** | It is an operator taste gate | `hitl.confirm`/`hitl.select`; opt-in `decision.mode: evidence` routes through `gate-evidence` |
|
|
30
|
+
|
|
31
|
+
A model is a regression wherever an exact check exists. A decision with no safe fallback is a gate,
|
|
32
|
+
not a decision.
|
|
33
|
+
|
|
34
|
+
## 2. Create
|
|
35
|
+
|
|
36
|
+
1. **Select first.** `spur decision list --json` across every layer; `spur decision show <id> --json`
|
|
37
|
+
on near matches. An existing id whose criteria fit is reused, never cloned under a new id.
|
|
38
|
+
2. **Pick the layer** (the composer ladder, [spur-composer](../../../spur-composer/SKILL.md)):
|
|
39
|
+
scratch → `.spur/decisions/<file>.yaml` (project) → shared `config/decisions/<file>.yaml` (spur
|
|
40
|
+
repository only, recorded operator consent + `build:bundle`). Winners are chosen **per file
|
|
41
|
+
basename** before the hub loads, so a project file named like a shipped one replaces that whole
|
|
42
|
+
shipped file — copy every id you still need, or use a new basename.
|
|
43
|
+
3. **Author the entry** (format version 1; unknown keys are rejected at every level):
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
version: 1
|
|
47
|
+
defaults:
|
|
48
|
+
minConfidence: 0.8 # repo convention for pipeline decisions; upstream default is 0.7
|
|
49
|
+
decisions:
|
|
50
|
+
review-scope: # ^[a-z][a-z0-9_-]*$ — stable id, it keys the ledger
|
|
51
|
+
type: choice # choice | score | noul
|
|
52
|
+
description: Which review depth does this diff need? # documentation only, never sent
|
|
53
|
+
parameters:
|
|
54
|
+
wbs:
|
|
55
|
+
type: string # string | number | boolean | enum | json
|
|
56
|
+
description: Task WBS the diff belongs to.
|
|
57
|
+
criteria: # choice: >= 2 labels, each label's meaning in one sentence
|
|
58
|
+
light: Docs-only or test-only diff with no runtime surface.
|
|
59
|
+
full: Any runtime, contract, schema or security-relevant change.
|
|
60
|
+
fallback: full # must be a declared label; the safe answer on any backend failure
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- A parameter with no `default` is **required**. `instructions` is reserved: it is the implicit
|
|
64
|
+
channel `--evidence` and workflow `evidence:` feed. Never declare it.
|
|
65
|
+
- `fallback` is the outcome on `no-backend`, `timeout`, `error` and `low-confidence`. Choose the
|
|
66
|
+
answer that is **safe when wrong** (`full`, `fix`, `defer`, `standard`), not the most common one.
|
|
67
|
+
- Leave `maker` out of shipped catalogs. Operator config outranks the catalog
|
|
68
|
+
(`flag → decisions.makers.<id> → decisions.maker → catalog`) because only the machine owner
|
|
69
|
+
knows which backends exist there.
|
|
70
|
+
- Spur's `DecisionService` resolves the effective maker as one name. Upstream maker chains
|
|
71
|
+
(`maker: [a, b]`) and `shadow` exist in the schema but are not surfaced by `decision show`
|
|
72
|
+
or `status` today; prove them with `run` before relying on them.
|
|
73
|
+
4. **Gate it:** `spur decision status --json` must show no `loadErrors` / `duplicateIds` and exit 0;
|
|
74
|
+
`spur decision show <id> --json` must render the parameters, criteria and fallback you meant.
|
|
75
|
+
|
|
76
|
+
## 3. Wire into a workflow (optional)
|
|
77
|
+
|
|
78
|
+
Use the catalog-reference `decide` form; the inline `question`/`method`/`default` form is
|
|
79
|
+
deprecated (composition lint and the runner warn once per site):
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
- kind: decide
|
|
83
|
+
options:
|
|
84
|
+
id: review-scope # step id; one resultFile per step
|
|
85
|
+
decision: review-scope # catalog id
|
|
86
|
+
params: { wbs: '${vars.wbs}' }
|
|
87
|
+
evidence: # redacted + bounded to 2000 chars, joined into instructions
|
|
88
|
+
- .spur/run/${vars.wbs}-diffstat.json
|
|
89
|
+
resultFile: .spur/run/${vars.wbs}-review-scope.decision
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- Guards read the schemaVersion-1 `resultFile` row (`value`, `source`, `degraded`, `confidence`).
|
|
93
|
+
Route on `source == "model"` only where a degraded fallback must be distinguishable.
|
|
94
|
+
- `workflows.decideDecisionMaker` gates the workflow action. Off (the default) → every `decide`
|
|
95
|
+
serves its fallback with no model call. `spur decision run` ignores the switch.
|
|
96
|
+
- `evidence` and `instructions` are mutually exclusive; `params.instructions` fails the action.
|
|
97
|
+
- Validate with `spur workflow validate <file> --json` and `spur workflow run <file> --dry-run`.
|
|
98
|
+
|
|
99
|
+
## 4. Evaluate
|
|
100
|
+
|
|
101
|
+
Evidence before adoption — the S4a–c slices each landed only with recorded `run` evidence for the
|
|
102
|
+
effective maker (observability §5).
|
|
103
|
+
|
|
104
|
+
| Question | Evidence (read-only unless noted) |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| Does the contract say what I meant? | `spur decision show <id> --json` |
|
|
107
|
+
| Does the catalog load cleanly? | `spur decision status --json` → `ok`, `loadErrors`, `duplicateIds`, `errors` |
|
|
108
|
+
| Is the maker registered / configured / ever used? | `spur decision status` readiness marks (`ST`, `CONFIGURED BY`, `RECORDED`, `ACCEPTED`) |
|
|
109
|
+
| Does the maker answer right now? | `spur decision status --probe` (calls each effective maker once; writes nothing) |
|
|
110
|
+
| How well has it served? | `spur decision status --reliability [--since <iso>] --json` → per `decisionId × maker`: `samples`, `acceptedRate`, `fallbacks{reason}`, `medianConfidence`, p50/p95 duration |
|
|
111
|
+
| Does it classify known cases correctly? | `spur decision run <id> --param … --evidence <fixture> --json` per labelled fixture (records a ledger row) |
|
|
112
|
+
|
|
113
|
+
Build a small labelled fixture set — at least one clear case per label plus one ambiguous case — and
|
|
114
|
+
run it against each candidate maker with `--maker <name>`. Compare `value` to the label, not just
|
|
115
|
+
`source: model`: an accepted wrong answer is worse than a fallback.
|
|
116
|
+
|
|
117
|
+
**Read confidence per maker type.** Probability-native makers (`typesafe`, `laya-local`, `clef`)
|
|
118
|
+
return a model distribution. Sampled makers (`fm-local`) return agreement over k samples, so
|
|
119
|
+
`accepted` means "all samples agreed" and 1.0 is unanimity, not calibration. Choose a
|
|
120
|
+
probability-native maker where the floor must discriminate.
|
|
121
|
+
|
|
122
|
+
## 5. Triage
|
|
123
|
+
|
|
124
|
+
| Symptom | Likely cause | Next step |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| `status` exits 1, `loadErrors` names a file | Schema violation (unknown key, fallback not a declared label, bad `${params.*}` ref) | Fix the file; the whole catalog file is skipped until it loads |
|
|
127
|
+
| `duplicateIds` non-empty | Same id in two winning files of different basenames | Rename or delete one; any `run`/`decide` of that id fails meanwhile |
|
|
128
|
+
| `run` exits 1 | Caller mistake: unknown id, undeclared/missing/invalid param, unregistered `--maker`, unreadable evidence | Read the message; nothing reached a backend |
|
|
129
|
+
| `source: default`, `reason: no-backend` | Maker cannot be constructed (missing credentials, wrong host) | `status --probe`; set credentials or override `decisions.makers.<id>` |
|
|
130
|
+
| `reason: timeout` | Cold local model or unreachable host | Re-probe; prefer a warm or hosted maker for pipeline-critical ids |
|
|
131
|
+
| `reason: error` | Backend rejected the call or returned an invalid answer | Check `decision_logs.error`; on `typesafe`, parameterless decisions hit the known `state: null` 422 until the ts-libs bump (design §5) |
|
|
132
|
+
| `reason: low-confidence`, repeated | Criteria labels overlap, evidence is too thin, or a sampled maker disagrees with itself | Sharpen criteria (§6), add evidence, or switch to a probability-native maker |
|
|
133
|
+
| `RECORDED > 0`, `ACCEPTED 0` | Maker is wired but has never once succeeded | Treat as broken, not healthy; triage by `fallbacks` reason |
|
|
134
|
+
| Config names a maker `status` calls unregistered | Typo, or `clef` without `CLOUDFLARE_ACCOUNT_ID`/`CLOUDFLARE_AUTH_TOKEN` | Loud by design — fix the name or the environment |
|
|
135
|
+
| A `decide` step always degrades | `workflows.decideDecisionMaker` is off | Intended default; enable only after §4 evidence |
|
|
136
|
+
|
|
137
|
+
## 6. Enhance
|
|
138
|
+
|
|
139
|
+
Tune one lever at a time and re-run the same fixture set; a change with no before/after evidence
|
|
140
|
+
pair is a preference.
|
|
141
|
+
|
|
142
|
+
| Lever | When | Where |
|
|
143
|
+
| --- | --- | --- |
|
|
144
|
+
| **Criteria wording** | Low confidence or wrong labels on clear cases | Make labels mutually exclusive and observable ("touches runtime code"), not evaluative ("risky") |
|
|
145
|
+
| **Evidence** | The model cannot see what decides the answer | Add or trim workflow `evidence` files; keep each well under the 2000-char bound |
|
|
146
|
+
| **Parameters** | The answer depends on a structured fact | Declare a typed parameter instead of burying it in evidence |
|
|
147
|
+
| **`minConfidence`** | Fallback rate is too high with correct answers, or too low with wrong ones | Per-decision field; lower only with fixture evidence that low-confidence answers were right |
|
|
148
|
+
| **Maker** | Reliability differs by backend | Operator config `decisions.makers.<id>` (not the shipped catalog) |
|
|
149
|
+
| **Fallback** | The safe-when-wrong answer changed | Change only with the owning workflow's guard reviewed in the same change |
|
|
150
|
+
| **Adoption class** | A deterministic parse now covers the input | Demote to rescue-only or keep-deterministic |
|
|
151
|
+
|
|
152
|
+
Never rename a shipped id: the ledger, Board Decisions tab and workflow `decision:` references all
|
|
153
|
+
key on it. Add a new id and retire the old one through the workflow change.
|
|
154
|
+
|
|
155
|
+
## 7. Best practices
|
|
156
|
+
|
|
157
|
+
- **Determinism first, model second.** Every adopted decision keeps a deterministic route or a safe
|
|
158
|
+
fallback so the pipeline behaves identically with the switch off.
|
|
159
|
+
- **One question per id.** A decision that needs "and" in its description is two decisions.
|
|
160
|
+
- **Labels are a contract.** Guards and downstream shell read the label strings; treat a label
|
|
161
|
+
rename as a breaking change.
|
|
162
|
+
- **Probe is not evidence.** `--probe` proves liveness; only `--reliability` and labelled `run`
|
|
163
|
+
results prove quality, and the probe never writes the rows it would inflate.
|
|
164
|
+
- **Never route pipeline correctness on `maker-liveness`.** It serves only `status --probe`.
|
|
165
|
+
- **Measure before you migrate.** Land the catalog entry, gather `run` evidence, then adopt in a
|
|
166
|
+
workflow — one decision point per change.
|