bullswarm 0.4.0 → 0.9.0
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/AGENTS.md +39 -1
- package/CHANGELOG.md +202 -0
- package/GOAL.md +135 -0
- package/README.md +223 -6
- package/connectors/_schema.json +23 -0
- package/connectors/claude-code.json +12 -1
- package/connectors/codex.json +13 -1
- package/connectors/command-code.json +17 -1
- package/connectors/echo.json +12 -0
- package/connectors/grok.json +11 -1
- package/connectors/opencode2.json +11 -1
- package/docs/dynamic-workflow-handoff.md +952 -0
- package/docs/dynamic-workflow-qa.md +107 -0
- package/docs/workflow-agent-usability-audit-2026-08-27.md +196 -0
- package/docs/workflow-design.md +195 -0
- package/fixtures/failures/01-rate-limit-head.json +6 -0
- package/fixtures/failures/03-pure-intent.json +6 -0
- package/fixtures/failures/04-cnf.json +6 -0
- package/fixtures/failures/05-unauthorized.json +6 -0
- package/fixtures/failures/06-short-conn.json +6 -0
- package/fixtures/failures/07-empty.json +6 -0
- package/fixtures/failures/08-tool-starved.json +6 -0
- package/fixtures/failures/09-auth-short.json +6 -0
- package/fixtures/failures/10-intent-short.json +6 -0
- package/fixtures/failures/11-503.json +6 -0
- package/fixtures/failures/12-blocked.json +6 -0
- package/fixtures/failures/13-announcement-477b.json +7 -0
- package/fixtures/real/01-rate-limit-discussion.json +7 -0
- package/fixtures/real/02-intent-opener.json +7 -0
- package/fixtures/real/03-dts-tokens.json +7 -0
- package/fixtures/real/04-rename.json +6 -0
- package/fixtures/real/05-lookup.json +6 -0
- package/fixtures/real/06-tests.json +6 -0
- package/fixtures/real/07-boilerplate.json +6 -0
- package/fixtures/real/09-smoke.json +6 -0
- package/fixtures/real/10-review.json +6 -0
- package/fixtures/real/11-convert.json +6 -0
- package/fixtures/real/12-tidy.json +6 -0
- package/package.json +7 -2
- package/skill/SKILL.md +363 -31
- package/src/cli.js +70 -22
- package/src/lib/config.js +8 -0
- package/src/lib/route.js +24 -5
- package/src/lib/state.js +1 -0
- package/src/lib/strategy.js +218 -0
- package/src/lib/usage.js +171 -0
- package/src/lib/watch.js +66 -9
- package/src/setup.js +79 -3
- package/src/strategy-cli.js +244 -0
- package/src/workflow/cli.js +510 -16
- package/src/workflow/dashboard.js +291 -0
- package/src/workflow/decision.js +152 -0
- package/src/workflow/draft-cli.js +451 -0
- package/src/workflow/draft.js +270 -0
- package/src/workflow/events.js +66 -0
- package/src/workflow/goal.js +129 -0
- package/src/workflow/runner.js +470 -16
- package/src/workflow/runs-cli.js +189 -0
- package/src/workflow/runtime.js +837 -70
- package/src/workflow/semaphore.js +56 -0
- package/src/workflow/short-id.js +267 -0
- package/src/workflow/template.js +26 -1
- package/src/workflow/tui.js +26 -0
- package/src/workflow/validate.js +120 -3
- package/workflows/adaptive-code-review.json +45 -0
- package/workflows/agent-model-comparison.json +49 -0
- package/workflows/connector-audit.json +60 -0
- package/workflows/smoke-two-step.json +41 -0
- package/workflows/verify-and-cap.json +62 -0
package/AGENTS.md
CHANGED
|
@@ -17,14 +17,52 @@ content. Published as `bullswarm` on npm.
|
|
|
17
17
|
3. Connector quirks live in `connectors/*.json`, never in core logic.
|
|
18
18
|
4. Quarantine always auto-releases; recursion depth is core-owned via env
|
|
19
19
|
(`BULLSWARM_DEPTH`).
|
|
20
|
+
5. Workflow dispatches must honor the same guarantees as single runs:
|
|
21
|
+
`BULLSWARM_DEPTH` is propagated, burst-gated pools are excluded, and
|
|
22
|
+
auth verdicts quarantine the pool + append to the shared decision log
|
|
23
|
+
(R6/R7/R8 in `src/workflow/runtime.js`).
|
|
24
|
+
6. Adversarial verification is a first-class primitive: a `verify` step
|
|
25
|
+
reads a prior outFile and demands a JSON `{ok, concerns, summary}`
|
|
26
|
+
verdict before downstream steps can trust the work (R-skeptic).
|
|
27
|
+
7. Workflows can be built incrementally from the shell
|
|
28
|
+
(`bullswarm workflow draft create/phase/step/set/...`). Drafts are
|
|
29
|
+
stored under `~/.bullswarm/drafts/<name>/` and are runnable by name
|
|
30
|
+
without an upfront JSON. JSON is still the durable artifact — drafts
|
|
31
|
+
are JSON documents, just built one mutation at a time.
|
|
32
|
+
8. Goal-driven execution is zero-graph by default: `bullswarm workflow goal`
|
|
33
|
+
internalizes the planner contract, chooses the orchestrator and workers,
|
|
34
|
+
persists the generated workflow, and can detach so observation never
|
|
35
|
+
depends on the initiating agent or CLI process.
|
|
20
36
|
|
|
21
37
|
## Development
|
|
22
38
|
|
|
23
39
|
```bash
|
|
24
|
-
npm test #
|
|
40
|
+
npm test # 195 tests, no network needed (meters read from cache)
|
|
25
41
|
node bin/bullswarm.js doctor --json # readiness report
|
|
42
|
+
node bin/bullswarm.js workflow list # discover workflows
|
|
43
|
+
node bin/bullswarm.js workflow runs # ongoing workflow instances
|
|
44
|
+
node bin/bullswarm.js workflow runs --all # including historical
|
|
45
|
+
node bin/bullswarm.js workflow validate <file> # dry-run
|
|
46
|
+
BULLSWARM_HOME=/tmp/bs node bin/bullswarm.js workflow run <file> # sandboxed run
|
|
47
|
+
# Build a workflow from the shell:
|
|
48
|
+
bullswarm workflow draft create my-audit
|
|
49
|
+
bullswarm workflow draft phase add my-audit discover
|
|
50
|
+
bullswarm workflow draft step add my-audit discover list-files --type run --prompt 'List files'
|
|
51
|
+
bullswarm workflow draft run my-audit
|
|
52
|
+
# Operate on a run by shortId (6 chars) or full runId (`wf-...`):
|
|
53
|
+
bullswarm workflow runs show <shortId>
|
|
54
|
+
bullswarm workflow runs delete <shortId> --yes
|
|
26
55
|
```
|
|
27
56
|
|
|
57
|
+
## Using bullswarm from another agent
|
|
58
|
+
|
|
59
|
+
If you are an agent that wants to offload bounded work via bullswarm,
|
|
60
|
+
read `skill/SKILL.md` — that's the agent-facing user guide. It covers
|
|
61
|
+
when to reach for `run` vs `workflow draft`, the verify-step pattern,
|
|
62
|
+
how to write prompts that pass the content gate, and the failure modes
|
|
63
|
+
you'll hit. The skill is published alongside the package and is the
|
|
64
|
+
canonical reference for the CLI surface.
|
|
65
|
+
|
|
28
66
|
- Zero runtime dependencies. Node >= 18. Tests must never require network:
|
|
29
67
|
prime `~/.bullswarm/meters/*.json` caches with fresh timestamps if needed.
|
|
30
68
|
- Every verb must work non-interactively (no TTY). The interactive wizard is
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# bullswarm changelog
|
|
2
|
+
|
|
3
|
+
## 0.9.0 — resilient dynamic workflow routing
|
|
4
|
+
|
|
5
|
+
- Added cooperative `SIGTERM`/`SIGINT` handling, durable `interrupted` states,
|
|
6
|
+
dead/stale owner reconciliation, and clean resume after interruption.
|
|
7
|
+
- Added capability-context filtering for model recommendations plus an explicit
|
|
8
|
+
`strategy apply --yes` approval gate and TTL-based automatic refresh.
|
|
9
|
+
- Added setup-time worktree policy and strategy-autopilot choices.
|
|
10
|
+
- Added per-attempt routing reasons/candidate surplus to durable events, state,
|
|
11
|
+
decision logs, and the printable workflow tree.
|
|
12
|
+
- Added top-level `runs` and `--version` aliases, complete `workflow goal`
|
|
13
|
+
budget help, and correct phase/terminal display for completed runs.
|
|
14
|
+
|
|
15
|
+
## 0.8.0 — autonomous goals, model strategy, and auditable usage
|
|
16
|
+
|
|
17
|
+
- Added `workflow goal` for bounded observe-plan-execute loops without an
|
|
18
|
+
upfront graph, including planner-owned expansion, completion policy,
|
|
19
|
+
detachment, resume, cancellation, ordered events, and durable action and
|
|
20
|
+
attempt ledgers.
|
|
21
|
+
- Added first-class `decide` and adversarial `verify` actions with strict JSON
|
|
22
|
+
contracts, capability-aware routing, bounded retries/escalation, and hard
|
|
23
|
+
expansion/dispatch/time limits.
|
|
24
|
+
- Added `strategy refresh/show/set-subscription/assign` to discover models from
|
|
25
|
+
installed CLIs, combine connector-owned dated price/benchmark metadata with
|
|
26
|
+
live quota surplus, and persist high/medium/low effort preferences.
|
|
27
|
+
- Added connector-owned model selection plus `--effort` routing for ordinary
|
|
28
|
+
runs and workflow actions. Safety eligibility always overrides preferences.
|
|
29
|
+
- Added per-attempt agent/model, standard-read/cache-read/cache-write/output
|
|
30
|
+
token estimates, API-equivalent cost, subscription-normalized quota, and
|
|
31
|
+
honest partial totals when a provider omits model or usage data.
|
|
32
|
+
- Added `workflow tui <runId>` as a printable historical phase/action/attempt
|
|
33
|
+
tree in both TTY and non-TTY environments, alongside JSON state/events.
|
|
34
|
+
- Expanded the offline suite to 195 tests. A fresh-home real-provider trial
|
|
35
|
+
autonomously fixed and independently verified a failing Node fixture; a
|
|
36
|
+
deliberately undersized dispatch budget also stopped truthfully rather than
|
|
37
|
+
claiming completion.
|
|
38
|
+
|
|
39
|
+
## 0.7.0 — short run IDs + workflow runs
|
|
40
|
+
|
|
41
|
+
Workflow runs were opaque (`wf-mtapqmfm-ad9ba7` everywhere) and
|
|
42
|
+
there was no way to list or operate on past runs except by
|
|
43
|
+
file-system diving. v0.7.0 adds:
|
|
44
|
+
|
|
45
|
+
- **6-character short IDs** (Crockford-style 32-char alphabet, no
|
|
46
|
+
`0/1/i/l/o` for visual clarity). Every new run gets a `shortId`
|
|
47
|
+
on both `state.json` and `report.json`. The full `wf-...` runId
|
|
48
|
+
stays the durable handle.
|
|
49
|
+
- **`bullswarm workflow runs ...`** sub-verb:
|
|
50
|
+
- `runs` (default = ongoing only) — list with a `●`/`○` marker
|
|
51
|
+
- `runs --all` — ongoing + historical
|
|
52
|
+
- `runs --historical` — only historical
|
|
53
|
+
- `runs --name <wf>` — filter by workflow
|
|
54
|
+
- `runs --limit N` — cap result count
|
|
55
|
+
- `runs show <id>` — dump `state.json` + `report.json`. Accepts
|
|
56
|
+
shortId, full runId, or run-dir path.
|
|
57
|
+
- `runs delete <id> --yes` — remove a run directory. Refuses
|
|
58
|
+
ongoing runs without `--force`.
|
|
59
|
+
- **Resume by short ID**: `bullswarm workflow run <wf> --resume
|
|
60
|
+
<shortId>` resolves the shortId to the full runId before any
|
|
61
|
+
dispatch. Bogus tokens fail fast, before workflow load.
|
|
62
|
+
- **`isOngoing(runDir, state)`** helper: classifies a run as
|
|
63
|
+
ongoing when `state.finishedAt` is unset AND `state.json` was
|
|
64
|
+
modified within the last 90 s. After the 90 s window a run is
|
|
65
|
+
treated as historical even if `finishedAt` was never written
|
|
66
|
+
(e.g. process killed before terminal `persist()`).
|
|
67
|
+
|
|
68
|
+
### New files
|
|
69
|
+
|
|
70
|
+
- `src/workflow/short-id.js` — Crockford-style generator, resolver,
|
|
71
|
+
`isOngoing`, `listRuns`
|
|
72
|
+
- `src/workflow/runs-cli.js` — `cmdRuns` dispatch
|
|
73
|
+
- `tests/workflow-runs.test.js` — 16 new tests
|
|
74
|
+
|
|
75
|
+
### Tests
|
|
76
|
+
|
|
77
|
+
- 16 new tests covering shortId generation, resolution, lock-free
|
|
78
|
+
ongoing detection, list filtering, show, delete, and the resume
|
|
79
|
+
pre-flight.
|
|
80
|
+
- Full suite is 147 green (131 prior + 16 new), stable across 3
|
|
81
|
+
stress runs.
|
|
82
|
+
- Verified end-to-end by `cmd -p --yolo` against a real CLI
|
|
83
|
+
installation: every step of the runbook passed.
|
|
84
|
+
|
|
85
|
+
## 0.6.0 — incremental workflow drafts (CLI builder)
|
|
86
|
+
|
|
87
|
+
The static `workflow run <file>` shape required every workflow to be
|
|
88
|
+
authored as a JSON file in advance. That's not "dynamic" — it's a script
|
|
89
|
+
of record. v0.6.0 introduces `bullswarm workflow draft ...`, a
|
|
90
|
+
sub-verb group that lets you build a workflow interactively from the
|
|
91
|
+
shell, one mutation at a time. Drafts persist under
|
|
92
|
+
`~/.bullswarm/drafts/<name>/` and are promoted to first-class
|
|
93
|
+
workflows (discoverable, runnable by name, validatable) the moment
|
|
94
|
+
they're created.
|
|
95
|
+
|
|
96
|
+
### New CLI surface
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
bullswarm workflow draft create <name> [--description ...] [--input k=v]...
|
|
100
|
+
bullswarm workflow draft show <name>
|
|
101
|
+
bullswarm workflow draft list
|
|
102
|
+
bullswarm workflow draft phase add <name> <phase>
|
|
103
|
+
bullswarm workflow draft phase remove <name> <phase>
|
|
104
|
+
bullswarm workflow draft step add <name> <phase> <step-id> --type run|fanout|verify [--lane ... --prompt ... --add-dir ... --pool ... --items-from ... --review ... --concurrency N --timeout N --on-error ... --step-template <json>]
|
|
105
|
+
bullswarm workflow draft step remove <name> <phase> <step-id>
|
|
106
|
+
bullswarm workflow draft step set <name> <phase> <step-id> <field> --value <text>
|
|
107
|
+
bullswarm workflow draft set <name> <field> --value <text>
|
|
108
|
+
bullswarm workflow draft validate <name>
|
|
109
|
+
bullswarm workflow draft export <name> <out-file>
|
|
110
|
+
bullswarm workflow draft delete <name> --yes
|
|
111
|
+
bullswarm workflow draft run <name> [--input k=v]... [--resume id] [--json] [--quiet]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- Every mutation re-validates immediately and persists the verdict on
|
|
115
|
+
`meta.json.lastValidation`. `bullswarm workflow list` shows drafts
|
|
116
|
+
with a `(draft)` tag.
|
|
117
|
+
- `bullswarm workflow run <draft-name>` and `workflow validate
|
|
118
|
+
<draft-name>` accept a draft name the same way they accept a JSON
|
|
119
|
+
filename — the new `workflowDirs()` entry `~/.bullswarm/drafts/`
|
|
120
|
+
makes drafts first-class.
|
|
121
|
+
- `bullswarm workflow draft export <name> <file>` promotes a draft
|
|
122
|
+
to a checked-in JSON for version control.
|
|
123
|
+
- Partial drafts (zero phases, or a phase with zero steps) are
|
|
124
|
+
treated as BUILDING, not INVALID — the validator's
|
|
125
|
+
`phases-must-be-non-empty` rule is downgraded to a warning during
|
|
126
|
+
construction. Real schema violations (bad lane, duplicate step id,
|
|
127
|
+
etc.) still return nonzero.
|
|
128
|
+
- `delete` requires `--yes` so a stray arrow-key can't nuke a draft.
|
|
129
|
+
- The `BULLSWARM_HOME` env var redirects drafts to a sandbox under
|
|
130
|
+
any temp dir, so the same `autoSetup` flow agents use elsewhere
|
|
131
|
+
works here.
|
|
132
|
+
|
|
133
|
+
### Tests
|
|
134
|
+
|
|
135
|
+
- 25 new tests in `tests/workflow-draft.test.js`. Two layers:
|
|
136
|
+
module-level (no spawn) for every mutation, CLI-level (spawnSync)
|
|
137
|
+
for the user-facing contract.
|
|
138
|
+
- Full suite is now 131 green (106 prior + 25 new).
|
|
139
|
+
|
|
140
|
+
### Files
|
|
141
|
+
|
|
142
|
+
- New: `src/workflow/draft.js` — storage, atomic writes, validation hook
|
|
143
|
+
- New: `src/workflow/draft-cli.js` — `cmdDraft` dispatch + flag parsing
|
|
144
|
+
- New: `tests/workflow-draft.test.js`
|
|
145
|
+
- Modified: `src/workflow/cli.js` (added `draft` sub-verb, drafts in
|
|
146
|
+
`workflowDirs()` and `discover()`)
|
|
147
|
+
|
|
148
|
+
## 0.5.0 — gap-closure release
|
|
149
|
+
|
|
150
|
+
Workflow parity with Claude Code dynamic workflows plus deep-QA hardening.
|
|
151
|
+
All 10 gaps identified in the v0.4.0 audit are closed; 23 new tests
|
|
152
|
+
added; full suite is 105 green (82 prior + 23 new).
|
|
153
|
+
|
|
154
|
+
### Workflow runtime (R-numbered doctrine)
|
|
155
|
+
|
|
156
|
+
- **R4 — global concurrency limiter**: a real `Semaphore` (`src/workflow/semaphore.js`) is shared by every `runSingle` and every fanout worker. Per-fanout worker count is capped at `min(per-fanout, limiter.permits, items.length)`. A `step.blocked` event fires when items queue behind the cap.
|
|
157
|
+
- **R6 — recursion-guard propagation**: every workflow dispatch computes `childDepthEnv(parentEnv)` and passes it to `watchOnce`. The runtime asserts `assertDepthAllowed(coreState, parentEnv)` before each dispatch. A workflow that itself spawns `bullswarm` is refused at the core's depth limit instead of recursing forever. `src/lib/watch.js` now honors caller-supplied `opts.env` so the depth env actually reaches the child.
|
|
158
|
+
- **R7 — quarantine + decision log on workflow auth failures**: when a dispatch inside a workflow returns `quarantineHint: true`, the runtime calls `quarantinePool(state, poolName, why, now)` against the core state file and appends a `source: "workflow"` entry to the shared `decisionLog` so `bullswarm health` and `pools` see workflow runs. The live `pools` view is updated so the next dispatch in the same run does not re-select the benched pool.
|
|
159
|
+
- **R8 — burst-gate exclusion in workflows**: `preparePools` now drops any pool with `burstGate === true` (5h ≥ 90 %), matching the single-run path.
|
|
160
|
+
- **R10 — fingerprint-aligned fanout resume**: every fanout result is now stamped with `sha1(JSON.stringify(item)).slice(0,12)`. On resume, items are matched by fingerprint first; positional alignment is a fallback for state.json from prior versions. Reordering, adding, or removing items no longer breaks resume.
|
|
161
|
+
- **R9 — outputText truncation**: `recordOutput` caps `state.outputs[id].outputText` at `OUTPUT_TEXT_CAP_BYTES = 64 KB`. The on-disk outFile always holds the full transcript. Persisted state.json is now bounded.
|
|
162
|
+
|
|
163
|
+
### New step type: `verify` (skeptic)
|
|
164
|
+
|
|
165
|
+
- Adversarial review of a prior step. Schema: `{ type: "verify", review: "outputs.<prior>.outFile", lane, prompt?, timeoutSec? }`. The runtime reads the prior outFile, inlines it into a structured prompt asking for `RETURN ONLY {"ok": <bool>, "concerns": [...], "summary": ...}`, dispatches through the standard pool-routed pipeline, and parses the first JSON object in the response. Step is `ok:true` only if dispatch verifies AND the JSON `ok` is `true`. The parsed `verify` object is recorded on `state.outputs[id].verify` so downstream steps can reference `concerns` and `summary`.
|
|
166
|
+
- Validated: `review` must resolve to a known prior outFile or a declared input; `inputs.<k>.required` is now type-checked and runtime-enforced.
|
|
167
|
+
- See `workflows/verify-and-cap.json` for an end-to-end example.
|
|
168
|
+
|
|
169
|
+
### New settings
|
|
170
|
+
|
|
171
|
+
- `settings.maxAgents` — hard cap; a step that would push dispatch count past the cap fails with `why: "spend guard: maxAgents=... reached"`.
|
|
172
|
+
- `settings.warnAtAgents` — advisory; a `workflow.large` event fires once when the threshold is crossed. TUI renders it as `⚠ Large workflow: N dispatches ≥ threshold M`.
|
|
173
|
+
- `settings.concurrency` is now validated to be `≤ 16`, matching Claude Code's runtime cap.
|
|
174
|
+
- `inputs.<k>.required: true` is now a hard pre-flight refusal. `runWorkflow` throws `required input "<k>" missing` before any dispatch.
|
|
175
|
+
|
|
176
|
+
### New runtime events
|
|
177
|
+
|
|
178
|
+
- `item.skipped` — emitted by fanout resume; was dropped silently in TTY mode. Now rendered as `⏭ <stepId>[i] ok from previous run (resume)`.
|
|
179
|
+
- `step.blocked` — emitted when items queue behind the global cap; rendered as `⋈ N item(s) queued behind concurrency cap in <stepId>`.
|
|
180
|
+
- `workflow.large` — emitted once when the dispatch threshold is crossed.
|
|
181
|
+
|
|
182
|
+
### CLI
|
|
183
|
+
|
|
184
|
+
- `BULLSWARM_HOME` env var now overrides the workflow CLI's `BULLSWARM_DIR` (previously hardcoded to `~/.bullswarm`). Matches the meter registry.
|
|
185
|
+
- `--input k=v` accepts JSON-encoded values so arrays and objects can be passed: `--input 'items=["a","b"]'`. The legacy string form is unchanged.
|
|
186
|
+
|
|
187
|
+
### TUI
|
|
188
|
+
|
|
189
|
+
- `item.skipped`, `step.blocked`, and `workflow.large` are all rendered in human mode (previously `item.skipped` was TTY-invisible).
|
|
190
|
+
|
|
191
|
+
### Tests
|
|
192
|
+
|
|
193
|
+
- 23 new tests in `tests/workflow-gaps.test.js`, one per gap closure.
|
|
194
|
+
- 105 total tests, all green, no network, ~1 s.
|
|
195
|
+
|
|
196
|
+
### Files
|
|
197
|
+
|
|
198
|
+
- New: `src/workflow/semaphore.js`
|
|
199
|
+
- New: `tests/workflow-gaps.test.js`
|
|
200
|
+
- New: `workflows/verify-and-cap.json`
|
|
201
|
+
- New: `CHANGELOG.md`
|
|
202
|
+
- Modified: `src/workflow/runtime.js`, `src/workflow/runner.js`, `src/workflow/validate.js`, `src/workflow/tui.js`, `src/workflow/cli.js`, `src/lib/watch.js`
|
package/GOAL.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# bullswarm — Goal Statement
|
|
2
|
+
|
|
3
|
+
**Status:** PROTOTYPE · **Owner:** cowcow02 · **Created:** 2026-08-21
|
|
4
|
+
|
|
5
|
+
## One sentence
|
|
6
|
+
|
|
7
|
+
A standalone CLI that lets *any* coding agent offload work to *any other* coding
|
|
8
|
+
agent CLI on the same machine — routing by lane, pacing by subscription meter,
|
|
9
|
+
and verifying by content — so no provider's quota expires unused and no agent's
|
|
10
|
+
"success" is taken at face value.
|
|
11
|
+
|
|
12
|
+
## Why this exists
|
|
13
|
+
|
|
14
|
+
Every agent CLI assumes it is the center of the universe. Multi-subscription
|
|
15
|
+
developers (Claude Max + Codex + Grok + …) watch quota expire on some pools
|
|
16
|
+
while others are exhausted mid-task, and every delegate CLI can exit 0 while
|
|
17
|
+
having done nothing. No existing router treats subscription windows as the
|
|
18
|
+
scheduling resource; proxy routers spend API credits instead of subscriptions;
|
|
19
|
+
prompt-policy layers can't compel dispatch. bullswarm sits *above* all agents as
|
|
20
|
+
the neutral coordinator vendors will never build.
|
|
21
|
+
|
|
22
|
+
## Outcome
|
|
23
|
+
|
|
24
|
+
A working prototype installed at `~/.bullswarm/` with:
|
|
25
|
+
|
|
26
|
+
1. **`bullswarm` CLI** with four verbs (`setup` detailed in #8):
|
|
27
|
+
- `setup` — interactive front door: discover → enable → route → write
|
|
28
|
+
- `run` — route → dispatch → watch → verify → one JSON verdict
|
|
29
|
+
(`ok`, `keepOnClaude`, `why`, `pick.command`, `contentUsableDespiteExit`)
|
|
30
|
+
- `health` — re-judge saved outputs against verdicts; surface gate failures
|
|
31
|
+
and quarantine clusters after every round
|
|
32
|
+
- `pools` — show each pool's meter state, pace position, quarantine status
|
|
33
|
+
2. **Connector registry** (`~/.bullswarm/connectors/*.json`): declarative per-CLI
|
|
34
|
+
spawn command, auth-failure signatures, output extraction, verify contract,
|
|
35
|
+
quirk fields (e.g. PWD resolution). Seeded with codex, grok,
|
|
36
|
+
command-code, opencode2 — extracted from the proven `/offload` skill.
|
|
37
|
+
3. **Meter layer**: per-pool window definition (5h / weekly / none) with
|
|
38
|
+
programmatic readers where providers expose usage, manual declaration
|
|
39
|
+
(`--meter pool=window,pct`) where they don't. Unmetered pools pace as
|
|
40
|
+
time-proportional and are labeled as such.
|
|
41
|
+
4. **Pacing brain**: time-adjusted pace (elapsed% − used%; most-behind wins),
|
|
42
|
+
incumbency margin, cost guard (pace may only promote a cheaper pool),
|
|
43
|
+
lanes by work nature (analyze/build/chore) — never a hard-coded lane→pool map.
|
|
44
|
+
5. **Verify gate**: content-based judgment ported intact from delegate-watch —
|
|
45
|
+
exit code never trusted alone, announcement-vs-work splitting, failure
|
|
46
|
+
patterns scoped to first 400 chars (whole text under 600), fixture suite
|
|
47
|
+
green before any release.
|
|
48
|
+
6. **Recursion guard**: depth limit owned by the core; an offloaded agent that
|
|
49
|
+
calls bullswarm cannot exceed configured depth.
|
|
50
|
+
7. **MCP server**: exposes `run`/`health`/`pools` so Claude Code, Codex, Cursor
|
|
51
|
+
or any MCP client can offload without shell plumbing.
|
|
52
|
+
8. **Setup wizard as the front door**: bare `bullswarm` with no config (or
|
|
53
|
+
`bullswarm setup`) launches an interactive guide that:
|
|
54
|
+
- **discovers** installed agent CLIs (binary on PATH + config dir present +
|
|
55
|
+
cheap auth probe — never credential entry), showing quota/burn-rate state
|
|
56
|
+
per pool immediately; burn rate starts empty and is labeled "learning"
|
|
57
|
+
until the decision log fills it;
|
|
58
|
+
- lets the user **toggle which discovered pools to enable**;
|
|
59
|
+
- **suggests a routing table** (lane → pool defaults from enabled pools)
|
|
60
|
+
presented as an editable artifact, not a questionnaire;
|
|
61
|
+
- writes `~/.bullswarm/` config + connectors, idempotent and re-runnable
|
|
62
|
+
(`bullswarm setup` repairs);
|
|
63
|
+
- can generate an agent-facing integration block for CLAUDE.md / AGENTS.md,
|
|
64
|
+
shown as a diff with explicit approval before any write, delimited by
|
|
65
|
+
versioned `bullswarm:begin/end` markers (pilotfish pattern);
|
|
66
|
+
- a thin companion skill (`bullswarm-setup`) ships alongside so agents can
|
|
67
|
+
recommend running `/bullswarm:setup` to users — the skill nudges, the CLI
|
|
68
|
+
owns the flow.
|
|
69
|
+
|
|
70
|
+
## Success proofs
|
|
71
|
+
|
|
72
|
+
The prototype is done when ALL hold:
|
|
73
|
+
|
|
74
|
+
- [x] `bullswarm run --lane analyze --add-dir <repo> --task-file t.md --json`
|
|
75
|
+
returns a verdict whose shape matches the delegate-watch contract, using
|
|
76
|
+
a real pool, end to end, on this machine.
|
|
77
|
+
- [x] The verify gate passes its full fixture suite (≥17 fixtures:
|
|
78
|
+
true failures AND real outputs) unchanged in behavior vs. `/offload`.
|
|
79
|
+
- [x] `bullswarm pools` reflects a manually declared meter change within one
|
|
80
|
+
run, and pace ordering flips the pick when a pool crosses the margin.
|
|
81
|
+
- [x] A wrong-repo scenario (stale PWD) produces a correct-repo dispatch for
|
|
82
|
+
every connector whose quirk field declares it.
|
|
83
|
+
- [x] `bullswarm health` flags a planted FAILED-verdict-but-good-output case
|
|
84
|
+
and a two-quarantine cluster.
|
|
85
|
+
- [x] An MCP client (Claude Code) completes one offload round via the MCP
|
|
86
|
+
server with zero shell commands.
|
|
87
|
+
- [x] Recursion guard stops a self-calling delegate at the configured depth.
|
|
88
|
+
- [x] Bare `bullswarm` on a machine with no `~/.bullswarm/` launches the
|
|
89
|
+
wizard; discovery lists at least the four seeded connectors with correct
|
|
90
|
+
found/not-found status, and completing it produces a working `run`.
|
|
91
|
+
- [x] The wizard's CLAUDE.md/AGENTS.md integration step shows a diff and
|
|
92
|
+
writes nothing without explicit approval; re-running setup is idempotent
|
|
93
|
+
(no duplicate marker blocks).
|
|
94
|
+
- [x] `bullswarm setup` on an already-configured machine reports current state
|
|
95
|
+
and repairs a deliberately broken connector file.
|
|
96
|
+
|
|
97
|
+
## Invariants
|
|
98
|
+
|
|
99
|
+
- Judge by CONTENT, not exit code. A non-zero exit is never a success;
|
|
100
|
+
`ok:true` requires passing verification.
|
|
101
|
+
- Never hard-code lane→pool mappings; pools serve lanes only via runtime
|
|
102
|
+
selection over declared capability.
|
|
103
|
+
- Delegate output is input to verify, never the answer. Final synthesis,
|
|
104
|
+
architecture decisions, and anything needing live conversation context stay
|
|
105
|
+
with the caller.
|
|
106
|
+
- Quarantine must have a re-probe path; a recovered pool must return to
|
|
107
|
+
service automatically (this fixes the known `/offload` gap).
|
|
108
|
+
- Connector quirks live in connector files, never in core logic.
|
|
109
|
+
- Stealth/retention-hostile models are opt-in per connector, flagged in the
|
|
110
|
+
registry, never defaults.
|
|
111
|
+
|
|
112
|
+
## Non-goals (prototype)
|
|
113
|
+
|
|
114
|
+
- No hosted service, no daemon required for basic operation.
|
|
115
|
+
- No per-host hook integrations beyond MCP.
|
|
116
|
+
- No measured routing table yet (smart-router-style pass@k benchmarking is
|
|
117
|
+
post-prototype).
|
|
118
|
+
- No savings ledger yet (post-prototype).
|
|
119
|
+
- Windows support deferred; macOS/Linux first.
|
|
120
|
+
|
|
121
|
+
## Authority envelope
|
|
122
|
+
|
|
123
|
+
Build freely inside `~/Repo/bullswarm`. Installing to `~/.bullswarm/` and
|
|
124
|
+
reading existing `~/.claude/skills/offload/*` sources for extraction is
|
|
125
|
+
authorized. Do NOT modify the live `/offload` skill during extraction — copy,
|
|
126
|
+
never move. No publishing (npm/GitHub push) without explicit instruction.
|
|
127
|
+
|
|
128
|
+
## Provenance
|
|
129
|
+
|
|
130
|
+
Extracted from the working `/offload` system (~/.claude/skills/offload/):
|
|
131
|
+
delegate-route.mjs (routing brain), delegate-watch.mjs (verify+watch),
|
|
132
|
+
delegate-health.mjs (re-judging), SKILL.md (operational doctrine). The four
|
|
133
|
+
2026-08-21 failure modes (wrong-repo silence, three verify-gate bugs, invisible
|
|
134
|
+
workflow health, exit-1-after-success) are the regression baseline this
|
|
135
|
+
prototype must never reintroduce.
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# bullswarm
|
|
2
2
|
|
|
3
|
-
Route work across coding-agent CLIs.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Route work across coding-agent CLIs. For a goal, Bullswarm can choose a capable
|
|
4
|
+
orchestrator, build and expand the plan, route bounded worker actions by quota,
|
|
5
|
+
verify the result, and finish without an initiating agent authoring a graph.
|
|
6
|
+
Every delegate output is judged by content before it counts.
|
|
6
7
|
|
|
7
8
|
## The doctrine (non-negotiable)
|
|
8
9
|
|
|
@@ -12,9 +13,9 @@ most quota left; every delegate output is judged by content before it counts.
|
|
|
12
13
|
2. **Pace by meter.** The scheduling resource is the subscription window:
|
|
13
14
|
elapsed% minus used%, most-behind pool wins. Pace may only promote a
|
|
14
15
|
*cheaper* pool. Lanes are work-nature, never hard-coded to pools.
|
|
15
|
-
3. **Delegate output is
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
3. **Delegate output is evidence, never authority.** A goal orchestrator may
|
|
17
|
+
synthesize completion, but only after the deterministic runtime accepts its
|
|
18
|
+
bounded plan and durable verification evidence.
|
|
18
19
|
4. **Quarantine re-probes.** A benched pool must be able to return to service
|
|
19
20
|
automatically; a lane is never allowed to silently go down.
|
|
20
21
|
|
|
@@ -30,7 +31,9 @@ npm install -g bullswarm # or: node bin/bullswarm.js directly from a checkout
|
|
|
30
31
|
bullswarm # first run: interactive setup wizard
|
|
31
32
|
bullswarm setup # re-run or repair
|
|
32
33
|
bullswarm pools # meter state, pace position, quarantine status
|
|
34
|
+
bullswarm strategy refresh --apply --yes # approve capability-aware tier autopilot
|
|
33
35
|
bullswarm run --lane analyze --add-dir ~/some-repo --task-file /tmp/t.md --json
|
|
36
|
+
bullswarm workflow goal "Fix the failing tests and verify the change" --cwd ~/some-repo
|
|
34
37
|
bullswarm health # re-judge saved outputs; catch gate failures
|
|
35
38
|
```
|
|
36
39
|
|
|
@@ -42,6 +45,220 @@ bullswarm health # re-judge saved outputs; catch gate failures
|
|
|
42
45
|
| `run` | route → dispatch → watch → verify → one JSON verdict |
|
|
43
46
|
| `health` | Re-judge saved outputs against their verdicts; surface verify-gate failures and quarantine clusters |
|
|
44
47
|
| `pools` | Show each pool's meter state, pace position, quarantine status |
|
|
48
|
+
| `strategy` | Discover models, record subscription value, recommend or assign high/medium/low effort routes |
|
|
49
|
+
| `doctor` | Machine-readable readiness report; self-heals on first call |
|
|
50
|
+
| `workflow` | Start an autonomous goal, or run / validate / draft / inspect explicit workflows and their live instances. |
|
|
51
|
+
|
|
52
|
+
## Model strategy and invocation telemetry
|
|
53
|
+
|
|
54
|
+
Bullswarm can inventory the models exposed by installed agent CLIs and combine
|
|
55
|
+
connector-declared, dated pricing/benchmark metadata with live quota surplus:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bullswarm strategy refresh
|
|
59
|
+
bullswarm strategy show --json
|
|
60
|
+
bullswarm strategy apply --yes --refresh-hours 24
|
|
61
|
+
bullswarm strategy auto status
|
|
62
|
+
bullswarm strategy set-subscription command-code \
|
|
63
|
+
--plan GOAT --monthly-usd 10 --included-usd 70 --quota-window monthly
|
|
64
|
+
bullswarm strategy assign high --pool claude-code --model claude-opus-4-6
|
|
65
|
+
bullswarm run --effort high --lane analyze --task-file /tmp/task.md --json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Interactive setup asks whether to enable strategy autopilot; non-interactive
|
|
69
|
+
setup requires the explicit `setup --yes --strategy` flag. Recommendations are
|
|
70
|
+
context-filtered before ranking: high requires analysis plus workflow-planning,
|
|
71
|
+
medium requires build/edit capabilities, and low targets bounded chores. An
|
|
72
|
+
approved policy refreshes stale discovery before later runs and re-applies the
|
|
73
|
+
best eligible models on its configured interval. Disable it with
|
|
74
|
+
`strategy auto off --yes`. Discovery commands, model argument syntax, pricing,
|
|
75
|
+
and benchmark declarations remain connector-owned. Unknown license value,
|
|
76
|
+
prices, and benchmarks stay `null` rather than being guessed. An assignment is
|
|
77
|
+
only a preference: quarantine, exhaustion, burst gates, and capability checks
|
|
78
|
+
still win.
|
|
79
|
+
|
|
80
|
+
Every run and workflow attempt reports its selected agent/model and estimated
|
|
81
|
+
usage. When a delegate does not expose counters, Bullswarm labels its UTF-8
|
|
82
|
+
byte/4 token estimate. The breakdown separates standard read, cache read,
|
|
83
|
+
cache write, and output; API-equivalent cost and normalized subscription quota
|
|
84
|
+
remain unknown unless the connector and user-provided subscription data can
|
|
85
|
+
support them. `workflow tui --json <id>` exposes the aggregate and the full
|
|
86
|
+
phase/step/attempt tree.
|
|
87
|
+
|
|
88
|
+
## One-command autonomous goals
|
|
89
|
+
|
|
90
|
+
For normal multi-step work, give Bullswarm the goal—not a JSON graph:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Foreground: streams progress and returns when terminal.
|
|
94
|
+
bullswarm workflow goal \
|
|
95
|
+
"Fix the failing tests with the smallest correct change and verify them" \
|
|
96
|
+
--cwd ~/some-repo
|
|
97
|
+
|
|
98
|
+
# Detached: the initiating CLI exits; the workflow continues independently.
|
|
99
|
+
bullswarm workflow goal \
|
|
100
|
+
"Audit and repair the parser, then run its acceptance tests" \
|
|
101
|
+
--cwd ~/some-repo --detach --json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Bullswarm first honors an approved high-tier provider/model assignment when it
|
|
105
|
+
remains eligible, otherwise it selects an eligible `workflow-planning`
|
|
106
|
+
orchestrator by live quota surplus. The orchestrator observes durable evidence, proposes bounded actions,
|
|
107
|
+
and decides when another expansion or verification is necessary. Bullswarm
|
|
108
|
+
validates the proposal, owns agent/process selection, routes workers, and calls
|
|
109
|
+
the orchestrator again until completion, cancellation, failure, approval, or a
|
|
110
|
+
budget limit. No initial phases, prompts, JSON schema, or agent choice are
|
|
111
|
+
required from the user.
|
|
112
|
+
|
|
113
|
+
The detached response includes a short ID and exact observation commands:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bullswarm workflow runs show <shortId>
|
|
117
|
+
bullswarm workflow tui <shortId> # printable phase/action/attempt tree
|
|
118
|
+
bullswarm workflow tui --json <shortId>
|
|
119
|
+
bullswarm workflow events --json <shortId> --after 0
|
|
120
|
+
bullswarm workflow action show --json <shortId> <actionId>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Resume a process-interrupted autonomous run from its persisted workflow:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
bullswarm workflow goal --resume <shortId> --json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`--orchestrator <pool>` exists for controlled testing; ordinary use should
|
|
130
|
+
leave selection on `auto`. Hard limits can be adjusted with `--max-agents`,
|
|
131
|
+
`--max-expansion-rounds`, `--max-actions`, `--max-items-per-expansion`, and
|
|
132
|
+
`--max-workflow-seconds`. Interactive setup also records a worktree-isolation
|
|
133
|
+
preference (`agent-decides`, `off`, or `required`); Bullswarm communicates that
|
|
134
|
+
policy to the orchestrator without imposing repository topology itself.
|
|
135
|
+
|
|
136
|
+
## Building a workflow from the shell
|
|
137
|
+
|
|
138
|
+
Use an explicit draft when the graph itself is a durable contract and should
|
|
139
|
+
not be planner-defined. `bullswarm workflow draft ...` lets you assemble it one
|
|
140
|
+
mutation at a time. No upfront JSON required. Drafts persist under
|
|
141
|
+
`~/.bullswarm/drafts/<name>/` and become first-class workflows
|
|
142
|
+
(discoverable, runnable by name) the moment they exist.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
bullswarm workflow draft create audit-code \
|
|
146
|
+
--description "Audit the source code" --input targetDir=.
|
|
147
|
+
bullswarm workflow draft phase add audit-code discover
|
|
148
|
+
bullswarm workflow draft phase add audit-code review
|
|
149
|
+
bullswarm workflow draft step add audit-code discover list-files \
|
|
150
|
+
--type run --lane chore --prompt "List every .js file in src/" \
|
|
151
|
+
--addDir '{{inputs.targetDir}}'
|
|
152
|
+
bullswarm workflow draft step add audit-code review per-file \
|
|
153
|
+
--type fanout --items-from 'outputs.list-files.outFile' \
|
|
154
|
+
--lane analyze --concurrency 2 \
|
|
155
|
+
--step-template '{"lane":"analyze","addDir":"{{inputs.targetDir}}","prompt":"Review {{item}}"}'
|
|
156
|
+
bullswarm workflow draft show audit-code # inspect the JSON
|
|
157
|
+
bullswarm workflow draft run audit-code # execute it
|
|
158
|
+
bullswarm workflow draft export audit-code workflows/audit-code.json # promote to file
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`step add` re-validates after every mutation; partial drafts (zero
|
|
162
|
+
phases, etc.) are treated as building, not invalid. `set` and
|
|
163
|
+
`step set` patch fields in place. `delete` requires `--yes`.
|
|
164
|
+
|
|
165
|
+
## Operating on workflow runs
|
|
166
|
+
|
|
167
|
+
Every run gets a 6-character shortId (Crockford-style alphabet,
|
|
168
|
+
no `0/1/i/l/o`). The full `wf-...` runId stays the durable handle.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
bullswarm workflow runs # ongoing only (default)
|
|
172
|
+
bullswarm workflow runs --all # ongoing + historical
|
|
173
|
+
bullswarm workflow runs --historical # only historical
|
|
174
|
+
bullswarm workflow runs --name audit-code # filter by workflow
|
|
175
|
+
bullswarm workflow runs --limit 20 # cap the result count
|
|
176
|
+
bullswarm workflow runs show <shortId> # state + report + summary
|
|
177
|
+
bullswarm runs show <shortId> # top-level shorthand
|
|
178
|
+
bullswarm workflow runs delete <shortId> --yes # remove the run dir
|
|
179
|
+
|
|
180
|
+
# Resume by shortId — runs the same logic as the full runId
|
|
181
|
+
bullswarm workflow run audit-code --resume <shortId>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Live workflow dashboard
|
|
185
|
+
|
|
186
|
+
`workflow tui` is the interactive, Claude-style `/workflows` view. It watches
|
|
187
|
+
ongoing runs from disk and supports `j`/`k` or arrow-key selection, Enter for
|
|
188
|
+
details, `c` to request a cooperative stop, `r` to refresh, and `q` to quit.
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
bullswarm workflow tui
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The same dashboard is agent-friendly and never requires a TTY when used with
|
|
195
|
+
JSON/control flags:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
bullswarm workflow tui --json # ongoing dashboard rows
|
|
199
|
+
bullswarm workflow tui --json --all # ongoing + historical runs
|
|
200
|
+
bullswarm workflow tui --json <shortId> # inspect one run
|
|
201
|
+
bullswarm workflow tui --json --cancel <id> # request cooperative stop
|
|
202
|
+
bullswarm workflow capabilities --json # pools, lanes, models, meters, limits
|
|
203
|
+
bullswarm workflow inspect <file-or-name> # workflow shape and semantics
|
|
204
|
+
bullswarm workflow events --json <id> --after 20
|
|
205
|
+
bullswarm workflow action show --json <id> <actionId>
|
|
206
|
+
bullswarm workflow approval approve --json <id> # then resume the run
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Cancellation is persisted as `cancelling`, terminates an active child process,
|
|
210
|
+
records its termination signal and latency evidence, then commits `cancelled`.
|
|
211
|
+
`SIGTERM` and `SIGINT` use the same cooperative child termination path but
|
|
212
|
+
commit a distinct resumable `interrupted` state. On every workflow command,
|
|
213
|
+
active states with a dead/stale owner are automatically reconciled to
|
|
214
|
+
`interrupted` instead of remaining falsely `running`.
|
|
215
|
+
|
|
216
|
+
Each attempt records the phase/action, selected pool and model, effort tier,
|
|
217
|
+
routing reason, all eligible candidates with quota surplus, timestamps,
|
|
218
|
+
artifact paths, outcome, and reported-or-estimated token/cost/quota usage.
|
|
219
|
+
`workflow tui <id>` renders this breakdown for completed runs as well as live
|
|
220
|
+
ones; `workflow tui --json <id>` exposes the durable audit document.
|
|
221
|
+
|
|
222
|
+
### Adaptive workflows
|
|
223
|
+
|
|
224
|
+
Static workflows remain zero-extra-LLM orchestration. An adaptive workflow adds
|
|
225
|
+
an explicit `decide` step and hard limits:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"mode": "adaptive",
|
|
230
|
+
"settings": {
|
|
231
|
+
"maxAgents": 12,
|
|
232
|
+
"maxExpansionRounds": 3,
|
|
233
|
+
"maxActions": 20,
|
|
234
|
+
"maxItemsPerExpansion": 8,
|
|
235
|
+
"maxWorkflowSeconds": 1800
|
|
236
|
+
},
|
|
237
|
+
"phases": [{
|
|
238
|
+
"name": "review",
|
|
239
|
+
"steps": [
|
|
240
|
+
{ "id": "initial", "type": "run", "prompt": "Inspect the code." },
|
|
241
|
+
{
|
|
242
|
+
"id": "planner",
|
|
243
|
+
"type": "decide",
|
|
244
|
+
"requiresCapabilities": ["workflow-planning", "strong-analysis"],
|
|
245
|
+
"prompt": "Judge sufficiency and propose only bounded missing work."
|
|
246
|
+
}
|
|
247
|
+
]
|
|
248
|
+
}]
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The planner returns versioned JSON. It may propose `needs_more_work` with
|
|
253
|
+
bounded `run`, inline-`fanout`, or `verify` actions. The deterministic runtime
|
|
254
|
+
validates IDs, dependencies, operation types, capabilities, and budgets before
|
|
255
|
+
appending anything. It executes ready actions, observes their durable results,
|
|
256
|
+
and calls the planner again. `events.jsonl`, `state.json`, the TUI, and JSON
|
|
257
|
+
inspection expose the same plan, actions, attempts, decisions, budgets, and
|
|
258
|
+
artifacts. See `workflows/adaptive-code-review.json` for a complete example.
|
|
259
|
+
Planner actions cannot set `pool`, `addDir`, or `taskFile`. If those need to be
|
|
260
|
+
fixed by the initiator, declare them under the `decide` step's `actionDefaults`;
|
|
261
|
+
otherwise eligible capable pools are ranked by live quota surplus.
|
|
45
262
|
|
|
46
263
|
## The verdict
|
|
47
264
|
|