@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.
Files changed (87) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +64 -57
  3. package/config/corpus-baseline.json +601 -49
  4. package/config/plugin-scripts.json +2 -2
  5. package/config/rules/boundary/config-loading-ownership.yaml +21 -0
  6. package/config/workflows/history-anatomy.yaml +395 -0
  7. package/package.json +9 -9
  8. package/plugins/sp/README.md +19 -6
  9. package/plugins/sp/commands/dev-find-issue.md +25 -46
  10. package/plugins/sp/commands/dev-idea.md +3 -3
  11. package/plugins/sp/commands/dev-run.md +22 -3
  12. package/plugins/sp/lib/artifact-digest.generated.d.mts +7 -0
  13. package/plugins/sp/lib/artifact-digest.generated.mjs +48 -0
  14. package/plugins/sp/plugin.json +1 -1
  15. package/plugins/sp/references/environment-lens.md +66 -0
  16. package/plugins/sp/references/roles.md +5 -5
  17. package/plugins/sp/scripts/history-anatomy-cache.mjs +818 -0
  18. package/plugins/sp/scripts/history-anatomy-cache.ts +1014 -0
  19. package/plugins/sp/skills/dogfood-testing/references/report-template.md +30 -0
  20. package/plugins/sp/skills/history-anatomy/SKILL.md +67 -0
  21. package/plugins/sp/skills/history-anatomy/references/modes.md +82 -0
  22. package/plugins/sp/skills/history-anatomy/references/operations.md +80 -0
  23. package/plugins/sp/skills/history-anatomy/references/report-contract.md +183 -0
  24. package/plugins/sp/skills/spur-cli/references/agent.md +15 -6
  25. package/plugins/sp/skills/spur-cli/references/message.md +4 -2
  26. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +6 -4
  27. package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -2
  28. package/plugins/sp/skills/spur-dev/references/execution-batch.md +14 -1
  29. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +7 -0
  30. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +25 -13
  31. package/spur.js +1958 -1133
  32. package/web/_astro/{BoardApp.CBIzcvqi.js → BoardApp.CKolAjUz.js} +102 -102
  33. package/web/_astro/BoardApp.DXD--ybM.js +1 -0
  34. package/web/_astro/{TaskDetail.D2N60cfE.js → TaskDetail.Bre7G4gC.js} +1 -1
  35. package/web/_astro/{arc.D-EfJJwf.js → arc.7luwOGiC.js} +1 -1
  36. package/web/_astro/{architectureDiagram-3BPJPVTR.CgvTTzqp.js → architectureDiagram-3BPJPVTR.F6KaHXp-.js} +1 -1
  37. package/web/_astro/{blockDiagram-GPEHLZMM.CnOohvvn.js → blockDiagram-GPEHLZMM.CCGHeRVi.js} +1 -1
  38. package/web/_astro/{c4Diagram-AAUBKEIU.BFcBGUy_.js → c4Diagram-AAUBKEIU.CpqewGmd.js} +1 -1
  39. package/web/_astro/channel.DxfOFf1l.js +1 -0
  40. package/web/_astro/{chunk-2J33WTMH.C-6MR-XY.js → chunk-2J33WTMH.CB9vKa5F.js} +1 -1
  41. package/web/_astro/{chunk-4BX2VUAB.BN4LP5AR.js → chunk-4BX2VUAB.ifGXoUA3.js} +1 -1
  42. package/web/_astro/{chunk-55IACEB6.tUJ_CTtZ.js → chunk-55IACEB6.VIaRo7l8.js} +1 -1
  43. package/web/_astro/{chunk-727SXJPM.BNCk-sxv.js → chunk-727SXJPM.DzPE41OS.js} +1 -1
  44. package/web/_astro/{chunk-AQP2D5EJ.BkpFIbNa.js → chunk-AQP2D5EJ.UF2QRXYF.js} +1 -1
  45. package/web/_astro/{chunk-FMBD7UC4.DcSZ87PN.js → chunk-FMBD7UC4.D2zXKa1R.js} +1 -1
  46. package/web/_astro/{chunk-ND2GUHAM.BkLvHFFf.js → chunk-ND2GUHAM.Cb9bDyvx.js} +1 -1
  47. package/web/_astro/{chunk-QZHKN3VN.HOdgszax.js → chunk-QZHKN3VN.nUKFBiLD.js} +1 -1
  48. package/web/_astro/{classDiagram-4FO5ZUOK.CWfRiY6b.js → classDiagram-4FO5ZUOK.DZg9K9mO.js} +1 -1
  49. package/web/_astro/{classDiagram-v2-Q7XG4LA2.CWfRiY6b.js → classDiagram-v2-Q7XG4LA2.DZg9K9mO.js} +1 -1
  50. package/web/_astro/{cose-bilkent-S5V4N54A.C6j4PxoN.js → cose-bilkent-S5V4N54A.D9STo90d.js} +1 -1
  51. package/web/_astro/{dagre-BM42HDAG.BATZG1II.js → dagre-BM42HDAG.D3IbwhHz.js} +1 -1
  52. package/web/_astro/{diagram-2AECGRRQ.B0f5yY6x.js → diagram-2AECGRRQ.BWTDxBe9.js} +1 -1
  53. package/web/_astro/{diagram-5GNKFQAL.Bewupqv0.js → diagram-5GNKFQAL.XnXlonHG.js} +1 -1
  54. package/web/_astro/{diagram-KO2AKTUF.C23r1tB2.js → diagram-KO2AKTUF.CywOngCO.js} +1 -1
  55. package/web/_astro/{diagram-LMA3HP47.DUErdBOR.js → diagram-LMA3HP47.DY1D21Iu.js} +1 -1
  56. package/web/_astro/{diagram-OG6HWLK6.BubmwAjb.js → diagram-OG6HWLK6.DQxb59KA.js} +1 -1
  57. package/web/_astro/{erDiagram-TEJ5UH35.BE_Qs5mv.js → erDiagram-TEJ5UH35.CF2U-pQZ.js} +1 -1
  58. package/web/_astro/{flowDiagram-I6XJVG4X.COWdbzon.js → flowDiagram-I6XJVG4X.BJK4M3in.js} +1 -1
  59. package/web/_astro/{ganttDiagram-6RSMTGT7.5EGYC4MK.js → ganttDiagram-6RSMTGT7.BSniMzdB.js} +1 -1
  60. package/web/_astro/{gitGraphDiagram-PVQCEYII.bUUV7iEw.js → gitGraphDiagram-PVQCEYII.Dxg-yRov.js} +1 -1
  61. package/web/_astro/index.BVXdIsZV.css +1 -0
  62. package/web/_astro/{infoDiagram-5YYISTIA.CbiInFvz.js → infoDiagram-5YYISTIA.BY4CgO_n.js} +1 -1
  63. package/web/_astro/{ishikawaDiagram-YF4QCWOH.CB7lrSsJ.js → ishikawaDiagram-YF4QCWOH.BmWDZtwF.js} +1 -1
  64. package/web/_astro/{journeyDiagram-JHISSGLW.rhGZgWt8.js → journeyDiagram-JHISSGLW.CpB1YWDP.js} +1 -1
  65. package/web/_astro/{kanban-definition-UN3LZRKU.DPeZD_lP.js → kanban-definition-UN3LZRKU.k-fukQX9.js} +1 -1
  66. package/web/_astro/{linear.l60Nyp5b.js → linear.BNNCobvI.js} +1 -1
  67. package/web/_astro/{mermaid.core.DmtMJcmL.js → mermaid.core.DnpzzuPU.js} +4 -4
  68. package/web/_astro/{mindmap-definition-RKZ34NQL.Cc47AcCn.js → mindmap-definition-RKZ34NQL.D9NnlLBu.js} +1 -1
  69. package/web/_astro/{pieDiagram-4H26LBE5.B8cN-S9g.js → pieDiagram-4H26LBE5.CKhoMiyC.js} +1 -1
  70. package/web/_astro/{quadrantDiagram-W4KKPZXB.DY1FN89L.js → quadrantDiagram-W4KKPZXB.BkAygRlm.js} +1 -1
  71. package/web/_astro/{requirementDiagram-4Y6WPE33.CnM6VbV8.js → requirementDiagram-4Y6WPE33.CX8ibmwc.js} +1 -1
  72. package/web/_astro/{sankeyDiagram-5OEKKPKP.B9DcGfNV.js → sankeyDiagram-5OEKKPKP.Dvurpa0Y.js} +1 -1
  73. package/web/_astro/{sequenceDiagram-3UESZ5HK.ymxaNlAY.js → sequenceDiagram-3UESZ5HK.veO8c2tk.js} +1 -1
  74. package/web/_astro/{stateDiagram-AJRCARHV.DDOJ3d8P.js → stateDiagram-AJRCARHV.DpMr4CO3.js} +1 -1
  75. package/web/_astro/{stateDiagram-v2-BHNVJYJU.Ck0Nb_KY.js → stateDiagram-v2-BHNVJYJU.CKjso86_.js} +1 -1
  76. package/web/_astro/{timeline-definition-PNZ67QCA.BNOvZwAN.js → timeline-definition-PNZ67QCA.DayoPp_2.js} +1 -1
  77. package/web/_astro/{vennDiagram-CIIHVFJN.D3k5ivSF.js → vennDiagram-CIIHVFJN.XNHf04O9.js} +1 -1
  78. package/web/_astro/{wardley-L42UT6IY.BylaxVqn.js → wardley-L42UT6IY.CpM_031g.js} +1 -1
  79. package/web/_astro/{wardleyDiagram-YWT4CUSO.HLNtFUm9.js → wardleyDiagram-YWT4CUSO.lIAjSkZJ.js} +1 -1
  80. package/web/_astro/{xychartDiagram-2RQKCTM6.B-WooKSU.js → xychartDiagram-2RQKCTM6.D8_2K6U1.js} +1 -1
  81. package/web/index.html +2 -2
  82. package/plugins/sp/commands/dev-history-load.md +0 -63
  83. package/plugins/sp/scripts/history-load.mjs +0 -268
  84. package/plugins/sp/scripts/history-load.ts +0 -400
  85. package/web/_astro/BoardApp.BtRfVADq.js +0 -1
  86. package/web/_astro/channel.kIu33Gui.js +0 -1
  87. package/web/_astro/index.Cestp9nh.css +0 -1
