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 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 goal "Fix the failing tests and verify the change" --cwd ~/some-repo
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 verified workflow. |
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—not a JSON graph:
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
- # Default: starts independently, prints observation/result commands, and returns.
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 and verify them" \
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
- # Follow low-noise semantic progress immediately after launch.
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
- Resume a process-interrupted autonomous run from its persisted workflow:
303
+ Manage a run with first-class verbs:
290
304
 
291
305
  ```bash
292
- bullswarm workflow goal --resume <shortId> --json
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. Ordinary
297
- use can leave selection on `auto`. For controlled provider QA only,
298
- `--strict-orchestrator <pool>` requires that exact pool and fails if it is not
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
- --strict-orchestrator codex --orchestrator-model gpt-5.6-sol \
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