@gobing-ai/spur 0.3.94 → 0.3.96
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/README.md +42 -0
- package/board/index.d.ts +38 -0
- package/config/plugin-scripts.json +3 -52
- package/config/rules/boundary/sp-script-placement.yaml +19 -0
- package/config/rules/strict/runtime-boundaries.yaml +5 -0
- package/config/rules/structure/test-location.yaml +2 -0
- package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +1 -1
- package/config/rules/typescript/output-boundaries.yaml +15 -2
- package/config/script-placement-baseline.json +51 -0
- package/config/workflows/feature-verification.yaml +7 -4
- package/config/workflows/history-anatomy.yaml +23 -11
- package/config/workflows/idea-pipeline.yaml +87 -86
- package/config/workflows/pr-review.yaml +18 -9
- package/config/workflows/task-pipeline.yaml +84 -109
- package/config/workflows/wrapup-pipeline.yaml +173 -46
- package/package.json +15 -11
- package/plugins/sp/README.md +8 -10
- package/plugins/sp/agents/super-reviewer.md +43 -18
- package/plugins/sp/commands/dev-fixgha.md +83 -0
- package/plugins/sp/commands/dev-gitmsg.md +8 -6
- package/plugins/sp/commands/dev-gtd.md +2 -2
- package/plugins/sp/commands/dev-idea.md +22 -12
- package/plugins/sp/commands/dev-plan.md +8 -9
- package/plugins/sp/commands/dev-review.md +22 -13
- package/plugins/sp/commands/dev-verify.md +7 -4
- package/plugins/sp/commands/dev-verifyall.md +5 -4
- package/plugins/sp/commands/dev-wrap.md +1 -1
- package/plugins/sp/commands/spur-init.md +2 -2
- package/plugins/sp/hooks/context-post-tool.ts +2 -2
- package/plugins/sp/hooks/context-session-start.ts +2 -1
- package/plugins/sp/hooks/context-session-stop.ts +22 -14
- package/plugins/sp/hooks/pi/guard-extension.ts +109 -150
- package/plugins/sp/lib/history-anatomy.generated.d.mts +112 -0
- package/plugins/sp/lib/history-anatomy.generated.mjs +686 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +6 -5
- package/plugins/sp/lib/inline-run.generated.d.mts +13 -2
- package/plugins/sp/lib/inline-run.generated.mjs +33 -16
- package/plugins/sp/lib/quality-gate.generated.d.mts +104 -0
- package/plugins/sp/lib/quality-gate.generated.mjs +438 -0
- package/plugins/sp/lib/residual-scan.generated.d.mts +62 -0
- package/plugins/sp/lib/residual-scan.generated.mjs +210 -0
- package/plugins/sp/lib/spur-bin.ts +36 -0
- package/plugins/sp/lib/step-profile.generated.d.mts +71 -0
- package/plugins/sp/lib/step-profile.generated.mjs +174 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +3 -3
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +3 -3
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +2 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +1 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +9 -7
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +8 -7
- package/plugins/sp/scripts/feature-verification-steps.ts +6 -6
- package/plugins/sp/scripts/history-anatomy-cache.mjs +23 -22
- package/plugins/sp/scripts/history-anatomy-cache.ts +23 -928
- package/plugins/sp/scripts/inline-run-setup.mjs +90 -315
- package/plugins/sp/scripts/inline-run-setup.ts +109 -639
- package/plugins/sp/scripts/pr-reviewing.mjs +2 -0
- package/plugins/sp/scripts/pr-reviewing.ts +1 -0
- package/plugins/sp/scripts/quality-gate.mjs +38 -21
- package/plugins/sp/scripts/quality-gate.ts +20 -660
- package/plugins/sp/scripts/residual-scan.mjs +138 -159
- package/plugins/sp/scripts/residual-scan.ts +102 -499
- package/plugins/sp/scripts/script-root.mjs +129 -0
- package/plugins/sp/scripts/script-root.ts +199 -0
- package/plugins/sp/scripts/workflow-step-profile.mjs +27 -16
- package/plugins/sp/scripts/workflow-step-profile.ts +22 -314
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +12 -3
- package/plugins/sp/scripts/wrapup-drift-probe.ts +6 -3
- package/plugins/sp/scripts/wrapup-steps.mjs +42 -40
- package/plugins/sp/scripts/wrapup-steps.ts +64 -46
- package/plugins/sp/skills/code-improvement/SKILL.md +5 -4
- package/plugins/sp/skills/code-verification/SKILL.md +46 -16
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +13 -2
- package/plugins/sp/skills/functional-review/SKILL.md +8 -5
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
- package/plugins/sp/skills/history-anatomy/references/modes.md +2 -1
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +2 -2
- package/plugins/sp/skills/spur-cli/SKILL.md +3 -3
- package/plugins/sp/skills/spur-cli/references/agent.md +10 -10
- package/plugins/sp/skills/spur-cli/references/features.md +17 -6
- package/plugins/sp/skills/spur-cli/references/init.md +17 -16
- package/plugins/sp/skills/spur-cli/references/self.md +3 -2
- package/plugins/sp/skills/spur-cli/references/serve.md +10 -10
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +28 -5
- package/plugins/sp/skills/spur-cli/references/tasks.md +14 -8
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +4 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +11 -9
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +1 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +86 -70
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +3 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +107 -44
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +5 -9
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +3 -3
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +31 -21
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +19 -19
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +4 -3
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +35 -6
- package/plugins/sp/skills/spur-doctor/SKILL.md +1 -1
- package/plugins/sp/skills/sys-architecture/SKILL.md +3 -2
- package/plugins/sp/tsconfig.json +8 -0
- package/spur.js +6638 -4775
- package/web/_astro/BoardApp.BIjMatT1.js +1 -0
- package/web/_astro/{BoardApp.FTEs3-N8.js → BoardApp.GvjIe9Z6.js} +150 -153
- package/web/_astro/TaskDetail.BZM3EAFx.js +1 -0
- package/web/_astro/_commonjsHelpers.CqkleIqs.js +1 -0
- package/web/_astro/{arc.uuAf51IT.js → arc.HkRiZnoI.js} +1 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.BDdK-tgZ.js +36 -0
- package/web/_astro/{blockDiagram-GPEHLZMM.D1mGCq3p.js → blockDiagram-GPEHLZMM.CZ9kOBxx.js} +1 -1
- package/web/_astro/board-facade-react-dom-client.B2U5wMvk.js +1 -0
- package/web/_astro/board-facade-react-dom.Cd2MuMhF.js +1 -0
- package/web/_astro/board-facade-react-jsx-dev-runtime.B_L3JzfC.js +1 -0
- package/web/_astro/board-facade-react-jsx-runtime.BY2yfHRi.js +1 -0
- package/web/_astro/board-facade-react-router-dom.Dy5pjzOw.js +1 -0
- package/web/_astro/board-facade-react-router.DjjqU27_.js +1 -0
- package/web/_astro/board-facade-react.Dgf4GRyj.js +1 -0
- package/web/_astro/{c4Diagram-AAUBKEIU.CMsolcde.js → c4Diagram-AAUBKEIU.DXK9qeRD.js} +1 -1
- package/web/_astro/channel.DlhX2MEt.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CrGA3fik.js → chunk-2J33WTMH.BTD2WeX5.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DsLVVla0.js → chunk-4BX2VUAB.Ci6Qbcvk.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.Dxc59Tfi.js → chunk-55IACEB6.yl3zsj7p.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.CaEVE2Wy.js → chunk-727SXJPM.ClXZsfyR.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BiJ4HXeI.js → chunk-AQP2D5EJ.BmKWZBcP.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Mxf1fru5.js → chunk-FMBD7UC4.By30fcb7.js} +1 -1
- package/web/_astro/chunk-JMJ3UQ3L.BQJEJHu4.js +34 -0
- package/web/_astro/{chunk-ND2GUHAM.pyOWQixH.js → chunk-ND2GUHAM.24NmrD-k.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BmEsg4vr.js → chunk-QZHKN3VN.BN4sKdcS.js} +1 -1
- package/web/_astro/chunk-YNUBSHFH.CxeAygfi.js +7 -0
- package/web/_astro/{classDiagram-4FO5ZUOK.BHhhMFTO.js → classDiagram-4FO5ZUOK.CJpoMPb5.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BHhhMFTO.js → classDiagram-v2-Q7XG4LA2.CJpoMPb5.js} +1 -1
- package/web/_astro/client.BhluLQqe.js +1 -0
- package/web/_astro/client.DBpSRLnx.js +9 -0
- package/web/_astro/cose-bilkent-S5V4N54A.BraxQ2Nt.js +1 -0
- package/web/_astro/{cynefin-OW5HDTMX.C2j1_lKL.js → cynefin-OW5HDTMX.gzoU73oL.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.hZ2NCTdT.js → dagre-BM42HDAG.wyDfWySU.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.Bfw5_EzK.js → diagram-2AECGRRQ.h2_EbMxV.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Bt1V_Tmk.js → diagram-5GNKFQAL.Db6dcs89.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.DEk-YFwp.js → diagram-KO2AKTUF.NVwzxu_U.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.CDjndtQm.js → diagram-LMA3HP47.B-eNgDQk.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.cFnUHScG.js → diagram-OG6HWLK6.Bsa8ZRbJ.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DlhYp7NV.js → erDiagram-TEJ5UH35.BospRE5Q.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.DNTpsxfx.js → flowDiagram-I6XJVG4X.DMzvHwAA.js} +1 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.Dmdxgd-M.js +292 -0
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DkEqNI0P.js → gitGraphDiagram-PVQCEYII.CaqdO0rL.js} +1 -1
- package/web/_astro/index.5dn-Zm-2.js +1 -0
- package/web/_astro/index.C-IqPpW2.js +1 -0
- package/web/_astro/index.Cyc_GA4f.js +1 -0
- package/web/_astro/index.EoZlzLK-.css +1 -0
- package/web/_astro/index.tZfqwSut.js +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CrjioCTG.js → infoDiagram-5YYISTIA.DDVD9Wn7.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.BcK0CN8n.js → ishikawaDiagram-YF4QCWOH.EKyCUFsL.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.p0CbBDX1.js → journeyDiagram-JHISSGLW.By2-RkYB.js} +1 -1
- package/web/_astro/jsx-runtime.DWOiEOII.js +1 -0
- package/web/_astro/{kanban-definition-UN3LZRKU.puHIFt6J.js → kanban-definition-UN3LZRKU.ar-WmlyR.js} +1 -1
- package/web/_astro/{linear.Bb-3a1d7.js → linear.BnzMBgo_.js} +1 -1
- package/web/_astro/{mermaid.core.CJDgXOJs.js → mermaid.core.DSqeFu2Y.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.BoAZEI9t.js → mindmap-definition-RKZ34NQL.1XcF8Wh2.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.CJNSdqY7.js → pieDiagram-4H26LBE5.DnItHOdK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DtTy7_0Z.js → quadrantDiagram-W4KKPZXB.BQQyrnBt.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BNYV98Xg.js → requirementDiagram-4Y6WPE33.Dmzxun82.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.DRq9DGHp.js → sankeyDiagram-5OEKKPKP.BBIeRKYB.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B7KdBFCm.js → sequenceDiagram-3UESZ5HK.CUNVdBBf.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.CD62ZJ2H.js → stateDiagram-AJRCARHV.DlFf2sJm.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CeVk1TAj.js → stateDiagram-v2-BHNVJYJU.DXR7I1H5.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.C_ZPA5tT.js → timeline-definition-PNZ67QCA.BcO-GyX2.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CrThO_FQ.js → vennDiagram-CIIHVFJN.ChCECmmW.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DSZCA5nl.js → wardleyDiagram-YWT4CUSO.CRaT12mD.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.KI7baTuk.js → xychartDiagram-2RQKCTM6.B3lsHVpj.js} +1 -1
- package/web/board-runtime.json +69 -0
- package/web/index.html +2 -2
- package/plugins/sp/lib/artifact-digest.generated.d.mts +0 -7
- package/plugins/sp/lib/artifact-digest.generated.mjs +0 -48
- package/plugins/sp/scripts/feature-sync-bounded.mjs +0 -298
- package/plugins/sp/scripts/feature-sync-bounded.ts +0 -479
- package/plugins/sp/scripts/idea-coverage-check.ts +0 -168
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +0 -298
- package/plugins/sp/scripts/record-feature-sync.mjs +0 -63
- package/plugins/sp/scripts/record-feature-sync.ts +0 -84
- package/plugins/sp/scripts/script-contract-check.ts +0 -377
- package/plugins/sp/scripts/stage-registry-adapter.ts +0 -1533
- package/plugins/sp/scripts/surface-drift-inventory.ts +0 -989
- package/plugins/sp/scripts/task-evidence-precheck.ts +0 -187
- package/plugins/sp/scripts/task-size-precheck.ts +0 -210
- package/plugins/sp/scripts/transition-shim-check.ts +0 -238
- package/plugins/sp/scripts/validate-commands.ts +0 -689
- package/plugins/sp/scripts/validate-flag-contracts.ts +0 -878
- package/plugins/sp/scripts/verify-answer-lint.ts +0 -547
- package/web/_astro/BoardApp.C02hAHPO.js +0 -1
- package/web/_astro/TaskDetail.C-GdsS-t.js +0 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.CGe629A1.js +0 -36
- package/web/_astro/channel.fsgl7o5j.js +0 -1
- package/web/_astro/client.yhYJvxCU.js +0 -9
- package/web/_astro/cose-bilkent-S5V4N54A.2fH4YOlp.js +0 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.DC_p36PI.js +0 -292
- package/web/_astro/index.De90oHcH.js +0 -1
- package/web/_astro/index.Hjbr15fG.css +0 -1
|
@@ -13,17 +13,28 @@
|
|
|
13
13
|
# pauses,
|
|
14
14
|
# even under --auto (Iron Law #6: irreversible action -> surface to human).
|
|
15
15
|
#
|
|
16
|
-
# Shape: start -> task-resolve -> doc-sync -> learnings-
|
|
16
|
+
# Shape: start -> task-resolve -> doc-sync -> learnings-validate -> learnings-append
|
|
17
|
+
# -> doc-tripwire (1037: repo-wide tripwire over the still-uncommitted wrap
|
|
18
|
+
# diff; repair also enters it; the task-resolve fast path does not)
|
|
19
|
+
# -> metrics-record
|
|
17
20
|
# -> feature-transition (conditional: if vars.feature set)
|
|
18
21
|
# -> feature-verify (post-transition feature check gate, 0915 F1)
|
|
19
22
|
# -> branch-cleanup (conditional: if vars.merge=true)
|
|
20
23
|
# -> done
|
|
21
24
|
# doc-sync routes a contract violation to `repair` (cheap, no
|
|
22
25
|
# re-dispatch — ADR-118 pilot) and an executor failure to `failed`;
|
|
26
|
+
# learnings-validate (0986) rejects a nonempty narration-only capture to
|
|
27
|
+
# the same `repair` edge with a distinct invalid-learnings-shape status —
|
|
28
|
+
# expectFile proves existence, never shape — while empty/missing captures
|
|
29
|
+
# keep the soft skip by passing through to learnings-append;
|
|
30
|
+
# learnings-append and repair converge on doc-tripwire (1037), which runs
|
|
31
|
+
# docTripwireCmd — the repo-wide tripwires over the still-uncommitted wrap
|
|
32
|
+
# diff — before metrics-record; the task-resolve fast path never enters it;
|
|
23
33
|
# task-resolve with a VALIDATED empty list short-circuits to `skipped`;
|
|
24
34
|
# invalid wrap input, an unresolved/non-completed task, a failed metrics
|
|
25
|
-
# capture, a failed required sync,
|
|
26
|
-
# `failed` (0770) instead of being
|
|
35
|
+
# capture, a failed required sync, a failed repo-wide tripwire (1037), or
|
|
36
|
+
# a failed feature gate routes to `failed` (0770) instead of being
|
|
37
|
+
# absorbed by an always-defensive skip.
|
|
27
38
|
#
|
|
28
39
|
# Vars (passed as a JSON object via `--vars`):
|
|
29
40
|
# tasks — JSON array of WBS strings, passed as a JSON-encoded STRING value
|
|
@@ -75,7 +86,7 @@
|
|
|
75
86
|
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
76
87
|
kind: state-machine
|
|
77
88
|
name: wrapup-pipeline
|
|
78
|
-
version: "
|
|
89
|
+
version: "7"
|
|
79
90
|
description: "Post-execution wrap-up: doc-sync (doc drift + learning capture), metrics, feature-transition, branch-cleanup"
|
|
80
91
|
iterationBound: 10
|
|
81
92
|
initialState: start
|
|
@@ -100,6 +111,13 @@ vars:
|
|
|
100
111
|
# TRUSTED CONFIG ONLY — this string is executed via `sh -c` (same surface as
|
|
101
112
|
# task-pipeline's qualityGateCmd). Never interpolate untrusted input into it.
|
|
102
113
|
featureGateCmd: '$spurBin feature check "$feature"'
|
|
114
|
+
# Repo-wide tripwire over the wrap diff (1037): runs `bun run test-repo-wide`
|
|
115
|
+
# only when package.json declares the script, so other projects no-op. Callers
|
|
116
|
+
# can override it with --vars; an empty string disables the check (the hop
|
|
117
|
+
# still writes PASS).
|
|
118
|
+
# TRUSTED CONFIG ONLY — this string is executed via `sh -c` (same surface as
|
|
119
|
+
# featureGateCmd). Never interpolate untrusted input into it.
|
|
120
|
+
docTripwireCmd: 'if jq -e ''.scripts["test-repo-wide"]'' package.json >/dev/null 2>&1; then bun run test-repo-wide; fi'
|
|
103
121
|
__hitlAnswer: ""
|
|
104
122
|
|
|
105
123
|
states:
|
|
@@ -108,6 +126,12 @@ states:
|
|
|
108
126
|
Pipeline start. Task statuses are NOT mutated by wrap-up — wrap-up consumes
|
|
109
127
|
completed tasks and produces learning/metrics/doc artifacts only.
|
|
110
128
|
onEnter:
|
|
129
|
+
# 0960 R2: run-start script-resolution identity — record which tree this run
|
|
130
|
+
# resolved (source-repo vs installed) before any step executes. Never aborts.
|
|
131
|
+
- kind: shell
|
|
132
|
+
options:
|
|
133
|
+
command: >-
|
|
134
|
+
S=plugins/sp/scripts/script-root.ts; [ -f config/plugin-scripts.json -a -f "$S" ] || S="$(superskill script path sp script-root.mjs 2>/dev/null)"; RUNNER=bun; case "$S" in *.mjs) RUNNER=node ;; esac; [ -f "$S" ] && "$RUNNER" "$S" --run-id "$__runId" --spur-bin "$spurBin" || echo "script-root failed closed — run 'superskill install sp --marketplace gobing-ai/spur'" >&2; exit 0
|
|
111
135
|
- kind: note
|
|
112
136
|
options:
|
|
113
137
|
message: "Wrap-up pipeline start for tasks: ${vars.tasks}. Task statuses are NOT mutated."
|
|
@@ -143,12 +167,10 @@ states:
|
|
|
143
167
|
options:
|
|
144
168
|
command: >-
|
|
145
169
|
mkdir -p .spur/run &&
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
149
|
-
node "$W" resolve;
|
|
170
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/wrapup-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/wrapup-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; if [ -f "$S" ]; then
|
|
171
|
+
"$RUNNER" "$S" resolve;
|
|
150
172
|
else
|
|
151
|
-
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
173
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp --marketplace gobing-ai/spur'" >&2;
|
|
152
174
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-resolve.status";
|
|
153
175
|
fi
|
|
154
176
|
# (0944 R1-R3) deterministic drift probe — runs ONLY when the caller left mode
|
|
@@ -163,13 +185,14 @@ states:
|
|
|
163
185
|
command: >-
|
|
164
186
|
if [ -n "$mode" ]; then
|
|
165
187
|
printf '%s\n' "$mode" > ".spur/run/$__runId-mode.txt";
|
|
166
|
-
elif [ -f plugins/sp/scripts/wrapup-drift-probe.ts ]; then
|
|
167
|
-
bun plugins/sp/scripts/wrapup-drift-probe.ts;
|
|
168
|
-
elif W="$(superskill script path sp wrapup-drift-probe.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
169
|
-
node "$W";
|
|
170
188
|
else
|
|
171
|
-
|
|
172
|
-
|
|
189
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/wrapup-drift-probe.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/wrapup-drift-probe.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
|
|
190
|
+
if [ -f "$S" ]; then
|
|
191
|
+
"$RUNNER" "$S";
|
|
192
|
+
else
|
|
193
|
+
printf '{"clean":false,"reasons":["probe script not found"],"paths":[]}' > ".spur/run/$__runId-drift-probe.json";
|
|
194
|
+
printf '\n' > ".spur/run/$__runId-mode.txt";
|
|
195
|
+
fi;
|
|
173
196
|
fi
|
|
174
197
|
- kind: file.read.into-var
|
|
175
198
|
options:
|
|
@@ -190,12 +213,10 @@ states:
|
|
|
190
213
|
options:
|
|
191
214
|
command: >-
|
|
192
215
|
mkdir -p .spur/run .spur/memory &&
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
196
|
-
node "$W" route-reason;
|
|
216
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/wrapup-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/wrapup-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; if [ -f "$S" ]; then
|
|
217
|
+
"$RUNNER" "$S" route-reason;
|
|
197
218
|
else
|
|
198
|
-
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
219
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp --marketplace gobing-ai/spur'" >&2;
|
|
199
220
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-resolve.status";
|
|
200
221
|
fi
|
|
201
222
|
|
|
@@ -234,6 +255,34 @@ states:
|
|
|
234
255
|
expectFile: .spur/run/${vars.__runId}-wrapup-learnings.md
|
|
235
256
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
236
257
|
|
|
258
|
+
- id: learnings-validate
|
|
259
|
+
description: >
|
|
260
|
+
Structural shape gate between doc-sync and the append (0986): expectFile
|
|
261
|
+
asserts the capture EXISTS and nothing about its shape, so a
|
|
262
|
+
stream-of-thought capture could be appended verbatim to the tracked
|
|
263
|
+
memory file. This state classifies a NONEMPTY capture — a date, a
|
|
264
|
+
four-digit task WBS, and at least one markdown bullet — and writes PASS
|
|
265
|
+
or invalid-learnings-shape to a run-scoped status. An empty or missing
|
|
266
|
+
capture keeps the existing soft skip (PASS) so learnings-append still
|
|
267
|
+
performs its no-op; an unclassifiable status fails loud instead of
|
|
268
|
+
appending it. Structural check only — the doc-sync prompt owns prose
|
|
269
|
+
quality; no new engine-level content contract.
|
|
270
|
+
onEnter:
|
|
271
|
+
# (warn) structural check only; the doc-sync prompt owns prose quality (0986 Design).
|
|
272
|
+
# The WBS predicate excludes digit/dash neighbours so a date's year cannot satisfy it.
|
|
273
|
+
- kind: shell
|
|
274
|
+
options:
|
|
275
|
+
command: >-
|
|
276
|
+
mkdir -p .spur/run &&
|
|
277
|
+
S=".spur/run/$__runId-wrapup-learnings.status" &&
|
|
278
|
+
F=".spur/run/$__runId-wrapup-learnings.md" &&
|
|
279
|
+
if [ ! -s "$F" ] || awk '/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/{d=1} /(^|[^0-9-])[0-9][0-9][0-9][0-9]([^0-9-]|$)/{w=1} /^[[:space:]]*[-*] /{b=1} END{exit !(d+w+b==3)}' "$F"; then
|
|
280
|
+
printf 'PASS\n' > "$S";
|
|
281
|
+
else
|
|
282
|
+
printf 'invalid-learnings-shape\n' > "$S";
|
|
283
|
+
fi &&
|
|
284
|
+
exit 0
|
|
285
|
+
|
|
237
286
|
- id: learnings-append
|
|
238
287
|
description: >
|
|
239
288
|
Best-effort soft append of the captured learnings to .spur/memory/learnings.md
|
|
@@ -259,17 +308,45 @@ states:
|
|
|
259
308
|
description: >
|
|
260
309
|
Contract-violation repair (ADR-118 pilot, 0871): doc-sync's agent.run missed
|
|
261
310
|
its declared post-condition after a clean exit, so wrap-up does NOT re-dispatch
|
|
262
|
-
the expensive agent on this attempt.
|
|
263
|
-
|
|
264
|
-
|
|
311
|
+
the expensive agent on this attempt. Also the destination for a nonempty
|
|
312
|
+
capture that fails learnings-validate's shape gate (0986). The miss is
|
|
313
|
+
recorded to a run-scoped repair status — text distinguishing a narration-only
|
|
314
|
+
shape failure from the missing-file contract violation — and wrap-up proceeds
|
|
315
|
+
through the doc-tripwire hop (1037) to metrics-record; the run log and
|
|
316
|
+
action trace already name the violated contract and the observed value.
|
|
265
317
|
onEnter:
|
|
266
318
|
- kind: shell
|
|
267
319
|
options:
|
|
268
320
|
command: >-
|
|
269
321
|
mkdir -p .spur/run &&
|
|
270
|
-
|
|
322
|
+
R=".spur/run/$__runId-wrapup-repair.status" &&
|
|
323
|
+
V="$(cat .spur/run/$__runId-wrapup-learnings.status 2>/dev/null)" &&
|
|
324
|
+
if [ "$V" = invalid-learnings-shape ]; then printf 'invalid-learnings-shape: narration-only learnings capture — append skipped, repair recorded (0986)\n' > "$R";
|
|
325
|
+
else printf 'contract-violation: doc-sync learnings capture missed its declared contract — repair skipped re-dispatch (ADR-118 pilot)\n' > "$R";
|
|
326
|
+
fi &&
|
|
271
327
|
exit 0
|
|
272
328
|
|
|
329
|
+
- id: doc-tripwire
|
|
330
|
+
description: >
|
|
331
|
+
Repo-wide tripwire over the wrap diff (1037): the doc-sync edits are still
|
|
332
|
+
uncommitted when wrap-up reaches a terminal success, and the repo-wide
|
|
333
|
+
tripwires (repo-wide-tests/) execute only inside spur-check-feature — once
|
|
334
|
+
a wrap edit is committed on a clean tree, the working-diff tests (e.g.
|
|
335
|
+
adr-supersession (e)) can no longer see it. Entered from learnings-append
|
|
336
|
+
and repair, before metrics or feature state mutate, it runs the trusted
|
|
337
|
+
`docTripwireCmd` and records PASS or FAIL to a run-scoped status file; the
|
|
338
|
+
action always exits 0 so status truth lives in the file (0783 R4). Only a
|
|
339
|
+
verified run writes PASS; an empty docTripwireCmd disables the check and
|
|
340
|
+
still writes PASS. The no-doc-sync fast path (task-resolve →
|
|
341
|
+
metrics-record) never enters this state.
|
|
342
|
+
onEnter:
|
|
343
|
+
- kind: shell
|
|
344
|
+
options:
|
|
345
|
+
command: >-
|
|
346
|
+
sh -c "$docTripwireCmd" &&
|
|
347
|
+
printf 'PASS\n' > ".spur/run/$__runId-wrapup-doc-tripwire.status" ||
|
|
348
|
+
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-doc-tripwire.status"
|
|
349
|
+
|
|
273
350
|
- id: metrics-record
|
|
274
351
|
description: >
|
|
275
352
|
Append one JSONL row per task to .spur/memory/wrapup-metrics.jsonl deterministically.
|
|
@@ -288,18 +365,17 @@ states:
|
|
|
288
365
|
options:
|
|
289
366
|
command: >-
|
|
290
367
|
mkdir -p .spur/run &&
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
294
|
-
node "$W" metrics;
|
|
368
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/wrapup-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/wrapup-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; if [ -f "$S" ]; then
|
|
369
|
+
"$RUNNER" "$S" metrics;
|
|
295
370
|
else
|
|
296
|
-
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
371
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp --marketplace gobing-ai/spur'" >&2;
|
|
297
372
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-metrics.status";
|
|
298
373
|
fi
|
|
299
374
|
|
|
300
375
|
- id: feature-transition
|
|
301
376
|
description: >
|
|
302
|
-
If vars.feature is set, sync feature status via
|
|
377
|
+
If vars.feature is set, sync feature status via `spur feature sync` (repeated-BLOCKED
|
|
378
|
+
suppression is built into the sync service, so no wrapper script is needed)
|
|
303
379
|
(0411). The shell terminates `exit 0` so artifacts already landed are never
|
|
304
380
|
discarded, but the outcome is truthful (0770 + 0783 R4): sync succeeds only
|
|
305
381
|
with a valid proposal matching vars.feature, no gateBlocked/requiresConfirm
|
|
@@ -322,12 +398,10 @@ states:
|
|
|
322
398
|
options:
|
|
323
399
|
command: >-
|
|
324
400
|
mkdir -p .spur/run &&
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
328
|
-
node "$W" feature-transition;
|
|
401
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/wrapup-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/wrapup-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; if [ -f "$S" ]; then
|
|
402
|
+
"$RUNNER" "$S" feature-transition;
|
|
329
403
|
else
|
|
330
|
-
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
404
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp --marketplace gobing-ai/spur'" >&2;
|
|
331
405
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-sync.status";
|
|
332
406
|
fi
|
|
333
407
|
|
|
@@ -387,9 +461,10 @@ states:
|
|
|
387
461
|
- id: failed
|
|
388
462
|
description: >
|
|
389
463
|
Terminal — wrap-up failed (0770): invalid wrap input, an unresolved or
|
|
390
|
-
non-completed task, a failed metrics capture, a failed required sync,
|
|
391
|
-
a failed feature gate.
|
|
392
|
-
rows, route reason) are
|
|
464
|
+
non-completed task, a failed metrics capture, a failed required sync, a
|
|
465
|
+
failed repo-wide tripwire (1037), or a failed feature gate.
|
|
466
|
+
Already-written artifacts (learnings, metrics rows, route reason) are
|
|
467
|
+
preserved; nothing is rolled back.
|
|
393
468
|
|
|
394
469
|
transitions:
|
|
395
470
|
# ── start -> task-resolve ──
|
|
@@ -460,8 +535,8 @@ transitions:
|
|
|
460
535
|
guard:
|
|
461
536
|
kind: contract-violation
|
|
462
537
|
- from: doc-sync
|
|
463
|
-
to: learnings-
|
|
464
|
-
description: Doc drift repair + learning capture succeeded —
|
|
538
|
+
to: learnings-validate
|
|
539
|
+
description: Doc drift repair + learning capture succeeded — validate the capture's shape before appending.
|
|
465
540
|
guard:
|
|
466
541
|
kind: action-ok
|
|
467
542
|
- from: doc-sync
|
|
@@ -475,20 +550,72 @@ transitions:
|
|
|
475
550
|
guard:
|
|
476
551
|
kind: always
|
|
477
552
|
|
|
478
|
-
# ──
|
|
553
|
+
# ── learnings-validate: shape gate (0986) — invalid-shape to repair, PASS to append ──
|
|
554
|
+
# Declaration order matters: the discriminating invalid-shape edge is tried
|
|
555
|
+
# first, then PASS; an unreadable status fails loud rather than appending an
|
|
556
|
+
# unclassified capture.
|
|
557
|
+
- from: learnings-validate
|
|
558
|
+
to: repair
|
|
559
|
+
description: >
|
|
560
|
+
Nonempty capture failed the structural shape gate (no date/WBS/bullet) —
|
|
561
|
+
route to the cheap repair edge and never append narration (0986 R2).
|
|
562
|
+
guard:
|
|
563
|
+
kind: shell
|
|
564
|
+
options:
|
|
565
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-learnings.status 2>/dev/null)" = invalid-learnings-shape'
|
|
566
|
+
- from: learnings-validate
|
|
567
|
+
to: learnings-append
|
|
568
|
+
description: Capture is shape-valid (or empty/missing, keeping the soft skip) — append.
|
|
569
|
+
guard:
|
|
570
|
+
kind: shell
|
|
571
|
+
options:
|
|
572
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-learnings.status 2>/dev/null)" = PASS'
|
|
573
|
+
- from: learnings-validate
|
|
574
|
+
to: failed
|
|
575
|
+
terminalReason: failed-check
|
|
576
|
+
description: >
|
|
577
|
+
Validation status missing or unreadable — fail loud instead of appending
|
|
578
|
+
a capture whose shape was never classified.
|
|
579
|
+
guard:
|
|
580
|
+
kind: always
|
|
581
|
+
|
|
582
|
+
# ── doc-sync exits converge on the doc-tripwire hop (1037) before metrics ──
|
|
479
583
|
- from: learnings-append
|
|
480
|
-
to:
|
|
481
|
-
description: Learning capture appended (or soft-skipped) —
|
|
584
|
+
to: doc-tripwire
|
|
585
|
+
description: Learning capture appended (or soft-skipped) — run the repo-wide tripwire over the wrap diff.
|
|
482
586
|
guard:
|
|
483
587
|
kind: always
|
|
484
588
|
|
|
485
|
-
# ── repair: cheap path, no re-dispatch -> metrics-record ──
|
|
486
589
|
- from: repair
|
|
487
|
-
to:
|
|
488
|
-
description: Contract-violation repair recorded —
|
|
590
|
+
to: doc-tripwire
|
|
591
|
+
description: Contract-violation repair recorded — run the tripwire before metrics without re-dispatch.
|
|
489
592
|
guard:
|
|
490
593
|
kind: always
|
|
491
594
|
|
|
595
|
+
# ── doc-tripwire: repo-wide tripwire gate (1037) ──
|
|
596
|
+
# Declaration order matters: the FAIL edge is tried first so a failed tripwire
|
|
597
|
+
# can never be absorbed by the PASS edge; a missing status matches neither
|
|
598
|
+
# edge and follows the engine's no-match behavior for status-file states.
|
|
599
|
+
- from: doc-tripwire
|
|
600
|
+
to: failed
|
|
601
|
+
terminalReason: failed-check
|
|
602
|
+
description: >
|
|
603
|
+
Repo-wide tripwire FAILED on the still-uncommitted wrap diff (1037): an
|
|
604
|
+
edit the doc-sync stage made (e.g. an in-place historical ADR change)
|
|
605
|
+
violates a working-diff test. Learnings and docs already on disk stay
|
|
606
|
+
put; nothing is rolled back.
|
|
607
|
+
guard:
|
|
608
|
+
kind: shell
|
|
609
|
+
options:
|
|
610
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-doc-tripwire.status 2>/dev/null)" = FAIL'
|
|
611
|
+
- from: doc-tripwire
|
|
612
|
+
to: metrics-record
|
|
613
|
+
description: Repo-wide tripwire PASS (or the check disabled by an empty docTripwireCmd) — record metrics.
|
|
614
|
+
guard:
|
|
615
|
+
kind: shell
|
|
616
|
+
options:
|
|
617
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-doc-tripwire.status 2>/dev/null)" = PASS'
|
|
618
|
+
|
|
492
619
|
# ── metrics-record: fail edge, then conditional routing (feature → merge → done) ──
|
|
493
620
|
# Declaration order matters: the FAIL edge is tried first (0770), then
|
|
494
621
|
# feature-transition (if feature is set), then branch-cleanup (if merge=true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.96",
|
|
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",
|
|
@@ -24,12 +24,16 @@
|
|
|
24
24
|
"spur": "spur.js"
|
|
25
25
|
},
|
|
26
26
|
"exports": {
|
|
27
|
-
"./schemas/*": "./schemas/*"
|
|
27
|
+
"./schemas/*": "./schemas/*",
|
|
28
|
+
"./board": {
|
|
29
|
+
"types": "./board/index.d.ts"
|
|
30
|
+
}
|
|
28
31
|
},
|
|
29
32
|
"files": [
|
|
30
33
|
"spur.js",
|
|
31
34
|
"config",
|
|
32
35
|
"schemas",
|
|
36
|
+
"board",
|
|
33
37
|
"web",
|
|
34
38
|
"README.md",
|
|
35
39
|
"plugins/",
|
|
@@ -45,7 +49,7 @@
|
|
|
45
49
|
"dev": "bun run src/index.ts",
|
|
46
50
|
"build": "bun run ../../scripts/spur-dev.ts build-cli",
|
|
47
51
|
"build:binaries": "bun run ../../scripts/spur-dev.ts build-binaries",
|
|
48
|
-
"build:bundle": "bun run ../../scripts/spur-dev.ts bundle-web && bun build src/index.ts --target=bun --outfile spur.js && bun run ../../scripts/spur-dev.ts bundle-config config && bun run ../../scripts/spur-dev.ts bundle-plugins",
|
|
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 && bun run ../../scripts/spur-dev.ts bundle-config config && bun run ../../scripts/spur-dev.ts bundle-plugins",
|
|
49
53
|
"test": "bun test tests --coverage --coverage-dir=../../.coverage --pass-with-no-tests",
|
|
50
54
|
"typecheck": "tsc --noEmit",
|
|
51
55
|
"prepack": "bun run build:bundle",
|
|
@@ -53,14 +57,14 @@
|
|
|
53
57
|
},
|
|
54
58
|
"devDependencies": {
|
|
55
59
|
"@commander-js/extra-typings": "^14.0.0",
|
|
56
|
-
"@gobing-ai/ts-db": "^0.5.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.5.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.5.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.5.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.5.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.5.
|
|
60
|
+
"@gobing-ai/ts-db": "^0.5.11",
|
|
61
|
+
"@gobing-ai/ts-ai-runner": "^0.5.11",
|
|
62
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.5.11",
|
|
63
|
+
"@gobing-ai/ts-infra": "^0.5.11",
|
|
64
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.11",
|
|
65
|
+
"@gobing-ai/ts-rule-engine": "^0.5.11",
|
|
66
|
+
"@gobing-ai/ts-runtime": "^0.5.11",
|
|
67
|
+
"@gobing-ai/ts-utils": "^0.5.11",
|
|
64
68
|
"@types/bun": "1.3.14",
|
|
65
69
|
"@types/figlet": "^1.7.0",
|
|
66
70
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -133,11 +133,12 @@ list this README is checked against.
|
|
|
133
133
|
| `dev-find-conflict` | Authority-aware semantic audit across source, task, feature, and project authority files — detect conflicts, resolve claim-specific authority, and route confirmed repairs through owner surfaces |
|
|
134
134
|
| `dev-find-next` | Prompt-first feature frontier prioritizer — ranks the open feature frontier by derived importance/urgency with per-candidate evidence; gates unactionable features; emits tree defects as proposals only |
|
|
135
135
|
| `dev-fixall` | Fix all lint, type, and test errors systematically across the working tree |
|
|
136
|
+
| `dev-fixgha` | Find and fix failing GitHub Actions runs — gh fetch → diagnose → root-cause fix → commit → push → re-verify until green; optional context/filter argument |
|
|
136
137
|
| `dev-simplify` | Simplify recently-changed code for clarity without changing behavior — incremental, test-after-each, revert on regression |
|
|
137
138
|
| `dev-refactor` | Lens-routed refactoring with a preservation contract — taste lenses (api/architect/tests/ui) classify findings on the shared schema; cutting/breaking changes pause for operator approval; forwards to sp:code-refactoring |
|
|
138
139
|
| `dev-arch` | Survey a codebase (or module tree) for shallow modules and deepening opportunities — emit a ranked MARKDOWN candidate report that feeds the planning half; never auto-refactors |
|
|
139
140
|
| `dev-reverse` | Reverse-engineer a codebase — analyze unfamiliar repos, generate HLD/architecture docs, audit quality/security, and produce onboarding documentation |
|
|
140
|
-
| `dev-gitmsg` | Generate conventional commit message(s) from the current change set via one bounded
|
|
141
|
+
| `dev-gitmsg` | Generate conventional commit message(s) from the current change set via one bounded gather call, optionally commit |
|
|
141
142
|
| `dev-gtd` | Get things done — quality gate (auto-fix) → conventional commit → push → gh verify in one flow; optional act CI simulation via `--act` |
|
|
142
143
|
| `dev-changelog` | Generate changelog from git commits |
|
|
143
144
|
|
|
@@ -269,9 +270,9 @@ plugins/sp/
|
|
|
269
270
|
│ # + careful-guard.{ts,test.ts} + context-hooks.test.ts + token-estimate.test.ts
|
|
270
271
|
│ # + shared policy modules: agent-hint.ts, destructive-policy.{ts,test.ts}, task-file-policy.{ts,test.ts}
|
|
271
272
|
│ # + pi/guard-extension.{ts,test.ts} (plugin.json `extensions.pi` entry point)
|
|
272
|
-
├── scripts/ # Executable helpers, split from prompts (ADR-031) —
|
|
273
|
+
├── scripts/ # Executable helpers, split from prompts (ADR-031) — batch-preflight.ts + scripts/<skill>/
|
|
273
274
|
│ # (daily-summary: {daily-summary, logger}.ts; dogfood-testing: {detect-pipeline-driving, validate-report}.ts)
|
|
274
|
-
├── tests/ # Plugin tests —
|
|
275
|
+
├── tests/ # Plugin tests — skill-structure.test.ts + batch-preflight.test.ts + per-skill suites (command-contract moved to scripts/commands/)
|
|
275
276
|
├── evals/ # Skill behavioral eval harness (scenarios + judge + run-eval runner)
|
|
276
277
|
├── plugin.json # Marketplace entry
|
|
277
278
|
└── README.md # This file
|
|
@@ -399,7 +400,7 @@ hand-editable source for the operator command surface. Per-platform adapters are
|
|
|
399
400
|
output** owned by `superskill` (`superskill install sp`) and never committed here. Plugin `sp` ships
|
|
400
401
|
no per-platform artifacts — only the platform-independent thin wrappers.
|
|
401
402
|
|
|
402
|
-
**Thin-wrapper contract** is enforced by `scripts/validate-commands.ts`:
|
|
403
|
+
**Thin-wrapper contract** is enforced by `scripts/commands/validate-commands.ts`:
|
|
403
404
|
|
|
404
405
|
```bash
|
|
405
406
|
bun run validate-commands # validate all 39 commands
|
|
@@ -415,7 +416,7 @@ gate (a) is strengthened: the ordered three-heading set `## Argument Flags` →
|
|
|
415
416
|
`## Implementation` is required, and gate (e) checks the `argument-hint` is syntax-only (no
|
|
416
417
|
Markdown links), the `## Argument Flags` table has exactly `Flag | Description | Default` columns,
|
|
417
418
|
the command carries exactly one glossary reference, and canonical hint tokens have bidirectional
|
|
418
|
-
parity with table rows. The same gates are tested in `
|
|
419
|
+
parity with table rows. The same gates are tested in `scripts/commands/command-contract.test.ts` and
|
|
419
420
|
`tests/command-flag-parity.test.ts`. See
|
|
420
421
|
`docs/design/dev-command-argument-contract.md` for the full contract.
|
|
421
422
|
|
|
@@ -506,15 +507,12 @@ hold `SKILL.md` and prompt-side companions only.
|
|
|
506
507
|
| `hooks/context-*.ts` | Runtime for the three registered context hooks (session-start, post-tool, session-stop) — token-cost estimation + ledger append for `sp:indexed-context` |
|
|
507
508
|
| `hooks/careful-guard.ts` | Opt-in destructive-command guard (unwired — see Hooks above) |
|
|
508
509
|
| `scripts/batch-preflight.ts` | Pure TABLE A STOP evaluation for `super-planner` — skip doomed pipeline launches without spawning a Skill subprocess; recovery hints map stuck statuses to a single `/sp:dev-*` hop |
|
|
509
|
-
| `scripts/workflow-step-profile.ts` |
|
|
510
|
+
| `scripts/workflow-step-profile.ts` | Thin glue over the generated lib bundle (`lib/step-profile.generated.mjs` from `packages/app/src/workflow/step-profile.ts`) — read-only step profile from `spur workflow trace`: per node and action-kind durations, idle gaps, session mode and `cacheHit` coverage, plus the ADR-115 cache-window flags `sp:spur-doctor` turns into workflow-optimization proposals |
|
|
510
511
|
| `scripts/dogfood-testing/detect-pipeline-driving.ts` | Word-boundary detector for pipeline-driving testees (leading-space invariant) |
|
|
511
512
|
| `scripts/dogfood-testing/validate-report.ts` | Pure `validateReport(md)` — footer-mandatory + 7-check finalize-or-abort contract with stable error codes |
|
|
512
513
|
| `scripts/daily-summary/{daily-summary,logger}.ts` | ccusage + git-history orchestration helpers for `sp:daily-summary` |
|
|
513
|
-
| `scripts/feature-sync-bounded.ts` | Bounded retry-suppression wrapper for `spur feature sync` during batch/wrap-up runs — suppresses identical L4-blocked repeats |
|
|
514
|
-
| `scripts/stage-registry-adapter.ts` | dev-next golden-path adapter over the canonical stage registry — TABLE A/B/C resolution bridge for the status-aware facade |
|
|
515
|
-
| `scripts/task-size-precheck.ts` | Pipeline size precheck guard (R2) — evaluates R-item/Plan-count limits to PASS/FAIL |
|
|
516
514
|
| `scripts/task-diffstat.ts` | 0943 triage-lane diffstat producer — numstat + untracked scan vs the run base; writes `<wbs>-diffstat.json` with the sensitive-path flag; fails safe (sensitive) |
|
|
517
|
-
| `scripts/validate-flag-contracts.ts`
|
|
515
|
+
| `scripts/commands/validate-flag-contracts.ts` | Mechanical consistency gate — compares flag claims across command files, flag-glossary, cross-cutting, dev-operations, and ADR; reports disagreements |
|
|
518
516
|
| `*.test.ts` | Unit suites — in `hooks/` for guards, in `tests/<skill>/` per ADR-031 pairing |
|
|
519
517
|
|
|
520
518
|
**Design principle:** Scripts are **deterministic enforcement**. Unlike skills (which are advisory
|
|
@@ -26,7 +26,8 @@ skills: [sp:code-verification, sp:functional-review, sp:code-improvement]
|
|
|
26
26
|
|
|
27
27
|
The **review specialist** for the sp plugin. Runs the multi-dimensional review defined by
|
|
28
28
|
`/sp:dev-review` — functional traceability, SECUA quality, and architectural depth — either
|
|
29
|
-
standalone (a source path or a
|
|
29
|
+
standalone (a task, a task set, a source path, or a path list) or as the pipeline's Phase 7
|
|
30
|
+
review step.
|
|
30
31
|
|
|
31
32
|
## Role
|
|
32
33
|
|
|
@@ -44,8 +45,8 @@ write `## Review`. This coordinator is the single `## Review` writer in coordina
|
|
|
44
45
|
fallback only and never overwrites authored Review.
|
|
45
46
|
|
|
46
47
|
Your job: establish scope, dispatch each requested dimension to its skill, collect findings, merge
|
|
47
|
-
them into a ranked report, and write the report to the task's `## Review` section (
|
|
48
|
-
emit it as advisory output (
|
|
48
|
+
them into a ranked report, and write the report to the task's `## Review` section (per task target)
|
|
49
|
+
or emit it as advisory output (path target).
|
|
49
50
|
|
|
50
51
|
## When to use
|
|
51
52
|
|
|
@@ -57,9 +58,13 @@ emit it as advisory output (standalone mode).
|
|
|
57
58
|
|
|
58
59
|
### Direct-Entry (standalone)
|
|
59
60
|
|
|
60
|
-
Invoked by the operator or `/sp:dev-review
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
Invoked by the operator or `/sp:dev-review` — usually as the coordinator definition the
|
|
62
|
+
invoking session acts under (`/sp:dev-review` runs its review inline; it does not dispatch this
|
|
63
|
+
agent). The target kind decides the output contract: **WBS target → the merged report is written
|
|
64
|
+
to the task's `## Review` section** (via `spur task update <wbs> --section Review --from-file`);
|
|
65
|
+
**path target → advisory output only** (no task mutation). With multiple targets the contract
|
|
66
|
+
applies per target — see [Multi-target coordination](#multi-target-coordination-task-1023) below.
|
|
67
|
+
Only when invoked under the pipeline do blocker/major findings block a gate.
|
|
63
68
|
|
|
64
69
|
### Pipeline Phase 7
|
|
65
70
|
|
|
@@ -68,12 +73,29 @@ Invoked by `task-pipeline.yaml`'s `review` step. The pipeline hands you the task
|
|
|
68
73
|
return a PASS/PARTIAL/FAIL verdict to the pipeline's `approve(HITL)` gate. `blocker`/`major`
|
|
69
74
|
findings block the gate; `minor`/`advisory` are recorded but do not block.
|
|
70
75
|
|
|
76
|
+
### Multi-target coordination (task 1023)
|
|
77
|
+
|
|
78
|
+
- **Task targets (`--tasks <selector>` / `--feature <id>[,<id>]`).** The set resolves once through
|
|
79
|
+
the batch selector grammar ([execution-batch.md § Step 1](../skills/spur-dev/references/execution-batch.md#step-1--selector-resolution-r1))
|
|
80
|
+
and freezes. Fan out one WBS-mode review per task and write each task's **own** merged
|
|
81
|
+
`## Review` — never merge two tasks into one Review. Tasks in `backlog`/`todo`/`blocked` are
|
|
82
|
+
reported **NOT-STARTED** and skipped (§ 3a outcome vocabulary); a per-task failure does not stop
|
|
83
|
+
the remaining tasks. End the run with a combined summary table (WBS, verdict, P1/P2 counts).
|
|
84
|
+
- **Path targets (`--scope <path>[,<path>]`).** Paths must exist, are normalized, and
|
|
85
|
+
nested/duplicate paths are merged. Run one path-scope sub-review (Step 3p) per surviving path —
|
|
86
|
+
each eligible for native-subagent dispatch per
|
|
87
|
+
[dispatch-surface.md](../skills/parallel-execution/references/dispatch-surface.md) — then merge
|
|
88
|
+
the fragments, run **one** cross-path architecture pass (`sp:code-improvement` over the
|
|
89
|
+
inter-path imports), and emit **one** advisory report. No task mutation.
|
|
90
|
+
- **`--triage` with multiple targets** buckets findings across all targets once; identical
|
|
91
|
+
`file:line` findings are deduped before bucketing.
|
|
92
|
+
|
|
71
93
|
## Skill invocation
|
|
72
94
|
|
|
73
95
|
| Platform | Invocation |
|
|
74
96
|
| ---------- | ----------- |
|
|
75
|
-
| Claude Code |
|
|
76
|
-
| Other platforms |
|
|
97
|
+
| Claude Code | The review coordinator dispatches `Skill(skill="sp:code-verification"/"sp:functional-review"/"sp:code-improvement", args="...")` — under `/sp:dev-review` the coordinator is the invoking session (this agent is not dispatched); when this agent is dispatched directly, it dispatches the same skills |
|
|
98
|
+
| Other platforms | The coordinator invokes the three skills' review modes directly — this agent when dispatched, the invoking session under `/sp:dev-review` |
|
|
77
99
|
|
|
78
100
|
## Dispatch surface
|
|
79
101
|
|
|
@@ -94,13 +116,17 @@ HITL gate unless `--auto` was passed.
|
|
|
94
116
|
|
|
95
117
|
### Always
|
|
96
118
|
|
|
97
|
-
- [ ] Establish scope first:
|
|
98
|
-
|
|
119
|
+
- [ ] Establish scope first per target kind: task targets (task diff → `sp:code-verification`
|
|
120
|
+
Step 3, one review per task) or path targets (tracked files under the path →
|
|
121
|
+
`sp:code-verification` Step 3p, one sub-review per path). Defer to that recipe — no
|
|
122
|
+
restated copy.
|
|
99
123
|
- [ ] Dispatch each requested dimension to its owning skill — do not inline the review logic.
|
|
100
124
|
- [ ] Merge findings into a single ranked report, emitting native priority cells
|
|
101
125
|
(`P1 (blocker)` > `P2 (major)` > `P3 (minor)` > `P4 (advisory)` — see Output Format).
|
|
102
|
-
- [ ]
|
|
103
|
-
`spur task update <wbs> --section Review --from-file
|
|
126
|
+
- [ ] With a WBS target (standalone or pipeline), write the merged report to that task's
|
|
127
|
+
`## Review` section via `spur task update <wbs> --section Review --from-file` — per task
|
|
128
|
+
under a task set, then the combined summary table; with a path target, emit as advisory
|
|
129
|
+
output (one merged report for a path list, including the cross-path architecture pass).
|
|
104
130
|
- [ ] Cite `file:line` evidence for every finding — no vague "implemented correctly."
|
|
105
131
|
- [ ] Apply the honesty gate: no PASS verdict without fresh, pasted verification evidence.
|
|
106
132
|
|
|
@@ -139,10 +165,11 @@ fails it. One explicit mapping, no transcription step anywhere downstream:
|
|
|
139
165
|
Severity words stay visible in the same cell — the mapping adds the machine-readable label, it does
|
|
140
166
|
not replace the semantics.
|
|
141
167
|
|
|
142
|
-
**Section-relative headings.** In
|
|
143
|
-
`### Review` section, so every heading inside it MUST be `####` or deeper. A
|
|
144
|
-
the body becomes a new top-level task section and corrupts the document.
|
|
145
|
-
(emitted as output, not written to a task) the same body may be rendered one level
|
|
168
|
+
**Section-relative headings.** In WBS mode (standalone or pipeline) the report body is written
|
|
169
|
+
*into* the task's `### Review` section, so every heading inside it MUST be `####` or deeper. A
|
|
170
|
+
`##`/`###` heading in the body becomes a new top-level task section and corrupts the document. With
|
|
171
|
+
a path target (emitted as output, not written to a task) the same body may be rendered one level
|
|
172
|
+
shallower.
|
|
146
173
|
|
|
147
174
|
```markdown
|
|
148
175
|
#### Review Report — <wbs|path>
|
|
@@ -180,8 +207,6 @@ rejected by the checker, and so they should be:
|
|
|
180
207
|
| 1 | P4 (advisory) | — | No P1–P3 findings: 6 changed files reviewed across all six dimensions; R1–R3 traceable to tests | `packages/app/src/workflow/proof-input-fingerprint.ts:102-160` |
|
|
181
208
|
```
|
|
182
209
|
|
|
183
|
-
With `--json`, emit the same shape as a JSON object for machine consumption.
|
|
184
|
-
|
|
185
210
|
## Out of scope
|
|
186
211
|
|
|
187
212
|
- Implementing fixes (that's `sp:code-implementation` / `sp:super-coder`).
|