@@ -32,9 +32,9 @@
32
32
  "twin": "feature-sync-bounded.mjs"
33
33
  },
34
34
  {
35
- "rel": "history-load.ts",
35
+ "rel": "history-anatomy-cache.ts",
36
36
  "contract": "standard",
37
- "twin": "history-load.mjs"
37
+ "twin": "history-anatomy-cache.mjs"
38
38
  },
39
39
  {
40
40
  "rel": "pr-reviewing.ts",
@@ -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.61",
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.42",
57
- "@gobing-ai/ts-ai-runner": "^0.4.42",
58
- "@gobing-ai/ts-dual-workflow-engine": "^0.4.42",
59
- "@gobing-ai/ts-infra": "^0.4.42",
60
- "@gobing-ai/ts-llm-jsonl-importer": "^0.4.42",
61
- "@gobing-ai/ts-rule-engine": "^0.4.42",
62
- "@gobing-ai/ts-runtime": "^0.4.42",
63
- "@gobing-ai/ts-utils": "^0.4.42",
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",
@@ -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` | Review agent session logs, identify performance bottlenecks and behavioral anti-patterns, and generate a structured task file with proposed fixes |
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 `/sp:dev-find-issue` |
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
- **39 commands** (see the Command index above for the full list), organized by the surface they wrap:
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-*` | 33 | `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:issue-finding`, `sp:conflict-finding`, `sp:reverse-engineering`, `sp:pr-reviewing`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
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 39 `.md` files in `commands/` are the authoritative,
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.