@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
|
@@ -155,15 +155,28 @@ workflows:
|
|
|
155
155
|
# catalogs. `paths` registers extra catalog folders (absolute or
|
|
156
156
|
# project-relative); the first layer wins per file basename (ADR-113 style).
|
|
157
157
|
# `maker` selects the default DecisionMaker for every decision point, and
|
|
158
|
-
# `makers` overrides it per decision id.
|
|
159
|
-
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
158
|
+
# `makers` overrides it per decision id. The value is any maker name the
|
|
159
|
+
# registry currently registers — the list lives in the CLI, not here, so
|
|
160
|
+
# `spur decision status` (registeredMakers) is the authority, together with each
|
|
161
|
+
# maker's own prerequisites (a local maker needs its local stack; a hosted maker
|
|
162
|
+
# registers only when its credentials are set). An unregistered name is a config
|
|
163
|
+
# error, never a silent fallback. Inspect the effective choice per decision with
|
|
164
|
+
# the same command. `init` never overwrites this file — until you add the keys,
|
|
165
|
+
# the shipped catalog's maker applies (see `status`).
|
|
165
166
|
decisions:
|
|
166
167
|
paths: []
|
|
167
168
|
maker: typesafe
|
|
168
169
|
# makers:
|
|
169
|
-
# task-
|
|
170
|
+
# task-semantic-risk: laya-local
|
|
171
|
+
# What "the decision was right" means (task 1263 R5): per decision id, the recorded outcomes
|
|
172
|
+
# that count as correct for each served value. `String(value)` keys, so a yes/no decision uses
|
|
173
|
+
# "true"/"false". The outcome verb records them (`spur decision outcome <invocation-id> ...`);
|
|
174
|
+
# `spur decision status --reliability` scores accuracy against this map and reports null for a
|
|
175
|
+
# decision with no entry, rather than guessing.
|
|
176
|
+
outcomeMap:
|
|
177
|
+
failure-class:
|
|
178
|
+
fix: [fixed]
|
|
179
|
+
stop: [not-fixed]
|
|
180
|
+
task-semantic-risk:
|
|
181
|
+
"false": [none, p4, p3]
|
|
182
|
+
"true": [p1, p2]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
$schema: "@gobing-ai/spur/schemas/decision-catalog.schema.json"
|
|
2
|
+
# Executor-failure rescue catalog (feature P1, task 1264).
|
|
3
|
+
#
|
|
4
|
+
# The executor loop escalates on `FAILURE_RULES` matches only (0407 precision bias). Anything the
|
|
5
|
+
# rules miss — a reworded rate limit, "credits depleted", a proxy error body — ends the run as a
|
|
6
|
+
# task defect. This decision classifies ONLY that residue, after the rules and the terminal checks
|
|
7
|
+
# (timeout, permission denial, confirmed quota) have had their say, and only while
|
|
8
|
+
# `workflows.executorFailureDecisionMaker` is on. It ships off by default: shipping off routes
|
|
9
|
+
# nothing, and turning it on is an operator call backed by replay evidence in task 1264's Q&A.
|
|
10
|
+
#
|
|
11
|
+
# Resolution: shared layer, overridable per basename through `.spur/decisions/` or
|
|
12
|
+
# `decisions.paths` (first layer wins, ADR-113 style).
|
|
13
|
+
version: 1
|
|
14
|
+
|
|
15
|
+
defaults:
|
|
16
|
+
# Higher than the catalog floor: a false `resource-exhaustion` costs a failover attempt, and a
|
|
17
|
+
# false `task-defect` equals today's behaviour — so the uncertainty must resolve downward.
|
|
18
|
+
minConfidence: 0.85
|
|
19
|
+
|
|
20
|
+
decisions:
|
|
21
|
+
executor-failure-class:
|
|
22
|
+
type: choice
|
|
23
|
+
description: Is an unmatched agent-dispatch failure resource exhaustion, an auth failure, or a task defect?
|
|
24
|
+
instructions: |
|
|
25
|
+
You are classifying why one agent dispatch exited non-zero, after every deterministic
|
|
26
|
+
rule already declined to classify it.
|
|
27
|
+
Failure output: ${params.instructions}
|
|
28
|
+
Answer `resource-exhaustion` only when the output states a provider-side capacity or
|
|
29
|
+
billing limit: a quota/credit/billing message, a 429 or rate-limit body, a token or
|
|
30
|
+
request budget, or an "overloaded"/"capacity" error. Answer `auth` only when the
|
|
31
|
+
output states a credential or authorization fault: an invalid/expired key or token, a
|
|
32
|
+
401/403 body, or a missing credential for the provider. Answer `task-defect` for
|
|
33
|
+
everything else: a compile or test failure, a missing file, a malformed prompt, a
|
|
34
|
+
socket/proxy error, or output that does not name a provider limit at all.
|
|
35
|
+
Classify only what the output says. Do not infer a vendor, and do not guess.
|
|
36
|
+
parameters:
|
|
37
|
+
wbs:
|
|
38
|
+
type: string
|
|
39
|
+
description: Task WBS the failing dispatch belongs to, when known.
|
|
40
|
+
# Optional: the executor seam knows only the run id, and a required param would
|
|
41
|
+
# reject every rescue before it reached a maker.
|
|
42
|
+
default: ""
|
|
43
|
+
criteria:
|
|
44
|
+
resource-exhaustion: >
|
|
45
|
+
The output names a provider-side limit — quota, credits, billing period, rate
|
|
46
|
+
limit, 429, token budget, or capacity.
|
|
47
|
+
auth: >
|
|
48
|
+
The output names a credential or authorization fault — invalid or expired key or
|
|
49
|
+
token, 401/403, or a missing credential.
|
|
50
|
+
task-defect: >
|
|
51
|
+
The output names no provider limit or credential fault — a code/test/file error, a
|
|
52
|
+
prompt problem, or a transport error that is not a provider quota.
|
|
53
|
+
fallback: task-defect
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
$schema: "@gobing-ai/spur/schemas/decision-catalog.schema.json"
|
|
2
|
-
# Decision catalogs for the task pipeline (feature
|
|
2
|
+
# Decision catalogs for the task pipeline (feature P1, ADR-134).
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
4
|
+
# The shipped `config/workflows/task-pipeline.yaml` decide actions reference these ids
|
|
5
|
+
# (`failure-class`, and `task-semantic-risk` once its evidence bar is met). Each entry's
|
|
6
|
+
# reliability is measured from recorded `decision.*` events — `spur decision status
|
|
7
|
+
# --reliability` — and an adoption slice only keeps a decision point while that evidence
|
|
8
|
+
# shows it adds information the deterministic guards do not.
|
|
9
9
|
#
|
|
10
10
|
# Resolution: this file ships in the shared layer (the installed package's
|
|
11
11
|
# config/decisions/). A project can override it per basename through
|
|
@@ -17,39 +17,55 @@ defaults:
|
|
|
17
17
|
minConfidence: 0.8
|
|
18
18
|
|
|
19
19
|
decisions:
|
|
20
|
-
task-
|
|
21
|
-
type:
|
|
22
|
-
description:
|
|
20
|
+
task-semantic-risk:
|
|
21
|
+
type: noul
|
|
22
|
+
description: >
|
|
23
|
+
Does this task's change set change behaviour a reviewer must reason about beyond what
|
|
24
|
+
the diffstat already shows? (false projects the fast lane, true or a fallback the
|
|
25
|
+
standard lane.)
|
|
26
|
+
instructions: |
|
|
27
|
+
You are classifying one Spur task's change set for review depth.
|
|
28
|
+
Change set: ${params.instructions}
|
|
29
|
+
Answer true when the change alters behaviour a reviewer must reason about: control
|
|
30
|
+
flow, a data shape, persistence, security, an external contract, or error handling.
|
|
31
|
+
Answer false only when the change is mechanical — docs, comments, formatting, renames,
|
|
32
|
+
test-only edits, or a dependency bump with no source edit.
|
|
33
|
+
Judge the change set only; do not score its quality or estimate its size.
|
|
23
34
|
parameters:
|
|
24
35
|
wbs:
|
|
25
36
|
type: string
|
|
26
|
-
description: Task WBS
|
|
37
|
+
description: Task WBS whose change set is being classified.
|
|
27
38
|
criteria:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
"true": >
|
|
40
|
+
The change set touches executable behaviour — a branch, a boundary, a stored
|
|
41
|
+
schema, a public signature, or a failure path — so a reviewer must read the diff,
|
|
42
|
+
not only its diffstat.
|
|
43
|
+
"false": >
|
|
44
|
+
The change set is mechanical — docs, comments, formatting, renames, test-only
|
|
45
|
+
edits, or a version bump with no executable change — so the diffstat is enough.
|
|
46
|
+
fallback: true
|
|
32
47
|
|
|
33
48
|
failure-class:
|
|
34
49
|
type: choice
|
|
35
50
|
description: Is a failed quality gate fixable by the repair agent, or should the run stop?
|
|
51
|
+
instructions: |
|
|
52
|
+
You are classifying one failed quality-gate run for Spur's task pipeline.
|
|
53
|
+
Gate output: ${params.instructions}
|
|
54
|
+
Answer `fix` when the output names a concrete defect inside this repository that the
|
|
55
|
+
repair agent can act on: a failing test with an expected/actual diff, a type error
|
|
56
|
+
naming a file and symbol, a lint rule id with a file:line, or a missing export or
|
|
57
|
+
import. Answer `stop` when the failure is environmental or not repairable by editing
|
|
58
|
+
this tree: a missing tool or binary, a permission or disk error, a network or registry
|
|
59
|
+
failure, a gate timeout, or output that names no in-tree file.
|
|
36
60
|
parameters:
|
|
37
61
|
wbs:
|
|
38
62
|
type: string
|
|
39
63
|
description: Task WBS whose gate failed.
|
|
40
64
|
criteria:
|
|
41
|
-
fix:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
description: Is a non-PASS review fixable by the repair agent, or should the run stop?
|
|
48
|
-
parameters:
|
|
49
|
-
wbs:
|
|
50
|
-
type: string
|
|
51
|
-
description: Task WBS whose review did not certify PASS.
|
|
52
|
-
criteria:
|
|
53
|
-
fix: The findings look fixable — send them to the repair agent.
|
|
54
|
-
stop: The findings are not mechanically fixable — stop the run for the operator.
|
|
65
|
+
fix: >
|
|
66
|
+
The output names an in-tree defect — a failing test, a type error with a file and
|
|
67
|
+
symbol, a lint rule id with a file:line, or a missing import.
|
|
68
|
+
stop: >
|
|
69
|
+
The output names no in-tree defect — a missing tool, a permission or disk error,
|
|
70
|
+
a network or registry failure, or a timeout — so editing the tree cannot fix it.
|
|
55
71
|
fallback: fix
|
|
@@ -396,7 +396,7 @@ states:
|
|
|
396
396
|
# (probe-then-full), `deferred` under the opt-in batch policy.
|
|
397
397
|
#
|
|
398
398
|
# The three former routing states are decision CALLS here and in `review` (D65 1239 R1):
|
|
399
|
-
# the lane decision (0943 R1/R2, catalog `task-
|
|
399
|
+
# the lane decision (0943 R1/R2, catalog `task-semantic-risk`, 1262 R5) picks the review depth, and the
|
|
400
400
|
# gate's own failure class (catalog `failure-class`) drives the red-gate transitions.
|
|
401
401
|
# Both run unconditionally — the engine has no onEnter conditionals — and both degrade to
|
|
402
402
|
# their catalog fallback with no model call while `workflows.decideDecisionMaker` is off.
|
|
@@ -407,7 +407,7 @@ states:
|
|
|
407
407
|
title: Run quality gate
|
|
408
408
|
description: >
|
|
409
409
|
Typed quality gate: resolve the task path/priority, produce the diffstat lane
|
|
410
|
-
evidence, consult `task-
|
|
410
|
+
evidence, consult `task-semantic-risk` for the review depth (deterministic safety floor
|
|
411
411
|
first), run `${vars.qualityGateCmd}` through `spur task gate <wbs> <mode>` under the
|
|
412
412
|
host-wide lock (tree-hash receipt reuse on the same tree), then classify a red gate
|
|
413
413
|
through `failure-class`. Writes the typed outcome to
|
|
@@ -446,27 +446,30 @@ states:
|
|
|
446
446
|
options:
|
|
447
447
|
command: >-
|
|
448
448
|
mkdir -p .spur/run; if [ -n "$mode" ]; then printf '%s\n' "$mode" > ".spur/run/$wbs-mode.txt"; exit 0; fi; DF=".spur/run/$wbs-diffstat.json"; if ! jq -e 'type == "object"' "$DF" >/dev/null 2>&1; then printf 'safety\n' > ".spur/run/$wbs-mode.txt"; exit 0; fi; jq -r 'if .sensitive == true or ((.insertions // 0) + (.deletions // 0)) > 400 then "safety" else empty end' "$DF" 2>/dev/null > ".spur/run/$wbs-mode.txt"; exit 0
|
|
449
|
-
# (d) lane decision —
|
|
450
|
-
#
|
|
451
|
-
#
|
|
449
|
+
# (d) lane decision (1262 R5) — one narrow question: does this change set alter
|
|
450
|
+
# behaviour beyond its diffstat? `false` projects the fast lane; `true` or the catalog
|
|
451
|
+
# fallback projects standard. Degrades to that fallback with no model call whenever
|
|
452
|
+
# workflows.decideDecisionMaker is off (the bundled catalog owns question, criteria and
|
|
453
|
+
# fallback), and `skipWhenEvidenceEmpty` keeps a missing diffstat from costing a call.
|
|
452
454
|
- kind: decide
|
|
453
455
|
options:
|
|
454
|
-
id: task-
|
|
455
|
-
decision: task-
|
|
456
|
+
id: task-semantic-risk
|
|
457
|
+
decision: task-semantic-risk
|
|
456
458
|
params:
|
|
457
459
|
wbs: ${vars.wbs}
|
|
458
460
|
evidence:
|
|
459
461
|
- .spur/run/${vars.wbs}-diffstat.json
|
|
460
462
|
- ${vars.taskSpecPath}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
#
|
|
464
|
-
#
|
|
465
|
-
#
|
|
463
|
+
skipWhenEvidenceEmpty: true
|
|
464
|
+
resultFile: .spur/run/${vars.wbs}-semantic-risk.decision
|
|
465
|
+
# (d) project the decision and append the route reason (1007 R3: the non-empty mode
|
|
466
|
+
# file is never overridden; the append keeps the failure signal of the original pair).
|
|
467
|
+
# `no` (a noul row stores the label, not a boolean) → fast lane; anything else (`yes`,
|
|
468
|
+
# degraded default, missing row) stays empty → the standard review path.
|
|
466
469
|
- kind: shell
|
|
467
470
|
options:
|
|
468
471
|
command: >-
|
|
469
|
-
MF=".spur/run/$wbs-mode.txt"; [ -s "$MF" ] || jq -r 'if .value == "
|
|
472
|
+
MF=".spur/run/$wbs-mode.txt"; [ -s "$MF" ] || jq -r 'if (.value == false or .value == "no") then "fast" else empty end' ".spur/run/$wbs-semantic-risk.decision" 2>/dev/null > "$MF"; m="$(cat "$MF")"; RUN_ID="$__runId"; [ -n "$RUN_ID" ] || RUN_ID="pipeline-$wbs"; mkdir -p .spur/memory; printf '%s %s %s\n' "$RUN_ID" "$wbs" "$(jq -rn --arg m "$m" --arg c "$mode" 'if $c != "" then ($c + ":caller-set") else {"fast":"fast:semantic-risk mechanical change","safety":"safety:deterministic-high","":"safety:standard lane"}[$m] // "safety:unrecognized mode" end')" >> .spur/memory/task-pipeline-routes.log
|
|
470
473
|
# (d) review depth from the resolved lane (D65 1239 R2): the fast lane reviews the
|
|
471
474
|
# requirement/AC traceability only — that table is the certification input, so the
|
|
472
475
|
# cheap lane never drops the evidence, it drops the SECUA/architecture passes.
|
|
@@ -515,6 +518,14 @@ states:
|
|
|
515
518
|
args: ["task", "gate", "${vars.wbs}", "${vars.gateMode}", "--no-logo"]
|
|
516
519
|
resultFile: .spur/run/${vars.__runId}-gate.status
|
|
517
520
|
softFail: true
|
|
521
|
+
# (d) record what the PREVIOUS gate visit's failure-class answer turned out to be
|
|
522
|
+
# (1263 R3a): a recheck visit means the last class was `fix` and the repair hop ran, so
|
|
523
|
+
# this visit's gate status says whether it was right. First write wins, the step never
|
|
524
|
+
# changes routing, and a missing invocationId (degraded row) or a first visit is a no-op.
|
|
525
|
+
- kind: shell
|
|
526
|
+
options:
|
|
527
|
+
command: >-
|
|
528
|
+
[ "$gateMode" = recheck ] || exit 0; ID="$(jq -r '.invocationId // empty' ".spur/run/$wbs-failure-class.decision" 2>/dev/null)"; [ -n "$ID" ] || exit 0; $spurBin decision outcome "$ID" --gate-status "$__runId" --source gate-recheck --no-logo >/dev/null 2>&1; exit 0
|
|
518
529
|
# (d) failure class of the gate this visit produced (0943 R3): stop → failed
|
|
519
530
|
# before the cap can mislabel it, fix → the bounded remediation hop. A missing or
|
|
520
531
|
# corrupt row fails closed to failed-check. Runs unconditionally (no onEnter
|
|
@@ -528,6 +539,9 @@ states:
|
|
|
528
539
|
wbs: ${vars.wbs}
|
|
529
540
|
evidence:
|
|
530
541
|
- .spur/run/${vars.wbs}-test-gate.findings
|
|
542
|
+
# 1262 R4: a green gate writes a 0-byte findings file — there is nothing to read,
|
|
543
|
+
# so the row degrades to the catalog `fix` fallback with no maker call and no events.
|
|
544
|
+
skipWhenEvidenceEmpty: true
|
|
531
545
|
resultFile: .spur/run/${vars.wbs}-failure-class.decision
|
|
532
546
|
|
|
533
547
|
# ── remediate hop (bounded repair; former `test-fix`) ─────────────────────
|
|
@@ -557,15 +571,17 @@ states:
|
|
|
557
571
|
options:
|
|
558
572
|
command: >-
|
|
559
573
|
printf '%s\n' "$(( $(cat ".spur/run/$wbs-test-fix-attempt" 2>/dev/null || echo 0) + 1 ))" > ".spur/run/$wbs-test-fix-attempt"; [ -f ".spur/run/$wbs-residuals.json" ] && echo '--- residual artifact (F96 fix targets; deferrals go to residual-deferrals.json, P3/markers only) ---' >> ".spur/run/$wbs-test-gate.log" && cat ".spur/run/$wbs-residuals.json" >> ".spur/run/$wbs-test-gate.log"; exit 0
|
|
560
|
-
# Review-lane input:
|
|
561
|
-
#
|
|
562
|
-
#
|
|
563
|
-
#
|
|
564
|
-
#
|
|
574
|
+
# Review-lane input: a non-PASS review status routes into this same bounded repair hop
|
|
575
|
+
# (1262 R6), but it stages no gate evidence — the fixer would receive a GREEN gate log
|
|
576
|
+
# and an empty findings list. Project the reviewer's answer into the same log the other
|
|
577
|
+
# lane uses, and only on the review lane: remediate after a GREEN gate this run means
|
|
578
|
+
# review sent it. The review status file is no lane marker — it outlives its review, so
|
|
579
|
+
# a red recheck after a review repair would re-feed that stale answer.
|
|
580
|
+
# Own action, not an append to the one above (ADR-115 cap).
|
|
565
581
|
- kind: shell
|
|
566
582
|
options:
|
|
567
583
|
command: >-
|
|
568
|
-
[
|
|
584
|
+
[ "$(cat ".spur/run/$__runId-gate.status" 2>/dev/null)" = PASS ] && [ -f ".spur/run/$__runId-review-answer.txt" ] && echo '--- review verdict (remediation input, review lane) ---' >> ".spur/run/$wbs-test-gate.log" && cat ".spur/run/$__runId-review-answer.txt" >> ".spur/run/$wbs-test-gate.log"; exit 0
|
|
569
585
|
# R3 (0482): project the extracted gate anchors into a var so the dispatch input
|
|
570
586
|
# can NAME the failing file:line, not merely point at a log. A vars template cannot
|
|
571
587
|
# run a shell, so the read is an action, not an inline `$(cat ...)` substitution.
|
|
@@ -630,21 +646,29 @@ states:
|
|
|
630
646
|
# spec than the implement stage recorded in __agentRouting_implement.
|
|
631
647
|
# 0943 R1/R2: `--focus` carries the resolved lane depth — `functional` for the
|
|
632
648
|
# fast lane (traceability, which is the certification input), `all` otherwise.
|
|
633
|
-
# D65 1240: this answer IS the certification input — `spur task verdict --from-answer`
|
|
649
|
+
# D65 1240 + 1254: this answer IS the certification input — `spur task verdict --from-answer`
|
|
634
650
|
# derives the run's verdict from its requirement rows, so the answer contract is part
|
|
635
651
|
# of the prompt. A report body ending with a `| WBS | Verdict | P1 | … |` summary and
|
|
636
652
|
# no per-requirement rows derives UNKNOWN and can never certify, which looped every
|
|
637
653
|
# run through review -> remediate.
|
|
654
|
+
# 1254: the review emits TWO artifacts with different consumers — the `## Review`
|
|
655
|
+
# section (finding dispositions, deriveReviewConfidence) and this captured answer
|
|
656
|
+
# (requirement/AC evidence, deriveVerifyConfidence). The prompt has to teach both
|
|
657
|
+
# lanes and the fact that a single `Confidence:` line may only carry the second one.
|
|
658
|
+
# 1254: the prompt stays inside the 1000-char composition cap — the full
|
|
659
|
+
# contract (tables, vocabularies, the two confidence lanes, AC identity vs
|
|
660
|
+
# feature credit) is owned by `plugins/sp/agents/super-reviewer.md` Output Format,
|
|
661
|
+
# which this pointer names.
|
|
638
662
|
input: >-
|
|
639
|
-
/sp:dev-review --tasks ${vars.wbs} --auto --focus ${vars.reviewFocus}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
663
|
+
/sp:dev-review --tasks ${vars.wbs} --auto --focus ${vars.reviewFocus} Answer contract (full: super-reviewer Output
|
|
664
|
+
Format). Two artifacts: the `## Review` section (dispositions, deriveReviewConfidence) and your captured answer
|
|
665
|
+
(certification input for `spur task verdict`). The answer has one `Confidence: HIGH|MEDIUM|LOW` line, EVIDENCE-derived
|
|
666
|
+
(deriveVerifyConfidence), never the section's disposition level. End with one `Verdict: PASS|PARTIAL|FAIL` line
|
|
667
|
+
preceded by `| Req | Status | Evidence |` (one row per requirement; MET | PARTIAL | UNMET) and `| AC | Status |
|
|
668
|
+
Evidence Type | Evidence |` (one row per AC; MET | PARTIAL | UNMET | N/A). Evidence types (`+` compound allowed): test
|
|
669
|
+
| command | static-ref | manual-review | llm-judge | n/a. Evidence cells cite `path:line` or a named check. AC rows
|
|
670
|
+
key on the task's identities or a declared `AC-N` alias; a linked scenario covers its task and a task-local criterion
|
|
671
|
+
needs no feature credit. Open P1-P3 blocks completion.
|
|
648
672
|
# The captured review answer is the run's certification input (and the
|
|
649
673
|
# `task verdict` input below): expectFile fails the step when no answer landed.
|
|
650
674
|
answerFile: .spur/run/${vars.__runId}-review-answer.txt
|
|
@@ -681,21 +705,14 @@ states:
|
|
|
681
705
|
options:
|
|
682
706
|
command: >-
|
|
683
707
|
mkdir -p .spur/run; S=FAIL; if [ "$(cat ".spur/run/$__runId-review-verdict.status" 2>/dev/null)" = PASS ] && [ "$(jq -r '.verdict // empty' ".spur/run/$wbs-verdict.json" 2>/dev/null)" = PASS ] && $spurBin task residual "$wbs" review-gate --no-logo >&2; then S=PASS; fi; printf '%s\n' "$S" > ".spur/run/$wbs-review.status"; exit 0
|
|
684
|
-
# (d)
|
|
685
|
-
#
|
|
686
|
-
#
|
|
687
|
-
#
|
|
688
|
-
|
|
689
|
-
- kind: decide
|
|
708
|
+
# (d) record the review severity as the lane decision's outcome (1263 R3b): the
|
|
709
|
+
# question `task-semantic-risk` answered is "is this risky?", and the Review table's
|
|
710
|
+
# worst finding is the answer as observed. Resolved rows count (a fixed P2 was still
|
|
711
|
+
# risky). First write wins, so a later review visit changes nothing.
|
|
712
|
+
- kind: shell
|
|
690
713
|
options:
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
params:
|
|
694
|
-
wbs: ${vars.wbs}
|
|
695
|
-
evidence:
|
|
696
|
-
- .spur/run/${vars.__runId}-review-answer.txt
|
|
697
|
-
- ${vars.taskSpecPath}
|
|
698
|
-
resultFile: .spur/run/${vars.wbs}-review-failure-class.decision
|
|
714
|
+
command: >-
|
|
715
|
+
[ -f ".spur/run/$wbs-semantic-risk.decision" ] || exit 0; ID="$(jq -r '.invocationId // empty' ".spur/run/$wbs-semantic-risk.decision" 2>/dev/null)"; [ -n "$ID" ] || exit 0; $spurBin decision outcome "$ID" --review-severity "$wbs" --source "task-pipeline review" --no-logo >/dev/null 2>&1; exit 0
|
|
699
716
|
# (d) Operator approval as a DECISION POINT, not a state (D65 1239 R1/R5, ADR-140
|
|
700
717
|
# item 5): interactively the operator responder answers; under `profile=auto` the
|
|
701
718
|
# declared binding answers (evidence status var, catalog fallback when the maker
|
|
@@ -1010,15 +1027,6 @@ transitions:
|
|
|
1010
1027
|
kind: shell
|
|
1011
1028
|
options:
|
|
1012
1029
|
command: 'test "$(cat ".spur/run/$wbs-approval.status" 2>/dev/null)" = DENIED'
|
|
1013
|
-
- from: review
|
|
1014
|
-
to: failed
|
|
1015
|
-
terminalReason: failed-check
|
|
1016
|
-
description: Review failure class stop — the run terminates at failed, never bypassed.
|
|
1017
|
-
guard:
|
|
1018
|
-
kind: shell
|
|
1019
|
-
options:
|
|
1020
|
-
command: >-
|
|
1021
|
-
jq -e '.value == "stop"' ".spur/run/$wbs-review-failure-class.decision" >/dev/null 2>&1
|
|
1022
1030
|
- from: review
|
|
1023
1031
|
to: failed
|
|
1024
1032
|
terminalReason: retry-exhausted
|
|
@@ -1031,12 +1039,16 @@ transitions:
|
|
|
1031
1039
|
test "$fix_attempts" -ge "$qualityGateMaxFixAttempts"
|
|
1032
1040
|
- from: review
|
|
1033
1041
|
to: remediate
|
|
1034
|
-
description: Review
|
|
1042
|
+
description: Review did not certify and the attempt cap still allows a repair — the shared bounded repair hop, then gate → review on the remediated tree.
|
|
1035
1043
|
guard:
|
|
1036
1044
|
kind: shell
|
|
1037
1045
|
options:
|
|
1046
|
+
# 1262 R6: no decision row and no model call. The review status file is the whole
|
|
1047
|
+
# signal — it exists and is not PASS — and the cap guard above already bounds the
|
|
1048
|
+
# loop, so a non-PASS review always has exactly one forward route.
|
|
1038
1049
|
command: >-
|
|
1039
|
-
|
|
1050
|
+
test -f ".spur/run/$wbs-review.status" &&
|
|
1051
|
+
test "$(cat ".spur/run/$wbs-review.status" 2>/dev/null)" != PASS
|
|
1040
1052
|
# Defense: a review that did not certify and no clearer route — fail closed instead of
|
|
1041
1053
|
# dead-ending the run (a FAIL, PARTIAL, missing or unparseable certification lands here).
|
|
1042
1054
|
- from: review
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.17",
|
|
4
4
|
"description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spur",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"spur.js",
|
|
34
34
|
"config",
|
|
35
|
+
"worker",
|
|
35
36
|
"schemas",
|
|
36
37
|
"board",
|
|
37
38
|
"web",
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
"dev": "bun run src/index.ts",
|
|
50
51
|
"build": "bun run ../../scripts/spur-dev.ts build-cli",
|
|
51
52
|
"build:binaries": "bun run ../../scripts/spur-dev.ts build-binaries",
|
|
52
|
-
"build:bundle": "bun run ../../scripts/spur-dev.ts bundle-web && bun run ../../scripts/spur-dev.ts emit-board-types && bun build src/index.ts --target=bun --outfile spur.js --external @johnhenry/backend-webgpu && bun run ../../scripts/spur-dev.ts bundle-config config && bun run ../../scripts/spur-dev.ts bundle-plugins",
|
|
53
|
+
"build:bundle": "bun run ../../scripts/spur-dev.ts bundle-web && bun run ../../scripts/spur-dev.ts emit-board-types && bun build src/index.ts --target=bun --outfile spur.js --external @johnhenry/backend-webgpu && bun run ../../scripts/spur-dev.ts bundle-config config && bun run ../../scripts/spur-dev.ts bundle-laya-worker && bun run ../../scripts/spur-dev.ts bundle-plugins",
|
|
53
54
|
"test": "bun test tests --coverage --coverage-dir=../../.coverage --pass-with-no-tests",
|
|
54
55
|
"typecheck": "tsc --noEmit",
|
|
55
56
|
"prepack": "bun run build:bundle",
|
|
@@ -57,14 +58,14 @@
|
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@commander-js/extra-typings": "^14.0.0",
|
|
60
|
-
"@gobing-ai/ts-db": "^0.5.
|
|
61
|
-
"@gobing-ai/ts-ai-runner": "^0.5.
|
|
62
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.5.
|
|
63
|
-
"@gobing-ai/ts-infra": "^0.5.
|
|
64
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.
|
|
65
|
-
"@gobing-ai/ts-rule-engine": "^0.5.
|
|
66
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
67
|
-
"@gobing-ai/ts-utils": "^0.5.
|
|
61
|
+
"@gobing-ai/ts-db": "^0.5.32",
|
|
62
|
+
"@gobing-ai/ts-ai-runner": "^0.5.32",
|
|
63
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.5.32",
|
|
64
|
+
"@gobing-ai/ts-infra": "^0.5.32",
|
|
65
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.32",
|
|
66
|
+
"@gobing-ai/ts-rule-engine": "^0.5.32",
|
|
67
|
+
"@gobing-ai/ts-runtime": "^0.5.32",
|
|
68
|
+
"@gobing-ai/ts-utils": "^0.5.32",
|
|
68
69
|
"@types/bun": "1.4.3",
|
|
69
70
|
"@types/figlet": "^1.7.0",
|
|
70
71
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -29,7 +29,7 @@ One feature, start to finish — see the Command index below for exact command n
|
|
|
29
29
|
```
|
|
30
30
|
idea/plan vague description → feature + AC + decomposed task batch
|
|
31
31
|
↓
|
|
32
|
-
run <wbs> → pipeline: precheck → implement →
|
|
32
|
+
run <wbs> → pipeline: precheck → implement → gate ⇄ remediate → review → done (decision points route repair, stop and approval)
|
|
33
33
|
↓
|
|
34
34
|
verify <wbs> → traceability + AC verdict (PASS clears the gate; this also runs inside the run step)
|
|
35
35
|
↓
|
|
@@ -319,7 +319,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
319
319
|
|
|
320
320
|
| Skill | Ver | Domain |
|
|
321
321
|
| --------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
322
|
-
| `spur-dev` | 1.
|
|
322
|
+
| `spur-dev` | 1.2 | Thin orchestration spine — drives planning→execution, gates, HITL, and dispatches competencies; never inlines implementation/testing/decomposition/review |
|
|
323
323
|
| `spur-cli` | 1.0 | CLI facade — one reference per `spur` noun (`task`, `feature`, `rule`, `workflow`), each with verb tables, flag guides, `--json` shapes, and write-contract rules |
|
|
324
324
|
| `sys-architecture` | 1.0 | Architecture / ADR judgment — module boundaries, data flow, transport/storage/auth choices, build-vs-extend decisions |
|
|
325
325
|
| `spec-decomposition` | 1.0 | Feature/spec → validated task-batch decomposition — scenario-to-task mapping, variant selection, granularity sizing, batch-JSON production |
|
|
@@ -348,10 +348,10 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
348
348
|
| `conflict-finding` | 1.0 | Authority-aware semantic audit — four-pillar (source/task/feature/authority) conflict discovery, claim-specific authority resolution, reproducible evidence, confirmed owner-routed remediation; backs `/sp:dev-find-conflict` |
|
|
349
349
|
| `fleet-join` | 1.0 | Guest fleet occupancy — join as a live guest occupant, loop `spur agent wait --inbox` to pull work, reply through `spur message reply`, then leave; G73 (task 1081) |
|
|
350
350
|
| `next-feature` | 1.0 | Prompt-first feature frontier prioritizer — sync-first precondition, B3 actionability gate (cited, never restated), tiered rubric over measured signals, D1–D4 defect proposals conforming to the restructure map schema; backs `/sp:dev-find-next` |
|
|
351
|
-
| `pr-reviewing` |
|
|
351
|
+
| `pr-reviewing` | 2.0.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; direct `spur builder pr-status`/`pr-check`/`pr-open`/`pr-review` sequence; backs `/sp:dev-pr-review` |
|
|
352
352
|
| `indexed-context` | 1.0 | Cross-agent project context — anatomy/learnings/pitfalls/buglog/memory in `.spur/context/`; hook-tracked token-ledger; graceful degradation on agents without hooks |
|
|
353
353
|
| `history-anatomy` | 1.0 | Diagnostic interpretation owner over already-imported history — daily/ad-hoc mode contract, closed finding taxonomy, twelve-section report contract, `enrich`/`validate` rubrics; no workflow launch, no JSONL fallback, no corpus mutation |
|
|
354
|
-
| `session-review` | 1.
|
|
354
|
+
| `session-review` | 1.3.0 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
|
|
355
355
|
| `spur-composer` | 1.0 | Cross-noun composition — workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning; applies accepted `spur-doctor` proposals through `spur` verbs; never judges its own output and never runs a recurring loop |
|
|
356
356
|
| `spur-doctor` | 1.0 | Cross-noun evaluation — read-only CLI evidence per noun (task/feature/rule/workflow/agent spec), reflection over `history-anatomy` findings through a closed action-class map, and a proposal table; writes nothing; diagnoses artifacts, not runtime environments (`spur agent doctor`'s job) |
|
|
357
357
|
| `spur-check` | 1.0 | Two-tier check primitive (ADR-124) — light changed-scope checks during development, the full `spur self exec check` chain at the quality boundary, and the fingerprint-bound `<wbs>-check-receipt.json` with the `status` reuse rule; composes with `/sp:dev-fixall --gate-log` |
|
|
@@ -42,6 +42,9 @@ Use for:
|
|
|
42
42
|
ladder, trace-driven rule tuning, and applying accepted doctor proposals.
|
|
43
43
|
- Evaluation and reflection campaigns via `sp:spur-doctor`: read-only evidence, history-finding
|
|
44
44
|
reflection, and a proposal table.
|
|
45
|
+
- Decision campaigns: catalog health and reliability audits (`spur decision status --json`,
|
|
46
|
+
`--reliability`, `--probe`) through `sp:spur-doctor`'s decision flags, and new or tuned decision
|
|
47
|
+
points through the decision lifecycle and `sp:spur-composer` (shared ids need operator consent).
|
|
45
48
|
|
|
46
49
|
One bounded campaign per dispatch. Do not use for one CLI invocation. Do not use for
|
|
47
50
|
planning→implementation→verification lifecycle or batch task execution; `sp:spur-dev` owns that
|
|
@@ -89,6 +89,9 @@ You own the spaces **between** task runs:
|
|
|
89
89
|
timeout prints one checkpoint and exits 1; the run continues, never cancelled or relaunched) plus
|
|
90
90
|
`.spur/run/<wbs>-verdict.json`, accepted only when the trace's `.run.runId` equals the dispatched
|
|
91
91
|
run and the verdict's mtime ≥ the trace's `.run.startedAt` — otherwise `stale-evidence` (Step 3.3).
|
|
92
|
+
A `failed` run's cause is its decision row (`failure-class` / `review-failure-class` = `stop`, or
|
|
93
|
+
approval `DENIED`); report it per [reporting a run](../skills/spur-dev/references/decision-points.md#reporting-a-run)
|
|
94
|
+
and do not re-judge it before recovery.
|
|
92
95
|
- **One-shot recovery (optional)** - on non-PASS / stuck status, consult next-router **once** for that
|
|
93
96
|
WBS (`recoveryHint` / dry-run plan): print the child command, or dispatch once only when the batch
|
|
94
97
|
was started with `--auto` and cardinality is 1. Never self-loop until done.
|
|
@@ -135,7 +138,8 @@ Your decision-autonomy is **at the batch level**, bounded by the global Decision
|
|
|
135
138
|
| Continue/halt between task runs | Whether to auto-approve a HITL gate inside a task (only `--auto` does, via `vars.profile`) |
|
|
136
139
|
|
|
137
140
|
Surface blockers/HITL **only at the batch boundary** (between task runs). A pipeline run that pauses
|
|
138
|
-
on its
|
|
141
|
+
on its `review`-state approval decision point (interactive profiles only; under `profile=auto` the
|
|
142
|
+
decision point answers itself, and a deferred answer is no objection) is surfaced to the operator as a
|
|
139
143
|
batch-level event: "task 0042 is awaiting approval - `spur workflow continue <run-id> --yes` to
|
|
140
144
|
approve, or provide feedback". You do not answer the gate from inside a step.
|
|
141
145
|
|