@gobing-ai/spur 0.3.80 → 0.3.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/config.example.yaml +29 -18
- package/config/config.global.yaml +10 -11
- package/config/pipeline-budgets.json +34 -2
- package/config/plugin-scripts.json +25 -0
- package/config/rules/boundary/config-loading-ownership.yaml +0 -3
- package/config/rules/boundary/dao-boundary.yaml +4 -17
- package/config/rules/boundary/planning-folder-hardcode.yaml +0 -1
- package/config/rules/boundary/sp-no-vendor-refs.yaml +3 -2
- package/config/rules/boundary/sp-runtime-path.yaml +3 -14
- package/config/rules/quality/coverage-gate.yaml +3 -14
- package/config/rules/quality/tsdoc-exports.yaml +4 -7
- package/config/rules/strict/http-boundaries.yaml +5 -8
- package/config/rules/strict/runtime-boundaries.yaml +1 -5
- package/config/rules/structure/protected-files.yaml +9 -3
- package/config/rules/structure/test-focus-skip.yaml +0 -2
- package/config/rules/structure/test-location.yaml +0 -5
- package/config/rules/surface/check-cli-surface.yaml +3 -2
- package/config/rules/typescript/bun-tooling.yaml +5 -7
- package/config/rules/typescript/guarded-happy-dom-register.yaml +0 -2
- package/config/rules/typescript/happy-dom-teardown.yaml +0 -2
- package/config/rules/typescript/no-biome-suppressions.yaml +0 -2
- package/config/rules/typescript/no-debugger.yaml +0 -2
- package/config/rules/typescript/no-eslint-suppressions.yaml +0 -4
- package/config/rules/typescript/no-leaky-module-mocks.yaml +6 -13
- package/config/rules/typescript/no-module-scope-import-calls.yaml +0 -2
- package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +0 -3
- package/config/rules/typescript/no-unmocked-module-eval-side-effects.yaml +0 -3
- package/config/rules/typescript/output-boundaries.yaml +0 -3
- package/config/rules/typescript/prefer-accessible-role-for-button-queries.yaml +0 -3
- package/config/rules/ui/ui-import-boundary.yaml +1 -5
- package/config/transition-shims.json +7 -7
- package/config/workflows/basic.yaml +4 -0
- package/config/workflows/docs-pipeline.yaml +13 -14
- package/config/workflows/feature-dev.yaml +20 -65
- package/config/workflows/history-anatomy.yaml +22 -1
- package/config/workflows/idea-pipeline.yaml +53 -97
- package/config/workflows/pr-review.yaml +21 -33
- package/config/workflows/task-pipeline.yaml +87 -330
- package/config/workflows/wayfinder-resolution.yaml +12 -26
- package/config/workflows/wrapup-pipeline.yaml +48 -189
- package/package.json +9 -9
- package/plugins/sp/README.md +10 -1
- package/plugins/sp/agents/expert-spur.md +41 -19
- package/plugins/sp/lib/idea-handoff.generated.d.mts +17 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +1301 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/feature-dev-precheck.mjs +146 -0
- package/plugins/sp/scripts/feature-dev-precheck.ts +238 -0
- package/plugins/sp/scripts/idea-handoff.mjs +27 -0
- package/plugins/sp/scripts/idea-handoff.ts +44 -0
- package/plugins/sp/scripts/quality-gate.mjs +165 -0
- package/plugins/sp/scripts/quality-gate.ts +217 -0
- package/plugins/sp/scripts/workflow-step-profile.mjs +319 -0
- package/plugins/sp/scripts/workflow-step-profile.ts +456 -0
- package/plugins/sp/scripts/wrapup-steps.mjs +350 -0
- package/plugins/sp/scripts/wrapup-steps.ts +466 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +29 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +56 -14
- package/plugins/sp/skills/spur-cli/references/message.md +30 -3
- package/plugins/sp/skills/spur-cli/references/projects.md +45 -1
- package/plugins/sp/skills/spur-cli/references/self.md +5 -4
- package/plugins/sp/skills/spur-cli/references/serve.md +5 -4
- package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
- package/plugins/sp/skills/spur-cli/references/team.md +21 -1
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +6 -3
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +57 -18
- package/plugins/sp/skills/spur-composer/SKILL.md +145 -0
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +24 -0
- package/plugins/sp/skills/spur-doctor/SKILL.md +138 -0
- package/plugins/sp/skills/taste-refactoring-api/README.md +43 -0
- package/plugins/sp/skills/taste-refactoring-api/SKILL.md +334 -0
- package/plugins/sp/skills/taste-refactoring-api/checklists/daily-api-review.md +71 -0
- package/plugins/sp/skills/taste-refactoring-api/examples/refactor-example.md +72 -0
- package/plugins/sp/skills/taste-refactoring-api/examples/review-template.md +93 -0
- package/plugins/sp/skills/taste-refactoring-api/references/api-refactoring-playbook.md +253 -0
- package/plugins/sp/skills/taste-refactoring-api/references/protocol-modes.md +79 -0
- package/plugins/sp/skills/taste-refactoring-api/references/research-basis.md +58 -0
- package/plugins/sp/skills/taste-refactoring-architect/README.md +26 -0
- package/plugins/sp/skills/taste-refactoring-architect/SKILL.md +471 -0
- package/plugins/sp/skills/taste-refactoring-architect/checklists/daily-architecture-review.md +48 -0
- package/plugins/sp/skills/taste-refactoring-architect/examples/refactor-example.md +55 -0
- package/plugins/sp/skills/taste-refactoring-architect/examples/review-template.md +51 -0
- package/plugins/sp/skills/taste-refactoring-architect/references/architecture-refactoring-playbook.md +173 -0
- package/plugins/sp/skills/taste-refactoring-architect/references/research-basis.md +28 -0
- package/plugins/sp/skills/taste-refactoring-tests/README.md +28 -0
- package/plugins/sp/skills/taste-refactoring-tests/SKILL.md +482 -0
- package/plugins/sp/skills/taste-refactoring-tests/checklists/daily-test-review.md +39 -0
- package/plugins/sp/skills/taste-refactoring-tests/examples/refactor-example.md +85 -0
- package/plugins/sp/skills/taste-refactoring-tests/examples/review-template.md +59 -0
- package/plugins/sp/skills/taste-refactoring-tests/references/research-basis.md +47 -0
- package/plugins/sp/skills/taste-refactoring-tests/references/test-refactoring-playbook.md +222 -0
- package/plugins/sp/skills/taste-refactoring-ui/README.md +12 -0
- package/plugins/sp/skills/taste-refactoring-ui/SKILL.md +290 -0
- package/plugins/sp/skills/taste-refactoring-ui/checklists/daily-ui-review.md +72 -0
- package/plugins/sp/skills/taste-refactoring-ui/examples/review-template.md +51 -0
- package/plugins/sp/skills/taste-refactoring-ui/references/refactoring-ui-playbook.md +170 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +2 -2
- package/plugins/sp/skills/wayfinder/references/pipeline-resolution.md +30 -0
- package/schemas/spur-config.schema.json +49 -0
- package/spur.js +46754 -44121
- package/web/_astro/{BoardApp.CHQ1lycZ.js → BoardApp.B1U26g3I.js} +97 -95
- package/web/_astro/BoardApp.Csgyg-lS.js +1 -0
- package/web/_astro/{TaskDetail.GKfQJ60c.js → TaskDetail.DwPqpq7v.js} +1 -1
- package/web/_astro/{arc.DWEtA3Tx.js → arc.CweZEjN2.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.DB42oWmP.js → architectureDiagram-3BPJPVTR.D89pbDuv.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.rhv-zNQV.js → blockDiagram-GPEHLZMM.BOuTeEpX.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.Ci4-4VvY.js → c4Diagram-AAUBKEIU.CASbkWZF.js} +1 -1
- package/web/_astro/channel.Cx6sXxhq.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.Cc9veUgf.js → chunk-2J33WTMH.BKQYtOvY.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.Bec9c4eI.js → chunk-4BX2VUAB.9sHLdMtG.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DoV8S1iB.js → chunk-55IACEB6.wOLXWlPs.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DwR-Qlyj.js → chunk-727SXJPM.DovFbwg3.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.ND_a81WY.js → chunk-AQP2D5EJ.B1Weod1X.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Wv_jwG48.js → chunk-FMBD7UC4.TEMS04st.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CXKXCMmp.js → chunk-ND2GUHAM.Cp8VT1wQ.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.nkaoNYQq.js → chunk-QZHKN3VN.BzATdEcP.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.cMQcVlQu.js → classDiagram-4FO5ZUOK.C9BOCfAO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.cMQcVlQu.js → classDiagram-v2-Q7XG4LA2.C9BOCfAO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.OaDJ7Mr2.js → cose-bilkent-S5V4N54A.DUnr4UAw.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.Chi8IphF.js → cynefin-OW5HDTMX.rYq5uM3D.js} +1 -1
- package/web/_astro/{cytoscape.esm.DzSz-X2X.js → cytoscape.esm.BB4DxJjf.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.CzK2t_Fp.js → dagre-BM42HDAG.CWeNKe3I.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DRvxlVS7.js → diagram-2AECGRRQ.DCkfls10.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CnYvNdwA.js → diagram-5GNKFQAL.D5U4JCka.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CpLpMw5R.js → diagram-KO2AKTUF.BZJgqaqG.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.JTb78qUA.js → diagram-LMA3HP47.DoMeHvPR.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Bk-1jDIb.js → diagram-OG6HWLK6.B50qwwWX.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D8hN9GZq.js → erDiagram-TEJ5UH35.DdGPG6LK.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.-6zQr6m5.js → flowDiagram-I6XJVG4X.QP2MJ12u.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DboLQ9ca.js → ganttDiagram-6RSMTGT7.BI6LgKSy.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.4tYvJKGR.js → gitGraphDiagram-PVQCEYII.npPZiC2G.js} +1 -1
- package/web/_astro/index.DayyIngm.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.Bd9rXpsB.js → infoDiagram-5YYISTIA.DCJCBVbp.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CvMoaf67.js → ishikawaDiagram-YF4QCWOH.BMLV-3I1.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.Ccy1CA7y.js → journeyDiagram-JHISSGLW.LE58crde.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.0MaMqHNS.js → kanban-definition-UN3LZRKU.BPbz8rH9.js} +1 -1
- package/web/_astro/{linear.CHXgcIbN.js → linear.DhZaBtYh.js} +1 -1
- package/web/_astro/{mermaid.core.Ca-kcelG.js → mermaid.core.BD5-jXum.js} +6 -6
- package/web/_astro/{mindmap-definition-RKZ34NQL.BUIDlHa0.js → mindmap-definition-RKZ34NQL.MTJyrQ65.js} +1 -1
- package/web/_astro/ordinal.BYWQX77i.js +1 -0
- package/web/_astro/{pieDiagram-4H26LBE5.2dX3CU1s.js → pieDiagram-4H26LBE5.BrDhDvIS.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.B3LBlRiv.js → quadrantDiagram-W4KKPZXB.71d73_5N.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.X12I2uNx.js → requirementDiagram-4Y6WPE33.Bga6UF-z.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BXohIHqx.js → sankeyDiagram-5OEKKPKP.BnHs4K82.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.C37ZIUzg.js → sequenceDiagram-3UESZ5HK.DsfY2gnj.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BRgz317z.js → stateDiagram-AJRCARHV.DvsTSc9a.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.7VYSXN9-.js → stateDiagram-v2-BHNVJYJU.DxzzmHUR.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BVNz_HiN.js → timeline-definition-PNZ67QCA.4ZuQmOTt.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CHVDkPX4.js → vennDiagram-CIIHVFJN.Ck5Q86SG.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.EQQ_qT9v.js → wardleyDiagram-YWT4CUSO.BK7k2hXr.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DrAT9WoP.js → xychartDiagram-2RQKCTM6.DfCrgauK.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.DV9kx0wo.js +0 -1
- package/web/_astro/channel.BAI6xLeV.js +0 -1
- package/web/_astro/index.Dcr_8fiK.css +0 -1
- package/web/_astro/ordinal.DBvzRdQf.js +0 -1
|
@@ -19,8 +19,8 @@ use it well*.
|
|
|
19
19
|
|
|
20
20
|
| Verb | Purpose | Key flags |
|
|
21
21
|
| ---- | ------- | --------- |
|
|
22
|
-
| `send <body>` | Enqueue a message for an agent | `--to <id>` `--role <name>` `--from <id>` `--wait` `--until <state>` `--timeout <ms>` `--json` |
|
|
23
|
-
| `inbox` | List messages addressed to an agent | `--agent <id>` `--json` |
|
|
22
|
+
| `send <body>` | Enqueue a message for an agent | `--to <id>` `--role <name>` `--from <id>` `--request-key <key>` `--wait` `--until <state>` `--timeout <ms>` `--json` |
|
|
23
|
+
| `inbox` | List messages addressed to an agent | `--agent <id>` `--unresolved` `--json` |
|
|
24
24
|
| `reply <msg-id> <body>` | Thread a reply to a message | `--json` |
|
|
25
25
|
| `watch` | Follow an agent inbox - surface new messages as they arrive | `--agent <id>` `--interval <ms>` `--json` |
|
|
26
26
|
|
|
@@ -34,6 +34,7 @@ spur message send "Please review PR 42" --to reviewer
|
|
|
34
34
|
spur message send "Task 0040 is blocked" --to worker-1 --from operator
|
|
35
35
|
spur message send "Done" --to planner --json
|
|
36
36
|
spur message send "Review 0042" --to reviewer --wait --until invoke-exit --timeout 30000
|
|
37
|
+
spur message send "Done" --to manager --request-key 0695-report-42 # retry-safe: same key replays the original receipt
|
|
37
38
|
spur message send "Start the pass" --role reviewer # resolves to exactly one instance
|
|
38
39
|
```
|
|
39
40
|
|
|
@@ -51,6 +52,9 @@ wait; enqueue is **not** rolled back if the wait later fails.
|
|
|
51
52
|
| `--to <id>` | Recipient agent id. Mutually exclusive with `--role`; exactly one of the two is required. |
|
|
52
53
|
| `--role <name>` | Address by Layer-1 role or executor name. Must resolve to exactly one materialized instance; zero (`count=0`, candidates `none`) or multi (`count=N` + candidates) matches are hard errors (exit 1); unknown name exits 2 naming the accepted vocabulary (`AGENT_ROLE_NAMES` ∪ executor names). Resolution yields the same spec-id path as `--to`; `--wait` snapshots that occupant pin. (0685 R6 / ADR-075 amendment) |
|
|
53
54
|
| `--from <id>` | Sender id (default: `operator`). |
|
|
55
|
+
| `--request-key <key>` | Caller-minted idempotency key. The same key with the same body + recipient replays the original receipt (`replayed: true`, no second row/delivery); the same key with a different payload fails with a request-key-conflict error (0832). |
|
|
56
|
+
| `replayed` receipt field | Present on keyed sends: `true` when this submission was a replay of an earlier accepted send. |
|
|
57
|
+
| `requestKey` receipt field | Present on keyed sends, including replays; echoes the accepted key. Blank keys are rejected. |
|
|
54
58
|
| `--wait` | Block until the recipient reaches `--until` (snapshots occupant before send). |
|
|
55
59
|
| `--until <state>` | Wait target: `injected` \| `invoke-exit` (repeatable OR). Default `invoke-exit`. |
|
|
56
60
|
| `--timeout <ms>` | Caller deadline in milliseconds. |
|
|
@@ -64,11 +68,33 @@ wait; enqueue is **not** rolled back if the wait later fails.
|
|
|
64
68
|
```bash
|
|
65
69
|
spur message inbox --agent worker-1
|
|
66
70
|
spur message inbox --agent worker-1 --json
|
|
71
|
+
spur message inbox --agent worker-1 --unresolved --json
|
|
67
72
|
```
|
|
68
73
|
|
|
69
74
|
Lists messages addressed to `--agent <id>`, oldest first. The body is truncated in plain-text output;
|
|
70
75
|
`--json` returns the full body.
|
|
71
76
|
|
|
77
|
+
### Delivery failure states (0834)
|
|
78
|
+
|
|
79
|
+
`--unresolved` filters the listing to messages the delivery reconciler holds, and every `--json` row
|
|
80
|
+
gains the operator-read fields: `injectAttempts`, `injectError`, `reason`, `runId`, `taskId`, `runStatus`,
|
|
81
|
+
`artifacts`. The hold reasons are distinct and durable — never one overloaded status column:
|
|
82
|
+
|
|
83
|
+
Delivered messages remain eligible for holds until their receipt is verified. Interrupted runs
|
|
84
|
+
carry their persisted origin and run status; exhausted attempts keep the same reason on repeated reads.
|
|
85
|
+
|
|
86
|
+
| `reason` | Meaning |
|
|
87
|
+
| -------- | --------- |
|
|
88
|
+
| `delivery-failed` | The drain marked the delivery failed (`injectError` carries why), or its run's receipt outcome is `errored`. |
|
|
89
|
+
| `attempts-exhausted` | The message burned its bounded redelivery budget (`MAX_INJECT_ATTEMPTS`, 0831); the reconciler marks it `failed` — the reconciler's only write. |
|
|
90
|
+
| `outcome-unknown` | The drain consumed it and no completion receipt ever arrived: the agent may have edited files. **Never requeued, never auto-released** — a human decides. |
|
|
91
|
+
| `run-exit-only` | Its run exited (receipt outcome `run-exit-only`) with no workflow verification result. |
|
|
92
|
+
|
|
93
|
+
`runId`, `taskId`, and `artifacts` (path-only refs) come only from the persisted run row that lists
|
|
94
|
+
the message in its receipt; nothing is inferred from terminal output or process lists. The same
|
|
95
|
+
reconciler runs once at `spur agent loop` startup and writes a `reconcile:` summary to the run log
|
|
96
|
+
before the first drain.
|
|
97
|
+
|
|
72
98
|
## `reply` - thread a reply
|
|
73
99
|
|
|
74
100
|
```bash
|
|
@@ -107,7 +133,8 @@ lines.
|
|
|
107
133
|
## See also
|
|
108
134
|
|
|
109
135
|
- **`spur agent` (see [agent.md](agent.md))** - `run --drain` and `loop` consume the inbox.
|
|
110
|
-
- **`spur
|
|
136
|
+
- **`spur task` (see [tasks.md](tasks.md))** - `task update --assignee` wires an agent spec to a
|
|
137
|
+
task (0848 moved home of `spur team assign`).
|
|
111
138
|
- **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
|
|
112
139
|
|
|
113
140
|
> **Shared option declarations (0618):** options shared across command modules resolve from
|
|
@@ -19,9 +19,10 @@ shapes live in `apps/cli/src/commands/projects.ts`.
|
|
|
19
19
|
| ---- | ------- | --------- |
|
|
20
20
|
| `add <path>` | Upsert an existing path in the registry | `--name <name>` `--json` |
|
|
21
21
|
| `remove <target>` | Remove an entry by display name or path | `--json` |
|
|
22
|
-
| `list` | List entries with live running status | `--json` |
|
|
22
|
+
| `list` | List entries with live running status | `--json` `--fleet` |
|
|
23
23
|
| `start <target>` | Start or reuse a detached project server | `--port <n>` `--json` |
|
|
24
24
|
| `stop <target>` | Best-effort stop the listener and clear its recorded port | `--json` |
|
|
25
|
+
| `migrate [path]` | Preview (default) or apply the legacy `agent.team` → `fleet.json` conversion (0847) | `--dry-run` `--apply` `--json` |
|
|
25
26
|
|
|
26
27
|
Every verb also advertises `--json-envelope`; use the facade's machine-output contract. Success is
|
|
27
28
|
exit `0`; validation, registry, spawn, health, or lookup failure is exit `1`.
|
|
@@ -36,6 +37,49 @@ exit `0`; validation, registry, spawn, health, or lookup failure is exit `1`.
|
|
|
36
37
|
defaults the display name to its basename. It upserts; it does not start a server. The current
|
|
37
38
|
source does not enforce a `.spur/` marker or directory type.
|
|
38
39
|
- `list` probes recorded ports and heals stale entries to `port: 0` before reporting `running`.
|
|
40
|
+
- `list --fleet` (0835) additionally resolves each project's fleet declaration at
|
|
41
|
+
`<project>/.spur/fleet.json` under the existing verb (no new noun). Per project it prints one line
|
|
42
|
+
per member: instance id (the spec id / mailbox identity), `role`, resolved `executor`,
|
|
43
|
+
`fsWrite` capability state, and derived `write` flag. A project with no declaration reports
|
|
44
|
+
`no declaration (.spur/fleet.json)`; an all-disabled roster reports `no enabled members`; a project
|
|
45
|
+
whose executors fail resolution reports the error without failing the listing. Under `--json` each
|
|
46
|
+
project gains `fleet` (the resolved fleet, `null` on resolution failure) and, on failure,
|
|
47
|
+
`fleetError`.
|
|
48
|
+
- `list --fleet` (0836) also reports the project's orchestrator binding: one
|
|
49
|
+
`orchestrator:` line per project with state `bound-online <id> (holder <spec-id>)`,
|
|
50
|
+
`bound-offline <id> (no live claim)`, `missing (no-orchestrator-declared)`, or
|
|
51
|
+
`unresolvable (<reason>)` — missing (nothing bound) and bound-offline (bound, no live
|
|
52
|
+
claim) are distinct states with distinct next actions, and an unresolvable pointer is an
|
|
53
|
+
error, never inferred. Reading the live claim touches the project's own `.spur/spur.db`
|
|
54
|
+
(lazily; only when the pointer resolves). Under `--json` each project gains
|
|
55
|
+
`orchestrator` (the binding, `null` on resolution failure) and, on failure,
|
|
56
|
+
`orchestratorError`.
|
|
57
|
+
- `list --fleet` (0838) also reports the project's persisted strategy (0838): one
|
|
58
|
+
`strategy:` line — `rest (default)` when nothing is persisted (the read never
|
|
59
|
+
writes; only the runtime's `setStrategy`/`resume` persist), `<name> (v<n>)` for a
|
|
60
|
+
persisted row, or `unavailable (<error>)` on a db failure. Under `--json` each
|
|
61
|
+
project gains `strategy` (`{ strategy, strategyVersion }`, `null` when
|
|
62
|
+
unpersisted) and, on failure, `strategyError`.
|
|
63
|
+
- `migrate [path]` (0847) converts the single legacy `agent.team.<id>` roster whose
|
|
64
|
+
`work_dir` resolves to the project into `<project>/.spur/fleet.json`, preserving
|
|
65
|
+
every spec id verbatim (explicit member ids freeze the `<role>-<n>` derivation).
|
|
66
|
+
Dry-run is the default: it emits the 0846 plan (steps + conflicts + warnings) and
|
|
67
|
+
writes nothing — an existing project db is opened read-only without migrations;
|
|
68
|
+
an absent db or table contributes no addressed identities.
|
|
69
|
+
`--apply` validates first, deep-equals an existing declaration (`unchanged`, no
|
|
70
|
+
rewrite), backs up a differing prior file to `.bak`, then atomically writes the
|
|
71
|
+
declaration (`converted`). It is purely additive — specs, `config.yaml`, and the
|
|
72
|
+
database are never touched — and it refuses to write while any conflict exists
|
|
73
|
+
(`addressed-id-without-spec`, `two-teams-one-project`, …). A registry name that
|
|
74
|
+
differs from the legacy team ID is `project-name-mismatch`: align that name
|
|
75
|
+
explicitly before conversion so fleet resolution preserves the spec-id prefix.
|
|
76
|
+
Exit codes: `0` for a
|
|
77
|
+
clean preview or `converted`/`unchanged`/`nothing-to-convert`; `2` when blocked
|
|
78
|
+
(the JSON payload still carries the full plan/result); `1` on error. Under
|
|
79
|
+
`--json` the payload is the raw `MigrationPlan` (preview) or `ConversionResult`
|
|
80
|
+
(apply). `rollback` is a service-level API (no CLI verb): restore the `.bak` a
|
|
81
|
+
previous apply created, remove a file that apply created when no `.bak` exists,
|
|
82
|
+
or report `nothing-to-roll-back`.
|
|
39
83
|
|
|
40
84
|
## Server lifecycle
|
|
41
85
|
|
|
@@ -95,8 +95,9 @@ directory. Only flag is `--json`.
|
|
|
95
95
|
|
|
96
96
|
## What this skill is NOT
|
|
97
97
|
|
|
98
|
-
- **Not the team supervisor.** `self serve` hosts the supervisor API; `spur
|
|
99
|
-
`
|
|
98
|
+
- **Not the team supervisor.** `self serve` hosts the supervisor API; `spur agent start` / `stop` /
|
|
99
|
+
`agent list --specs` are the verbs that drive and inspect it (0848). See
|
|
100
|
+
**[agent.md](agent.md)**.
|
|
100
101
|
- **Not a production server.** This is the local fallback. Production deployment uses the Cloudflare
|
|
101
102
|
Worker build (`apps/server/`), not `self serve`.
|
|
102
103
|
|
|
@@ -105,8 +106,8 @@ directory. Only flag is `--json`.
|
|
|
105
106
|
- **[init.md](init.md)** - `init` / `status` verbs: scaffold semantics and the Phase 1.5 / 1.6
|
|
106
107
|
post-scaffold validation probes.
|
|
107
108
|
- **[serve.md](serve.md)** - `serve` verb: server flags and the `--json` dry-probe contract.
|
|
108
|
-
- **`spur
|
|
109
|
-
supervisor API.
|
|
109
|
+
- **`spur agent` (see [agent.md](agent.md))** - `start`/`stop`/`list --specs` require `self serve`
|
|
110
|
+
for the supervisor API.
|
|
110
111
|
- **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
|
|
111
112
|
|
|
112
113
|
> **Shared option declarations (0618):** options shared across command modules resolve from
|
|
@@ -46,13 +46,14 @@ the team supervisor API become available at `http://<host>:<port>`.
|
|
|
46
46
|
|
|
47
47
|
## What this skill is NOT
|
|
48
48
|
|
|
49
|
-
- **Not the team supervisor.** `spur serve` hosts the supervisor API; `spur
|
|
50
|
-
`
|
|
49
|
+
- **Not the team supervisor.** `spur serve` hosts the supervisor API; `spur agent start` / `stop` /
|
|
50
|
+
`agent list --specs` are the verbs that drive and inspect it (0848). See
|
|
51
|
+
**[agent.md](agent.md)**.
|
|
51
52
|
- **Not a production server.** This is the local fallback. Production deployment uses the Cloudflare
|
|
52
53
|
Worker build (`apps/server/`), not `spur serve`.
|
|
53
54
|
|
|
54
55
|
## See also
|
|
55
56
|
|
|
56
|
-
- **`spur
|
|
57
|
-
supervisor API.
|
|
57
|
+
- **`spur agent` (see [agent.md](agent.md))** - `start`/`stop`/`list --specs` require `spur serve`
|
|
58
|
+
for the supervisor API.
|
|
58
59
|
- **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
|
|
@@ -40,7 +40,7 @@ re-reading or re-tokenizing the task.
|
|
|
40
40
|
| ---- | ------- | --------- |
|
|
41
41
|
| `create <title>` | Allocate a new task (race-safe WBS) | `--feature <id>` `--parent <wbs>` `--template <variant>` `--dedupe-within <s>` `--allow-duplicate-name` `--folder` `--json` |
|
|
42
42
|
| `show <wbs>` | Print one task's frontmatter + body | `--folder` `--json` |
|
|
43
|
-
| `update <wbs> [status]` | Lifecycle transition, section replace, **or** frontmatter set | `--section <name> --from-file <path>` `--feature <id>` `--priority <p>` `--no-lifecycle` `--force-done` `--reason <text>` `--verdict-dir <path>` `--folder` `--json` |
|
|
43
|
+
| `update <wbs> [status]` | Lifecycle transition, section replace, **or** frontmatter set | `--section <name> --from-file <path>` `--assignee <spec-id>` (moved home of `spur team assign`; exclusive with `--section`) `--feature <id>` `--priority <p>` `--no-lifecycle` `--force-done` `--reason <text>` `--verdict-dir <path>` `--folder` `--json` |
|
|
44
44
|
| `deps <wbs> <op> [values...]` | Mutate `dependencies[]` frontmatter array (ops: `set`, `add`, `remove`, `clear`) | `--folder` `--json` |
|
|
45
45
|
| `sections <wbs> <op> [name]` | Initialize, add, or list canonical task sections (ops: `init`, `add`, `list`) | `--folder` `--json` |
|
|
46
46
|
| `list` | List tasks, filtered | `--status <s>` `--phase <p>` `--parent <wbs>` `--feature <id>` `--folder` `--json` |
|
|
@@ -5,7 +5,27 @@ see_also:
|
|
|
5
5
|
- spur-cli
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# spur team - team coordination and supervision
|
|
8
|
+
# spur team - team coordination and supervision (DEPRECATED — 0848)
|
|
9
|
+
|
|
10
|
+
> **Deprecated (0848, feature G64):** every `spur team` capability has moved to its owning noun.
|
|
11
|
+
> The noun keeps working until the G64 cutover window is recorded, emitting a one-time stderr
|
|
12
|
+
> warning per process. Migrate invocations now:
|
|
13
|
+
>
|
|
14
|
+
> | Old verb | New home |
|
|
15
|
+
> | --- | --- |
|
|
16
|
+
> | `spur team assign <task-id> <agent-id>` | `spur task update <wbs> --assignee <spec-id>` |
|
|
17
|
+
> | `spur team status` | `spur agent list --specs` (same live-run merge) |
|
|
18
|
+
> | `spur team status --by-team` | dropped — one project has one fleet; `spur agent list --specs` is the single fleet listing |
|
|
19
|
+
> | `spur team up <team>` | fleet materialization at `spur serve` start (`.spur/fleet.json`); `up --check` diff → `spur projects list --fleet` |
|
|
20
|
+
> | `spur team down <team> [--purge]` | `spur agent stop <spec-id>` per member (`spur agent delete <id>` replaces `--purge`) |
|
|
21
|
+
> | `spur team start <agent-id>` | `spur agent start <spec-id>` |
|
|
22
|
+
> | `spur team stop <agent-id>` | `spur agent stop <spec-id>` |
|
|
23
|
+
|
|
24
|
+
> **Retiring:** `spur team` is a retiring surface for spur-* guidance. `sp:expert-spur`,
|
|
25
|
+
> `sp:spur-composer` and `sp:spur-doctor` forbid it, and coordination or recurring loops belong to
|
|
26
|
+
> `sp:super-planner` or a workflow. Reach agent specs through `spur agent ... --specs` and use
|
|
27
|
+
> `spur message` for coordination transport. This reference is retained for CLI parity while the
|
|
28
|
+
> noun still ships; do not build new guidance on it.
|
|
9
29
|
|
|
10
30
|
`spur team` is the CLI for **coordinating team agent assignments and supervision**. It sits above
|
|
11
31
|
`spur agent` specs: `up` / `down` materialize and tear down rosters, `start` / `stop` manage
|
|
@@ -65,9 +65,12 @@ Reconciliation core — run this **before authoring anything**. Authoring withou
|
|
|
65
65
|
workflows breeds redundant, diverged definitions (two near-identical approval flows, an import flow
|
|
66
66
|
re-implemented under a new name). Inputs: the clarified process intent. Steps:
|
|
67
67
|
|
|
68
|
-
1. **Enumerate existing workflows** — list
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
1. **Enumerate existing workflows** — `spur workflow list --json` across **all layers**
|
|
69
|
+
(`project`, `registered`, `shared` — the listed `layers` are the folders a name can resolve
|
|
70
|
+
from). Never glob `.spur/workflows`: a folder scan misses the registered and shared layers.
|
|
71
|
+
Match from each entry's `name`, `kind`, `source` (the layer it came from) and `description`
|
|
72
|
+
(the intent), then read the strongest candidates' definitions — states/nodes — so matches are
|
|
73
|
+
found by *substance*, not just by filename.
|
|
71
74
|
2. **Classify the strongest match** against the new intent:
|
|
72
75
|
|
|
73
76
|
| Match | Meaning | Action |
|
|
@@ -130,24 +130,63 @@ The flags (`--detail`, `--verbose`, `--trace-file`, `--follow`, `--output`) are
|
|
|
130
130
|
## 3. Node simplicity budget
|
|
131
131
|
|
|
132
132
|
Simplicity is the operating constraint, and it is already measurable — `spur workflow validate`
|
|
133
|
-
reports it. Do not invent a second threshold; author to the
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
| `
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
133
|
+
reports it with a `warn`/`error` level. Do not invent a second threshold; author to the ADR-115
|
|
134
|
+
tiers frozen in [surface governance §1.2](../../../../../../docs/design/harness-surface-governance.md).
|
|
135
|
+
|
|
136
|
+
| Element | Clean | Warn (advisory) | Error |
|
|
137
|
+
| --- | --- | --- | --- |
|
|
138
|
+
| `shell` action `command` | ≤5 logical commands (split on newline, `;`, `&&`, `||`; blank/`#`/structure tokens skipped) | **6–10** | **>10** commands or **>800** characters |
|
|
139
|
+
| Shell transition guard | ≤3 logical commands — one predicate over a result file | **4–5** | **>5** |
|
|
140
|
+
| `agent.run` `input` | A slash command or skill invocation (ADR-043), ≤1000 chars | non-slash prompt (severity by raw length: <200 low, ≤1000 medium) | **>1000** chars, slash-led or not |
|
|
141
|
+
| `agent.run` output check | `expectFile` or `requireDiff` declared | neither declared | — |
|
|
142
|
+
| Node count | Every node earns its transition round-trip | A node that always runs immediately after another, with no guard between them, is one node | — |
|
|
143
|
+
|
|
144
|
+
**When a program breaches a cap, do not reformat to dodge the measure.** Joining lines with `&&`
|
|
145
|
+
moves the complexity, not the ownership. Move the program to one of the five recorded owners from
|
|
146
|
+
`docs/design/workflow-shell-ownership.md`: (a) public `spur` verb (consent-gated), (b) application
|
|
147
|
+
service, (c) least-privilege built-in action kind, (d) workflow-relative external extension, or
|
|
148
|
+
(e) a deliberately-stays-shell exception. (e) is valid only inside the warn band — above an error
|
|
149
|
+
cap the program moves to (a)–(d).
|
|
150
|
+
|
|
151
|
+
**Every remaining warn-band shell program carries a one-line `#` reason**: a YAML comment directly
|
|
152
|
+
above the action or guard, e.g. `# (e) <why it stays shell>` or `# (d) <script> owns <what>`. Never
|
|
153
|
+
write it as a shell `#` line inside a folded `>-` scalar — folding joins the lines, so the `#`
|
|
154
|
+
comments out the rest of the program. YAML comments do not count toward the measure.
|
|
155
|
+
|
|
156
|
+
**Posture is binding (ADR-115).** Warn-level findings never change a `validate` exit status and
|
|
157
|
+
never block a run. An error-level finding makes `validate` exit 1 and gates the spur repository's
|
|
158
|
+
shipped shared workflow layer (layer id `shared` in `spur workflow list --json`) in `spur-check`
|
|
159
|
+
(task 0826). No composition finding ever blocks `run`, `run --dry-run` or `continue`, and a finding
|
|
160
|
+
is never a reason to hot-edit an executing pipeline.
|
|
161
|
+
|
|
162
|
+
### Consolidation and cache windows (ADR-115)
|
|
163
|
+
|
|
164
|
+
Two composition rules sit next to this budget: the table above stays the measure surface, these
|
|
165
|
+
decide where steps are cut. The rules are owned by the
|
|
166
|
+
[workflow composition contract](../../../../../../docs/design/workflow-composition-contract.md#composition-budgets-adr-115);
|
|
167
|
+
the text below is the operating summary, not a second owner.
|
|
168
|
+
|
|
169
|
+
**Consolidation — one model step per judgment.** Merge adjacent `agent.run` steps only when they
|
|
170
|
+
share a role and an executor **and** nothing between them must stay separate: a deterministic gate,
|
|
171
|
+
a HITL state, or an independence boundary. Never merge an author step with the review or verify
|
|
172
|
+
step that certifies it — those keep `freshSession: true`. A new model step in a shared workflow
|
|
173
|
+
raises its `pipeline-budgets` `modelQueries`, which needs a recorded decision, and every shared
|
|
174
|
+
workflow with a model query carries a budget entry.
|
|
175
|
+
|
|
176
|
+
**Cache windows — step boundaries follow the cache window, not the clock.** Provider prompt caches
|
|
177
|
+
expire after an idle window and refresh on every hit (Anthropic: 5 minutes by default; OpenAI:
|
|
178
|
+
5–10 minutes in memory). The window W defaults to 300 s, the shortest common default:
|
|
179
|
+
|
|
180
|
+
- A tool call inside `agent.run` that runs longer than W idles the model — its next request
|
|
181
|
+
re-reads a cold prefix. Run that work in a deterministic step instead.
|
|
182
|
+
- An `agent.run` that resumes the inherited session after a gap longer than W (a HITL wait, a slow
|
|
183
|
+
deterministic step) rewrites the whole session into the cache. When the prior step's artifact
|
|
184
|
+
carries what the step needs, prefer `freshSession: true` with that artifact as the handoff.
|
|
185
|
+
- A deterministic step should finish within W at p50. An `agent.run` with p50 above 2W is a split
|
|
186
|
+
candidate only at a real artifact seam — each split adds a model query and a cold prefix, so it
|
|
187
|
+
must pay for itself in retry granularity or observability.
|
|
188
|
+
|
|
189
|
+
These are runtime budgets, judged from run traces and step profiles — never `validate` findings.
|
|
151
190
|
|
|
152
191
|
---
|
|
153
192
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spur-composer
|
|
3
|
+
description: "Select, compose and tune spur artifacts — tasks, features, rules, workflows and agent specs. Owns workflow catalog selection, the ephemeral→project→shared ladder, the ADR-115 budgets, trace-driven rule tuning, and applying accepted sp:spur-doctor proposals. Triggers: compose a workflow, tune a rule, apply doctor proposals."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
metadata:
|
|
7
|
+
author: spur
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: artifact-composition
|
|
10
|
+
interactions:
|
|
11
|
+
- inversion
|
|
12
|
+
- companion
|
|
13
|
+
operations:
|
|
14
|
+
- select
|
|
15
|
+
- compose
|
|
16
|
+
- tune
|
|
17
|
+
- apply
|
|
18
|
+
openclaw:
|
|
19
|
+
emoji: "🎼"
|
|
20
|
+
see_also:
|
|
21
|
+
- sp:spur-cli
|
|
22
|
+
- sp:spur-doctor
|
|
23
|
+
- sp:super-planner
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# sp:spur-composer — compose, select and tune spur artifacts
|
|
27
|
+
|
|
28
|
+
One cross-noun method (ADR-114, [spur artifact evolution](../../../../docs/design/spur-artifact-evolution.md)
|
|
29
|
+
§2): **select** an existing artifact, **compose** a new one up the ladder, **tune** it against
|
|
30
|
+
evidence, and **apply** the proposals the operator accepts from `sp:spur-doctor`. It never judges
|
|
31
|
+
its own output and never runs a recurring loop — evaluation is the doctor's job.
|
|
32
|
+
|
|
33
|
+
## Boundary — read before composing
|
|
34
|
+
|
|
35
|
+
- **Verbs and flags live in `sp:spur-cli`.** This skill links references; it never restates a verb
|
|
36
|
+
or flag catalog: [../spur-cli/SKILL.md](../spur-cli/SKILL.md).
|
|
37
|
+
- **Recurring loops and coordination go to `sp:super-planner`** or a workflow — not here. This skill
|
|
38
|
+
runs one bounded composition or tuning pass per invocation.
|
|
39
|
+
- **Forbidden surfaces: `spur team` and `spur agent loop`.** Agent specs are reached only through
|
|
40
|
+
`spur agent create|edit|delete|list --specs`.
|
|
41
|
+
- **Writes land only through `spur` verbs** and the ladder's gated file steps (§ below). The shared
|
|
42
|
+
step additionally needs recorded operator consent plus `build:bundle` parity.
|
|
43
|
+
|
|
44
|
+
## Covered nouns
|
|
45
|
+
|
|
46
|
+
| Noun | Composition / tuning method | Verb reference |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| task | Apply accepted doctor rows via the CLI-gated corpus surface; author variants through the task reference's conventions | [../spur-cli/references/tasks.md](../spur-cli/references/tasks.md) |
|
|
49
|
+
| feature | Apply accepted rows through `spur feature update --section --from-file`; keep acceptance criteria in Gherkin | [../spur-cli/references/features.md](../spur-cli/references/features.md) |
|
|
50
|
+
| rule | The trace-driven tuning loop (§ Rule tuning loop) | [../spur-cli/references/rules.md](../spur-cli/references/rules.md) · [fine-tuning](../spur-cli/references/rules/fine-tuning.md) |
|
|
51
|
+
| workflow | Catalog selection, the composition ladder, and the ADR-115 budgets (§ below) | [../spur-cli/references/workflows.md](../spur-cli/references/workflows.md) · [operations](../spur-cli/references/workflows/operations.md) |
|
|
52
|
+
| agent spec | Compose and edit `.spur/agents/<id>.yaml` only through `spur agent create|edit|delete|list --specs` | [../spur-cli/references/agent.md](../spur-cli/references/agent.md) |
|
|
53
|
+
|
|
54
|
+
Do not drive the planning→execution lifecycle from here — that is `sp:spur-dev`.
|
|
55
|
+
|
|
56
|
+
## Workflow catalog selection
|
|
57
|
+
|
|
58
|
+
Run this **before composing anything new**, exactly as the
|
|
59
|
+
[find-existing-workflow](../spur-cli/references/workflows/operations.md#sub-procedure-find-existing-workflow)
|
|
60
|
+
procedure: the catalog is `spur workflow list --json` across all layers, and each entry's
|
|
61
|
+
`description` is its intent.
|
|
62
|
+
|
|
63
|
+
| Catalog match | Action |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| Matches the intent | **Run it as is.** No new artifact. |
|
|
66
|
+
| Near match | **Same-name override in the project layer** (`.spur/workflows/<name>.yaml`) — the project layer wins name resolution — and tune from there. |
|
|
67
|
+
| No match | **Compose** up the ladder (§ Composition ladder). |
|
|
68
|
+
|
|
69
|
+
Never glob a folder to enumerate candidates: layers you skip that way are layers a bare name
|
|
70
|
+
cannot resolve from.
|
|
71
|
+
|
|
72
|
+
## Composition ladder
|
|
73
|
+
|
|
74
|
+
| Step | Location | Gate before use |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| ephemeral | A scratch file outside every layer (for example under `.spur/run/`), run by explicit path | `spur workflow validate`, `spur workflow run --dry-run`, a `spur workflow show` preview |
|
|
77
|
+
| project | `.spur/workflows/<name>.yaml` | The same gates |
|
|
78
|
+
| shared | the spur repository's shipped shared workflow layer (layer id `shared` in `spur workflow list --json`) as `<name>.yaml` | The same gates, **plus recorded operator consent and `build:bundle` parity** |
|
|
79
|
+
|
|
80
|
+
- `spur workflow validate --json` exits 1 on an error-level composition finding, so a definition
|
|
81
|
+
over a cap cannot climb. Warn-level findings do not block a step.
|
|
82
|
+
- Verify each step through the shared
|
|
83
|
+
[validate-and-dry-run](../spur-cli/references/workflows/operations.md#sub-procedure-validate-and-dry-run)
|
|
84
|
+
core. The shared step is a promotion, not a copy: record the operator consent that authorizes it,
|
|
85
|
+
then rebuild the bundle (`bun run --filter @gobing-ai/spur build:bundle`) so the shipped config
|
|
86
|
+
matches.
|
|
87
|
+
- In an adopting project the shared layer is the installed package and is read-only — the project
|
|
88
|
+
step is the tuning path there.
|
|
89
|
+
|
|
90
|
+
## Composition budgets (ADR-115)
|
|
91
|
+
|
|
92
|
+
The consolidation and cache-window rules are taught once in
|
|
93
|
+
[workflow-fit-and-tuning.md](../spur-cli/references/workflows/workflow-fit-and-tuning.md#consolidation-and-cache-windows-adr-115)
|
|
94
|
+
and owned by the
|
|
95
|
+
[workflow composition contract](../../../../docs/design/workflow-composition-contract.md#composition-budgets-adr-115);
|
|
96
|
+
link them, never restate them. While composing or tuning a workflow, apply them with the ADR-115
|
|
97
|
+
budgets:
|
|
98
|
+
|
|
99
|
+
- **Merge adjacent model steps** only when they share a role and an executor **and** no gate, HITL
|
|
100
|
+
state or independence boundary sits between them.
|
|
101
|
+
- **Never merge an author step with the review or verify step that certifies it** — those keep
|
|
102
|
+
`freshSession: true`.
|
|
103
|
+
- **Run long deterministic work outside `agent.run`** — an in-step tool call that outlasts the
|
|
104
|
+
cache window idles the model and cold-rewrites the prefix.
|
|
105
|
+
|
|
106
|
+
A new model step in a shared workflow raises its `pipeline-budgets` `modelQueries`; that needs a
|
|
107
|
+
recorded decision before the shared step.
|
|
108
|
+
|
|
109
|
+
## Rule tuning loop
|
|
110
|
+
|
|
111
|
+
Start from trace evidence, never from a guess:
|
|
112
|
+
|
|
113
|
+
1. `spur rule trace <runId> --json` — read the per-rule `evaluations` findings and severities.
|
|
114
|
+
2. Classify each hit: true positive, false positive, or noise.
|
|
115
|
+
3. Tune with the [fine-tuning levers](../spur-cli/references/rules/fine-tuning.md) — severity,
|
|
116
|
+
glob scoping, exemptions, preset composition.
|
|
117
|
+
4. `spur rule validate` on the tuned rule files.
|
|
118
|
+
5. `spur rule run` on the affected inputs (constitution T11 — affected inputs, not a corpus sweep).
|
|
119
|
+
6. Trace again and compare. A tuning with no trace pair behind it is a preference.
|
|
120
|
+
|
|
121
|
+
## Applying doctor proposals
|
|
122
|
+
|
|
123
|
+
`sp:spur-doctor` ([../spur-doctor/SKILL.md](../spur-doctor/SKILL.md)) returns a proposal table;
|
|
124
|
+
the operator accepts rows; **this skill applies them**:
|
|
125
|
+
|
|
126
|
+
1. For each accepted row, run its `apply` route — always the `spur` verb or ladder step named in
|
|
127
|
+
the row. Composer never invents a write route.
|
|
128
|
+
2. Re-run that row's `verify` evidence and confirm it clears. An accepted row that cannot verify
|
|
129
|
+
is reported as not applied, never waved through.
|
|
130
|
+
3. A `task` row carries the history-anatomy finding `key` in the task body — the existing handoff
|
|
131
|
+
route. Keep it.
|
|
132
|
+
4. A row that changes a shared workflow goes through the ladder's shared step and its recorded
|
|
133
|
+
consent.
|
|
134
|
+
|
|
135
|
+
A caller that wants a record saves the accepted table under `docs/reports/`; this skill creates no
|
|
136
|
+
artifact store.
|
|
137
|
+
|
|
138
|
+
## What this skill is not
|
|
139
|
+
|
|
140
|
+
- **Not the judge.** `sp:spur-doctor` evaluates artifacts and proposes; code review is
|
|
141
|
+
`sp:super-reviewer`.
|
|
142
|
+
- **Not a loop.** Recurring evolution loops and multi-agent coordination belong to
|
|
143
|
+
`sp:super-planner` or a workflow definition.
|
|
144
|
+
- **Not a catalog.** Verb, flag, output and exit semantics live in the `sp:spur-cli` references
|
|
145
|
+
linked above.
|
|
@@ -270,6 +270,30 @@ missing title match. After batch creation, `handoff-finalize`:
|
|
|
270
270
|
(runall is then omitted), otherwise `/sp:dev-runall --feature <id> --auto`. The terminal
|
|
271
271
|
handoff note points at this report.
|
|
272
272
|
|
|
273
|
+
**Ready preparation (ready-prepare, 0788).** The input is the `.wbs` array in
|
|
274
|
+
`.spur/run/<runId>-idea-batch-create-result.json`. For EACH wbs: resolve the task file with
|
|
275
|
+
`spur task path <wbs> --json` and apply the ready-refinement checklist — make requirements,
|
|
276
|
+
design, plan, acceptance criteria, decisions, dependencies and premises present and
|
|
277
|
+
non-placeholder so `spur task check <wbs> --json` exits 0. Write planning sections only, through
|
|
278
|
+
`spur task update <wbs> --section <Name> --from-file <file>` — never Solution, Testing, Review
|
|
279
|
+
or History. Record one checklist row per id, with concrete evidence of how you verified it.
|
|
280
|
+
Compute the planning digest with the project's own implementation when this is a monorepo
|
|
281
|
+
checkout — resolve the file with `spur task path <wbs> --json`, then run:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
bun -e 'const m = await import("./packages/app/src/services/task-readiness"); console.log(m.computePlanningDigest(await Bun.file(process.argv[1]).text()))' <task-file>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
When that is impossible in this checkout, set status `skipped` instead of guessing a digest.
|
|
288
|
+
Finally write `.spur/run/<runId>-idea-ready.json` with exactly this shape:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{"runId":"<runId>","depth":"ready","tasks":[{"wbs":"<wbs>","status":"ready" | "failed" | "skipped","planningDigest":"<sha256 hex>","checks":[{"id":"requirements" | "design" | "plan" | "ac" | "decisions" | "dependencies" | "premises","pass":true,"evidence":"<how verified>"}]}]}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
A task you cannot fully prepare gets status `failed` or `skipped` — never fabricate evidence;
|
|
295
|
+
the handoff degrades to refineall.
|
|
296
|
+
|
|
273
297
|
## Step 6: Refine before execute (the spec-completion gate)
|
|
274
298
|
|
|
275
299
|
`batch-create` accepts optional `design` / `plan` / `acceptance_criteria` fields (plus
|