@gobing-ai/spur 0.3.80 → 0.3.82
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 +31 -18
- package/config/config.global.yaml +13 -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/docs/99_PROJECT_CONSTITUTION.md +75 -13
- package/config/transition-shims.json +0 -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 +12 -3
- 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/inline-run-setup.ts +69 -1
- package/plugins/sp/scripts/quality-gate.mjs +216 -0
- package/plugins/sp/scripts/quality-gate.ts +287 -0
- package/plugins/sp/scripts/surface-drift-inventory.ts +0 -2
- package/plugins/sp/scripts/task-size-precheck.ts +44 -16
- package/plugins/sp/scripts/verify-answer-lint.ts +17 -1
- 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/code-review/references/review-lenses.md +3 -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/SKILL.md +4 -8
- package/plugins/sp/skills/spur-cli/references/agent.md +44 -69
- package/plugins/sp/skills/spur-cli/references/message.md +30 -3
- package/plugins/sp/skills/spur-cli/references/projects.md +25 -1
- package/plugins/sp/skills/spur-cli/references/self.md +6 -5
- package/plugins/sp/skills/spur-cli/references/serve.md +8 -7
- package/plugins/sp/skills/spur-cli/references/tasks.md +1 -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 +10 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +4 -6
- package/plugins/sp/skills/spur-dev/references/glossary.md +1 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +11 -1
- 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 +105 -85
- package/spur.js +44616 -43320
- package/web/_astro/BoardApp.D-WlxiN2.js +1 -0
- package/web/_astro/{BoardApp.CHQ1lycZ.js → BoardApp.D8bM9pKL.js} +97 -95
- package/web/_astro/{TaskDetail.GKfQJ60c.js → TaskDetail.BPRqgVUE.js} +1 -1
- package/web/_astro/{arc.DWEtA3Tx.js → arc.BPrPES3z.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.DB42oWmP.js → architectureDiagram-3BPJPVTR.qX_7q02P.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.rhv-zNQV.js → blockDiagram-GPEHLZMM.CUZfj5V7.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.Ci4-4VvY.js → c4Diagram-AAUBKEIU.CTaOr8hH.js} +1 -1
- package/web/_astro/channel.DGZaFHZx.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.Cc9veUgf.js → chunk-2J33WTMH.Dt-9wf3h.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.Bec9c4eI.js → chunk-4BX2VUAB.CTC2sdoN.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DoV8S1iB.js → chunk-55IACEB6.DQcxt2_g.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DwR-Qlyj.js → chunk-727SXJPM.DXFPSn-a.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.ND_a81WY.js → chunk-AQP2D5EJ.BCx3U4bT.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Wv_jwG48.js → chunk-FMBD7UC4.DL2tJkdO.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CXKXCMmp.js → chunk-ND2GUHAM.DZyflMro.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.nkaoNYQq.js → chunk-QZHKN3VN.CUI2mT09.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.cMQcVlQu.js → classDiagram-4FO5ZUOK.g4rX4Fr1.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.cMQcVlQu.js → classDiagram-v2-Q7XG4LA2.g4rX4Fr1.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.OaDJ7Mr2.js → cose-bilkent-S5V4N54A.CzWJLqp0.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.Chi8IphF.js → cynefin-OW5HDTMX.WgsvQeCR.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.Dzv6ngql.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DRvxlVS7.js → diagram-2AECGRRQ.CpJ4a9rU.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CnYvNdwA.js → diagram-5GNKFQAL.CzPlF_dq.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CpLpMw5R.js → diagram-KO2AKTUF.TAkZNTcQ.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.JTb78qUA.js → diagram-LMA3HP47.uCjoKSag.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Bk-1jDIb.js → diagram-OG6HWLK6.eMplIjoK.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D8hN9GZq.js → erDiagram-TEJ5UH35.Bf7zoXGz.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.-6zQr6m5.js → flowDiagram-I6XJVG4X.B_bHj3gN.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DboLQ9ca.js → ganttDiagram-6RSMTGT7.BasrHRMj.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.4tYvJKGR.js → gitGraphDiagram-PVQCEYII.C6iphq1x.js} +1 -1
- package/web/_astro/index.DayyIngm.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.Bd9rXpsB.js → infoDiagram-5YYISTIA.HXmDMhW4.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CvMoaf67.js → ishikawaDiagram-YF4QCWOH.BSmW8NiU.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.Ccy1CA7y.js → journeyDiagram-JHISSGLW.DEQow5fo.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.0MaMqHNS.js → kanban-definition-UN3LZRKU.IVm9cTdc.js} +1 -1
- package/web/_astro/{linear.CHXgcIbN.js → linear.CrsM73_9.js} +1 -1
- package/web/_astro/{mermaid.core.Ca-kcelG.js → mermaid.core.CfBeDJls.js} +6 -6
- package/web/_astro/{mindmap-definition-RKZ34NQL.BUIDlHa0.js → mindmap-definition-RKZ34NQL.C3j60Y-0.js} +1 -1
- package/web/_astro/ordinal.BYWQX77i.js +1 -0
- package/web/_astro/{pieDiagram-4H26LBE5.2dX3CU1s.js → pieDiagram-4H26LBE5.B-aCMeEA.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.B3LBlRiv.js → quadrantDiagram-W4KKPZXB.Cib965yq.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.X12I2uNx.js → requirementDiagram-4Y6WPE33.D61cS4O-.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BXohIHqx.js → sankeyDiagram-5OEKKPKP.GKF2qVPy.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.C37ZIUzg.js → sequenceDiagram-3UESZ5HK.DZnq8F2h.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BRgz317z.js → stateDiagram-AJRCARHV.DXUFmdgM.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.7VYSXN9-.js → stateDiagram-v2-BHNVJYJU.BtHmhLEz.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BVNz_HiN.js → timeline-definition-PNZ67QCA.Cy-WW2ln.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CHVDkPX4.js → vennDiagram-CIIHVFJN.SLp5b9KI.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.EQQ_qT9v.js → wardleyDiagram-YWT4CUSO.Bww45mWV.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DrAT9WoP.js → xychartDiagram-2RQKCTM6.DR4swI6a.js} +1 -1
- package/web/apple-touch-icon.png +0 -0
- package/web/favicon.ico +0 -0
- package/web/favicon.svg +17 -4
- package/web/icon-192.png +0 -0
- package/web/icon-512.png +0 -0
- package/web/index.html +2 -2
- package/web/site.webmanifest +31 -0
- package/web/spur_logo.svg +1 -0
- package/plugins/sp/skills/spur-cli/references/team.md +0 -145
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-cli-agent
|
|
3
|
-
description: "spur-cli noun reference: operate `spur agent` as the coding-agent execution surface - run prompts, wait on pinned occupants,
|
|
3
|
+
description: "spur-cli noun reference: operate `spur agent` as the coding-agent execution surface - run prompts, wait on pinned occupants, list agent specs, start/stop supervised processes, and check readiness."
|
|
4
4
|
see_also:
|
|
5
5
|
- spur-cli
|
|
6
6
|
---
|
|
@@ -9,7 +9,7 @@ see_also:
|
|
|
9
9
|
|
|
10
10
|
`spur agent` is the CLI for **running and inspecting coding agents**. It wraps the agents the
|
|
11
11
|
operator already has installed (Claude Code, Codex, omp, OpenCode, Antigravity, etc.) behind a
|
|
12
|
-
uniform run, wait,
|
|
12
|
+
uniform run, wait, and supervision surface, so the rest of the harness can dispatch work without
|
|
13
13
|
hard-coding a specific agent.
|
|
14
14
|
|
|
15
15
|
This is a **companion reference**, not an orchestrator. It documents *what each verb is and how to
|
|
@@ -22,16 +22,14 @@ that before using `run` for fan-out dispatch.
|
|
|
22
22
|
| Verb | Purpose | Key flags |
|
|
23
23
|
| ---- | ------- | --------- |
|
|
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
|
-
| `loop` | Persistent self-draining inbox loop for a team member (supervisor-managed) | `--spec <id>` `--agent <id>` `--poll <ms>` |
|
|
26
25
|
| `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
|
|
26
|
+
| `list` | List detected coding agents, or agent specs with `--specs` (live run status merged from `spur serve`) | `--specs` `--server <url>` `--json` |
|
|
28
27
|
| `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `delete <id>` | Remove an agent spec | `--force` |
|
|
28
|
+
| `start <spec-id>` | Start a supervised agent process (requires `spur serve`) | `--server <url>` `--json` |
|
|
29
|
+
| `stop <spec-id>` | Stop a supervised agent process (requires `spur serve`) | `--server <url>` `--json` |
|
|
32
30
|
|
|
33
|
-
`list`, `doctor`, `run`, `wait`, and `
|
|
34
|
-
|
|
31
|
+
`list`, `doctor`, `run`, `wait`, `start`, and `stop` accept `--json` plus `--json-envelope`. The hidden
|
|
32
|
+
`loop` is a supervisor-internal process surface. **Exit codes:** `0` success, `1` failure, and `2`
|
|
35
33
|
invalid usage; `run` can also propagate the invoked agent's non-zero result.
|
|
36
34
|
|
|
37
35
|
## `run` - execute a prompt via a coding agent
|
|
@@ -54,7 +52,7 @@ through a coding agent as an external process, producing a persisted run record
|
|
|
54
52
|
| `--mode <mode>` | Agent output mode: `text` or `json`. |
|
|
55
53
|
| `--continue` | Resume the previous agent session instead of starting fresh. |
|
|
56
54
|
| `--cwd <path>` | Working directory for agent execution (default: current directory). |
|
|
57
|
-
| `--spec <id>` |
|
|
55
|
+
| `--spec <id>` | 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
56
|
| `--drain` | Prepend pending inbox messages addressed to `--spec <id>` before the prompt. |
|
|
59
57
|
| `--json` | Output machine-readable JSON where supported. |
|
|
60
58
|
| `--json-envelope` | Wrap JSON using the facade's standard output contract. |
|
|
@@ -83,26 +81,15 @@ can fail when the external agent writes its own storage outside the sandbox's al
|
|
|
83
81
|
`AgentStorage` SQLite DB). This is not a reason to abandon `spur agent run` - triggers 1-4 still
|
|
84
82
|
justify it - but ensure the run executes in a context that can write the target agent's storage.
|
|
85
83
|
|
|
86
|
-
## `loop` -
|
|
84
|
+
## `loop` - supervisor-internal self-draining wrapper (hidden)
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
under supervision.
|
|
96
|
-
|
|
97
|
-
### Flags
|
|
98
|
-
|
|
99
|
-
| Flag | Purpose |
|
|
100
|
-
|------|---------|
|
|
101
|
-
| `--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>` | Idle poll interval in milliseconds (default: `2000`). |
|
|
103
|
-
|
|
104
|
-
The loop runs until `SIGINT` / `SIGTERM`. Each iteration: check inbox -> if messages, drain each
|
|
105
|
-
into `run` with `--drain` -> else sleep for `--poll` ms.
|
|
86
|
+
`spur agent loop --spec <id> [--poll <ms>]` is spawned by the `spur serve` supervisor for each
|
|
87
|
+
materialized agent spec; it is hidden from `--help` and not an operator verb (use `spur agent start`).
|
|
88
|
+
It waits for a wake on the `system_events` ledger — a human request (`message.sent`), a strategy
|
|
89
|
+
change (`strategy.changed`), a capacity change (`fleet.capacity.changed`), or a completion receipt
|
|
90
|
+
(`agent.invoke.exit`) — then drains the inbox into an `agent run` invocation. An idle wake records
|
|
91
|
+
the hold reason instead of dispatching; with no wake event it still drains every `--poll` ms
|
|
92
|
+
(default `2000`). It runs until `SIGINT` / `SIGTERM`.
|
|
106
93
|
|
|
107
94
|
## `wait` - identity-pinned occupant wait (G4 wave 2)
|
|
108
95
|
|
|
@@ -143,16 +130,26 @@ exits 2 naming the accepted vocabulary. Resolution collapses onto the same ident
|
|
|
143
130
|
| `timeout` | 1 | Caller `--timeout` elapsed (or aborted via SIGINT). |
|
|
144
131
|
| `usage` | 2 | Invalid flags, or `--until blocked` as the sole target (no first-class signal in wave 2). |
|
|
145
132
|
|
|
146
|
-
## `list` - detected agents and
|
|
133
|
+
## `list` - detected agents and agent specs
|
|
147
134
|
|
|
148
135
|
```bash
|
|
149
136
|
spur agent list # detected coding agents on this machine
|
|
150
|
-
spur agent list --specs #
|
|
137
|
+
spur agent list --specs # agent specs under .spur/agents/
|
|
151
138
|
spur agent list --json # machine-readable
|
|
152
139
|
```
|
|
153
140
|
|
|
154
141
|
Without `--specs`, lists coding agents detected on the host (by binary on `PATH`). With `--specs`,
|
|
155
|
-
lists
|
|
142
|
+
lists agent specs (`.spur/agents/*.yaml`) **with live run status merged from the server's
|
|
143
|
+
supervisor**: each row carries a trailing status column
|
|
144
|
+
(`running` / `stopped` / `errored` / `unknown`) and `pid=<n>` where a process exists. When `spur serve`
|
|
145
|
+
is unreachable, the listing falls back to all `stopped` with a stderr warning. `--server <url>`
|
|
146
|
+
(default `http://localhost:3000/api`) targets the supervisor API.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
spur agent list --specs
|
|
150
|
+
# planner claude reviewer claude plans the work running pid=4132
|
|
151
|
+
# worker-1 pi worker pi implements stopped
|
|
152
|
+
```
|
|
156
153
|
|
|
157
154
|
## `doctor` - readiness check
|
|
158
155
|
|
|
@@ -168,63 +165,41 @@ Checks whether each agent is installed and ready to run. Text mode renders a cap
|
|
|
168
165
|
(`cheap|standard|capable-*`), MODEL the pinned config model (`—` when undeclared), and ROLES lists
|
|
169
166
|
candidate pipeline roles with `*` on the elected one. Exit `1` if any checked agent is not ready.
|
|
170
167
|
|
|
171
|
-
## `
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
spur agent create worker-1 --type claude --tags team:alpha --model sonnet
|
|
175
|
-
spur agent create reviewer --type codex --autonomy review --auto-start
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
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 `spur team up` can materialize a roster and `spur
|
|
180
|
-
agent loop` can self-drain its inbox.
|
|
181
|
-
|
|
182
|
-
### Flags
|
|
183
|
-
|
|
184
|
-
| Flag | Purpose |
|
|
185
|
-
| ------ | --------- |
|
|
186
|
-
| `--type <agent-type>` | Agent spec type (e.g. `claude`, `codex`, `omp`). |
|
|
187
|
-
| `--tags <a,b>` | Comma-separated team identity tags (e.g. `team:alpha,role:worker`). |
|
|
188
|
-
| `--model <name>` | Agent model argument. |
|
|
189
|
-
| `--autonomy <level>` | Autonomy level (e.g. `full`, `review`). |
|
|
190
|
-
| `--system-prompt <text>` | Team identity system prompt. |
|
|
191
|
-
| `--name <name>` | Agent display name. |
|
|
192
|
-
| `--workspace <path>` | Workspace path for this agent. |
|
|
193
|
-
| `--purpose <text>` | Team identity purpose. |
|
|
194
|
-
| `--auto-start` | Auto-start flag (start on `team up` without manual `team start`). |
|
|
195
|
-
| `--no-identity-preamble` | Disable the identity preamble prepended to prompts. |
|
|
196
|
-
| `--json` | Output machine-readable JSON. |
|
|
197
|
-
|
|
198
|
-
## `edit` - open a spec in `$EDITOR`
|
|
168
|
+
## `start` - start a supervised process
|
|
199
169
|
|
|
200
170
|
```bash
|
|
201
|
-
spur agent
|
|
171
|
+
spur agent start worker-1
|
|
172
|
+
spur agent start worker-1 --json
|
|
202
173
|
```
|
|
203
174
|
|
|
204
|
-
|
|
175
|
+
Posts to the `spur serve` supervisor API
|
|
176
|
+
(`POST /api/agents/:id/start`) and prints `started <id> (pid=<n>, status=<s>)`. Requires a
|
|
177
|
+
reachable `spur serve`; `--server <url>` (default `http://localhost:3000/api`) targets it. Exit `1`
|
|
178
|
+
when the server is unreachable or the start fails.
|
|
205
179
|
|
|
206
|
-
## `
|
|
180
|
+
## `stop` - stop a supervised process
|
|
207
181
|
|
|
208
182
|
```bash
|
|
209
|
-
spur agent
|
|
183
|
+
spur agent stop worker-1
|
|
184
|
+
spur agent stop worker-1 --json
|
|
210
185
|
```
|
|
211
186
|
|
|
212
|
-
|
|
187
|
+
Posts to the supervisor API
|
|
188
|
+
(`POST /api/agents/:id/stop`) and prints `stopped <id>`. Same server requirement and flags as
|
|
189
|
+
`start`.
|
|
213
190
|
|
|
214
191
|
## What this skill is NOT
|
|
215
192
|
|
|
216
193
|
- **Not the dispatch decision.** *When* to use `spur agent run` vs a native subagent is the
|
|
217
194
|
**[dispatch-surface rule](../../parallel-execution/references/dispatch-surface.md)**, not this
|
|
218
195
|
reference. This reference documents the verbs; that rule decides which surface carries a dispatch.
|
|
219
|
-
- **Not the
|
|
220
|
-
`
|
|
196
|
+
- **Not the fleet orchestrator.** The `spur serve` supervisor drives the lifecycle: `spur agent
|
|
197
|
+
start` / `stop` manage supervised processes and `agent list --specs` reports live state.
|
|
221
198
|
|
|
222
199
|
## See also
|
|
223
200
|
|
|
224
201
|
- **[dispatch-surface.md](../../parallel-execution/references/dispatch-surface.md)** - native
|
|
225
202
|
subagent vs `spur agent run` decision rule. `--model` and `--agent` are its escalation levers.
|
|
226
|
-
- **`spur team` (see [team.md](team.md))** - team lifecycle that launches `agent loop` under
|
|
227
|
-
supervision.
|
|
228
203
|
- **`spur message` (see [message.md](message.md))** - the inbox `--drain` reads from.
|
|
229
204
|
- **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
|
|
230
205
|
|
|
@@ -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.
|
|
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,7 +19,7 @@ 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
25
|
|
|
@@ -36,6 +36,30 @@ exit `0`; validation, registry, spawn, health, or lookup failure is exit `1`.
|
|
|
36
36
|
defaults the display name to its basename. It upserts; it does not start a server. The current
|
|
37
37
|
source does not enforce a `.spur/` marker or directory type.
|
|
38
38
|
- `list` probes recorded ports and heals stale entries to `port: 0` before reporting `running`.
|
|
39
|
+
- `list --fleet` (0835/0858) additionally resolves each project's `agent.fleet` section from that
|
|
40
|
+
project's `.spur/config.yaml` under the existing verb (no new noun). Per project it prints one line
|
|
41
|
+
per member: instance id (the spec id / mailbox identity), `role`, resolved `executor`,
|
|
42
|
+
`fsWrite` capability state, and derived `write` flag. A project with no declaration reports
|
|
43
|
+
`no declaration (agent.fleet)`; a declared but switched-off fleet reports
|
|
44
|
+
`disabled (agent.fleet.enabled: false)` and still lists its roster; an all-disabled roster reports
|
|
45
|
+
`no enabled members`; a project whose config fails to load (a retired source, an invalid section)
|
|
46
|
+
reports the loader's message without failing the listing. Under `--json` each project gains `fleet`
|
|
47
|
+
(the resolved fleet, `null` on resolution failure) and, on failure, `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`.
|
|
39
63
|
|
|
40
64
|
## Server lifecycle
|
|
41
65
|
|
|
@@ -77,7 +77,7 @@ spur self serve --json # dry probe: print { port, url, pid, runni
|
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
Starts the Hono/Cloudflare-Worker server that serves the web Task Kanban and exposes the team
|
|
80
|
-
supervisor API (`/api/
|
|
80
|
+
supervisor API (`/api/processes/*` + `/api/agents/*`). It is the local fallback when no remote server is configured.
|
|
81
81
|
Flags: `--port <n>`, `--host <addr>`, `--no-open`, `--cwd <path>`, `--json` (a dry probe — reports
|
|
82
82
|
the resolved port/url without starting the server). Full flag semantics: **[serve.md](serve.md)**.
|
|
83
83
|
|
|
@@ -95,8 +95,9 @@ directory. Only flag is `--json`.
|
|
|
95
95
|
|
|
96
96
|
## What this skill is NOT
|
|
97
97
|
|
|
98
|
-
- **Not the
|
|
99
|
-
`
|
|
98
|
+
- **Not the agent 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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-cli-serve
|
|
3
|
-
description: "spur-cli noun reference: operate `spur serve` as the local web-server fallback - start the Hono/Cloudflare-Worker server that backs the web Task Kanban and the
|
|
3
|
+
description: "spur-cli noun reference: operate `spur serve` as the local web-server fallback - start the Hono/Cloudflare-Worker server that backs the web Task Kanban and the supervisor API. Single verb, five flags."
|
|
4
4
|
see_also:
|
|
5
5
|
- spur-cli
|
|
6
6
|
---
|
|
@@ -8,7 +8,7 @@ see_also:
|
|
|
8
8
|
# spur serve - local web server
|
|
9
9
|
|
|
10
10
|
`spur serve` starts the **Spur web server** - a local Hono / Cloudflare-Worker server that serves
|
|
11
|
-
the web Task Kanban and exposes the
|
|
11
|
+
the web Task Kanban and exposes the supervisor API (`/api/processes/*` + `/api/agents/*`). It is the local fallback
|
|
12
12
|
when no remote server is configured.
|
|
13
13
|
|
|
14
14
|
## Verb map
|
|
@@ -29,7 +29,7 @@ spur serve --json # dry probe: print { port, url, pid, running
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
Starts the server with the Hono app backed by the local SQLite database. The web Task Kanban and
|
|
32
|
-
the
|
|
32
|
+
the supervisor API become available at `http://<host>:<port>`.
|
|
33
33
|
|
|
34
34
|
### Flags
|
|
35
35
|
|
|
@@ -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
|
|
50
|
-
`
|
|
49
|
+
- **Not the agent 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>` (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` |
|
|
@@ -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
|
|