@gobing-ai/spur 0.3.61 → 0.3.63
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 +64 -57
- package/config/corpus-baseline.json +601 -49
- package/config/plugin-scripts.json +2 -2
- package/config/rules/boundary/config-loading-ownership.yaml +21 -0
- package/config/workflows/history-anatomy.yaml +395 -0
- package/package.json +9 -9
- package/plugins/sp/README.md +19 -6
- package/plugins/sp/commands/dev-find-issue.md +25 -46
- package/plugins/sp/commands/dev-idea.md +3 -3
- package/plugins/sp/commands/dev-run.md +22 -3
- package/plugins/sp/lib/artifact-digest.generated.d.mts +7 -0
- package/plugins/sp/lib/artifact-digest.generated.mjs +48 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/environment-lens.md +66 -0
- package/plugins/sp/references/roles.md +5 -5
- package/plugins/sp/scripts/history-anatomy-cache.mjs +818 -0
- package/plugins/sp/scripts/history-anatomy-cache.ts +1014 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +30 -0
- package/plugins/sp/skills/history-anatomy/SKILL.md +67 -0
- package/plugins/sp/skills/history-anatomy/references/modes.md +82 -0
- package/plugins/sp/skills/history-anatomy/references/operations.md +80 -0
- package/plugins/sp/skills/history-anatomy/references/report-contract.md +183 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +15 -6
- package/plugins/sp/skills/spur-cli/references/message.md +4 -2
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +6 -4
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -2
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +14 -1
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +7 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +25 -13
- package/spur.js +1958 -1133
- package/web/_astro/{BoardApp.CBIzcvqi.js → BoardApp.CKolAjUz.js} +102 -102
- package/web/_astro/BoardApp.DXD--ybM.js +1 -0
- package/web/_astro/{TaskDetail.D2N60cfE.js → TaskDetail.Bre7G4gC.js} +1 -1
- package/web/_astro/{arc.D-EfJJwf.js → arc.7luwOGiC.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.CgvTTzqp.js → architectureDiagram-3BPJPVTR.F6KaHXp-.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.CnOohvvn.js → blockDiagram-GPEHLZMM.CCGHeRVi.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BFcBGUy_.js → c4Diagram-AAUBKEIU.CpqewGmd.js} +1 -1
- package/web/_astro/channel.DxfOFf1l.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.C-6MR-XY.js → chunk-2J33WTMH.CB9vKa5F.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BN4LP5AR.js → chunk-4BX2VUAB.ifGXoUA3.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.tUJ_CTtZ.js → chunk-55IACEB6.VIaRo7l8.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BNCk-sxv.js → chunk-727SXJPM.DzPE41OS.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BkpFIbNa.js → chunk-AQP2D5EJ.UF2QRXYF.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DcSZ87PN.js → chunk-FMBD7UC4.D2zXKa1R.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.BkLvHFFf.js → chunk-ND2GUHAM.Cb9bDyvx.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.HOdgszax.js → chunk-QZHKN3VN.nUKFBiLD.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.CWfRiY6b.js → classDiagram-4FO5ZUOK.DZg9K9mO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.CWfRiY6b.js → classDiagram-v2-Q7XG4LA2.DZg9K9mO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.C6j4PxoN.js → cose-bilkent-S5V4N54A.D9STo90d.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.BATZG1II.js → dagre-BM42HDAG.D3IbwhHz.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.B0f5yY6x.js → diagram-2AECGRRQ.BWTDxBe9.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Bewupqv0.js → diagram-5GNKFQAL.XnXlonHG.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.C23r1tB2.js → diagram-KO2AKTUF.CywOngCO.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.DUErdBOR.js → diagram-LMA3HP47.DY1D21Iu.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BubmwAjb.js → diagram-OG6HWLK6.DQxb59KA.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BE_Qs5mv.js → erDiagram-TEJ5UH35.CF2U-pQZ.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.COWdbzon.js → flowDiagram-I6XJVG4X.BJK4M3in.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.5EGYC4MK.js → ganttDiagram-6RSMTGT7.BSniMzdB.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.bUUV7iEw.js → gitGraphDiagram-PVQCEYII.Dxg-yRov.js} +1 -1
- package/web/_astro/index.BVXdIsZV.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CbiInFvz.js → infoDiagram-5YYISTIA.BY4CgO_n.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CB7lrSsJ.js → ishikawaDiagram-YF4QCWOH.BmWDZtwF.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.rhGZgWt8.js → journeyDiagram-JHISSGLW.CpB1YWDP.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.DPeZD_lP.js → kanban-definition-UN3LZRKU.k-fukQX9.js} +1 -1
- package/web/_astro/{linear.l60Nyp5b.js → linear.BNNCobvI.js} +1 -1
- package/web/_astro/{mermaid.core.DmtMJcmL.js → mermaid.core.DnpzzuPU.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.Cc47AcCn.js → mindmap-definition-RKZ34NQL.D9NnlLBu.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.B8cN-S9g.js → pieDiagram-4H26LBE5.CKhoMiyC.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DY1FN89L.js → quadrantDiagram-W4KKPZXB.BkAygRlm.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CnM6VbV8.js → requirementDiagram-4Y6WPE33.CX8ibmwc.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.B9DcGfNV.js → sankeyDiagram-5OEKKPKP.Dvurpa0Y.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.ymxaNlAY.js → sequenceDiagram-3UESZ5HK.veO8c2tk.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DDOJ3d8P.js → stateDiagram-AJRCARHV.DpMr4CO3.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.Ck0Nb_KY.js → stateDiagram-v2-BHNVJYJU.CKjso86_.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BNOvZwAN.js → timeline-definition-PNZ67QCA.DayoPp_2.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.D3k5ivSF.js → vennDiagram-CIIHVFJN.XNHf04O9.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.BylaxVqn.js → wardley-L42UT6IY.CpM_031g.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.HLNtFUm9.js → wardleyDiagram-YWT4CUSO.lIAjSkZJ.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.B-WooKSU.js → xychartDiagram-2RQKCTM6.D8_2K6U1.js} +1 -1
- package/web/index.html +2 -2
- package/plugins/sp/commands/dev-history-load.md +0 -63
- package/plugins/sp/scripts/history-load.mjs +0 -268
- package/plugins/sp/scripts/history-load.ts +0 -400
- package/web/_astro/BoardApp.BtRfVADq.js +0 -1
- package/web/_astro/channel.kIu33Gui.js +0 -1
- package/web/_astro/index.Cestp9nh.css +0 -1
|
@@ -52,3 +52,24 @@ rules:
|
|
|
52
52
|
exclude:
|
|
53
53
|
- "**/node_modules/**"
|
|
54
54
|
- "**/tests/**"
|
|
55
|
+
|
|
56
|
+
- id: spur-config-loader-only-at-composition-roots
|
|
57
|
+
description: >
|
|
58
|
+
`loadSpurConfig` is called at the composition roots only (ADR-082). Every other
|
|
59
|
+
surface consumes the merged result threaded through its context — a per-slice load
|
|
60
|
+
re-reads a single layer's view and reintroduces the split-brain A5 removed.
|
|
61
|
+
severity: error
|
|
62
|
+
evaluator:
|
|
63
|
+
type: rg
|
|
64
|
+
config:
|
|
65
|
+
pattern: "loadSpurConfig\\("
|
|
66
|
+
include:
|
|
67
|
+
- "apps/**/src/**/*.ts"
|
|
68
|
+
- "packages/**/src/**/*.ts"
|
|
69
|
+
exclude:
|
|
70
|
+
- "packages/config/src/**"
|
|
71
|
+
- "apps/cli/src/index.ts"
|
|
72
|
+
- "apps/server/src/serve.ts"
|
|
73
|
+
- "apps/server/src/context.ts"
|
|
74
|
+
- "**/node_modules/**"
|
|
75
|
+
- "**/tests/**"
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# History-anatomy pipeline — daily/ad-hoc diagnostic report over already-imported history
|
|
2
|
+
# (feature I8, HA-S1 0660 / ADR-079).
|
|
3
|
+
#
|
|
4
|
+
# Orchestration is configuration (ADR-022): a state machine over the existing dual-workflow
|
|
5
|
+
# engine. The YAML owns ONLY the cache branch, deterministic stage ordering, executor dispatch,
|
|
6
|
+
# bounded correction, and atomic publication sequencing. The deterministic cache/digest/
|
|
7
|
+
# structure/publish work is 0659's dependency-free helper script; the judgment (mode validity,
|
|
8
|
+
# what counts as evidence, the report contract, enrich/validate rubrics) is 0658's skill. Per
|
|
9
|
+
# ADR-069 R1, cache-decide / digest / structure-check / publish must NOT be inline shell — every
|
|
10
|
+
# shell action here is glue length (a single helper invocation), because each of those programs
|
|
11
|
+
# would exceed the shell composition threshold and be flagged as an owned-capability candidate.
|
|
12
|
+
#
|
|
13
|
+
# Shape:
|
|
14
|
+
# start -> resolve-scope -> resolve-paths -> analyze -> cache-probe
|
|
15
|
+
# (hit -> refresh-provenance -> publish -> published)
|
|
16
|
+
# (miss -> render -> enrich -> structure-gate -> validate -> stamp -> publish)
|
|
17
|
+
# (validate FAIL -> correct (max 1) -> structure-gate ...; exhausted -> failed)
|
|
18
|
+
# (any all-paths failure -> failed)
|
|
19
|
+
#
|
|
20
|
+
# `analyze` precedes `cache-probe` deliberately: ADR-079 makes cache validity a DERIVED fact, so
|
|
21
|
+
# the semantic digest must come from a fresh analyze, never from the cached report being judged.
|
|
22
|
+
# The deterministic half is therefore never cached — only the model-authored half is reused.
|
|
23
|
+
#
|
|
24
|
+
# terminalStates: [published, failed]. Publication is reachable ONLY via `stamp` (guarded on a
|
|
25
|
+
# passing validation) or `refresh-provenance` (whose model half was itself published through a
|
|
26
|
+
# passing validation) — there is no edge into `publish` from structure-gate or enrich directly.
|
|
27
|
+
#
|
|
28
|
+
# Vars (all must be declared here — the vars: block is the only safe shape; `spur workflow
|
|
29
|
+
# validate` and the skill-structure test enforce it):
|
|
30
|
+
# mode — "daily" (default) | "ad-hoc" (validated in resolve-scope)
|
|
31
|
+
# date — YYYY-MM-DD for --date (daily); empty for ad-hoc
|
|
32
|
+
# since — inclusive ISO lower bound (ad-hoc; also normalizes daily via the DST-aware rule)
|
|
33
|
+
# until — inclusive ISO upper bound (ad-hoc)
|
|
34
|
+
# baselineSince — declared home for the baseline-leg lower bound the analyze stage references;
|
|
35
|
+
# actual values flow through the run-scoped env file emitted by resolve-paths
|
|
36
|
+
# (0674 R2/R5 — a referenced var must have a declared home, never an implicit one)
|
|
37
|
+
# baselineUntil — baseline-leg upper bound, same contract as baselineSince
|
|
38
|
+
# focus — ad-hoc focus string (required in ad-hoc mode, rejected in daily)
|
|
39
|
+
# recompute — "true" forces the full analyze/render/enrich/validate path (cache disposition
|
|
40
|
+
# forced-recompute)
|
|
41
|
+
# output — explicit report output path; default run directory
|
|
42
|
+
# agent — executor for the agent.run stages (enrich/validate)
|
|
43
|
+
# spurBin — PATH-independent spur invocation (overridden by CLI at run start)
|
|
44
|
+
# __runId — run-scoped id for explicit artifact paths (allocated in start)
|
|
45
|
+
# stepTimeoutMs — agent.run budget for enrich/validate
|
|
46
|
+
# correctionCount — bounded correction loop counter file path bits (name resolved in correct)
|
|
47
|
+
|
|
48
|
+
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
49
|
+
kind: state-machine
|
|
50
|
+
name: history-anatomy
|
|
51
|
+
description: "Daily/ad-hoc history-anatomy report: cache branch, deterministic analyze/render, skill enrichment, deterministic structure gate, independent evidence validation, bounded correction, atomic publication"
|
|
52
|
+
iterationBound: 20
|
|
53
|
+
initialState: start
|
|
54
|
+
terminalStates:
|
|
55
|
+
- published
|
|
56
|
+
- failed
|
|
57
|
+
failureStates:
|
|
58
|
+
- failed
|
|
59
|
+
vars:
|
|
60
|
+
mode: "daily"
|
|
61
|
+
date: ""
|
|
62
|
+
since: ""
|
|
63
|
+
until: ""
|
|
64
|
+
baselineSince: ""
|
|
65
|
+
baselineUntil: ""
|
|
66
|
+
focus: ""
|
|
67
|
+
recompute: "false"
|
|
68
|
+
output: ""
|
|
69
|
+
# 0676 R5: omp went quota-dead (HTTP 429) in the 2026-08-25 dogfood. The literal names a
|
|
70
|
+
# currently-reachable executor; `agent.default` in config still overrides via the precedence chain.
|
|
71
|
+
agent: "claude"
|
|
72
|
+
spurBin: "spur"
|
|
73
|
+
__runId: ""
|
|
74
|
+
stepTimeoutMs: "1800000"
|
|
75
|
+
correctionCount: "0"
|
|
76
|
+
workflowFile: "config/workflows/history-anatomy.yaml"
|
|
77
|
+
contractVersion: "1"
|
|
78
|
+
reportDir: "docs/report"
|
|
79
|
+
|
|
80
|
+
states:
|
|
81
|
+
- id: start
|
|
82
|
+
description: >
|
|
83
|
+
Allocate the run-scoped id and root. Every analyze/render path in this workflow writes to
|
|
84
|
+
an explicit unique path under this run id — no stage reads the mutable latest.json pointer.
|
|
85
|
+
onEnter:
|
|
86
|
+
- kind: shell
|
|
87
|
+
options:
|
|
88
|
+
command: >-
|
|
89
|
+
mkdir -p .spur/run;
|
|
90
|
+
if [ -z "$__runId" ]; then __runId=$(uuidgen | tr 'A-Z' 'a-z' | cut -c1-8); fi;
|
|
91
|
+
echo "$__runId" > .spur/run/history-anatomy-run.id
|
|
92
|
+
|
|
93
|
+
- id: resolve-scope
|
|
94
|
+
description: >
|
|
95
|
+
Dispatch the skill's mode validation (0658 references/modes.md): daily is the default and
|
|
96
|
+
rejects focus/since/until/output; ad-hoc requires a non-empty focus plus two ordered
|
|
97
|
+
inclusive bounds and rejects --date/--recompute. Writes the normalized selector artifact.
|
|
98
|
+
onEnter:
|
|
99
|
+
- kind: agent.run
|
|
100
|
+
options:
|
|
101
|
+
agent: ${vars.agent}
|
|
102
|
+
input: "Validate the mode arguments per sp:history-anatomy references/modes.md and write the normalized selector to .spur/run/${vars.__runId}-selector.json. mode=${vars.mode} date=${vars.date} since=${vars.since} until=${vars.until} focus=${vars.focus}. Reject conflicting arguments, naming the offending one; a rejection marks the run failed."
|
|
103
|
+
# Declared Layer-1 role (0538 R2): mode validation is a reviewer-standard judgment.
|
|
104
|
+
role: reviewer
|
|
105
|
+
expectFile: .spur/run/${vars.__runId}-selector.json
|
|
106
|
+
timeoutMs: ${vars.stepTimeoutMs}
|
|
107
|
+
|
|
108
|
+
- id: resolve-paths
|
|
109
|
+
description: >
|
|
110
|
+
Resolve the helper, the skill/contract logic paths, and the publication target once, into a
|
|
111
|
+
run-scoped env file every later stage sources. Keeps each downstream shell action at glue
|
|
112
|
+
length (ADR-069 R1) instead of repeating path arithmetic per stage.
|
|
113
|
+
onEnter:
|
|
114
|
+
- kind: shell
|
|
115
|
+
options:
|
|
116
|
+
# Path arithmetic lives in the helper (ADR-069 R1); the shell only locates it. Avoid
|
|
117
|
+
# `${...}` here — that syntax collides with the engine's own template interpolation.
|
|
118
|
+
command: >-
|
|
119
|
+
h=$(superskill script path sp history-anatomy-cache.mjs);
|
|
120
|
+
node "$h" paths --helper "$h" --report-dir "$reportDir" --date "$date"
|
|
121
|
+
--output "$output" --mode "$mode" --since "$since" --until "$until"
|
|
122
|
+
--out .spur/run/$__runId-paths.txt
|
|
123
|
+
|
|
124
|
+
- id: analyze
|
|
125
|
+
description: >
|
|
126
|
+
Deterministic analyze of the current window and the immediately preceding comparable
|
|
127
|
+
window, each to an explicit run-scoped path. Always reruns — the deterministic half is
|
|
128
|
+
never cached (ADR-079).
|
|
129
|
+
onEnter:
|
|
130
|
+
- kind: shell
|
|
131
|
+
options:
|
|
132
|
+
command: >-
|
|
133
|
+
mkdir -p .spur/run;
|
|
134
|
+
. .spur/run/$__runId-paths.env;
|
|
135
|
+
$spurBin history analyze --out .spur/run/$__runId-history-anatomy-current.json --since "$HA_SINCE" --until "$HA_UNTIL" --json
|
|
136
|
+
- kind: shell
|
|
137
|
+
options:
|
|
138
|
+
command: >-
|
|
139
|
+
. .spur/run/$__runId-paths.env;
|
|
140
|
+
$spurBin history analyze --out .spur/run/$__runId-history-anatomy-baseline.json --since "$HA_BASELINE_SINCE" --until "$HA_BASELINE_UNTIL" --json 2>/dev/null || true
|
|
141
|
+
|
|
142
|
+
- id: cache-probe
|
|
143
|
+
description: >
|
|
144
|
+
Deterministic cache probe via the helper (0659). Runs AFTER analyze because ADR-079 makes
|
|
145
|
+
validity a derived fact: the semantic digest must come from the fresh artifact, never from
|
|
146
|
+
the cached report being judged. A hit skips only enrichment, never the probe. Daily only;
|
|
147
|
+
ad-hoc always reports miss (`ad-hoc-never-cached`). Also writes the run's full provenance.
|
|
148
|
+
onEnter:
|
|
149
|
+
- kind: shell
|
|
150
|
+
options:
|
|
151
|
+
command: >-
|
|
152
|
+
. .spur/run/$__runId-paths.txt;
|
|
153
|
+
node "$HA_HELPER" probe --artifact .spur/run/$__runId-history-anatomy-current.json
|
|
154
|
+
--baseline .spur/run/$__runId-history-anatomy-baseline.json --target "$HA_TARGET"
|
|
155
|
+
--mode "$mode" --date "$HA_DATE" --recompute "$recompute" --executor "$agent"
|
|
156
|
+
--skill-dir "$HA_SKILL" --contract "$HA_SKILL/references/report-contract.md"
|
|
157
|
+
--workflow "$workflowFile" --contract-version "$contractVersion" --run-id "$__runId"
|
|
158
|
+
--out .spur/run/$__runId-provenance.json
|
|
159
|
+
> .spur/run/$__runId-cache-disposition.txt
|
|
160
|
+
|
|
161
|
+
- id: render
|
|
162
|
+
description: >
|
|
163
|
+
Render both artifacts with report --mode forensics, naming the exact analyze paths.
|
|
164
|
+
onEnter:
|
|
165
|
+
- kind: shell
|
|
166
|
+
options:
|
|
167
|
+
command: >-
|
|
168
|
+
mkdir -p .spur/run;
|
|
169
|
+
$spurBin history report .spur/run/$__runId-history-anatomy-current.json --mode forensics > .spur/run/$__runId-history-anatomy-current.md;
|
|
170
|
+
$spurBin history report .spur/run/$__runId-history-anatomy-baseline.json --mode forensics > .spur/run/$__runId-history-anatomy-baseline.md || true
|
|
171
|
+
|
|
172
|
+
- id: enrich
|
|
173
|
+
description: >
|
|
174
|
+
Model enrichment via the skill operation sp:history-anatomy enrich (0658 operations.md).
|
|
175
|
+
Consumes the two artifacts; authors the model half of the report. A porcelain baseline
|
|
176
|
+
is captured before dispatch and asserted after: any working-tree file created outside the
|
|
177
|
+
declared output fails the run (0676 R3).
|
|
178
|
+
onEnter:
|
|
179
|
+
- kind: shell
|
|
180
|
+
options:
|
|
181
|
+
command: >-
|
|
182
|
+
git status --porcelain > .spur/run/$__runId-baseline-enrich.txt || true
|
|
183
|
+
- kind: agent.run
|
|
184
|
+
options:
|
|
185
|
+
agent: ${vars.agent}
|
|
186
|
+
input: "Run sp:history-anatomy enrich: given .spur/run/${vars.__runId}-history-anatomy-current.json and -baseline.json, author the model half of the report (Baseline comparison, Findings, Recurrence ledger, Remediation options, Performance analysis, Workflow/process improvements, Positive patterns) to .spur/run/${vars.__runId}-candidate.md per references/report-contract.md. This operation never launches a workflow."
|
|
187
|
+
# Declared Layer-1 role (0538 R2): enrichment is model judgment.
|
|
188
|
+
role: reviewer
|
|
189
|
+
expectFile: .spur/run/${vars.__runId}-candidate.md
|
|
190
|
+
timeoutMs: ${vars.stepTimeoutMs}
|
|
191
|
+
- kind: shell
|
|
192
|
+
options:
|
|
193
|
+
command: >-
|
|
194
|
+
node "$(superskill script path sp history-anatomy-cache.mjs)" assert-clean --baseline .spur/run/$__runId-baseline-enrich.txt --expect .spur/run/$__runId-candidate.md
|
|
195
|
+
|
|
196
|
+
- id: structure-gate
|
|
197
|
+
description: >
|
|
198
|
+
Deterministic structure gate via the helper (0659). Asserts the twelve sections in order,
|
|
199
|
+
per-finding fields, no placeholders, evidence anchors. Not reachable on the hit path from
|
|
200
|
+
enrich — always gated before validation.
|
|
201
|
+
onEnter:
|
|
202
|
+
- kind: shell
|
|
203
|
+
options:
|
|
204
|
+
command: >-
|
|
205
|
+
node "$(superskill script path sp history-anatomy-cache.mjs)" check \
|
|
206
|
+
.spur/run/$__runId-candidate.md > .spur/run/$__runId-structure-gate.txt 2>&1 || true
|
|
207
|
+
|
|
208
|
+
- id: validate
|
|
209
|
+
description: >
|
|
210
|
+
Independent evidence validation via the skill operation sp:history-anatomy validate.
|
|
211
|
+
Publication is reachable only from a PASS here. Same undeclared-write assertion as enrich (0676 R3).
|
|
212
|
+
onEnter:
|
|
213
|
+
- kind: shell
|
|
214
|
+
options:
|
|
215
|
+
command: >-
|
|
216
|
+
git status --porcelain > .spur/run/$__runId-baseline-validate.txt || true
|
|
217
|
+
- kind: agent.run
|
|
218
|
+
options:
|
|
219
|
+
agent: ${vars.agent}
|
|
220
|
+
input: "Run sp:history-anatomy validate: independently check .spur/run/${vars.__runId}-candidate.md against the two artifacts per references/operations.md; write Verdict: PASS or FAIL to .spur/run/${vars.__runId}-validation.txt. This operation never launches a workflow."
|
|
221
|
+
# Declared Layer-1 role (0538 R2): independent verification.
|
|
222
|
+
role: reviewer
|
|
223
|
+
expectFile: .spur/run/${vars.__runId}-validation.txt
|
|
224
|
+
timeoutMs: ${vars.stepTimeoutMs}
|
|
225
|
+
- kind: shell
|
|
226
|
+
options:
|
|
227
|
+
command: >-
|
|
228
|
+
node "$(superskill script path sp history-anatomy-cache.mjs)" assert-clean --baseline .spur/run/$__runId-baseline-validate.txt --expect .spur/run/$__runId-validation.txt
|
|
229
|
+
|
|
230
|
+
- id: correct
|
|
231
|
+
description: >
|
|
232
|
+
One bounded correction pass. onEnter increments the counter; the retry edge guards on
|
|
233
|
+
correctionCount < 1, the second failure takes the -> failed edge.
|
|
234
|
+
onEnter:
|
|
235
|
+
- kind: shell
|
|
236
|
+
options:
|
|
237
|
+
command: >-
|
|
238
|
+
n=$(cat .spur/run/$__runId-correction-count 2>/dev/null || echo 0) &&
|
|
239
|
+
printf '%s\n' "$((n + 1))" > .spur/run/$__runId-correction-count
|
|
240
|
+
|
|
241
|
+
- id: refresh-provenance
|
|
242
|
+
description: >
|
|
243
|
+
Cache-hit path. Keeps the published model half verbatim and refreshes only validated_at,
|
|
244
|
+
the cache disposition, and the imported-snapshot banner — which is the EARLIEST per-source
|
|
245
|
+
lastImportedAt, so the report never claims a source was imported after its own recorded
|
|
246
|
+
timestamp. Emits the publishable artifact the shared publish state consumes.
|
|
247
|
+
onEnter:
|
|
248
|
+
- kind: shell
|
|
249
|
+
options:
|
|
250
|
+
command: >-
|
|
251
|
+
. .spur/run/$__runId-paths.txt;
|
|
252
|
+
node "$HA_HELPER" refresh --report "$HA_TARGET"
|
|
253
|
+
--out .spur/run/$__runId-publishable.md --disposition hit
|
|
254
|
+
|
|
255
|
+
- id: stamp
|
|
256
|
+
description: >
|
|
257
|
+
Cache-miss path. Attaches the full R7 frontmatter provenance block (identity tuple, window
|
|
258
|
+
state, generated/validated timestamps, artifact paths + digests, contract/skill/workflow
|
|
259
|
+
digests, per-source coverage + last_imported_at, spur/schema version, executor, run id,
|
|
260
|
+
cache disposition) and the freshness banner to the validated candidate.
|
|
261
|
+
onEnter:
|
|
262
|
+
- kind: shell
|
|
263
|
+
options:
|
|
264
|
+
command: >-
|
|
265
|
+
. .spur/run/$__runId-paths.txt;
|
|
266
|
+
node "$HA_HELPER" stamp --candidate .spur/run/$__runId-candidate.md
|
|
267
|
+
--provenance .spur/run/$__runId-provenance.json
|
|
268
|
+
--out .spur/run/$__runId-publishable.md
|
|
269
|
+
|
|
270
|
+
- id: publish
|
|
271
|
+
description: >
|
|
272
|
+
Atomic publication via the helper (0659). Reachable only from `stamp` (which is reachable
|
|
273
|
+
only from a passing validate) or from `refresh-provenance` on the cache-hit path — the
|
|
274
|
+
model half a hit reuses was itself published through a passing validation.
|
|
275
|
+
onEnter:
|
|
276
|
+
- kind: shell
|
|
277
|
+
options:
|
|
278
|
+
command: >-
|
|
279
|
+
. .spur/run/$__runId-paths.txt;
|
|
280
|
+
mkdir -p "$(dirname "$HA_TARGET")";
|
|
281
|
+
node "$HA_HELPER" publish .spur/run/$__runId-publishable.md "$HA_TARGET"
|
|
282
|
+
|
|
283
|
+
- id: published
|
|
284
|
+
description: Terminal — report published atomically after a passing validation.
|
|
285
|
+
|
|
286
|
+
- id: failed
|
|
287
|
+
description: Terminal — mode rejection, gate failure, or validation failure not corrected.
|
|
288
|
+
|
|
289
|
+
transitions:
|
|
290
|
+
- from: start
|
|
291
|
+
to: resolve-scope
|
|
292
|
+
description: Scope resolved.
|
|
293
|
+
guard:
|
|
294
|
+
kind: always
|
|
295
|
+
|
|
296
|
+
- from: resolve-scope
|
|
297
|
+
to: resolve-paths
|
|
298
|
+
description: Mode valid — resolve helper/skill/target paths once.
|
|
299
|
+
guard:
|
|
300
|
+
kind: always
|
|
301
|
+
|
|
302
|
+
- from: resolve-paths
|
|
303
|
+
to: analyze
|
|
304
|
+
description: Paths resolved — always rerun the deterministic half (ADR-079).
|
|
305
|
+
guard:
|
|
306
|
+
kind: always
|
|
307
|
+
|
|
308
|
+
- from: analyze
|
|
309
|
+
to: cache-probe
|
|
310
|
+
description: Fresh artifacts on disk — derive the digest and decide reuse.
|
|
311
|
+
guard:
|
|
312
|
+
kind: always
|
|
313
|
+
|
|
314
|
+
# Daily only takes the hit branch; ad-hoc always regenerates.
|
|
315
|
+
- from: cache-probe
|
|
316
|
+
to: refresh-provenance
|
|
317
|
+
description: Cache hit (daily) — refresh provenance and publish without re-enrichment.
|
|
318
|
+
guard:
|
|
319
|
+
kind: shell
|
|
320
|
+
options:
|
|
321
|
+
command: 'test "$mode" = daily && grep -q "^hit$" .spur/run/$__runId-cache-disposition.txt 2>/dev/null'
|
|
322
|
+
- from: cache-probe
|
|
323
|
+
to: render
|
|
324
|
+
description: Cache miss, forced recompute, or ad-hoc — render and re-enrich.
|
|
325
|
+
guard:
|
|
326
|
+
kind: always
|
|
327
|
+
|
|
328
|
+
- from: refresh-provenance
|
|
329
|
+
to: publish
|
|
330
|
+
description: Provenance refreshed — publish the cached model half.
|
|
331
|
+
guard:
|
|
332
|
+
kind: always
|
|
333
|
+
|
|
334
|
+
- from: render
|
|
335
|
+
to: enrich
|
|
336
|
+
description: Both artifacts rendered — enrich.
|
|
337
|
+
guard:
|
|
338
|
+
kind: always
|
|
339
|
+
|
|
340
|
+
- from: enrich
|
|
341
|
+
to: structure-gate
|
|
342
|
+
description: Candidate authored — deterministic structure gate.
|
|
343
|
+
guard:
|
|
344
|
+
kind: always
|
|
345
|
+
|
|
346
|
+
- from: structure-gate
|
|
347
|
+
to: validate
|
|
348
|
+
description: Candidate structurally sound — independent evidence validation.
|
|
349
|
+
guard:
|
|
350
|
+
kind: shell
|
|
351
|
+
options:
|
|
352
|
+
command: 'grep -q "^PASS$" .spur/run/$__runId-structure-gate.txt 2>/dev/null'
|
|
353
|
+
- from: structure-gate
|
|
354
|
+
to: failed
|
|
355
|
+
description: Structure gate FAIL — never publish a malformed candidate.
|
|
356
|
+
guard:
|
|
357
|
+
kind: always
|
|
358
|
+
|
|
359
|
+
- from: validate
|
|
360
|
+
to: stamp
|
|
361
|
+
description: Independent validation PASS — stamp provenance, then publish atomically.
|
|
362
|
+
guard:
|
|
363
|
+
kind: shell
|
|
364
|
+
options:
|
|
365
|
+
command: 'grep -q "Verdict: PASS" .spur/run/$__runId-validation.txt 2>/dev/null'
|
|
366
|
+
- from: validate
|
|
367
|
+
to: correct
|
|
368
|
+
description: Validation FAIL under the correction cap — one bounded pass.
|
|
369
|
+
guard:
|
|
370
|
+
kind: shell
|
|
371
|
+
options:
|
|
372
|
+
command: '! grep -q "Verdict: PASS" .spur/run/$__runId-validation.txt 2>/dev/null && test "$(cat .spur/run/$__runId-correction-count 2>/dev/null || echo 0)" -lt 1'
|
|
373
|
+
- from: validate
|
|
374
|
+
to: failed
|
|
375
|
+
description: Validation FAIL with the correction cap exhausted — terminate without publishing.
|
|
376
|
+
guard:
|
|
377
|
+
kind: always
|
|
378
|
+
|
|
379
|
+
- from: correct
|
|
380
|
+
to: structure-gate
|
|
381
|
+
description: Corrected candidate re-enters the deterministic gate, then re-validates.
|
|
382
|
+
guard:
|
|
383
|
+
kind: always
|
|
384
|
+
|
|
385
|
+
- from: stamp
|
|
386
|
+
to: publish
|
|
387
|
+
description: Provenance stamped — publish atomically.
|
|
388
|
+
guard:
|
|
389
|
+
kind: always
|
|
390
|
+
|
|
391
|
+
- from: publish
|
|
392
|
+
to: published
|
|
393
|
+
description: Report published.
|
|
394
|
+
guard:
|
|
395
|
+
kind: always
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.63",
|
|
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",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@commander-js/extra-typings": "^14.0.0",
|
|
56
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.4.43",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.4.43",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.43",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.4.43",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.43",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.4.43",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.4.43",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.4.43",
|
|
64
64
|
"@types/bun": "1.3.14",
|
|
65
65
|
"@types/figlet": "^1.7.0",
|
|
66
66
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -127,9 +127,8 @@ list this README is checked against.
|
|
|
127
127
|
| `dev-handover` | Generate a structured handover document when blocked — captures goal, progress, blocker, rejected approaches, and next steps |
|
|
128
128
|
| `dev-debug` | Systematic debugging protocol — reproduce, isolate, diagnose root cause, apply minimal fix, and verify with regression tests |
|
|
129
129
|
| `dev-daily` | Generate a daily summary report from agent usage data, git history, and notes |
|
|
130
|
-
| `dev-history-load` | On-demand cumulative history load + narrowed analyze — import (checkpoint-resume) then analyze, optionally by session/task/window, with optional forensics render |
|
|
131
130
|
| `dev-dogfood` | Dogfood an agent skill/command/CLI — drive it end-to-end with bounded auto-fix, self-monitor, and emit a comprehensive report |
|
|
132
|
-
| `dev-find-issue` |
|
|
131
|
+
| `dev-find-issue` | Generate the daily/ad-hoc history-anatomy diagnostic report over already-imported history — mode contract, closed finding taxonomy, twelve-section report contract, cache branch, atomic publication; forwards to sp:history-anatomy |
|
|
133
132
|
| `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
133
|
| `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
134
|
| `dev-fixall` | Fix all lint, type, and test errors systematically across the working tree |
|
|
@@ -240,6 +239,8 @@ plugins/sp/
|
|
|
240
239
|
│ │ └── references/{authority-resolution.md, comparison-protocol.md, finding-contract.md, remediation-routing.md}
|
|
241
240
|
│ ├── next-feature/ # Prompt-first feature frontier prioritizer (backs /sp:dev-find-next)
|
|
242
241
|
│ │ └── references/{signal-derivation.md, ranking-rubric.md, proposal-contract.md, handoff-routing.md}
|
|
242
|
+
│ ├── history-anatomy/ # Diagnostic interpretation owner over already-imported history (backs /sp:dev-find-issue)
|
|
243
|
+
│ │ └── references/{modes.md, report-contract.md, operations.md}
|
|
243
244
|
│ ├── sys-architecture/ # Architecture / ADR judgment competency
|
|
244
245
|
│ │ └── references/decision-method.md
|
|
245
246
|
│ ├── sys-debugging/ # Structured debugging protocol
|
|
@@ -312,11 +313,23 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
312
313
|
| `daily-summary` | 1.0.0 | Daily summary report generator — orchestrates ccusage CLI + git history into structured markdown summaries |
|
|
313
314
|
| `doc-evolve` | 1.0 | Key-document evolution per `docs/99_PROJECT_CONSTITUTION.md` — drift audits, same-commit sync checks, frontmatter-contract verification, machine-appended lessons |
|
|
314
315
|
| `reverse-engineering` | 1.1 | Codebase analysis / HLD generation / audit — depth-driven reverse engineering with orthogonal mode, focus, and format controls; backs `/sp:dev-reverse` |
|
|
315
|
-
| `issue-finding` | 1.1 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; backs
|
|
316
|
+
| `issue-finding` | 1.1 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; **legacy path** — superseded by `history-anatomy` for indexed reporting; backs no current command; directly invocable as sp:issue-finding |
|
|
316
317
|
| `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` |
|
|
317
318
|
| `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` |
|
|
318
319
|
| `pr-reviewing` | 1.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; spine SSOT `pr-review.yaml` + `scripts/pr-reviewing.ts`; backs `/sp:dev-pr-review` |
|
|
319
320
|
| `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 |
|
|
321
|
+
| `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 |
|
|
322
|
+
|
|
323
|
+
#### Bounded coexistence and retirement gate — `sp:issue-finding` (HA-S1 0661)
|
|
324
|
+
|
|
325
|
+
`sp:issue-finding` remains packaged and directly invocable as the **legacy path**; `/sp:dev-find-issue` resolves to `sp:history-anatomy`. No logic is shared between them. This coexistence is _bounded_, not permanent — the retirement gate below is the contract:
|
|
326
|
+
|
|
327
|
+
- **Parity fixtures** the new contract must cover before retirement is considered: typed history analysis; daily and focused range selection; repeated-work and error reporting; evidence and confidence; remediation proposals; performance analysis; process observations; positive patterns.
|
|
328
|
+
- **Intentional exclusions, not gaps:** raw history-file parsing and task creation are deliberately out of scope for `history-anatomy`; a missing parity item is checked against this list before it counts as a gap.
|
|
329
|
+
- **Adoption evidence:** successful `history-anatomy.yaml` workflow run records across both modes (`daily`, `ad-hoc`) and the available source families. No bespoke telemetry is added to count adoption.
|
|
330
|
+
- **Review point:** one minor release or 30 days after this feature ships, whichever is later.
|
|
331
|
+
- **Gate:** parity PASS + demonstrated use of both modes + no open high-impact regression + explicit operator approval. A failed gate records the missing evidence and one dated extension.
|
|
332
|
+
- **Retirement is a separate change.** This feature removes nothing; `sp:issue-finding` stays until the operator approves a dedicated retirement change.
|
|
320
333
|
|
|
321
334
|
Each skill directory contains:
|
|
322
335
|
|
|
@@ -338,11 +351,11 @@ Skills contain zero validation logic — the CLI is the gate.
|
|
|
338
351
|
|
|
339
352
|
Thin slash-command wrappers that parse user arguments and delegate to the corresponding skill. Each
|
|
340
353
|
command is a user-facing entry point that bridges natural language to skill invocation. There are
|
|
341
|
-
**
|
|
354
|
+
**38 commands** (see the Command index above for the full list), organized by the surface they wrap:
|
|
342
355
|
|
|
343
356
|
| Prefix | Count | Delegates to | Purpose |
|
|
344
357
|
| ------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
345
|
-
| `dev-*` |
|
|
358
|
+
| `dev-*` | 32 | `sp:spur-dev`, `sp:code-implementation`, `sp:code-testing`, `sp:code-verification`, `sp:code-simplification`, `sp:next-router`, `sp:brainstorm`, `sp:dogfood-testing`, `sp:parallel-execution`, `sp:sys-debugging`, `sp:daily-summary`, `sp:history-anatomy`, `sp:conflict-finding`, `sp:reverse-engineering`, `sp:pr-reviewing`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
|
|
346
359
|
| `rule-*` | 3 | `sp:spur-cli` | The rule surface — `rule-add`, `rule-refine`, `rule-scan` |
|
|
347
360
|
| `workflow-*` | 2 | `sp:spur-cli` | The workflow surface — `workflow-add`, `workflow-refine` |
|
|
348
361
|
| `spur-init` | 1 | `sp:doc-evolve` | Project bootstrap (`spur init`) with doc-evolve integration |
|
|
@@ -352,7 +365,7 @@ Each command file contains:
|
|
|
352
365
|
- YAML frontmatter (`description`, `argument-hint`, `allowed-tools`).
|
|
353
366
|
- A delegation block: `Skill(skill="sp:<skill-name>", args="<operation> $ARGUMENTS")`.
|
|
354
367
|
|
|
355
|
-
**Commands as SSOT (ADR-032).** The
|
|
368
|
+
**Commands as SSOT (ADR-032).** The 38 `.md` files in `commands/` are the authoritative,
|
|
356
369
|
hand-editable source for the operator command surface. Per-platform adapters are **install-time
|
|
357
370
|
output** owned by `superskill` (`superskill install sp`) and never committed here. Plugin `sp` ships
|
|
358
371
|
no per-platform artifacts — only the platform-independent thin wrappers.
|