@gobing-ai/spur 0.3.78 → 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/templates/AGENTS.md +26 -23
- package/config/templates/docs/00_ADR.md +13 -23
- package/config/templates/docs/01_PRD.md +5 -2
- package/config/templates/docs/02_ROADMAP.md +9 -13
- package/config/templates/docs/03_ARCHITECTURE.md +2 -2
- package/config/templates/docs/04_DESIGN.md +12 -31
- package/config/templates/docs/05_FEATURES.md +6 -18
- package/config/templates/docs/99_PROJECT_CONSTITUTION.md +162 -394
- 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 +22 -8
- package/plugins/sp/agents/expert-spur.md +41 -19
- package/plugins/sp/agents/super-reviewer.md +43 -8
- 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/verify-answer-lint.ts +21 -3
- 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/conflict-finding/SKILL.md +6 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +1 -1
- package/plugins/sp/skills/doc-evolve/SKILL.md +26 -40
- package/plugins/sp/skills/doc-evolve/references/operations.md +17 -30
- 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/verbs.md +17 -1
- package/plugins/sp/skills/spur-cli/references/tasks.md +32 -2
- 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/ac-style-guide.md +14 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -3
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +12 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +46 -4
- 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 +46936 -44198
- 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
|
@@ -15,41 +15,33 @@ it enforces; the skill never invents process.
|
|
|
15
15
|
|
|
16
16
|
| Operation | Authority § | What "done" means |
|
|
17
17
|
| --------- | ----------- | ----------------- |
|
|
18
|
-
| drift-audit | §7 | the
|
|
19
|
-
| sync-check | §5 (
|
|
18
|
+
| drift-audit | §7 | the affected §7 checks run, each backed by a command; report lists deltas (or the zero-delta commands) |
|
|
19
|
+
| sync-check | §5 (applicable §5 triggers) | every changed surface mapped to its trigger; the obligated doc confirmed edited in the same change |
|
|
20
20
|
| contract-verify | §4.3 (+ §4.1) | each doc's frontmatter `owns`/`authority` matches its §4.1 row; `updated_at` plausible |
|
|
21
|
-
| lesson-append | §8 | a
|
|
21
|
+
| lesson-append | §8 | a deduplicated lesson in existing learning/context storage, never appended to 99 |
|
|
22
22
|
|
|
23
23
|
## drift-audit — §7 checklist → detection commands
|
|
24
24
|
|
|
25
25
|
| §7 item | Detection (deterministic) | Authoritative doc |
|
|
26
26
|
| ------- | ------------------------- | ----------------- |
|
|
27
|
-
| Real CLI surface vs docs |
|
|
28
|
-
|
|
|
27
|
+
| Real CLI surface vs docs | Compare source-local help/registrations with owning `docs/design/` contracts | `04` satellites |
|
|
28
|
+
| Feature state matches evidence | Read the feature tool's generated index, then inspect affected acceptance evidence | `05` / feature records |
|
|
29
29
|
| Every shipped surface has a `01` scope row | surface set (above) vs `rg` of `01` scope table | `01` |
|
|
30
30
|
| `02` phase bullets name real things | read `02` current-phase bullets; grep each name in code/docs | `02` |
|
|
31
|
-
| `03` modules vs real tree | `
|
|
31
|
+
| `03` modules vs real tree | `rg --files apps packages` vs `03` module map | `03` |
|
|
32
32
|
| `04` covers every command/flag/config/schema | the verb/flag/config set vs `04` | `04` |
|
|
33
33
|
| `AGENTS.md` doc map == §4.1 | diff the two tables | `AGENTS.md` (§4.4) |
|
|
34
34
|
| frontmatter matches §4.1 + `updated_at` plausible | see contract-verify | each doc (§4.3) |
|
|
35
35
|
|
|
36
36
|
**Judgment:** is a candidate real drift (vs. an intentional, documented exception)? Which doc is
|
|
37
|
-
authoritative? What is the *minimal* repair (
|
|
37
|
+
authoritative? What is the *minimal* repair (preserve decision history and condense only editorial noise under §6.1)?
|
|
38
38
|
|
|
39
|
-
## sync-check —
|
|
39
|
+
## sync-check — applicable §5 triggers → obligations
|
|
40
40
|
|
|
41
|
-
Read the
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Surface changed in this diff?
|
|
48
|
-
git diff --name-only | rg 'apps/cli/src/commands/|packages/.*/schema|config/'
|
|
49
|
-
# Was 04 / AGENTS.md touched in the same diff?
|
|
50
|
-
git diff --name-only | rg 'docs/04_DESIGN.md|^AGENTS.md'
|
|
51
|
-
# Both non-empty → likely synced; surface-changed-but-no-04 → T3 drift.
|
|
52
|
-
```
|
|
41
|
+
Read the diff and the live constitution §5. Map changed facts to their owning document and
|
|
42
|
+
check that contract, not merely whether a filename appears in the diff. Unchanged index pointers
|
|
43
|
+
and entry guidance need no edits. T7 additionally requires the governance reason and existing
|
|
44
|
+
operator authorization under §6.8; include affected templates.
|
|
53
45
|
|
|
54
46
|
## contract-verify — §4.3
|
|
55
47
|
|
|
@@ -65,15 +57,10 @@ Compare `owns`/`authority` against the §4.1 row (verbatim in meaning; §4.1 win
|
|
|
65
57
|
|
|
66
58
|
## lesson-append — §8
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
1. Identify the per-file `### Lessons for <doc>` section (or the cross-cutting one).
|
|
73
|
-
2. `rg` that section for an equivalent lesson — if found, **bump its date**, don't duplicate.
|
|
74
|
-
3. Append the formatted line. If the lesson restates an existing §6 rule, it's already law — skip.
|
|
75
|
-
4. If it has recurred, **promote** it to a §6 rule / §5 trigger and remove from §8 (the only
|
|
76
|
-
sanctioned deletion).
|
|
60
|
+
1. Resolve the existing learning/context destination from the project's conventions.
|
|
61
|
+
2. Search for an equivalent lesson; skip duplicates and routine completion receipts.
|
|
62
|
+
3. Record the useful lesson with evidence outside the constitution.
|
|
63
|
+
4. Propose any governance correction separately; recurrence does not authorize a §6.8 edit.
|
|
77
64
|
|
|
78
65
|
## Drift-report shape
|
|
79
66
|
|
|
@@ -84,7 +71,7 @@ Checks run: <n> (§7 items) · Findings: <m>
|
|
|
84
71
|
|
|
85
72
|
| # | Doc | Reality says | Doc says | Authority | Trigger | Repair |
|
|
86
73
|
|---|-----|--------------|----------|-----------|---------|--------|
|
|
87
|
-
| 1 | 04_DESIGN |
|
|
74
|
+
| 1 | 04_DESIGN | Changed command contract | Satellite describes old behavior | 04 | T3 | update its owning satellite under §6.5 |
|
|
88
75
|
|
|
89
76
|
Zero-finding checks: <list the §7 items that returned no delta, with the command used>
|
|
90
77
|
```
|
|
@@ -128,7 +128,7 @@ rule at the source, so no per-path shim is needed:
|
|
|
128
128
|
| `spur agent run` (CLI) | `AgentService.run` → resolution → child process | Declared wins; absent inherits via `SPUR_ROLE`; envelope carries `roleOrigin` |
|
|
129
129
|
| Workflow `agent.run` step | `AgentRunActionRunner` → `AgentService.runTraced` | Step `role:` is **mandatory** (0538 R2, `agent-run.ts` fails a role-less step before dispatch) — always a declaration (`roleOrigin: 'declared'`); inheritance applies at the next fan-out boundary the step's subagent itself dispatches |
|
|
130
130
|
| `spur agent loop` | `AgentService.run` per drained iteration | Same resolution path as `spur agent run`; inherits its own `SPUR_ROLE` |
|
|
131
|
-
| `spur
|
|
131
|
+
| `spur serve` team supervisor → member | spawns `spur agent loop` | Member inherits the supervisor's `SPUR_ROLE` (recursive by construction) |
|
|
132
132
|
| Native subagent fan-out (this skill's default) | in-session `Task()`/`Skill()` | In-session subagents share the host session; when they themselves dispatch, the host's role is already in the session env — the rule holds at the next `spur agent run` boundary |
|
|
133
133
|
| `plugins/sp/evals/run-eval.ts` | `spawnSync('spur agent run', …)` per scenario | Out of scope: a top-level eval harness, not a fan-out — no dispatcher role exists to inherit; each scenario is an independent top-level run (documented, no shim) |
|
|
134
134
|
|
|
@@ -525,6 +525,35 @@ The payload is a top-level JSON **array** (no `tasks` wrapper):
|
|
|
525
525
|
]
|
|
526
526
|
```
|
|
527
527
|
|
|
528
|
+
## Idea-pipeline emission
|
|
529
|
+
|
|
530
|
+
When the idea-pipeline workflow dispatches you for a feature, read the brainstorm artifact, the
|
|
531
|
+
feature AC, and the design doc, then emit two run-scoped artifacts.
|
|
532
|
+
|
|
533
|
+
**Sizing first, before any JSON.** Apply the `Default to NOT decomposing` rubric to the whole
|
|
534
|
+
unit of work — if it scores 0–2 the correct output is a ONE-entry batch, not many.
|
|
535
|
+
|
|
536
|
+
**Scenario count is not task count.** Merge scenarios that one task delivers (same file surface,
|
|
537
|
+
same subsystem, or unreadable apart in review), and list every scenario a task covers in its
|
|
538
|
+
background. Merging never costs AC coverage — one task may carry several scenarios. Do not emit
|
|
539
|
+
one entry per scenario or per requirement by reflex.
|
|
540
|
+
|
|
541
|
+
**The batch.** Produce a task-batch JSON array at the workflow-provided batch path
|
|
542
|
+
(`.spur/run/<runId>-idea-task-batch.json`), validated against `task-batch.schema.json`.
|
|
543
|
+
Schema-permitted fields per entry: `name`, `background`, `requirements`, `design`, `plan`,
|
|
544
|
+
`acceptance_criteria`, `feature_id`, `parent_wbs`, `priority`, `tags`, `template` — schema
|
|
545
|
+
validation rejects anything else. `design`, `plan`, and `acceptance_criteria` are supported batch
|
|
546
|
+
fields and normal default planning fills them from your analysis; the per-task refine step after
|
|
547
|
+
batch-create still deepens them when a task needs more detail. Validate locally against the
|
|
548
|
+
schema before emitting.
|
|
549
|
+
|
|
550
|
+
**The order sidecar.** Also emit the private task-order sidecar at
|
|
551
|
+
`.spur/run/<runId>-idea-task-order.json`: a JSON array (one entry per batch item) of
|
|
552
|
+
`{ name: <exact batch item name>, depends_on_names: [<batch item names>] }` declaring
|
|
553
|
+
ordering/dependencies between the batch items; state `depends_on_names: []` per item when no
|
|
554
|
+
ordering exists. Every `name` and every dependency must match exactly one batch item `name` —
|
|
555
|
+
it is private workflow data, not part of task-batch.schema.json.
|
|
556
|
+
|
|
528
557
|
## Common schema violations
|
|
529
558
|
|
|
530
559
|
| Violation | Fix |
|
|
@@ -24,11 +24,13 @@ that before using `run` for fan-out dispatch.
|
|
|
24
24
|
| `run <prompt>` | Execute a prompt or slash command via a coding agent | `--agent <name>` `--spec <id>` `--model <name>` `--mode <mode>` `--continue` `--cwd <path>` `--drain` `--json` |
|
|
25
25
|
| `loop` | Persistent self-draining inbox loop for a team member (supervisor-managed) | `--spec <id>` `--agent <id>` `--poll <ms>` |
|
|
26
26
|
| `wait [<specId>]` | Identity-pinned wait for an occupant run to reach a lifecycle state (G4 wave 2; `--role` selector per 0685) | `--role <name>` `--run <runId>` `--until <state>...` `--timeout <ms>` `--json` |
|
|
27
|
-
| `list` | List detected coding agents, or team agent specs with `--specs` | `--specs` `--json` |
|
|
27
|
+
| `list` | List detected coding agents, or team agent specs with `--specs` (live run status merged from `spur serve`) | `--specs` `--server <url>` `--json` |
|
|
28
28
|
| `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
|
|
29
29
|
| `create <id>` | Write a team agent spec to `.spur/agents/<id>.yaml` | `--type` `--tags` `--model` `--autonomy` `--system-prompt` `--name` `--workspace` `--purpose` `--auto-start` `--no-identity-preamble` `--json` |
|
|
30
30
|
| `edit <id>` | Open an agent spec in `$EDITOR`, or print its path | - |
|
|
31
31
|
| `delete <id>` | Remove an agent spec | `--force` |
|
|
32
|
+
| `start <spec-id>` | Start a supervised agent process (requires `spur serve`; 0848 moved home of `spur team start`) | `--server <url>` `--json` |
|
|
33
|
+
| `stop <spec-id>` | Stop a supervised agent process (requires `spur serve`; 0848 moved home of `spur team stop`) | `--server <url>` `--json` |
|
|
32
34
|
|
|
33
35
|
`list`, `doctor`, `run`, `wait`, and `create` accept `--json` plus `--json-envelope`. `loop`, `edit`,
|
|
34
36
|
and `delete` are human/process-control surfaces. **Exit codes:** `0` success, `1` failure, and `2`
|
|
@@ -54,7 +56,7 @@ through a coding agent as an external process, producing a persisted run record
|
|
|
54
56
|
| `--mode <mode>` | Agent output mode: `text` or `json`. |
|
|
55
57
|
| `--continue` | Resume the previous agent session instead of starting fresh. |
|
|
56
58
|
| `--cwd <path>` | Working directory for agent execution (default: current directory). |
|
|
57
|
-
| `--spec <id>` | Team agent spec id (occupant addressing, 0542 R1). Pairs with `--drain`; with `--spec` alone the run is addressed to the occupant without touching the inbox. A legacy `--agent <spec-id>` still
|
|
59
|
+
| `--spec <id>` | Team agent spec id (occupant addressing, 0542 R1). Pairs with `--drain`; with `--spec` alone the run is addressed to the occupant without touching the inbox. A legacy `--agent <spec-id>` is still accepted as fallback addressing (task 0849 retired the `agent-flag-spec-id` deprecation warning). |
|
|
58
60
|
| `--drain` | Prepend pending inbox messages addressed to `--spec <id>` before the prompt. |
|
|
59
61
|
| `--json` | Output machine-readable JSON where supported. |
|
|
60
62
|
| `--json-envelope` | Wrap JSON using the facade's standard output contract. |
|
|
@@ -89,9 +91,13 @@ justify it - but ensure the run executes in a context that can write the target
|
|
|
89
91
|
spur agent loop --agent worker-1 --poll 2000
|
|
90
92
|
```
|
|
91
93
|
|
|
92
|
-
`loop` is the **persistent self-draining wrapper** used by the team supervisor. It
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
`loop` is the **persistent self-draining wrapper** used by the team supervisor. It waits for a
|
|
95
|
+
wake on the `system_events` ledger — a human request (`message.sent`), a strategy change
|
|
96
|
+
(`strategy.changed`), a capacity change (`fleet.capacity.changed`), or a completion receipt
|
|
97
|
+
(`agent.invoke.exit`) — then drains the inbox into an `agent run` invocation. An idle wake
|
|
98
|
+
records the hold reason instead of dispatching; with no wake event at all it still drains every
|
|
99
|
+
`--poll` ms (backstop). It
|
|
100
|
+
between drains. It is not typically invoked directly by the operator - `spur agent start` launches it
|
|
95
101
|
under supervision.
|
|
96
102
|
|
|
97
103
|
### Flags
|
|
@@ -99,10 +105,10 @@ under supervision.
|
|
|
99
105
|
| Flag | Purpose |
|
|
100
106
|
|------|---------|
|
|
101
107
|
| `--spec <id>` | **Required.** Team agent spec id / message recipient (0542 R1; legacy `--agent <spec-id>` still read with a one-time warning). |
|
|
102
|
-
| `--poll <ms>` |
|
|
108
|
+
| `--poll <ms>` | Wakeup backstop timeout in milliseconds — drains at least this often (default: `2000`). |
|
|
103
109
|
|
|
104
110
|
The loop runs until `SIGINT` / `SIGTERM`. Each iteration: check inbox -> if messages, drain each
|
|
105
|
-
into `run` with `--drain` -> else
|
|
111
|
+
into `run` with `--drain` -> else record the idle hold (an empty drain dispatches nothing).
|
|
106
112
|
|
|
107
113
|
## `wait` - identity-pinned occupant wait (G4 wave 2)
|
|
108
114
|
|
|
@@ -152,7 +158,17 @@ spur agent list --json # machine-readable
|
|
|
152
158
|
```
|
|
153
159
|
|
|
154
160
|
Without `--specs`, lists coding agents detected on the host (by binary on `PATH`). With `--specs`,
|
|
155
|
-
lists team agent specs (`.spur/agents/*.yaml`)
|
|
161
|
+
lists team agent specs (`.spur/agents/*.yaml`) **with live run status merged from the server's
|
|
162
|
+
supervisor** (0848, the moved home of `spur team status`): each row carries a trailing status column
|
|
163
|
+
(`running` / `stopped` / `errored` / `unknown`) and `pid=<n>` where a process exists. When `spur serve`
|
|
164
|
+
is unreachable, the listing falls back to all `stopped` with a stderr warning. `--server <url>`
|
|
165
|
+
(default `http://localhost:3000/api`) targets the supervisor API.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
spur agent list --specs
|
|
169
|
+
# planner claude reviewer claude plans the work running pid=4132
|
|
170
|
+
# worker-1 pi worker pi implements stopped
|
|
171
|
+
```
|
|
156
172
|
|
|
157
173
|
## `doctor` - readiness check
|
|
158
174
|
|
|
@@ -176,7 +192,8 @@ spur agent create reviewer --type codex --autonomy review --auto-start
|
|
|
176
192
|
```
|
|
177
193
|
|
|
178
194
|
Writes a team agent spec to `.spur/agents/<id>.yaml`. The spec captures the agent's identity
|
|
179
|
-
(type, model, autonomy, system prompt, tags) so
|
|
195
|
+
(type, model, autonomy, system prompt, tags) so the fleet declaration (`.spur/fleet.json`, converted
|
|
196
|
+
by `spur projects migrate`) can materialize a roster and `spur
|
|
180
197
|
agent loop` can self-drain its inbox.
|
|
181
198
|
|
|
182
199
|
### Flags
|
|
@@ -191,7 +208,7 @@ agent loop` can self-drain its inbox.
|
|
|
191
208
|
| `--name <name>` | Agent display name. |
|
|
192
209
|
| `--workspace <path>` | Workspace path for this agent. |
|
|
193
210
|
| `--purpose <text>` | Team identity purpose. |
|
|
194
|
-
| `--auto-start` | Auto-start flag (
|
|
211
|
+
| `--auto-start` | Auto-start flag (started by the supervisor when serve materializes the fleet; without it, start manually with `spur agent start`). |
|
|
195
212
|
| `--no-identity-preamble` | Disable the identity preamble prepended to prompts. |
|
|
196
213
|
| `--json` | Output machine-readable JSON. |
|
|
197
214
|
|
|
@@ -211,20 +228,45 @@ spur agent delete worker-1 --force
|
|
|
211
228
|
|
|
212
229
|
`--force` is required (guards against accidental deletion). Removes `.spur/agents/<id>.yaml`.
|
|
213
230
|
|
|
231
|
+
## `start` - start a supervised process (0848)
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
spur agent start worker-1
|
|
235
|
+
spur agent start worker-1 --json
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
The moved home of `spur team start`. Posts to the `spur serve` supervisor API
|
|
239
|
+
(`POST /api/team/agents/:id/start`) and prints `started <id> (pid=<n>, status=<s>)`. Requires a
|
|
240
|
+
reachable `spur serve`; `--server <url>` (default `http://localhost:3000/api`) targets it. Exit `1`
|
|
241
|
+
when the server is unreachable or the start fails.
|
|
242
|
+
|
|
243
|
+
## `stop` - stop a supervised process (0848)
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
spur agent stop worker-1
|
|
247
|
+
spur agent stop worker-1 --json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The moved home of `spur team stop`. Posts to the supervisor API
|
|
251
|
+
(`POST /api/team/agents/:id/stop`) and prints `stopped <id>`. Same server requirement and flags as
|
|
252
|
+
`start`. `spur agent delete` (with `--force`) remains the spec-removal counterpart of the old
|
|
253
|
+
`team down --purge`.
|
|
254
|
+
|
|
214
255
|
## What this skill is NOT
|
|
215
256
|
|
|
216
257
|
- **Not the dispatch decision.** *When* to use `spur agent run` vs a native subagent is the
|
|
217
258
|
**[dispatch-surface rule](../../parallel-execution/references/dispatch-surface.md)**, not this
|
|
218
259
|
reference. This reference documents the verbs; that rule decides which surface carries a dispatch.
|
|
219
|
-
- **Not the team orchestrator.** `spur
|
|
220
|
-
`
|
|
260
|
+
- **Not the team orchestrator.** The `spur serve` supervisor drives the lifecycle: `spur agent
|
|
261
|
+
start` / `stop` manage supervised processes and `agent list --specs` reports live state (0848
|
|
262
|
+
moved these homes off the deprecated `spur team` noun).
|
|
221
263
|
|
|
222
264
|
## See also
|
|
223
265
|
|
|
224
266
|
- **[dispatch-surface.md](../../parallel-execution/references/dispatch-surface.md)** - native
|
|
225
267
|
subagent vs `spur agent run` decision rule. `--model` and `--agent` are its escalation levers.
|
|
226
|
-
- **`spur team` (see [team.md](team.md))** - team
|
|
227
|
-
|
|
268
|
+
- **`spur team` (see [team.md](team.md))** - deprecated team noun (0848); its verbs moved to this
|
|
269
|
+
noun (`start`/`stop`/`list --specs`) and to `spur task update --assignee`.
|
|
228
270
|
- **`spur message` (see [message.md](message.md))** - the inbox `--drain` reads from.
|
|
229
271
|
- **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
|
|
230
272
|
|
|
@@ -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.
|
|
@@ -67,6 +67,20 @@ frontmatter scalar.
|
|
|
67
67
|
wholesale. No inline-body flag. Section names: `Background`, `Requirements`, `Acceptance Criteria`, `Q&A`, `Design`, `Plan`, `Solution`, `Testing`, `Review`, `References`, `History`, `Notes`.
|
|
68
68
|
- **Frontmatter** (`--feature <id>`, `--priority <p>`): sets the scalar frontmatter field on an
|
|
69
69
|
existing task — the only post-create path, allow-listed to `feature_id` / `parent_wbs` / `priority`.
|
|
70
|
+
- **AC controls** (`--ac-altitude <graduating|task-local>`, `--ac-numbering task-local`) — independent
|
|
71
|
+
of each other (task 0818 R5). `--ac-altitude task-local` skips the **DD-09 feature-AC subset** rule
|
|
72
|
+
because the task's scenarios are intentionally not the feature's ship criteria; `--ac-numbering
|
|
73
|
+
task-local` opts the task into the **Requirements↔AC coverage** check inside the task. Setting one
|
|
74
|
+
never implies the other. `graduating` remains the default and DD-09 stays enforced for graduating
|
|
75
|
+
tasks. Use it for an issue/fix-batch task that is genuinely linked to a feature but whose
|
|
76
|
+
regression scenarios sit below that feature's ship criteria, and record the rationale in the task
|
|
77
|
+
body:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# One frontmatter flag per call — `update` sets a single field and ignores the rest.
|
|
81
|
+
bun run apps/cli/src/index.ts task update 0818 --feature D6 --json
|
|
82
|
+
bun run apps/cli/src/index.ts task update 0818 --ac-altitude task-local --json
|
|
83
|
+
```
|
|
70
84
|
|
|
71
85
|
Exit code `2` when neither mode's required args are supplied (e.g. `--section` without `--from-file`,
|
|
72
86
|
or no status and no `--section`/frontmatter flag).
|
|
@@ -183,7 +197,9 @@ traceability. Bare = whole corpus; with a WBS = one task. The matrix is loaded f
|
|
|
183
197
|
|
|
184
198
|
**L4 traceability** resolves `feature_id` / `parent_wbs` / `dependencies` edges and checks **AC
|
|
185
199
|
coverage** (DD-09): a task's scenarios must be a subset of its linked feature's AC by normalized
|
|
186
|
-
title — orphans warn by default.
|
|
200
|
+
title — orphans warn by default. A task declaring `ac_altitude: task-local` is exempt from that
|
|
201
|
+
subset rule only (`--ac-altitude`, above); every graduating task is still enforced, and the exemption
|
|
202
|
+
does not touch `ac_numbering`'s Requirements↔AC coverage or any other layer.
|
|
187
203
|
|
|
188
204
|
`--json` emits an array of per-task results:
|
|
189
205
|
|
|
@@ -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` |
|
|
@@ -157,13 +157,43 @@ spur task update 0040 --section Review --from-file /tmp/review.md
|
|
|
157
157
|
first, then point `--from-file` at it.
|
|
158
158
|
|
|
159
159
|
**Frontmatter set** (the only post-create path to scalar fields, allow-listed to
|
|
160
|
-
`feature_id`/`parent_wbs`/`priority
|
|
160
|
+
`feature_id`/`parent_wbs`/`priority`, plus the two AC controls below):
|
|
161
161
|
|
|
162
162
|
```bash
|
|
163
163
|
spur task update 0040 --feature H2
|
|
164
164
|
spur task update 0040 --priority P1
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
+
### AC altitude — `--ac-altitude` (task 0818 R5)
|
|
168
|
+
|
|
169
|
+
`--ac-altitude` and `--ac-numbering` are **independent** controls that are easy to confuse:
|
|
170
|
+
|
|
171
|
+
| Flag | Controls | Default | `task-local` means |
|
|
172
|
+
| --- | --- | --- | --- |
|
|
173
|
+
| `--ac-altitude <graduating\|task-local>` | DD-09 **feature-AC subset** rule (task scenarios ⊆ linked feature AC) | `graduating` | the task's scenarios are deliberately **not** feature ship criteria — skip the subset rule |
|
|
174
|
+
| `--ac-numbering <task-local>` | **Requirements↔AC coverage** inside the task | off | opt the task into the R-to-AC coverage check |
|
|
175
|
+
|
|
176
|
+
Setting one says nothing about the other: a `task-local`-altitude task can still be under full
|
|
177
|
+
R-to-AC coverage, and usually should be.
|
|
178
|
+
|
|
179
|
+
**The standing pattern for an issue or fix-batch task.** Link it to the feature it substantively
|
|
180
|
+
belongs to — do not leave it orphaned and do not relink unrelated corpus to silence a diagnostic.
|
|
181
|
+
Then, *only* when its regression scenarios intentionally do not represent that feature's ship
|
|
182
|
+
criteria, declare `--ac-altitude task-local` and record the rationale in the task body (Background
|
|
183
|
+
or Design), so the choice is auditable rather than inferred:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# source-local CLI (before `bun link`, or when pinning to this checkout).
|
|
187
|
+
# One frontmatter flag per call: `update` applies a single field, so a second
|
|
188
|
+
# frontmatter flag in the same invocation is silently ignored.
|
|
189
|
+
bun run apps/cli/src/index.ts task update 0818 --feature D6 --json
|
|
190
|
+
bun run apps/cli/src/index.ts task update 0818 --ac-altitude task-local --json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`graduating` stays the default, and DD-09 stays enforced for every graduating task — this flag
|
|
194
|
+
expresses a real altitude distinction, not a gate escape hatch. Ordinary orphan warnings are
|
|
195
|
+
unchanged, and no checker policy changes.
|
|
196
|
+
|
|
167
197
|
The section-write-then-replace pattern is the workflow agents use to fill in `Plan` / `Solution` /
|
|
168
198
|
`Testing` / `Review` during a run. See
|
|
169
199
|
[tasks/section-editing.md](tasks/section-editing.md) for the full recipe. For pipeline
|
|
@@ -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 |
|