bullswarm 0.23.2 → 0.24.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/CHANGELOG.md +120 -0
- package/README.md +74 -15
- package/data/openrouter-benchmarks.json +14907 -14176
- package/docs/claude-dynamic-workflow-mechanics.md +9 -4
- package/docs/design/2026-09-06-caller-first-cli.md +173 -0
- package/docs/experiments/2026-09-06-caller-planner-evaluation.md +257 -0
- package/package.json +1 -1
- package/skill/SKILL.md +90 -4
- package/skill/references/operations.md +79 -9
- package/src/delegate.js +44 -5
- package/src/help.js +201 -17
- package/src/workflow/cli.js +786 -74
- package/src/workflow/dashboard.js +18 -1
- package/src/workflow/goal.js +18 -2
- package/src/workflow/ledger.js +34 -3
- package/src/workflow/runs-cli.js +4 -1
- package/src/workflow/steering.js +13 -2
- package/src/workflow/v2-planner.js +177 -11
- package/src/workflow/v2-runtime.js +259 -4
- package/src/workflow/v2-state.js +36 -3
- package/src/workflow/watch-cli.js +24 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,125 @@
|
|
|
1
1
|
# bullswarm changelog
|
|
2
2
|
|
|
3
|
+
## 0.24.0 — the calling agent is the Workflow Planner
|
|
4
|
+
|
|
5
|
+
**BREAKING.** `bullswarm workflow goal` now needs a program. Add
|
|
6
|
+
`--orchestrator auto` to any existing invocation to keep the previous
|
|
7
|
+
behaviour, or pass the program you authored with `--program <file.json>`.
|
|
8
|
+
|
|
9
|
+
- **Caller-first by default.** `workflow goal "<goal>"` with no
|
|
10
|
+
`--program`, `--scout`, or `--orchestrator` exits 2, launches nothing, and
|
|
11
|
+
prints the commands that come next (`{"error": "program-required", "next":
|
|
12
|
+
{contract, validate, launch, scout, orchestrator}}` under `--json`). The
|
|
13
|
+
kernel never plans on the caller's behalf unless the caller asks for it by
|
|
14
|
+
name. Exit codes are a contract: 0 done or paused durably for the caller
|
|
15
|
+
(nothing running), 1 the run ended without completing, 2 usage or validation
|
|
16
|
+
error with nothing launched.
|
|
17
|
+
|
|
18
|
+
- `bullswarm workflow goal --program <file.json>` makes the invoking agent the
|
|
19
|
+
Workflow Planner. The kernel validates the caller-authored V2 program against
|
|
20
|
+
the exact requirement ledger before anything launches, executes it with zero
|
|
21
|
+
planner and (by default) zero scout dispatches, and keeps every kernel-owned
|
|
22
|
+
guarantee: quota routing, isolated worktrees and changed-path ownership,
|
|
23
|
+
independent evidence, the requirement ledger, completion, and the stable
|
|
24
|
+
result envelope. This is Bullswarm's equivalent of Claude Code's `Workflow`
|
|
25
|
+
tool: the frontier model writes the program once and is consulted again only
|
|
26
|
+
at a real planning boundary. `--scout` alone has the kernel survey the
|
|
27
|
+
repository first and pause at the initial boundary for the caller's program.
|
|
28
|
+
|
|
29
|
+
- **Flag surface.** `--planner dispatched|caller` is removed; the presence of
|
|
30
|
+
`--orchestrator auto|<pool>` is the switch. `--strict-orchestrator <pool>`
|
|
31
|
+
becomes `--orchestrator <pool> --orchestrator-strict` and remains as a
|
|
32
|
+
deprecated alias for one release. `--suggested-plan`, `--no-scout`,
|
|
33
|
+
`--orchestrator-model`, and `--orchestrator-strict` are rejected without
|
|
34
|
+
`--orchestrator`: when the caller is the planner, the plan is the program.
|
|
35
|
+
|
|
36
|
+
- **New commands.** `workflow plan validate "<goal>" --program <file>` dry-runs
|
|
37
|
+
a program against the contract (same validator, same preview state, no run
|
|
38
|
+
created) and exits 0 with the accepted actions or 2 with the issues.
|
|
39
|
+
`workflow cancel <runId>` is a first-class verb that finalizes a run paused
|
|
40
|
+
for its caller planner inline, and `workflow resume <runId>` is the verb form
|
|
41
|
+
of `goal --resume`; `goal --resume` and `tui --cancel` remain as aliases.
|
|
42
|
+
|
|
43
|
+
- **`delegate`.** For workflow-shaped work it now returns the planning contract
|
|
44
|
+
(`action: "plan-required"`) plus the exact launch line, instead of launching
|
|
45
|
+
an orchestrated run on the caller's behalf. `--orchestrator auto|<pool>`
|
|
46
|
+
passes through for callers that do not want to plan.
|
|
47
|
+
|
|
48
|
+
- **Requirement granularity is surfaced, never forced.** When a goal collapses
|
|
49
|
+
to a single requirement, `plan contract` adds an `advice.requirements` line
|
|
50
|
+
and `delegate` adds the same text to its `handoff` (printed as
|
|
51
|
+
`Requirements ·`): one requirement means one pass/fail verdict for the whole
|
|
52
|
+
goal, and any gap reopens all of it, so numbering distinct deliverables
|
|
53
|
+
(`1. ... 2. ...`) buys a tracked requirement, a separate verdict, and gap
|
|
54
|
+
rounds scoped to the part that failed. A goal that already splits into
|
|
55
|
+
several requirements never carries the advice, and the text says explicitly
|
|
56
|
+
not to invent clauses to split a genuinely holistic outcome.
|
|
57
|
+
|
|
58
|
+
- New `bullswarm workflow plan` surface: `plan contract "<goal>"` prints the
|
|
59
|
+
requirement IDs the kernel will derive, the planning rules, the generic action
|
|
60
|
+
fields, the validation it enforces, and a worked example; `plan show <run>`
|
|
61
|
+
prints the durable planner request a paused run left behind (boundary,
|
|
62
|
+
context, consolidated gaps, known actions); `plan submit <run> --program
|
|
63
|
+
<file>` (or `--exhausted --reason <text>`) validates the response against the
|
|
64
|
+
exact durable state, records it as the next program revision with the same
|
|
65
|
+
counters a dispatched planner turn would produce (planner turn, expansion
|
|
66
|
+
round, program revision) plus a `planner.finished` event tagged
|
|
67
|
+
`source: "caller"` (no `planner.started` and no planner attempt is recorded,
|
|
68
|
+
because nothing was dispatched), and relaunches the kernel.
|
|
69
|
+
|
|
70
|
+
- Caller-planner pauses are authoritative and lossless. A resume without a
|
|
71
|
+
submission re-pauses on the same boundary and turn, even when steering was
|
|
72
|
+
queued meanwhile: the request is refreshed to list the pending steering
|
|
73
|
+
(`pendingSteering`), `plan show` does the same refresh, and a submission
|
|
74
|
+
marks exactly the listed steering delivered; steering queued after that stays
|
|
75
|
+
pending and opens a steering boundary after the resume. A cancellation
|
|
76
|
+
requested while paused refuses every submission and `plan show`, `watch`, and
|
|
77
|
+
the TUI point at the one `workflow goal --resume` that finalizes the
|
|
78
|
+
cancelled result; finalizing always clears the pause record, and the state
|
|
79
|
+
validator rejects a terminal run that still claims to be waiting. A caller
|
|
80
|
+
program supplied at launch is kept in the run directory until applied, so an
|
|
81
|
+
interruption during an opt-in scout does not lose it. Bare value flags
|
|
82
|
+
(`--program` with no file) are usage errors instead of a silent
|
|
83
|
+
dispatched-mode launch, and `plan submit` checks the goal directory before
|
|
84
|
+
touching state.
|
|
85
|
+
|
|
86
|
+
- Caller-planner runs pause durably instead of dispatching: at a planning
|
|
87
|
+
boundary the kernel writes `planner-request-turn-N.json`, records
|
|
88
|
+
`planner.awaiting` in state, emits `planner.awaiting_caller`, sets the run to
|
|
89
|
+
`waiting`, and exits. `workflow watch` ends at that pause (exit 0) and prints
|
|
90
|
+
the `plan show` command; `runs result` and the TUI Next line explain the
|
|
91
|
+
pause; resuming without a submission re-pauses on the same request. An
|
|
92
|
+
invalid initial program supplied through `--program` at launch is rejected
|
|
93
|
+
synchronously; one that fails only against live state pauses with a
|
|
94
|
+
correction request instead of dispatching anything.
|
|
95
|
+
|
|
96
|
+
- The dispatched planner prompt and the caller-facing contract now render from
|
|
97
|
+
one shared rulebook (`v2PlannerContractRules`), so the two planning modes
|
|
98
|
+
cannot drift. A durable `exhausted` planner decision now survives resume: the
|
|
99
|
+
kernel finalizes the partial result instead of reopening the boundary.
|
|
100
|
+
|
|
101
|
+
- `workflow capabilities` reports `plannerModes` and the `callerPlanner`
|
|
102
|
+
feature; the `bullswarm` skill and operations reference document the
|
|
103
|
+
caller-planner loop for frontier agents.
|
|
104
|
+
|
|
105
|
+
- Fixed (ledger): evidence records now carry the ledger-wide `workspaceRevision`
|
|
106
|
+
they inspected, and semantic evidence recorded on a newer workspace
|
|
107
|
+
supersedes older evidence for the same requirement (`stale: true`,
|
|
108
|
+
`staleReason: "workspace-superseded"`). Before, a cross-cutting requirement
|
|
109
|
+
such as "the full suite passes 19/19" kept its first failed verdict alive
|
|
110
|
+
forever, because no work action listed it in `affects`; a later passing
|
|
111
|
+
verdict then conflicted with it and the requirement stayed `blocked` on every
|
|
112
|
+
gap round. Same-workspace disagreement between two verifiers still blocks,
|
|
113
|
+
and a mechanical (pending) record never supersedes a judgment. Found live
|
|
114
|
+
while driving a caller-planner run.
|
|
115
|
+
|
|
116
|
+
- Fixed: a one-line goal with inline numbered clauses (`"1. Fix the parser.
|
|
117
|
+
2. Update the docs."`) produced a single requirement; only the
|
|
118
|
+
newline-separated form split. Both forms now yield one requirement per
|
|
119
|
+
clause, so `plan contract` advertises the IDs the run will enforce. Inline
|
|
120
|
+
markers are honored only when the list starts at 1, so prose such as
|
|
121
|
+
"version 2. Then" is not split.
|
|
122
|
+
|
|
3
123
|
## 0.22.1 — unified workflow dashboard navigation
|
|
4
124
|
|
|
5
125
|
- The workflow dashboard now keeps V2 runs in the unified list and timeline
|
package/README.md
CHANGED
|
@@ -79,7 +79,9 @@ bullswarm delegate --cwd ~/some-repo --prompt "Audit all commands, fix help, and
|
|
|
79
79
|
bullswarm delegate --dry-run --json --cwd ~/some-repo --prompt "Your task" # bounded classification + decision/plan; no work dispatch
|
|
80
80
|
bullswarm run --lane analyze --add-dir ~/some-repo --task-file /tmp/t.md --json
|
|
81
81
|
bullswarm run --lane analyze --add-dir ~/some-repo --prompt "Inspect the parser" --json
|
|
82
|
-
bullswarm workflow
|
|
82
|
+
bullswarm workflow plan contract "Fix the failing tests and verify the change" --cwd ~/some-repo --json # you are the planner
|
|
83
|
+
bullswarm workflow goal "Fix the failing tests and verify the change" --cwd ~/some-repo --program plan.json
|
|
84
|
+
bullswarm workflow goal "Fix the failing tests and verify the change" --cwd ~/some-repo --orchestrator auto # dispatch a planner agent
|
|
83
85
|
bullswarm health # re-judge saved outputs; catch gate failures
|
|
84
86
|
```
|
|
85
87
|
|
|
@@ -89,7 +91,7 @@ bullswarm health # re-judge saved outputs; catch gate failures
|
|
|
89
91
|
|---|---|
|
|
90
92
|
| `setup` | Discover installed agent CLIs, show quota state, toggle pools, suggest a routing table, write config. Approval-gated, idempotent. |
|
|
91
93
|
| `integrate` | Register or remove the canonical Bullswarm skill and global awareness rules for Codex, Claude, and Grok. |
|
|
92
|
-
| `delegate` | Explain and execute the smallest reliable shape: one content-verified agent or an autonomous
|
|
94
|
+
| `delegate` | Explain and execute the smallest reliable shape: one content-verified agent, or the planning contract for an autonomous workflow you author (`--orchestrator` dispatches a planner agent instead). |
|
|
93
95
|
| `run` | route → dispatch → watch → verify → one JSON verdict |
|
|
94
96
|
| `health` | Re-judge saved outputs against their verdicts; surface verify-gate failures and quarantine clusters |
|
|
95
97
|
| `pools` | Show each pool's meter state, pace position, quarantine status |
|
|
@@ -226,20 +228,32 @@ phase/step/attempt tree.
|
|
|
226
228
|
|
|
227
229
|
## One-command autonomous goals
|
|
228
230
|
|
|
229
|
-
For normal multi-step work, give Bullswarm the goal
|
|
231
|
+
For normal multi-step work, give Bullswarm the goal and the program you authored
|
|
232
|
+
for it—not a JSON graph of phases:
|
|
230
233
|
|
|
231
234
|
```bash
|
|
232
|
-
#
|
|
235
|
+
# 1. What the kernel will enforce: requirement IDs, rules, action schema, example.
|
|
236
|
+
bullswarm workflow plan contract \
|
|
237
|
+
"1. Fix the failing tests with the smallest correct change. 2. Verify them." \
|
|
238
|
+
--cwd ~/some-repo --json
|
|
239
|
+
|
|
240
|
+
# 2. Launch with your program. Starts independently, prints observation
|
|
241
|
+
# commands, and returns. Add --watch to follow low-noise progress.
|
|
233
242
|
bullswarm workflow goal \
|
|
234
|
-
"Fix the failing tests with the smallest correct change
|
|
235
|
-
--cwd ~/some-repo
|
|
243
|
+
"1. Fix the failing tests with the smallest correct change. 2. Verify them." \
|
|
244
|
+
--cwd ~/some-repo --program plan.json --watch
|
|
236
245
|
|
|
237
|
-
#
|
|
246
|
+
# Don't want to plan? Ask for a Workflow Planner agent explicitly.
|
|
238
247
|
bullswarm workflow goal \
|
|
239
248
|
"Audit and repair the parser, then run its acceptance tests" \
|
|
240
|
-
--cwd ~/some-repo --watch
|
|
249
|
+
--cwd ~/some-repo --orchestrator auto --watch
|
|
241
250
|
```
|
|
242
251
|
|
|
252
|
+
`workflow goal` needs a program: with neither `--program`, `--scout`, nor
|
|
253
|
+
`--orchestrator` it exits 2, launches nothing, and prints the commands above.
|
|
254
|
+
That is deliberate — the kernel never plans on the caller's behalf unless the
|
|
255
|
+
caller asks for it by name.
|
|
256
|
+
|
|
243
257
|
`--max-agents`, `--max-actions`, and `--max-expansion-rounds` are soft V2
|
|
244
258
|
planning targets. They encourage the Workflow Planner to consolidate optional
|
|
245
259
|
work, but the kernel never stops or rejects essential work merely because a
|
|
@@ -286,25 +300,30 @@ bullswarm workflow events --json <shortId> --after 0
|
|
|
286
300
|
bullswarm workflow action show --json <shortId> <actionId>
|
|
287
301
|
```
|
|
288
302
|
|
|
289
|
-
|
|
303
|
+
Manage a run with first-class verbs:
|
|
290
304
|
|
|
291
305
|
```bash
|
|
292
|
-
bullswarm workflow
|
|
306
|
+
bullswarm workflow steer <shortId> --message "<guidance>" # next planning boundary
|
|
307
|
+
bullswarm workflow cancel <shortId> --json # a paused run is finalized here
|
|
308
|
+
bullswarm workflow resume <shortId> --watch # verb form of goal --resume
|
|
293
309
|
```
|
|
294
310
|
|
|
295
311
|
`--orchestrator <pool>` expresses a preference and immediately falls back to
|
|
296
|
-
another eligible pool if that provider is quota-gated or unavailable
|
|
297
|
-
|
|
298
|
-
`--strict
|
|
299
|
-
available. Controlled comparisons can additionally pin the exact planner
|
|
312
|
+
another eligible pool if that provider is quota-gated or unavailable; plain
|
|
313
|
+
`--orchestrator auto` leaves selection to the kernel. For controlled provider
|
|
314
|
+
QA only, add `--orchestrator-strict` to require that exact pool and fail if it
|
|
315
|
+
is not available. Controlled comparisons can additionally pin the exact planner
|
|
300
316
|
and worker routes without changing global strategy:
|
|
301
317
|
|
|
302
318
|
```bash
|
|
303
319
|
bullswarm workflow goal "Implement and verify the change" --cwd . \
|
|
304
|
-
--
|
|
320
|
+
--orchestrator codex --orchestrator-strict --orchestrator-model gpt-5.6-sol \
|
|
305
321
|
--worker-pool opencode2 --worker-model kaihk/gpt-5.6-luna
|
|
306
322
|
```
|
|
307
323
|
|
|
324
|
+
These pins, plus `--suggested-plan` and `--no-scout`, apply only with
|
|
325
|
+
`--orchestrator`. When you are the planner, the plan is the program.
|
|
326
|
+
|
|
308
327
|
The worker lock covers scout, work actions, and evidence actions. A pool that cannot guarantee
|
|
309
328
|
the requested model is ineligible rather than silently substituting another
|
|
310
329
|
model.
|
|
@@ -333,6 +352,46 @@ writers and still enforces the changed-path boundary.
|
|
|
333
352
|
|
|
334
353
|
## Building a workflow from the shell
|
|
335
354
|
|
|
355
|
+
### You are the planner: `--program` and `workflow plan`
|
|
356
|
+
|
|
357
|
+
This is the default. The calling agent (Claude Code, Codex, or any frontier
|
|
358
|
+
model with the repository in context) is the Workflow Planner, instead of the
|
|
359
|
+
kernel paying for a dispatched scout and planner that cannot see the
|
|
360
|
+
conversation. The kernel keeps everything it owns — proposal validation, quota
|
|
361
|
+
routing, isolated worktrees and changed-path ownership, independent evidence,
|
|
362
|
+
the requirement ledger, completion, and the stable result envelope — while the
|
|
363
|
+
caller supplies the program, exactly the division of labour Claude Code's
|
|
364
|
+
`Workflow` tool uses between the authoring model and its harness.
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
bullswarm workflow plan contract "1. Fix the parser. 2. Update the docs." --cwd . --json
|
|
368
|
+
# → requirement IDs (requirement-1..n), rules, action fields, validation, example
|
|
369
|
+
bullswarm workflow plan validate "1. Fix the parser. 2. Update the docs." --cwd . --program plan.json --json
|
|
370
|
+
# → dry run against that contract; exit 0 valid, exit 2 with the issues; nothing launches
|
|
371
|
+
bullswarm workflow goal "1. Fix the parser. 2. Update the docs." --cwd . --program plan.json --watch
|
|
372
|
+
# → validated before launch; executes with zero planner/scout dispatches
|
|
373
|
+
bullswarm workflow plan show <shortId> --json # when the run pauses at a gap boundary
|
|
374
|
+
bullswarm workflow plan submit <shortId> --program plan-2.json --watch
|
|
375
|
+
bullswarm workflow plan submit <shortId> --exhausted --reason "<why no bounded action remains>"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Exit codes are a contract: **0** done or paused durably for you (nothing is
|
|
379
|
+
running), **1** the run ended without completing, **2** usage or validation
|
|
380
|
+
error with nothing launched. Every refusal names the commands that come next.
|
|
381
|
+
|
|
382
|
+
`--program` accepts the planner response envelope or a bare
|
|
383
|
+
`bullswarm.workflow.program.v2` document. An invalid program exits 2 with the
|
|
384
|
+
validator's issues and nothing is launched. When the kernel reaches a planning
|
|
385
|
+
boundary it does not guess: it writes `planner-request-turn-N.json` (the same
|
|
386
|
+
context a dispatched planner would receive, plus the consolidated gaps and any
|
|
387
|
+
queued steering), sets the run to `waiting`, exits, and `watch` prints the
|
|
388
|
+
`plan show` command. A submitted program contains only new actions and is
|
|
389
|
+
validated against the exact durable state at that boundary; `--exhausted`
|
|
390
|
+
finalizes a partial result with its gaps disclosed. `--scout` without
|
|
391
|
+
`--program` runs the kernel scout first and pauses at the initial boundary so
|
|
392
|
+
the caller plans against a real survey; scout units are advisory for a caller
|
|
393
|
+
planner.
|
|
394
|
+
|
|
336
395
|
Use an explicit draft when the graph itself is a durable contract and should
|
|
337
396
|
not be planner-defined. `bullswarm workflow draft ...` lets you assemble it one
|
|
338
397
|
mutation at a time. No upfront JSON required. Drafts persist under
|