@gobing-ai/spur 0.3.47 → 0.3.49

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 (148) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +94 -15
  3. package/config/transition-shims.json +33 -0
  4. package/config/workflows/basic.yaml +2 -0
  5. package/config/workflows/docs-pipeline.yaml +2 -0
  6. package/config/workflows/feature-dev.yaml +8 -0
  7. package/config/workflows/idea-pipeline.yaml +10 -0
  8. package/config/workflows/planning-pipeline.yaml +4 -0
  9. package/config/workflows/pr-review.yaml +338 -0
  10. package/config/workflows/task-pipeline.yaml +8 -0
  11. package/config/workflows/wayfinder-resolution.yaml +4 -0
  12. package/config/workflows/wrapup-pipeline.yaml +18 -1
  13. package/package.json +8 -8
  14. package/plugins/sp/README.md +9 -6
  15. package/plugins/sp/agents/expert-spur.md +1 -0
  16. package/plugins/sp/commands/dev-arch.md +2 -1
  17. package/plugins/sp/commands/dev-brainstorm.md +2 -1
  18. package/plugins/sp/commands/dev-changelog.md +1 -0
  19. package/plugins/sp/commands/dev-daily.md +1 -0
  20. package/plugins/sp/commands/dev-debug.md +2 -1
  21. package/plugins/sp/commands/dev-dogfood.md +2 -1
  22. package/plugins/sp/commands/{dev-featurechange.md → dev-feature-change.md} +8 -10
  23. package/plugins/sp/commands/dev-find-conflict.md +2 -1
  24. package/plugins/sp/commands/dev-find-issue.md +36 -43
  25. package/plugins/sp/commands/dev-find-next.md +5 -4
  26. package/plugins/sp/commands/dev-fixall.md +1 -0
  27. package/plugins/sp/commands/dev-gitmsg.md +1 -0
  28. package/plugins/sp/commands/dev-gtd.md +12 -12
  29. package/plugins/sp/commands/dev-handover.md +1 -0
  30. package/plugins/sp/commands/dev-history-load.md +63 -0
  31. package/plugins/sp/commands/dev-idea.md +1 -0
  32. package/plugins/sp/commands/dev-next.md +2 -1
  33. package/plugins/sp/commands/dev-parallel.md +2 -1
  34. package/plugins/sp/commands/dev-plan.md +2 -1
  35. package/plugins/sp/commands/dev-pr-review.md +39 -0
  36. package/plugins/sp/commands/dev-refine.md +5 -3
  37. package/plugins/sp/commands/dev-refineall.md +2 -1
  38. package/plugins/sp/commands/dev-refresh.md +2 -1
  39. package/plugins/sp/commands/dev-reverse.md +2 -1
  40. package/plugins/sp/commands/dev-review.md +2 -1
  41. package/plugins/sp/commands/dev-run.md +3 -2
  42. package/plugins/sp/commands/dev-runall.md +3 -2
  43. package/plugins/sp/commands/dev-simplify.md +2 -1
  44. package/plugins/sp/commands/dev-unit.md +2 -1
  45. package/plugins/sp/commands/dev-verify.md +2 -1
  46. package/plugins/sp/commands/dev-verifyall.md +2 -1
  47. package/plugins/sp/commands/dev-wrap.md +7 -5
  48. package/plugins/sp/commands/dev-wrapall.md +7 -5
  49. package/plugins/sp/commands/rule-add.md +1 -0
  50. package/plugins/sp/commands/rule-refine.md +1 -0
  51. package/plugins/sp/commands/rule-scan.md +1 -0
  52. package/plugins/sp/commands/spur-init.md +1 -0
  53. package/plugins/sp/commands/workflow-add.md +1 -0
  54. package/plugins/sp/commands/workflow-refine.md +1 -0
  55. package/plugins/sp/hooks/careful-guard.ts +5 -80
  56. package/plugins/sp/hooks/destructive-policy.ts +146 -0
  57. package/plugins/sp/hooks/pi/guard-extension.ts +33 -46
  58. package/plugins/sp/hooks/task-file-policy.ts +31 -0
  59. package/plugins/sp/hooks/task-write-guard.ts +4 -0
  60. package/plugins/sp/plugin.json +1 -1
  61. package/plugins/sp/references/roles.md +106 -0
  62. package/plugins/sp/scripts/feature-sync-bounded.ts +28 -2
  63. package/plugins/sp/scripts/history-load.ts +400 -0
  64. package/plugins/sp/scripts/pr-reviewing.ts +867 -0
  65. package/plugins/sp/scripts/stage-registry-adapter.ts +66 -31
  66. package/plugins/sp/scripts/surface-drift-inventory.ts +908 -0
  67. package/plugins/sp/scripts/task-size-precheck.ts +30 -4
  68. package/plugins/sp/scripts/transition-shim-check.ts +238 -0
  69. package/plugins/sp/scripts/validate-commands.ts +33 -2
  70. package/plugins/sp/scripts/validate-flag-contracts.ts +5 -2
  71. package/plugins/sp/skills/code-implementation/SKILL.md +9 -1
  72. package/plugins/sp/skills/code-verification/SKILL.md +29 -28
  73. package/plugins/sp/skills/issue-finding/SKILL.md +123 -141
  74. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +1 -1
  75. package/plugins/sp/skills/issue-finding/references/session-formats.md +87 -90
  76. package/plugins/sp/skills/next-feature/SKILL.md +6 -6
  77. package/plugins/sp/skills/next-feature/references/handoff-routing.md +5 -5
  78. package/plugins/sp/skills/next-feature/references/signal-derivation.md +7 -2
  79. package/plugins/sp/skills/next-router/SKILL.md +1 -1
  80. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +40 -2
  81. package/plugins/sp/skills/pr-reviewing/SKILL.md +285 -0
  82. package/plugins/sp/skills/spur-cli/SKILL.md +3 -0
  83. package/plugins/sp/skills/spur-cli/references/agent.md +12 -7
  84. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +5 -5
  85. package/plugins/sp/skills/spur-cli/references/features.md +1 -1
  86. package/plugins/sp/skills/spur-cli/references/team.md +10 -3
  87. package/plugins/sp/skills/spur-dev/SKILL.md +2 -0
  88. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +17 -0
  89. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +44 -23
  90. package/plugins/sp/skills/spur-dev/references/dev-operations.md +14 -11
  91. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +14 -12
  92. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +28 -7
  93. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +2 -0
  94. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +12 -2
  95. package/schemas/spur-config.schema.json +47 -3
  96. package/spur.js +12223 -7716
  97. package/web/_astro/BoardApp.8hiqShQn.js +1 -0
  98. package/web/_astro/{BoardApp.DKyrGxdo.js → BoardApp.BjQUNhuj.js} +74 -74
  99. package/web/_astro/{TaskDetail.6-27_LMa.js → TaskDetail.CVBuD6dF.js} +1 -1
  100. package/web/_astro/{arc.Df-9AQvS.js → arc.BMMjdODi.js} +1 -1
  101. package/web/_astro/{architectureDiagram-3BPJPVTR.VAI_-paS.js → architectureDiagram-3BPJPVTR.BU5ShzXf.js} +1 -1
  102. package/web/_astro/{blockDiagram-GPEHLZMM.DFpUY1ue.js → blockDiagram-GPEHLZMM.Bj1iEqPD.js} +1 -1
  103. package/web/_astro/{c4Diagram-AAUBKEIU.CF8doOpg.js → c4Diagram-AAUBKEIU.vX8wepCL.js} +1 -1
  104. package/web/_astro/channel.EwdSemIC.js +1 -0
  105. package/web/_astro/{chunk-2J33WTMH.BnjK3fjt.js → chunk-2J33WTMH.BKAipTym.js} +1 -1
  106. package/web/_astro/{chunk-4BX2VUAB.x6ZDnJKq.js → chunk-4BX2VUAB.B68XkPG7.js} +1 -1
  107. package/web/_astro/{chunk-55IACEB6.zY-0uu7w.js → chunk-55IACEB6.BmeDLcrc.js} +1 -1
  108. package/web/_astro/{chunk-727SXJPM.BZxKg_Vi.js → chunk-727SXJPM.PDuBA3Kw.js} +1 -1
  109. package/web/_astro/{chunk-AQP2D5EJ.Cpi9G9Td.js → chunk-AQP2D5EJ.C7A044za.js} +1 -1
  110. package/web/_astro/{chunk-FMBD7UC4.DWTB-Pif.js → chunk-FMBD7UC4.BtzKKFqR.js} +1 -1
  111. package/web/_astro/{chunk-ND2GUHAM.BPDQbiOG.js → chunk-ND2GUHAM.BJuDeeOy.js} +1 -1
  112. package/web/_astro/{chunk-QZHKN3VN.BRWIcuoM.js → chunk-QZHKN3VN.DSeMDgcQ.js} +1 -1
  113. package/web/_astro/{classDiagram-4FO5ZUOK.mGTCZsDO.js → classDiagram-4FO5ZUOK.D53Q4tCw.js} +1 -1
  114. package/web/_astro/{classDiagram-v2-Q7XG4LA2.mGTCZsDO.js → classDiagram-v2-Q7XG4LA2.D53Q4tCw.js} +1 -1
  115. package/web/_astro/{cose-bilkent-S5V4N54A.D1GEut-z.js → cose-bilkent-S5V4N54A.c712AFRH.js} +1 -1
  116. package/web/_astro/{dagre-BM42HDAG.BV0XG9Do.js → dagre-BM42HDAG.D-idisph.js} +1 -1
  117. package/web/_astro/{diagram-2AECGRRQ.DzpYxsjo.js → diagram-2AECGRRQ.DLgnsJCU.js} +1 -1
  118. package/web/_astro/{diagram-5GNKFQAL.Cm9YzJh4.js → diagram-5GNKFQAL.BiaxBVqx.js} +1 -1
  119. package/web/_astro/{diagram-KO2AKTUF.BjhottUj.js → diagram-KO2AKTUF.C8HX1vd8.js} +1 -1
  120. package/web/_astro/{diagram-LMA3HP47.BFsQW5kb.js → diagram-LMA3HP47.CfqDLLes.js} +1 -1
  121. package/web/_astro/{diagram-OG6HWLK6.8pdpzSWO.js → diagram-OG6HWLK6.15SDiEed.js} +1 -1
  122. package/web/_astro/{erDiagram-TEJ5UH35.Bd7KUJmJ.js → erDiagram-TEJ5UH35.DksYtOYM.js} +1 -1
  123. package/web/_astro/{flowDiagram-I6XJVG4X.7LWffkaE.js → flowDiagram-I6XJVG4X.DR_Au-HV.js} +1 -1
  124. package/web/_astro/{ganttDiagram-6RSMTGT7.BeDcO5tI.js → ganttDiagram-6RSMTGT7.CHhHrffI.js} +1 -1
  125. package/web/_astro/{gitGraphDiagram-PVQCEYII.Ca4n730A.js → gitGraphDiagram-PVQCEYII.B2Xehvam.js} +1 -1
  126. package/web/_astro/{index.Dbvuw6d4.css → index.DAxu50UF.css} +1 -1
  127. package/web/_astro/{infoDiagram-5YYISTIA.B0OakQYb.js → infoDiagram-5YYISTIA.C9c3CNNN.js} +1 -1
  128. package/web/_astro/{ishikawaDiagram-YF4QCWOH.DSmNQe-1.js → ishikawaDiagram-YF4QCWOH.BibUHkh8.js} +1 -1
  129. package/web/_astro/{journeyDiagram-JHISSGLW.Cy5ruEUu.js → journeyDiagram-JHISSGLW.BYoVHiyO.js} +1 -1
  130. package/web/_astro/{kanban-definition-UN3LZRKU.CUJXub0p.js → kanban-definition-UN3LZRKU.CM1K5wHE.js} +1 -1
  131. package/web/_astro/{linear.DC1jCCXn.js → linear.SPpjJUb-.js} +1 -1
  132. package/web/_astro/{mermaid.core.DxVP99Ab.js → mermaid.core.BAgx3nnb.js} +4 -4
  133. package/web/_astro/{mindmap-definition-RKZ34NQL.D0MaV6sJ.js → mindmap-definition-RKZ34NQL.D35oPG1R.js} +1 -1
  134. package/web/_astro/{pieDiagram-4H26LBE5.DCC6_q32.js → pieDiagram-4H26LBE5.DiWuRwk7.js} +1 -1
  135. package/web/_astro/{quadrantDiagram-W4KKPZXB.BeUOAM7C.js → quadrantDiagram-W4KKPZXB.B9PBzTWn.js} +1 -1
  136. package/web/_astro/{requirementDiagram-4Y6WPE33.Dbl4MASO.js → requirementDiagram-4Y6WPE33.CYuuamFN.js} +1 -1
  137. package/web/_astro/{sankeyDiagram-5OEKKPKP.HsLg0VS4.js → sankeyDiagram-5OEKKPKP.W24UhhtD.js} +1 -1
  138. package/web/_astro/{sequenceDiagram-3UESZ5HK.DT7DJTnZ.js → sequenceDiagram-3UESZ5HK.BpbNjA51.js} +1 -1
  139. package/web/_astro/{stateDiagram-AJRCARHV.d_ju1Vr1.js → stateDiagram-AJRCARHV.DqVsHudf.js} +1 -1
  140. package/web/_astro/{stateDiagram-v2-BHNVJYJU.DMCAjMJ4.js → stateDiagram-v2-BHNVJYJU.CzwHYX81.js} +1 -1
  141. package/web/_astro/{timeline-definition-PNZ67QCA.DNOHr62_.js → timeline-definition-PNZ67QCA.Bc3B6djw.js} +1 -1
  142. package/web/_astro/{vennDiagram-CIIHVFJN.B7dUy-1W.js → vennDiagram-CIIHVFJN.C-D5rh8O.js} +1 -1
  143. package/web/_astro/{wardley-L42UT6IY.DEqOXvBh.js → wardley-L42UT6IY.D7PdYCqn.js} +1 -1
  144. package/web/_astro/{wardleyDiagram-YWT4CUSO.BCRb2p6x.js → wardleyDiagram-YWT4CUSO.CwmJKXF3.js} +1 -1
  145. package/web/_astro/{xychartDiagram-2RQKCTM6.NxVQLdBh.js → xychartDiagram-2RQKCTM6.avDYnLsb.js} +1 -1
  146. package/web/index.html +2 -2
  147. package/web/_astro/BoardApp.Ce6zJYAH.js +0 -1
  148. package/web/_astro/channel.Uhm9O3UV.js +0 -1
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "plugins": [
8
8
  {
9
- "version": "0.3.47",
9
+ "version": "0.3.49",
10
10
  "name": "sp",
11
11
  "source": "./plugins/sp",
12
12
  "description": "Spur - my harness toolkits"
@@ -1,15 +1,18 @@
1
1
  # Spur project configuration example
2
- # Seeded by `spur init` as ~/.config/spur/config.yaml on first run (never overwritten).
2
+ # Seeded by `spur init` as ~/.config/spur/config.yaml on first run
3
+ # (never overwritten).
3
4
  # Copy / adapt into a project as `.spur/config.yaml`.
4
5
 
5
6
  $schema: "@gobing-ai/spur/schemas/spur-config.schema.json"
6
7
  # Config schema version (string). Current recommended: "1.1".
7
- # "1" remains accepted; there is no hard migrator yet. Prefer "1.1" for new projects
8
- # so editors and operators know the file targets the ADR-033 + planning shape.
8
+ # "1" remains accepted; there is no hard migrator yet. Prefer "1.1" for
9
+ # new projects so editors and operators know the file targets the ADR-033
10
+ # + planning shape.
9
11
  version: "1.1"
10
12
  name: my-project
11
13
 
12
- # ── Portable bootstrap (consumed by @gobing-ai/ts-infra runNodeApplication) ──
14
+ # ── Portable bootstrap (consumed by @gobing-ai/ts-infra
15
+ # runNodeApplication) ──
13
16
  # Shared across spur and (future) spur-server. Keys map 1:1 to ts-infra's
14
17
  # LoggingOptions / TelemetryOptions / database / SchedulerOptions.
15
18
  # Not validated by spurConfigSchema (bootstrap is owned by runNodeApplication).
@@ -33,46 +36,100 @@ bootstrap:
33
36
  scheduler:
34
37
  enabled: false # CLI is run-once; no scheduler
35
38
 
36
- # ── Spur app section (validated by spurConfigSchema in @gobing-ai/spur-config) ──
39
+ # ── Spur app section (validated by spurConfigSchema in
40
+ # @gobing-ai/spur-config) ──
37
41
  # Server runtime (port/host/openBrowser) is env-backed via PORT/HOST — not a
38
42
  # project-config key. See design §2.2.
39
43
  agent:
40
- # `default` is the executor selector for `--agent auto` when stage-registry
41
- # routing does not apply (or as a fallback). Resolved as an executor name
42
- # first, then a legacy agent name.
43
- default: omp
44
+ # `default` is the role used for `--agent auto` when the caller declares
45
+ # nothing (task 0542 R2 the value domain moved from executor names to
46
+ # roles). A role id selects its tier's cheapest eligible executor; a
47
+ # configured executor name still resolves during the transition with a
48
+ # one-time warning (shim agent-default-executor); any other value fails
49
+ # naming both accepted sets.
50
+ default: coder
51
+
52
+ # Role → tier map (SSOT: DEFAULT_AGENT_ROLES in packages/config, task 0572 /
53
+ # ADR-061; plugins/sp/references/roles.md is a parity-gated projection).
54
+ # Resolution: role → tier → cheapest USABLE executor whose tier >= the role's
55
+ # tier, climbing the ladder across gaps. Declare at least one usable executor
56
+ # at or above each rung or that role fails loudly at dispatch:
57
+ # scribe=cheap · coder=standard · reviewer=capable-1 · planner=capable-2
58
+ # Stage floors (stage-registry model_policy): changelog=cheap;
59
+ # implement/test/wrap/review/refine/brainstorm=standard;
60
+ # verify/dogfood=capable-1; plan=capable-2. A stage's fallback ladder
61
+ # (auth / resource-exhaustion / gate-fail) only advances when a higher rung
62
+ # has a usable executor — an empty rung turns a quota failure into a hang.
63
+ #
64
+ # Optional per-project override (0572): re-tier / re-stage a KNOWN role only —
65
+ # the vocabulary is closed; a config naming any other key fails at config load
66
+ # naming the accepted four. Per-field merge over the defaults (restate only
67
+ # what you override; a role you omit keeps its default wholesale):
68
+ # roles:
69
+ # reviewer:
70
+ # tier: capable-2 # e.g. pin review work one rung higher
71
+ # coder:
72
+ # stages: [implement] # e.g. stop folding test/wrap into coder
44
73
 
45
74
  # Canonical coding-agent ids (ts-ai-runner DISPLAY_ORDER, 0.4.8+):
46
- # claude, codex, gemini, pi, omp, opencode, antigravity-cli, openclaw, hermes, grok
47
- # Grok auth: non-empty XAI_API_KEY and/or ~/.grok/auth.json (no CLI auth-status verb).
75
+ # claude, codex, gemini, pi, omp, opencode, antigravity-cli,
76
+ # openclaw, hermes, grok
77
+ # Grok auth: non-empty XAI_API_KEY and/or ~/.grok/auth.json (no CLI
78
+ # auth-status verb).
48
79
 
49
80
  # Named executor profiles (ADR-033 / 0343). Each pairs a canonical agent with
50
- # an optional opaque model override and an explicit capability tier.
81
+ # an explicit model override and an explicit capability tier.
82
+ # `model` is pinned on every entry: omitting it defers to the agent CLI's own
83
+ # default, which drifts with CLI upgrades and account state — pin what your
84
+ # CLI would resolve today (`grok models`, omp config.yml modelRoles.default,
85
+ # ~/.codex/config.toml, ~/.claude.json). The ids below are working examples,
86
+ # not vendor defaults — re-pin for your accounts.
87
+ #
88
+ # Pairing philosophy (operator guidance, 2026-08): a `native` pair — a vendor's
89
+ # model served by that vendor's own CLI (gpt-5.6-* via codex, claude-*-5 via
90
+ # claude, grok-4.6 via grok, gemini-3.x via agy) — consistently outperforms the
91
+ # same model routed through a third-party CLI, and belongs at the capable rungs.
92
+ # `portable` models (glm-5.x, deepseek-v4-*, …) are provider-agnostic and best
93
+ # carried by omp or pi at the cheap/standard rungs. The ladder below mixes both
94
+ # classes on purpose; measure pairings with the history plane before promoting
95
+ # a portable model into a capable rung.
51
96
  # Live tiers: cheap | standard | capable-1 | capable-2 | capable-3
52
97
  # (1=low quality within capable, 3=high). DECLARE tier — inference never
53
98
  # invents capable-2/3. Stage routing starts on the cheapest executor whose
54
99
  # tier >= min_tier; same exact tier ties break by array order.
55
100
  # Legacy bare `capable` is accepted at runtime as synonym for capable-1.
56
101
  executors:
102
+ # cheap rung is optional: with none declared, scribe-role work starts one
103
+ # rung up at the cheapest standard executor. Add one when transcript-heavy
104
+ # mechanical commands (changelog/gitmsg/handover) get noisy on cost.
105
+ # - name: minimax
106
+ # agent: omp
107
+ # model: minimax/MiniMax-M3
108
+ # tier: cheap
57
109
  - name: omp
58
110
  agent: omp
111
+ model: opencode/deepseek-v4-flash
59
112
  tier: standard
60
113
  # - name: omp-zai
61
114
  # agent: omp
62
115
  # model: zai/glm-5.2
63
116
  # tier: standard
117
+ - name: pi
118
+ agent: pi
119
+ model: "k3"
120
+ tier: capable-1
64
121
  - name: grok
65
122
  agent: grok
123
+ model: grok-4.6
66
124
  tier: capable-2
67
125
  - name: claude
68
126
  agent: claude
127
+ model: k3
69
128
  tier: capable-3
70
129
  - name: codex
71
130
  agent: codex
131
+ model: gpt-5.6
72
132
  tier: capable-3
73
- # - name: pi
74
- # agent: pi
75
- # tier: capable-1
76
133
 
77
134
  # `default-by-phase` is a REMOVED (0452). Prefer
78
135
  # executor `tier` + stage-registry model_policy. When present, a matching
@@ -92,6 +149,13 @@ agent:
92
149
  # purpose: "Lead — planning & review"
93
150
  # - executor: omp
94
151
  # purpose: "Implementer"
152
+ # # Role is the primary axis (0543): a role-only member resolves an
153
+ # # executor through the tier ladder at materialization; the resolved
154
+ # # executor and the role are both recorded on the materialized spec.
155
+ # - role: reviewer
156
+ # - role: coder
157
+ # executor: omp
158
+ # purpose: "Pinned executor, role recorded alongside (pin beats policy)"
95
159
 
96
160
  rules:
97
161
  paths:
@@ -116,3 +180,18 @@ tasks:
116
180
 
117
181
  features:
118
182
  dir: docs/features
183
+
184
+ # ── History (task 0549 — completion-triggered refresh) ──
185
+ # Opt-in: when work completes (task → done, pipeline run reaching
186
+ # terminal status), enqueue ONE coalesced `history.refresh` job on the
187
+ # embedded job queue (never inline). Bursts inside debounce_ms join the
188
+ # pending job; the covered window spans all completions. The job reuses
189
+ # `spur history daily` semantics (import-all fan-out with per-source
190
+ # isolation + analyze + artifact write) and is consumed by `spur serve`'s
191
+ # job worker. Debounce default 600000 ms (10 min) follows
192
+ # docs/tasks4/0548-import-cost-measurement.md (steady-state all-fanout
193
+ # import ≈ 20.6 s; 10 min comfortably bounds burst coalescing).
194
+ # history:
195
+ # refresh:
196
+ # on_completion: false # set true to enable; disable with no code edits
197
+ # debounce_ms: 600000 # coalescing window; floor 1000 ms
@@ -0,0 +1,33 @@
1
+ {
2
+ "note": "Transition-shim manifest (task 0541, feature B2). Each entry records one compatibility path marked @transition-shim(<id>) in source. Every field is required. The gate (bun run transition-shim-check, inside `spur-check`) is two-sided: an unregistered marker fails, and a listed entry whose marker is gone fails. Emptying this file is the definition of the transition being complete (docs/04_DESIGN.md §2.5). Removal conditions must be objectively checkable against the repository, not 'when convenient'. Shims are registered by the tasks that create them (0536/0537/0538/0542).",
3
+ "entries": [
4
+ {
5
+ "id": "agent-bare-binary-name",
6
+ "wbs": "0536",
7
+ "file": "packages/app/src/services/agent-service.ts",
8
+ "keepsWorking": "a bare coding-agent binary name (codex, omp, claude with no matching agent.executors entry) remains a valid --agent value during the role transition, with a one-time warning emitted by warnBareBinaryOnce",
9
+ "removalCondition": "no bare-binary --agent value remains in docs/, config/workflows/, or plugins/sp/ (scan for --agent <binary-name> usages against agent.executors names)"
10
+ },
11
+ {
12
+ "id": "spec-without-executor-field",
13
+ "wbs": "0537",
14
+ "file": "apps/cli/src/commands/agent.ts",
15
+ "keepsWorking": "a pre-existing agent spec carrying only type (no executor field) still drains: --agent <specId> falls back to the spec's coding-agent type instead of resolving a missing executor",
16
+ "removalCondition": "every spec under .spur/agents/ records an executor field (scan .spur/agents/*.yaml for the key; re-materialize the demo team first)"
17
+ },
18
+ {
19
+ "id": "agent-flag-spec-id",
20
+ "wbs": "0542",
21
+ "file": "apps/cli/src/commands/agent.ts",
22
+ "keepsWorking": "a team spec id passed to --agent <spec-id> still addresses the spec and drives the drain path, warned once by warnAgentSpecIdOnce; --spec <id> is the canonical carrier",
23
+ "removalCondition": "no --agent <spec-id> usage remains in config/workflows/, plugins/sp/, or docs/ (scan for --agent values that match a .spur/agents/ spec id)"
24
+ },
25
+ {
26
+ "id": "agent-default-executor",
27
+ "wbs": "0542",
28
+ "file": "packages/app/src/services/agent-service.ts",
29
+ "keepsWorking": "a configured executor name in agent.default still resolves during the transition, warned once by warnAgentDefaultExecutorOnce; the value domain moved to roles (recommended default: coder)",
30
+ "removalCondition": "no agent.default value names an agent.executors entry (scan .spur/config.yaml and config/config.example.yaml against the agent.executors names)"
31
+ }
32
+ ]
33
+ }
@@ -80,6 +80,8 @@ states:
80
80
  options:
81
81
  agent: ${vars.agent}
82
82
  input: /sp:dev-fixall "${vars.qualityGateCmd}"
83
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
84
+ role: coder
83
85
  timeoutMs: ${vars.stepTimeoutMs}
84
86
 
85
87
  - id: done
@@ -67,6 +67,8 @@ states:
67
67
  options:
68
68
  agent: ${vars.agent}
69
69
  # Pure slash only (ADR-043). Do not bolt docs-only prose onto the input line.
70
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
71
+ role: coder
70
72
  input: /sp:dev-run --mode implement ${vars.wbs} --auto
71
73
  timeoutMs: ${vars.stepTimeoutMs}
72
74
  # Fail a silent no-op draft (same empty-implement class as task-pipeline R3).
@@ -84,6 +84,8 @@ states:
84
84
  options:
85
85
  agent: ${vars.agent}
86
86
  input: /sp:dev-brainstorm --feature ${vars.featureId}
87
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
88
+ role: planner
87
89
  timeoutMs: ${vars.stepTimeoutMs}
88
90
 
89
91
  - id: plan
@@ -95,6 +97,8 @@ states:
95
97
  options:
96
98
  agent: ${vars.agent}
97
99
  input: /sp:dev-plan --feature ${vars.featureId}
100
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
101
+ role: planner
98
102
  timeoutMs: ${vars.stepTimeoutMs}
99
103
 
100
104
  # Two pure-slash execute hops so vars.profile actually controls --auto (ADR-043).
@@ -109,6 +113,8 @@ states:
109
113
  options:
110
114
  agent: ${vars.agent}
111
115
  input: /sp:dev-runall --feature ${vars.featureId} --auto
116
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
117
+ role: planner
112
118
  timeoutMs: ${vars.stepTimeoutMs}
113
119
 
114
120
  - id: execute-tasks
@@ -120,6 +126,8 @@ states:
120
126
  options:
121
127
  agent: ${vars.agent}
122
128
  input: /sp:dev-runall --feature ${vars.featureId}
129
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
130
+ role: planner
123
131
  timeoutMs: ${vars.stepTimeoutMs}
124
132
 
125
133
  - id: feature-verify
@@ -108,6 +108,8 @@ states:
108
108
  options:
109
109
  agent: ${vars.agent}
110
110
  input: "Run sp:brainstorm for the idea: ${vars.idea}. The skill owns the approach-generation, design summary, and `needs_design` signal criteria; emit .spur/run/${vars.__runId}-idea-needs-design.json ({\"needs_design\": true|false}) and the design summary per the skill's `Design Approval Gate` and `The needs_design signal` sections. Also emit the idea-evaluation report to .spur/run/${vars.__runId}-idea-eval-report.md per plugins/sp/skills/spur-dev/references/idea-evaluation.md (urgency/necessity 0–5, premises, pros/cons, alternatives, enhanced idea, recommendation). At the END of the report, append a provenance footer block of the exact form: `---\\nrun_id: ${vars.__runId}\\ngenerated_at: <RFC3339 timestamp>\\n---` (omit the footer only if run_id is empty)."
111
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
112
+ role: planner
111
113
  expectFile: .spur/run/${vars.__runId}-idea-eval-report.md
112
114
  timeoutMs: ${vars.stepTimeoutMs}
113
115
 
@@ -140,6 +142,8 @@ states:
140
142
  options:
141
143
  agent: ${vars.agent}
142
144
  input: "Create a feature for the idea: ${vars.idea}. Read .spur/run/${vars.__runId}-idea-eval-report.md if present for the enhanced idea and scores. Use 'spur feature create \"<name>\" --json' to create it. Write the feature id to .spur/run/${vars.__runId}-idea-feature-id.txt. If an existing feature is appropriate, use its id instead. Also write two body-only intent artifacts: .spur/run/${vars.__runId}-idea-goal.md with concise Goal intent only (a short statement of what the feature achieves; never task breakdowns, checklists, or how-to steps), and .spur/run/${vars.__runId}-idea-scope.md with explicit in-scope and out-of-scope boundary bullets."
145
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
146
+ role: planner
143
147
  expectFile: .spur/run/${vars.__runId}-idea-feature-id.txt
144
148
  timeoutMs: ${vars.stepTimeoutMs}
145
149
  - kind: file.read.into-var
@@ -179,6 +183,8 @@ states:
179
183
  options:
180
184
  agent: ${vars.agent}
181
185
  input: "Generate acceptance criteria for feature ${vars.featureId}. Read the feature file and author R-numbered BDD Gherkin scenarios per ac-style-guide.md. Output only the complete Acceptance Criteria section body, including the gherkin code fence, with no surrounding commentary and no section heading."
186
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
187
+ role: planner
182
188
  answerFile: .spur/run/${vars.__runId}-idea-ac-content.md
183
189
  expectFile: .spur/run/${vars.__runId}-idea-ac-content.md
184
190
  timeoutMs: ${vars.stepTimeoutMs}
@@ -239,6 +245,8 @@ states:
239
245
  options:
240
246
  agent: ${vars.agent}
241
247
  input: "Run sp:sys-architecture for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and .spur/run/${vars.__runId}-idea-design-review.md. Produce ADR entries, architecture updates, and design satellites (docs/design/<slug>.md) following the constitution edit rules. Do not write task or feature corpus files directly. Design-review contract (.spur/run/${vars.__runId}-idea-design-review.md, fixed headings `## Proposed design`, `## Operator feedback`, `## Reconciliation`): on the first pass write the proposed design summary under `## Proposed design` and leave `## Operator feedback` empty; on retry with operator feedback present, revise the design/ADR artifacts, document the changes under `## Reconciliation`, and when the feedback invalidates an Acceptance Criteria scenario write the revised AC section body to a file and persist it via `$spurBin feature update \"$featureId\" --section \"Acceptance Criteria\" --from-file <file>` — never edit feature corpus files directly."
248
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
249
+ role: planner
242
250
  expectFile: .spur/run/${vars.__runId}-idea-design-review.md
243
251
  timeoutMs: ${vars.stepTimeoutMs}
244
252
  # expectFile proves existence only, and the onEnter skeleton pre-creates the file — so an
@@ -293,6 +301,8 @@ states:
293
301
  options:
294
302
  agent: ${vars.agent}
295
303
  input: "Run sp:spec-decomposition for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and design doc. SIZING FIRST, before any JSON: apply the skill's `Default to NOT decomposing` rubric to the whole unit of work — if it scores 0-2 the correct output is a ONE-entry batch, not many. Scenario count is not task count: merge scenarios that one task delivers (same file surface, same subsystem, or unreadable apart in review), and list every scenario a task covers in its background. Merging never costs AC coverage — one task may carry several scenarios. Do not emit one entry per scenario or per requirement by reflex. Then produce a task-batch JSON array at .spur/run/${vars.__runId}-idea-task-batch.json, validated against apps/cli/schemas/task-batch.schema.json. Schema-permitted fields per entry: `name`, `background`, `requirements`, `feature_id`, `parent_wbs`, `priority`, `tags`, `template` — schema validation rejects anything else. Acceptance Criteria, Design, and Plan sections are filled in by the per-task refine step after batch-create, NOT at decompose time. Validate locally against the schema before emitting. Also emit the private task-order sidecar at .spur/run/${vars.__runId}-idea-task-order.json: a JSON array (one entry per batch item) of `{ name: <exact batch item name>, depends_on_names: [<batch item names>] }` declaring ordering/dependencies between the batch items; use `[]` when no ordering exists. Every `name` and every dependency must match exactly one batch item `name` — it is private workflow data, not part of task-batch.schema.json."
304
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
305
+ role: planner
296
306
  expectFile: .spur/run/${vars.__runId}-idea-task-batch.json
297
307
  timeoutMs: ${vars.stepTimeoutMs}
298
308
  # R1 (0518): the task-order sidecar is the ordering contract for handoff-finalize.
@@ -102,6 +102,8 @@ states:
102
102
  options:
103
103
  agent: ${vars.agent}
104
104
  # `vars.feature` is optional and defaults to "" — the parent flag must be
105
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
106
+ role: planner
105
107
  # described conditionally, never interpolated bare. `--parent <empty> --json`
106
108
  # makes commander swallow `--json` as the parent value.
107
109
  input: "Skill(skill=\"sp:spur-cli\", args=\"feature create for slug ${vars.slug}\"). Run `${vars.spurBin} feature create \"${vars.slug}\" --json` (or reuse an existing id); append `--parent \"${vars.feature}\"` ONLY if the parent id between those quotes is non-empty — if it is empty, omit the --parent flag entirely. Write the feature id alone to .spur/run/${vars.__runId}-plan-feature-id.txt."
@@ -118,6 +120,8 @@ states:
118
120
  options:
119
121
  agent: ${vars.agent}
120
122
  input: "Skill(skill=\"sp:doc-evolve\", args=\"design-gen slug=${vars.slug}\"). Author docs/design/${vars.slug}.md from docs/plans/${vars.slug}-drafted.md; stage 04_DESIGN index edit only."
123
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
124
+ role: planner
121
125
  expectFile: docs/design/${vars.slug}.md
122
126
  timeoutMs: ${vars.stepTimeoutMs}
123
127