@gobing-ai/spur 0.3.60 → 0.3.62

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 (110) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +2 -2
  3. package/config/config.global.yaml +68 -57
  4. package/config/corpus-baseline.json +505 -57
  5. package/config/plugin-scripts.json +2 -2
  6. package/config/rules/boundary/config-loading-ownership.yaml +21 -0
  7. package/config/workflow-composition-baseline.json +1 -1
  8. package/config/workflows/history-anatomy.yaml +366 -0
  9. package/config/workflows/wayfinder-resolution.yaml +4 -6
  10. package/package.json +1 -1
  11. package/plugins/README.md +5 -4
  12. package/plugins/sp/README.md +22 -9
  13. package/plugins/sp/agents/super-planner.md +1 -1
  14. package/plugins/sp/commands/dev-find-issue.md +25 -46
  15. package/plugins/sp/commands/dev-pr-review.md +1 -1
  16. package/plugins/sp/commands/dev-run.md +22 -3
  17. package/plugins/sp/commands/dev-wrap.md +2 -2
  18. package/plugins/sp/commands/dev-wrapall.md +2 -2
  19. package/plugins/sp/lib/artifact-digest.generated.d.mts +7 -0
  20. package/plugins/sp/lib/artifact-digest.generated.mjs +48 -0
  21. package/plugins/sp/plugin.json +1 -1
  22. package/plugins/sp/references/roles.md +17 -14
  23. package/plugins/sp/scripts/history-anatomy-cache.mjs +669 -0
  24. package/plugins/sp/scripts/history-anatomy-cache.ts +818 -0
  25. package/plugins/sp/scripts/surface-drift-inventory.ts +51 -17
  26. package/plugins/sp/scripts/validate-commands.ts +11 -4
  27. package/plugins/sp/skills/code-verification/SKILL.md +1 -1
  28. package/plugins/sp/skills/code-verification/references/verdict-schema.md +1 -1
  29. package/plugins/sp/skills/history-anatomy/SKILL.md +67 -0
  30. package/plugins/sp/skills/history-anatomy/references/modes.md +82 -0
  31. package/plugins/sp/skills/history-anatomy/references/operations.md +67 -0
  32. package/plugins/sp/skills/history-anatomy/references/report-contract.md +133 -0
  33. package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
  34. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  35. package/plugins/sp/skills/pr-reviewing/SKILL.md +2 -2
  36. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +1 -1
  37. package/plugins/sp/skills/spur-cli/references/init.md +1 -1
  38. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
  39. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +1 -1
  40. package/plugins/sp/skills/spur-cli/references/workflows.md +4 -4
  41. package/plugins/sp/skills/spur-dev/SKILL.md +4 -4
  42. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +4 -4
  43. package/plugins/sp/skills/spur-dev/references/dev-operations.md +11 -11
  44. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +1 -1
  45. package/plugins/sp/skills/spur-dev/references/execution-batch.md +17 -4
  46. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +8 -1
  47. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +3 -2
  48. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +25 -13
  49. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +1 -1
  50. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +5 -2
  51. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +2 -2
  52. package/schemas/spur-config.schema.json +1 -1
  53. package/spur.js +1278 -890
  54. package/web/_astro/BoardApp.Z9jMwI9G.js +1 -0
  55. package/web/_astro/BoardApp.rkWGVwwK.js +178 -0
  56. package/web/_astro/{TaskDetail.B0l1uzsB.js → TaskDetail.B7ODt_bA.js} +1 -1
  57. package/web/_astro/{arc.DPruHC3P.js → arc.C5QRz6AQ.js} +1 -1
  58. package/web/_astro/{architectureDiagram-3BPJPVTR.CuOqAck6.js → architectureDiagram-3BPJPVTR.CHptn8gZ.js} +1 -1
  59. package/web/_astro/{blockDiagram-GPEHLZMM.Cxb7HDIA.js → blockDiagram-GPEHLZMM.b1nEDkDw.js} +1 -1
  60. package/web/_astro/{c4Diagram-AAUBKEIU.Dw7wa-0S.js → c4Diagram-AAUBKEIU.BWj8S_Qq.js} +1 -1
  61. package/web/_astro/channel.BJtn6CGV.js +1 -0
  62. package/web/_astro/{chunk-2J33WTMH.MECQitzo.js → chunk-2J33WTMH.q0BBuE1n.js} +1 -1
  63. package/web/_astro/{chunk-4BX2VUAB.p3ofhIGE.js → chunk-4BX2VUAB.DP2KDkAU.js} +1 -1
  64. package/web/_astro/{chunk-55IACEB6.BmQGsPZP.js → chunk-55IACEB6.CkCId72p.js} +1 -1
  65. package/web/_astro/{chunk-727SXJPM.CwrK23OA.js → chunk-727SXJPM.oHWzxMot.js} +1 -1
  66. package/web/_astro/{chunk-AQP2D5EJ.CUKI_QXp.js → chunk-AQP2D5EJ.DkkgxfMP.js} +1 -1
  67. package/web/_astro/{chunk-FMBD7UC4.7AtDgShM.js → chunk-FMBD7UC4.lmFJDvRK.js} +1 -1
  68. package/web/_astro/{chunk-ND2GUHAM.f_YJbTs3.js → chunk-ND2GUHAM.52jt0eHK.js} +1 -1
  69. package/web/_astro/{chunk-QZHKN3VN.0q7V3gEg.js → chunk-QZHKN3VN.Cg8KEFoD.js} +1 -1
  70. package/web/_astro/{classDiagram-4FO5ZUOK.C_hG3HMK.js → classDiagram-4FO5ZUOK.BuOUhxcD.js} +1 -1
  71. package/web/_astro/{classDiagram-v2-Q7XG4LA2.C_hG3HMK.js → classDiagram-v2-Q7XG4LA2.BuOUhxcD.js} +1 -1
  72. package/web/_astro/{cose-bilkent-S5V4N54A.vsaaaEMy.js → cose-bilkent-S5V4N54A.BRUU8E_0.js} +1 -1
  73. package/web/_astro/{dagre-BM42HDAG.BN7XFqQ4.js → dagre-BM42HDAG.GDbfFYVV.js} +1 -1
  74. package/web/_astro/{diagram-2AECGRRQ.ED6AfryZ.js → diagram-2AECGRRQ.CvIDBeJF.js} +1 -1
  75. package/web/_astro/{diagram-5GNKFQAL.Dxllzg8R.js → diagram-5GNKFQAL.DMgJjWOX.js} +1 -1
  76. package/web/_astro/{diagram-KO2AKTUF.RuWppieD.js → diagram-KO2AKTUF.njjl-0AP.js} +1 -1
  77. package/web/_astro/{diagram-LMA3HP47.CL32Xn6s.js → diagram-LMA3HP47.CcCqgP8M.js} +1 -1
  78. package/web/_astro/{diagram-OG6HWLK6.CUneEhqB.js → diagram-OG6HWLK6.Btqd-YVE.js} +1 -1
  79. package/web/_astro/{erDiagram-TEJ5UH35.DI-92Lec.js → erDiagram-TEJ5UH35.BbhML_Xo.js} +1 -1
  80. package/web/_astro/{flowDiagram-I6XJVG4X.69Aqa1FF.js → flowDiagram-I6XJVG4X.CkvsIgY8.js} +1 -1
  81. package/web/_astro/{ganttDiagram-6RSMTGT7.DdpClZpa.js → ganttDiagram-6RSMTGT7.m8IWD_wW.js} +1 -1
  82. package/web/_astro/{gitGraphDiagram-PVQCEYII.xqWfkvB4.js → gitGraphDiagram-PVQCEYII.5z87HXO-.js} +1 -1
  83. package/web/_astro/index.nWve6EHS.css +1 -0
  84. package/web/_astro/{infoDiagram-5YYISTIA.B3G5sfKm.js → infoDiagram-5YYISTIA.Bvyvsd7Q.js} +1 -1
  85. package/web/_astro/{ishikawaDiagram-YF4QCWOH.ahVNsoAQ.js → ishikawaDiagram-YF4QCWOH.DdWVYO87.js} +1 -1
  86. package/web/_astro/{journeyDiagram-JHISSGLW.PmFHLc-X.js → journeyDiagram-JHISSGLW.C3kOlYH1.js} +1 -1
  87. package/web/_astro/{kanban-definition-UN3LZRKU.Co1qOPTd.js → kanban-definition-UN3LZRKU.CfKTUHVC.js} +1 -1
  88. package/web/_astro/{linear.DoHZ-iRt.js → linear.CMDHnzgX.js} +1 -1
  89. package/web/_astro/{mermaid.core.DNRElYN2.js → mermaid.core.DN7-WrsP.js} +4 -4
  90. package/web/_astro/{mindmap-definition-RKZ34NQL.CdfJZidJ.js → mindmap-definition-RKZ34NQL.DcQxLvqG.js} +1 -1
  91. package/web/_astro/{pieDiagram-4H26LBE5.C1A8dby4.js → pieDiagram-4H26LBE5.Nu-Inbw6.js} +1 -1
  92. package/web/_astro/{quadrantDiagram-W4KKPZXB.NmZqjG_c.js → quadrantDiagram-W4KKPZXB.Dck2EChs.js} +1 -1
  93. package/web/_astro/{requirementDiagram-4Y6WPE33.tY36zYtK.js → requirementDiagram-4Y6WPE33.C--E5XuW.js} +1 -1
  94. package/web/_astro/{sankeyDiagram-5OEKKPKP.rOEGZYjo.js → sankeyDiagram-5OEKKPKP.B_0iRNna.js} +1 -1
  95. package/web/_astro/{sequenceDiagram-3UESZ5HK.Dpnw3S9J.js → sequenceDiagram-3UESZ5HK.PKuKr9mk.js} +1 -1
  96. package/web/_astro/{stateDiagram-AJRCARHV.DGpvQ3Wz.js → stateDiagram-AJRCARHV.ClhGHb-O.js} +1 -1
  97. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CbwQdEfu.js → stateDiagram-v2-BHNVJYJU.Bv6BBnvg.js} +1 -1
  98. package/web/_astro/{timeline-definition-PNZ67QCA.DAYUpUJT.js → timeline-definition-PNZ67QCA.BZm2ZvAH.js} +1 -1
  99. package/web/_astro/{vennDiagram-CIIHVFJN.C7JCCd6-.js → vennDiagram-CIIHVFJN.Dt6yZXry.js} +1 -1
  100. package/web/_astro/{wardley-L42UT6IY.BGgwOH5_.js → wardley-L42UT6IY.rUs-E00M.js} +1 -1
  101. package/web/_astro/{wardleyDiagram-YWT4CUSO.oIZqzI2l.js → wardleyDiagram-YWT4CUSO.BcWgv4cA.js} +1 -1
  102. package/web/_astro/{xychartDiagram-2RQKCTM6.DohcJzqm.js → xychartDiagram-2RQKCTM6.DH-M-cX9.js} +1 -1
  103. package/web/index.html +2 -2
  104. package/plugins/sp/commands/dev-history-load.md +0 -63
  105. package/plugins/sp/scripts/history-load.mjs +0 -268
  106. package/plugins/sp/scripts/history-load.ts +0 -400
  107. package/web/_astro/BoardApp.BJs3l7O8.js +0 -179
  108. package/web/_astro/BoardApp.D8InuCYx.js +0 -1
  109. package/web/_astro/channel.XCf1DcsL.js +0 -1
  110. package/web/_astro/index.DJl2RAVZ.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/**"
@@ -719,7 +719,7 @@
719
719
  },
720
720
  "collect:onEnter:1": {
721
721
  "kind": "shell",
722
- "invocation": "$spurBin workflow validate .spur/workflows/wayfinder-resolution.yaml > .spur/run/wayfinder/$wbs-workflow-check.txt",
722
+ "invocation": "$spurBin workflow validate wayfinder-resolution.yaml > .spur/run/wayfinder/$wbs-workflow-check.txt",
723
723
  "stateEffect": "read",
724
724
  "evidenceEffect": "write",
725
725
  "disposition": "SIMPLE"
@@ -0,0 +1,366 @@
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
+ # focus — ad-hoc focus string (required in ad-hoc mode, rejected in daily)
35
+ # recompute — "true" forces the full analyze/render/enrich/validate path (cache disposition
36
+ # forced-recompute)
37
+ # output — explicit report output path; default run directory
38
+ # agent — executor for the agent.run stages (enrich/validate)
39
+ # spurBin — PATH-independent spur invocation (overridden by CLI at run start)
40
+ # __runId — run-scoped id for explicit artifact paths (allocated in start)
41
+ # stepTimeoutMs — agent.run budget for enrich/validate
42
+ # correctionCount — bounded correction loop counter file path bits (name resolved in correct)
43
+
44
+ "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
45
+ kind: state-machine
46
+ name: history-anatomy
47
+ description: "Daily/ad-hoc history-anatomy report: cache branch, deterministic analyze/render, skill enrichment, deterministic structure gate, independent evidence validation, bounded correction, atomic publication"
48
+ iterationBound: 20
49
+ initialState: start
50
+ terminalStates:
51
+ - published
52
+ - failed
53
+ failureStates:
54
+ - failed
55
+ vars:
56
+ mode: "daily"
57
+ date: ""
58
+ since: ""
59
+ until: ""
60
+ focus: ""
61
+ recompute: "false"
62
+ output: ""
63
+ agent: "omp"
64
+ spurBin: "spur"
65
+ __runId: ""
66
+ stepTimeoutMs: "1800000"
67
+ correctionCount: "0"
68
+ workflowFile: "config/workflows/history-anatomy.yaml"
69
+ contractVersion: "1"
70
+ reportDir: "docs/report"
71
+
72
+ states:
73
+ - id: start
74
+ description: >
75
+ Allocate the run-scoped id and root. Every analyze/render path in this workflow writes to
76
+ an explicit unique path under this run id — no stage reads the mutable latest.json pointer.
77
+ onEnter:
78
+ - kind: shell
79
+ options:
80
+ command: >-
81
+ mkdir -p .spur/run;
82
+ if [ -z "$__runId" ]; then __runId=$(uuidgen | tr 'A-Z' 'a-z' | cut -c1-8); fi;
83
+ echo "$__runId" > .spur/run/history-anatomy-run.id
84
+
85
+ - id: resolve-scope
86
+ description: >
87
+ Dispatch the skill's mode validation (0658 references/modes.md): daily is the default and
88
+ rejects focus/since/until/output; ad-hoc requires a non-empty focus plus two ordered
89
+ inclusive bounds and rejects --date/--recompute. Writes the normalized selector artifact.
90
+ onEnter:
91
+ - kind: agent.run
92
+ options:
93
+ agent: ${vars.agent}
94
+ 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."
95
+ # Declared Layer-1 role (0538 R2): mode validation is a reviewer-standard judgment.
96
+ role: reviewer
97
+ expectFile: .spur/run/${vars.__runId}-selector.json
98
+ timeoutMs: ${vars.stepTimeoutMs}
99
+
100
+ - id: resolve-paths
101
+ description: >
102
+ Resolve the helper, the skill/contract logic paths, and the publication target once, into a
103
+ run-scoped env file every later stage sources. Keeps each downstream shell action at glue
104
+ length (ADR-069 R1) instead of repeating path arithmetic per stage.
105
+ onEnter:
106
+ - kind: shell
107
+ options:
108
+ # Path arithmetic lives in the helper (ADR-069 R1); the shell only locates it. Avoid
109
+ # `${...}` here — that syntax collides with the engine's own template interpolation.
110
+ command: >-
111
+ h=$(superskill script path sp history-anatomy-cache.mjs);
112
+ node "$h" paths --helper "$h" --report-dir "$reportDir" --date "$date"
113
+ --output "$output" --out .spur/run/$__runId-paths.env
114
+
115
+ - id: analyze
116
+ description: >
117
+ Deterministic analyze of the current window and the immediately preceding comparable
118
+ window, each to an explicit run-scoped path. Always reruns — the deterministic half is
119
+ never cached (ADR-079).
120
+ onEnter:
121
+ - kind: shell
122
+ options:
123
+ command: >-
124
+ mkdir -p .spur/run;
125
+ $spurBin history analyze --out .spur/run/$__runId-history-anatomy-current.json --since "$since" --until "$until" --json
126
+ - kind: shell
127
+ options:
128
+ command: >-
129
+ $spurBin history analyze --out .spur/run/$__runId-history-anatomy-baseline.json --since "$baselineSince" --until "$until" --json 2>/dev/null || true
130
+
131
+ - id: cache-probe
132
+ description: >
133
+ Deterministic cache probe via the helper (0659). Runs AFTER analyze because ADR-079 makes
134
+ validity a derived fact: the semantic digest must come from the fresh artifact, never from
135
+ the cached report being judged. A hit skips only enrichment, never the probe. Daily only;
136
+ ad-hoc always reports miss (`ad-hoc-never-cached`). Also writes the run's full provenance.
137
+ onEnter:
138
+ - kind: shell
139
+ options:
140
+ command: >-
141
+ . .spur/run/$__runId-paths.env;
142
+ node "$HA_HELPER" probe --artifact .spur/run/$__runId-history-anatomy-current.json
143
+ --baseline .spur/run/$__runId-history-anatomy-baseline.json --target "$HA_TARGET"
144
+ --mode "$mode" --date "$HA_DATE" --recompute "$recompute" --executor "$agent"
145
+ --skill-dir "$HA_SKILL" --contract "$HA_SKILL/references/report-contract.md"
146
+ --workflow "$workflowFile" --contract-version "$contractVersion" --run-id "$__runId"
147
+ --out .spur/run/$__runId-provenance.json
148
+ > .spur/run/$__runId-cache-disposition.txt
149
+
150
+ - id: render
151
+ description: >
152
+ Render both artifacts with report --mode forensics, naming the exact analyze paths.
153
+ onEnter:
154
+ - kind: shell
155
+ options:
156
+ command: >-
157
+ mkdir -p .spur/run;
158
+ $spurBin history report .spur/run/$__runId-history-anatomy-current.json --mode forensics > .spur/run/$__runId-history-anatomy-current.md;
159
+ $spurBin history report .spur/run/$__runId-history-anatomy-baseline.json --mode forensics > .spur/run/$__runId-history-anatomy-baseline.md || true
160
+
161
+ - id: enrich
162
+ description: >
163
+ Model enrichment via the skill operation sp:history-anatomy enrich (0658 operations.md).
164
+ Consumes the two artifacts; authors the model half of the report.
165
+ onEnter:
166
+ - kind: agent.run
167
+ options:
168
+ agent: ${vars.agent}
169
+ 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."
170
+ # Declared Layer-1 role (0538 R2): enrichment is model judgment.
171
+ role: reviewer
172
+ expectFile: .spur/run/${vars.__runId}-candidate.md
173
+ timeoutMs: ${vars.stepTimeoutMs}
174
+
175
+ - id: structure-gate
176
+ description: >
177
+ Deterministic structure gate via the helper (0659). Asserts the eleven sections in order,
178
+ per-finding fields, no placeholders, evidence anchors. Not reachable on the hit path from
179
+ enrich — always gated before validation.
180
+ onEnter:
181
+ - kind: shell
182
+ options:
183
+ command: >-
184
+ node "$(superskill script path sp history-anatomy-cache.mjs)" check \
185
+ .spur/run/$__runId-candidate.md > .spur/run/$__runId-structure-gate.txt 2>&1 || true
186
+
187
+ - id: validate
188
+ description: >
189
+ Independent evidence validation via the skill operation sp:history-anatomy validate.
190
+ Publication is reachable only from a PASS here.
191
+ onEnter:
192
+ - kind: agent.run
193
+ options:
194
+ agent: ${vars.agent}
195
+ 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."
196
+ # Declared Layer-1 role (0538 R2): independent verification.
197
+ role: reviewer
198
+ expectFile: .spur/run/${vars.__runId}-validation.txt
199
+ timeoutMs: ${vars.stepTimeoutMs}
200
+
201
+ - id: correct
202
+ description: >
203
+ One bounded correction pass. onEnter increments the counter; the retry edge guards on
204
+ correctionCount < 1, the second failure takes the -> failed edge.
205
+ onEnter:
206
+ - kind: shell
207
+ options:
208
+ command: >-
209
+ n=$(cat .spur/run/$__runId-correction-count 2>/dev/null || echo 0) &&
210
+ printf '%s\n' "$((n + 1))" > .spur/run/$__runId-correction-count
211
+
212
+ - id: refresh-provenance
213
+ description: >
214
+ Cache-hit path. Keeps the published model half verbatim and refreshes only validated_at,
215
+ the cache disposition, and the imported-snapshot banner — which is the EARLIEST per-source
216
+ lastImportedAt, so the report never claims a source was imported after its own recorded
217
+ timestamp. Emits the publishable artifact the shared publish state consumes.
218
+ onEnter:
219
+ - kind: shell
220
+ options:
221
+ command: >-
222
+ . .spur/run/$__runId-paths.env;
223
+ node "$HA_HELPER" refresh --report "$HA_TARGET"
224
+ --out .spur/run/$__runId-publishable.md --disposition hit
225
+
226
+ - id: stamp
227
+ description: >
228
+ Cache-miss path. Attaches the full R7 frontmatter provenance block (identity tuple, window
229
+ state, generated/validated timestamps, artifact paths + digests, contract/skill/workflow
230
+ digests, per-source coverage + last_imported_at, spur/schema version, executor, run id,
231
+ cache disposition) and the freshness banner to the validated candidate.
232
+ onEnter:
233
+ - kind: shell
234
+ options:
235
+ command: >-
236
+ . .spur/run/$__runId-paths.env;
237
+ node "$HA_HELPER" stamp --candidate .spur/run/$__runId-candidate.md
238
+ --provenance .spur/run/$__runId-provenance.json
239
+ --out .spur/run/$__runId-publishable.md
240
+
241
+ - id: publish
242
+ description: >
243
+ Atomic publication via the helper (0659). Reachable only from `stamp` (which is reachable
244
+ only from a passing validate) or from `refresh-provenance` on the cache-hit path — the
245
+ model half a hit reuses was itself published through a passing validation.
246
+ onEnter:
247
+ - kind: shell
248
+ options:
249
+ command: >-
250
+ . .spur/run/$__runId-paths.env;
251
+ mkdir -p "$(dirname "$HA_TARGET")";
252
+ node "$HA_HELPER" publish .spur/run/$__runId-publishable.md "$HA_TARGET"
253
+
254
+ - id: published
255
+ description: Terminal — report published atomically after a passing validation.
256
+
257
+ - id: failed
258
+ description: Terminal — mode rejection, gate failure, or validation failure not corrected.
259
+
260
+ transitions:
261
+ - from: start
262
+ to: resolve-scope
263
+ description: Scope resolved.
264
+ guard:
265
+ kind: always
266
+
267
+ - from: resolve-scope
268
+ to: resolve-paths
269
+ description: Mode valid — resolve helper/skill/target paths once.
270
+ guard:
271
+ kind: always
272
+
273
+ - from: resolve-paths
274
+ to: analyze
275
+ description: Paths resolved — always rerun the deterministic half (ADR-079).
276
+ guard:
277
+ kind: always
278
+
279
+ - from: analyze
280
+ to: cache-probe
281
+ description: Fresh artifacts on disk — derive the digest and decide reuse.
282
+ guard:
283
+ kind: always
284
+
285
+ # Daily only takes the hit branch; ad-hoc always regenerates.
286
+ - from: cache-probe
287
+ to: refresh-provenance
288
+ description: Cache hit (daily) — refresh provenance and publish without re-enrichment.
289
+ guard:
290
+ kind: shell
291
+ options:
292
+ command: 'test "$mode" = daily && grep -q "^hit$" .spur/run/$__runId-cache-disposition.txt 2>/dev/null'
293
+ - from: cache-probe
294
+ to: render
295
+ description: Cache miss, forced recompute, or ad-hoc — render and re-enrich.
296
+ guard:
297
+ kind: always
298
+
299
+ - from: refresh-provenance
300
+ to: publish
301
+ description: Provenance refreshed — publish the cached model half.
302
+ guard:
303
+ kind: always
304
+
305
+ - from: render
306
+ to: enrich
307
+ description: Both artifacts rendered — enrich.
308
+ guard:
309
+ kind: always
310
+
311
+ - from: enrich
312
+ to: structure-gate
313
+ description: Candidate authored — deterministic structure gate.
314
+ guard:
315
+ kind: always
316
+
317
+ - from: structure-gate
318
+ to: validate
319
+ description: Candidate structurally sound — independent evidence validation.
320
+ guard:
321
+ kind: shell
322
+ options:
323
+ command: 'grep -q "^PASS$" .spur/run/$__runId-structure-gate.txt 2>/dev/null'
324
+ - from: structure-gate
325
+ to: failed
326
+ description: Structure gate FAIL — never publish a malformed candidate.
327
+ guard:
328
+ kind: always
329
+
330
+ - from: validate
331
+ to: stamp
332
+ description: Independent validation PASS — stamp provenance, then publish atomically.
333
+ guard:
334
+ kind: shell
335
+ options:
336
+ command: 'grep -q "Verdict: PASS" .spur/run/$__runId-validation.txt 2>/dev/null'
337
+ - from: validate
338
+ to: correct
339
+ description: Validation FAIL under the correction cap — one bounded pass.
340
+ guard:
341
+ kind: shell
342
+ options:
343
+ 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'
344
+ - from: validate
345
+ to: failed
346
+ description: Validation FAIL with the correction cap exhausted — terminate without publishing.
347
+ guard:
348
+ kind: always
349
+
350
+ - from: correct
351
+ to: structure-gate
352
+ description: Corrected candidate re-enters the deterministic gate, then re-validates.
353
+ guard:
354
+ kind: always
355
+
356
+ - from: stamp
357
+ to: publish
358
+ description: Provenance stamped — publish atomically.
359
+ guard:
360
+ kind: always
361
+
362
+ - from: publish
363
+ to: published
364
+ description: Report published.
365
+ guard:
366
+ kind: always
@@ -64,13 +64,11 @@ states:
64
64
  - kind: shell
65
65
  options:
66
66
  command: "mkdir -p .spur/run/wayfinder && $spurBin task show $wbs --json > .spur/run/wayfinder/$wbs-input.json"
67
- # `.spur/workflows/` is the runtime read path in every layout — a symlink to
68
- # config/workflows/ inside the Spur monorepo, a real directory in a seeded
69
- # project. The previous `config/workflows/…` literal only resolved in the
70
- # monorepo and hard-failed `collect` anywhere else.
67
+ # `wayfinder-resolution.yaml` uses the project→bundled resolver (tasks 0648/0650):
68
+ # a bare name falls back to the bundled tree; an explicit project path wins.
71
69
  - kind: shell
72
70
  options:
73
- command: "$spurBin workflow validate .spur/workflows/wayfinder-resolution.yaml > .spur/run/wayfinder/$wbs-workflow-check.txt"
71
+ command: "$spurBin workflow validate wayfinder-resolution.yaml > .spur/run/wayfinder/$wbs-workflow-check.txt"
74
72
  - kind: shell
75
73
  options:
76
74
  command: "$spurBin task check $wbs > .spur/run/wayfinder/$wbs-precheck.txt"
@@ -112,7 +110,7 @@ states:
112
110
  onEnter:
113
111
  - kind: shell
114
112
  options:
115
- command: 'rm -f .spur/run/wayfinder/$wbs-resolution-verdict.txt'
113
+ command: "rm -f .spur/run/wayfinder/$wbs-resolution-verdict.txt"
116
114
  - kind: agent.run
117
115
  options:
118
116
  agent: ${vars.agent}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.3.60",
3
+ "version": "0.3.62",
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",
package/plugins/README.md CHANGED
@@ -228,7 +228,7 @@ graph TB
228
228
  subgraph "Corpus Layer"
229
229
  CORPUS["docs/tasks/ + docs/features/<br/>Markdown planning corpus"]
230
230
  RULES[".spur/rules/<br/>YAML constraint rules"]
231
- WFS[".spur/workflows/<br/>YAML workflow definitions"]
231
+ WFS["bundled workflows tree<br/>YAML workflow definitions"]
232
232
  end
233
233
 
234
234
  %% Command → Skill delegations
@@ -309,7 +309,7 @@ Tier 3 — Execution Layer (spur CLI + Guard Scripts)
309
309
 
310
310
  1. User types `/sp:dev-run 0090`
311
311
  2. **Command** delegates to `sp:spur-dev` skill (execution half)
312
- 3. **Skill** reads the task, loads `.spur/workflows/task-pipeline.yaml`, and runs `spur workflow run` with HITL surfacing
312
+ 3. **Skill** reads the task, loads `task-pipeline.yaml`, and runs `spur workflow run` with HITL surfacing
313
313
  4. **CLI** executes the workflow engine (`@gobing-ai/ts-dual-workflow-engine`), pauses at HITL gates, persists run state
314
314
  5. Result: task driven through implement → check → fix → verify lifecycle
315
315
 
@@ -351,8 +351,9 @@ The **workflow** and **rule** engines have their own lifecycles (author → vali
351
351
 
352
352
  ## Workflow Pipelines
353
353
 
354
- The plugin ships workflow YAMLs under `.spur/workflows/`.
355
- Each pipeline owns one lifecycle phase:
354
+ The plugin references workflow YAMLs by bare name; the CLI resolves them through the
355
+ bundled tree (two-tier model, task 0648/0650) — a project-local override wins when
356
+ present, otherwise the bundled copy is used. Each pipeline owns one lifecycle phase:
356
357
 
357
358
  | Workflow | Phase | Entry command | Status |
358
359
  | ------------------------ | --------------------------------- | --------------------------------- | ------------- |
@@ -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, eleven-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, eleven-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.
@@ -509,7 +522,7 @@ graph TB
509
522
  subgraph "Corpus layer"
510
523
  CORPUS["docs/tasks/ + docs/features/<br/>markdown planning corpus"]
511
524
  RULES[".spur/rules/<br/>YAML constraint rules"]
512
- WFS[".spur/workflows/<br/>YAML workflow definitions"]
525
+ WFS["bundled workflows tree<br/>YAML workflow definitions"]
513
526
  end
514
527
 
515
528
  CMD -->|"Skill(sp:spur-dev, ...)"| SKILL_DEV
@@ -557,7 +570,7 @@ graph TB
557
570
 
558
571
  1. User types `/sp:dev-run 0090`.
559
572
  2. **Command** delegates to `sp:spur-dev` skill (execution half).
560
- 3. **Skill** reads the task, loads `.spur/workflows/task-pipeline.yaml`, and runs
573
+ 3. **Skill** reads the task, loads `task-pipeline.yaml`, and runs
561
574
  `spur workflow run` with HITL surfacing.
562
575
  4. **CLI** executes the workflow engine (`@gobing-ai/ts-dual-workflow-engine`), pauses at HITL gates,
563
576
  persists run state.
@@ -575,7 +588,7 @@ graph TB
575
588
 
576
589
  ### Workflow pipelines
577
590
 
578
- The plugin ships workflow YAMLs under `.spur/workflows/`. Each
591
+ The plugin references workflow YAMLs by bare name; the CLI resolves them through the bundled tree (two-tier model, task 0648/0650) — project-local overrides win when present. Each
579
592
  pipeline owns one lifecycle phase:
580
593
 
581
594
  | Workflow | Phase | Entry command |
@@ -78,7 +78,7 @@ You own the spaces **between** task runs:
78
78
  - **Preflight (Step 2.5 / 3.0)** - before each pipeline launch, evaluate TABLE A STOP rows
79
79
  (`batch-preflight.ts` or equivalent). Skip A2/A7/A8/A9; still **launch `task-pipeline.yaml`** for
80
80
  ready WBS (never substitute a `dev-next` loop for the happy path).
81
- - **Run each ready task** through `.spur/workflows/task-pipeline.yaml` via `spur workflow run --async`
81
+ - **Run each ready task** through `task-pipeline.yaml` via `spur workflow run --async`
82
82
  (Step 3). The command/script layer polls `spur workflow trace` to terminal state - polling is
83
83
  transport, not planner reasoning (R3: the poll loop must not live in this agent's body; the planner
84
84
  inspects the terminal verdict, not the poll iterations). Follow the