bullswarm 0.20.0 → 0.22.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 +100 -1
- package/README.md +104 -54
- package/bin/check-v2-evidence.js +26 -0
- package/bin/check-v2-plan.js +36 -0
- package/connectors/opencode2.json +3 -2
- package/docs/dynamic-workflow-v2-execution-plan.md +825 -0
- package/docs/experiments/2026-08-29-dogfood-bullswarm-builds-bullswarm.md +189 -0
- package/docs/experiments/2026-08-31-v2-component-probes.md +52 -0
- package/docs/integration-audit-2026-08-31.md +411 -0
- package/package.json +1 -1
- package/skill/SKILL.md +13 -5
- package/skill/references/operations.md +11 -4
- package/src/cli.js +23 -8
- package/src/delegate.js +120 -3
- package/src/help.js +58 -43
- package/src/lib/opencode-kaihk.js +16 -4
- package/src/lib/run-heartbeat.js +59 -0
- package/src/lib/watch.js +34 -0
- package/src/workflow/action-validator.js +411 -0
- package/src/workflow/cli.js +124 -162
- package/src/workflow/dashboard.js +827 -145
- package/src/workflow/draft-cli.js +2 -2
- package/src/workflow/events.js +8 -3
- package/src/workflow/evidence-output.js +187 -0
- package/src/workflow/goal.js +24 -162
- package/src/workflow/ledger.js +261 -0
- package/src/workflow/ownership.js +133 -0
- package/src/workflow/runner.js +9 -24
- package/src/workflow/runs-cli.js +44 -1
- package/src/workflow/short-id.js +6 -2
- package/src/workflow/status.js +2 -1
- package/src/workflow/steering.js +7 -4
- package/src/workflow/tui.js +30 -7
- package/src/workflow/v2-dispatch.js +277 -0
- package/src/workflow/v2-outcome.js +288 -0
- package/src/workflow/v2-planner.js +259 -0
- package/src/workflow/v2-presentation.js +50 -0
- package/src/workflow/v2-runtime.js +797 -0
- package/src/workflow/v2-scheduler.js +159 -0
- package/src/workflow/v2-state.js +578 -0
- package/src/workflow/v2-workspace.js +103 -0
- package/src/workflow/watch-cli.js +62 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,111 @@
|
|
|
1
1
|
# bullswarm changelog
|
|
2
2
|
|
|
3
|
+
## 0.22.0 — autonomous Dynamic Workflow V2
|
|
4
|
+
|
|
5
|
+
- Autonomous goals now run on the V2 kernel: agents propose bounded programs
|
|
6
|
+
and requirement-scoped evidence, while Bullswarm deterministically owns
|
|
7
|
+
proposal validation, scheduling, workspace ownership, retries, the evidence
|
|
8
|
+
ledger, completion, and the stable result envelope. Retired autonomous V1
|
|
9
|
+
runs are intentionally not migrated; authored graph workflows remain a
|
|
10
|
+
separate supported engine.
|
|
11
|
+
|
|
12
|
+
- Worker and evidence contracts now use durable candidate files plus local
|
|
13
|
+
schema validators, preventing malformed agent output from entering workflow
|
|
14
|
+
state. Public V2 results are atomically published, recoverable after an
|
|
15
|
+
interrupted terminal write, deeply validated when read, and expose only a
|
|
16
|
+
stable failure summary shape.
|
|
17
|
+
|
|
18
|
+
- The interactive workflow application now combines the workflow list and
|
|
19
|
+
responsive run browser. Its main view presents a phase-aware timeline,
|
|
20
|
+
Workflow Planner milestones, live workers with their latest streamed event,
|
|
21
|
+
and a concise next action; technical prompts, sessions, usage, and artifact
|
|
22
|
+
paths remain available on demand. Narrow/mobile terminals use the same
|
|
23
|
+
hierarchy without requiring a separate command surface.
|
|
24
|
+
|
|
25
|
+
- `bullswarm run --heartbeat` and the default workflow watch provide compact,
|
|
26
|
+
interval-based progress instead of streaming raw agent output. Rich help and
|
|
27
|
+
the packaged agent skill document how to inspect, watch, browse, and obtain a
|
|
28
|
+
stable terminal result.
|
|
29
|
+
|
|
30
|
+
- Autonomous V2 `maxAgents`, `maxActions`, and `maxExpansionRounds` are now
|
|
31
|
+
soft planning targets instead of hard termination or proposal-rejection
|
|
32
|
+
limits. The planner sees usage and remaining-target signals and is urged to
|
|
33
|
+
consolidate optional work, while the kernel continues the smallest essential
|
|
34
|
+
program past a target. `concurrency` remains an execution bound on
|
|
35
|
+
simultaneous work, not on the total program size.
|
|
36
|
+
|
|
37
|
+
- OpenCode event-stream failures are now classified as transient provider
|
|
38
|
+
interruptions before structured-output validation runs. A recoverable
|
|
39
|
+
transport or schema attempt is recorded as `interrupted` while Bullswarm
|
|
40
|
+
performs its bounded mechanical retry; only an unrecovered final attempt is
|
|
41
|
+
recorded as `failed`, keeping provider instability distinct from agent work
|
|
42
|
+
rejection.
|
|
43
|
+
|
|
44
|
+
## 0.21.0 — unified TUI shell and LLM-first delegation
|
|
45
|
+
|
|
46
|
+
- The interactive workflow viewer is now one application shell instead of
|
|
47
|
+
several screens with their own rules. The workflows list, a run, a phase and
|
|
48
|
+
an agent are four depths of one hierarchy: every screen carries the same
|
|
49
|
+
persistent breadcrumb at the top (`Workflows › hdtdxs · timeline-segments ›
|
|
50
|
+
Verify › verify-renderer`), which drops its deepest segments first when the
|
|
51
|
+
terminal is too narrow to hold the whole path. All four depths share key
|
|
52
|
+
bindings generated from a single key-map definition: Up/Down (or k/j) move
|
|
53
|
+
within the current level, Enter and Right (or l) go one level in, Esc and
|
|
54
|
+
Left (or h) go one level out, and Tab/Shift+Tab jump to the next or previous
|
|
55
|
+
workflow, re-entering the sibling at the same depth when the equivalent phase
|
|
56
|
+
exists. The drill-down layout is uniform too — a left sidebar listing the
|
|
57
|
+
current level beside a right pane previewing the highlighted item — at every
|
|
58
|
+
depth and on narrow terminals as well, including the run list, which was a
|
|
59
|
+
full-width table with no preview pane before.
|
|
60
|
+
|
|
61
|
+
- Workflow timelines now render in phase-segmented sections with continued
|
|
62
|
+
headers for interleaved phases, grouped Preflight scout/planner milestones,
|
|
63
|
+
elapsed or running phase state, and consistent desktop, narrow, and scroll
|
|
64
|
+
continuation behavior without per-line phase prefixes. Phase-completion
|
|
65
|
+
summary rows are retained, so rows such as `└─✓ completed 4/4` remain visible
|
|
66
|
+
beneath their phase headers.
|
|
67
|
+
|
|
68
|
+
- Non-interactive `workflow tui <run-id>` output now includes the same static
|
|
69
|
+
segmented timeline as the interactive viewer, alongside the historical detail
|
|
70
|
+
tree, so real command output can be used to inspect and verify the layout.
|
|
71
|
+
|
|
72
|
+
- Documentation now describes concerns as an attribute of a completed
|
|
73
|
+
outcome — `outcome.concerns` on a delivered result — rather than
|
|
74
|
+
presenting `completed_with_concerns` as its own terminal status to handle
|
|
75
|
+
separately from `completed`. Run records that carry the
|
|
76
|
+
`completed_with_concerns` status value, including legacy runs recorded
|
|
77
|
+
before this framing, remain fully readable: `runs result`, the TUI, and
|
|
78
|
+
`workflow watch` still read it exactly like `completed` — a delivered
|
|
79
|
+
result with concerns to review, never a failure.
|
|
80
|
+
|
|
81
|
+
- Delegation classification now starts with deterministic signals and, in
|
|
82
|
+
automatic execution, lets an LLM refine the choice between a single delegate
|
|
83
|
+
and a workflow. `--dry-run` performs that same bounded low-effort
|
|
84
|
+
classification request (one analyze-lane, low-effort dispatch) before
|
|
85
|
+
printing the plan, so the preview matches what a live run would decide — it
|
|
86
|
+
never dispatches the work itself. `--classify deterministic` bypasses that
|
|
87
|
+
refinement and remains the instant, no-dispatch preview; `--classify llm`
|
|
88
|
+
requires the refinement and fails if no usable LLM decision is available.
|
|
89
|
+
An explicit `--mode single|workflow` remains the caller's choice and bypasses
|
|
90
|
+
automatic LLM classification.
|
|
91
|
+
|
|
92
|
+
- OpenCode connector portability: `connectors/opencode2.json` no longer
|
|
93
|
+
hardcodes `--model kaihk/gpt-5.6-luna` in `spawn.cmd`. A plain OpenCode
|
|
94
|
+
install with no KaiHK provider configured now dispatches with OpenCode's
|
|
95
|
+
own default model instead of failing to resolve a KaiHK-only model.
|
|
96
|
+
`src/lib/opencode-kaihk.js` still injects the explicit
|
|
97
|
+
`--model <providerId>/gpt-5.6-luna` for each discovered KaiHK provider, so
|
|
98
|
+
the primary `opencode2` pool and any extra `opencode2:<id>` pools keep
|
|
99
|
+
dispatching with their pinned per-provider model exactly as before.
|
|
100
|
+
|
|
3
101
|
## 0.20.0 — common agent delegation entry point
|
|
4
102
|
|
|
5
103
|
- `/bullswarm` and `bullswarm delegate` now give agents one transparent entry
|
|
6
104
|
point for arbitrary self-contained tasks: classify the request as one bounded
|
|
7
105
|
delegate or an autonomous workflow, show the reason and conceptual plan, then
|
|
8
106
|
execute the selected engine. Explicit mode and lane overrides remain
|
|
9
|
-
available, and `--dry-run --json` exposes the decision
|
|
107
|
+
available, and `--dry-run --json` exposes the decision after its bounded
|
|
108
|
+
classification request without dispatching the work itself.
|
|
10
109
|
- Workflow decisions persist the suggested conceptual plan alongside the
|
|
11
110
|
original intent, while the packaged skill keeps the common path concise and
|
|
12
111
|
moves operational detail into a focused reference.
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# bullswarm
|
|
2
2
|
|
|
3
|
-
Route work across coding-agent CLIs. For a goal, Bullswarm
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Route work across coding-agent CLIs. For a goal, Bullswarm chooses a capable
|
|
4
|
+
Workflow Planner, validates its bounded generic action program, routes work and
|
|
5
|
+
evidence agents by quota, and computes completion from a durable requirement
|
|
6
|
+
ledger without an initiating agent authoring a graph.
|
|
6
7
|
Every delegate output is judged by content before it counts.
|
|
7
8
|
|
|
8
9
|
For agents, `/bullswarm` (or `$bullswarm` where skills use that syntax) is the
|
|
@@ -22,11 +23,12 @@ bullswarm workflow draft step add --help
|
|
|
22
23
|
`workflow goal` launches a durable background runner, prints operating commands,
|
|
23
24
|
and returns by default. Add `--watch` to immediately follow low-noise progress
|
|
24
25
|
until terminal, or `--foreground` to keep execution owned by the initiating
|
|
25
|
-
terminal. Open the
|
|
26
|
-
`bullswarm workflow tui <shortId
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
terminals
|
|
26
|
+
terminal. Open the unified workflow home with bare `bullswarm workflow`, or
|
|
27
|
+
jump directly to one run with `bullswarm workflow tui <shortId>`. The default
|
|
28
|
+
detail view is a human timeline with Live agents and a plain-language Next
|
|
29
|
+
line; `v` reveals technical state. Wide terminals use a workflow sidebar plus
|
|
30
|
+
detail pane, while narrow/mobile terminals show one pane at a time. `q`
|
|
31
|
+
detaches safely.
|
|
30
32
|
|
|
31
33
|
## The doctrine (non-negotiable)
|
|
32
34
|
|
|
@@ -36,9 +38,9 @@ terminals give each level the full screen automatically.
|
|
|
36
38
|
2. **Pace by meter.** The scheduling resource is the subscription window:
|
|
37
39
|
elapsed% minus used%, most-behind pool wins. Pace may only promote a
|
|
38
40
|
*cheaper* pool. Lanes are work-nature, never hard-coded to pools.
|
|
39
|
-
3. **Delegate output is evidence, never authority.**
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
3. **Delegate output is evidence, never authority.** The Workflow Planner may
|
|
42
|
+
propose actions, but only the deterministic kernel validates the program,
|
|
43
|
+
accepts requirement-scoped evidence, and computes completion.
|
|
42
44
|
4. **Quarantine re-probes.** A benched pool must be able to return to service
|
|
43
45
|
automatically; a lane is never allowed to silently go down.
|
|
44
46
|
|
|
@@ -73,7 +75,7 @@ bullswarm pools # meter state, pace position, quarantine status
|
|
|
73
75
|
bullswarm strategy refresh --apply --yes # approve capability-aware tier autopilot
|
|
74
76
|
bullswarm delegate --cwd ~/some-repo --prompt "Explain the parser" # one agent
|
|
75
77
|
bullswarm delegate --cwd ~/some-repo --prompt "Audit all commands, fix help, and independently verify" # workflow
|
|
76
|
-
bullswarm delegate --dry-run --json --cwd ~/some-repo --prompt "Your task" #
|
|
78
|
+
bullswarm delegate --dry-run --json --cwd ~/some-repo --prompt "Your task" # bounded classification + decision/plan; no work dispatch
|
|
77
79
|
bullswarm run --lane analyze --add-dir ~/some-repo --task-file /tmp/t.md --json
|
|
78
80
|
bullswarm run --lane analyze --add-dir ~/some-repo --prompt "Inspect the parser" --json
|
|
79
81
|
bullswarm workflow goal "Fix the failing tests and verify the change" --cwd ~/some-repo
|
|
@@ -93,6 +95,25 @@ bullswarm health # re-judge saved outputs; catch gate failures
|
|
|
93
95
|
| `strategy` | Discover models, record subscription value, recommend or assign high/medium/low effort routes |
|
|
94
96
|
| `doctor` | Machine-readable readiness report; self-heals on first call |
|
|
95
97
|
| `workflow` | Start an autonomous goal, or run / validate / draft / inspect explicit workflows and their live instances. |
|
|
98
|
+
| `runs` | Short alias for `workflow runs`, including list, show, result, delete, and cleanup operations. |
|
|
99
|
+
| `version` / `--version` | Print the installed Bullswarm version. |
|
|
100
|
+
| `release` | Run the guarded local version-bump, commit, and tag workflow used before CI publishes to npm. |
|
|
101
|
+
|
|
102
|
+
### Delegate classification
|
|
103
|
+
|
|
104
|
+
With the default `--mode auto`, `delegate` first uses deterministic task
|
|
105
|
+
signals, then uses an LLM to refine the choice between a single delegate and a
|
|
106
|
+
workflow during execution. If that optional refinement is unavailable or
|
|
107
|
+
unusable, automatic mode uses the deterministic decision.
|
|
108
|
+
|
|
109
|
+
Use `--classify deterministic` to bypass the LLM refinement — this is the
|
|
110
|
+
instant, no-dispatch preview. Use `--classify llm` when an LLM decision is
|
|
111
|
+
required: the command fails if it cannot obtain a usable one. In automatic
|
|
112
|
+
mode, `--dry-run` still performs that same bounded low-effort classification
|
|
113
|
+
request (one analyze-lane, low-effort dispatch) and prints the resulting
|
|
114
|
+
decision — it never dispatches the work itself. An explicit `--mode single` or
|
|
115
|
+
`--mode workflow` is the caller's decision and bypasses automatic LLM
|
|
116
|
+
classification.
|
|
96
117
|
|
|
97
118
|
Discover and validate workflow definitions without executing them:
|
|
98
119
|
|
|
@@ -164,28 +185,36 @@ bullswarm workflow goal \
|
|
|
164
185
|
--cwd ~/some-repo --watch
|
|
165
186
|
```
|
|
166
187
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
`--max-agents`, `--max-actions`, and `--max-expansion-rounds` are soft V2
|
|
189
|
+
planning targets. They encourage the Workflow Planner to consolidate optional
|
|
190
|
+
work, but the kernel never stops or rejects essential work merely because a
|
|
191
|
+
target was reached. `--concurrency` still bounds simultaneous dispatches so
|
|
192
|
+
the scheduler can batch a wider useful program safely.
|
|
193
|
+
|
|
194
|
+
Bullswarm first runs optional read-only reconnaissance, then invokes one
|
|
195
|
+
logical, resumable Workflow Planner conversation. The planner proposes a
|
|
196
|
+
complete bounded program of generic actions. Work actions produce artifacts;
|
|
197
|
+
evidence actions independently judge named requirements. The kernel rejects
|
|
198
|
+
malformed, cyclic, overlapping, or needlessly serialized proposals before
|
|
199
|
+
dispatch, runs dependency-ready file-disjoint actions concurrently, and
|
|
200
|
+
updates the requirement ledger from schema-valid evidence. Only real
|
|
201
|
+
consolidated gaps re-enter the planner. There are no formal reviewer or repair
|
|
202
|
+
roles and no automatic semantic repair/reverify loop.
|
|
203
|
+
|
|
204
|
+
The planner does not author phases or declare success/failure. The kernel
|
|
205
|
+
derives stable presentation stages for the TUI and computes the final V2
|
|
206
|
+
result. Old autonomous run directories are not migrated or resumed;
|
|
207
|
+
explicitly naming one fails before any paid dispatch. Fixed JSON workflows and
|
|
208
|
+
drafts remain a separate authored-graph feature with their existing step
|
|
209
|
+
types.
|
|
182
210
|
|
|
183
211
|
The detached response includes a short ID and exact observation commands:
|
|
184
212
|
|
|
185
213
|
```bash
|
|
186
214
|
bullswarm workflow runs show <shortId>
|
|
187
215
|
bullswarm workflow watch <shortId> # low-noise live progress + terminal timing
|
|
188
|
-
bullswarm workflow
|
|
216
|
+
bullswarm workflow # unified human workflow home
|
|
217
|
+
bullswarm workflow tui <shortId> # jump directly to one run timeline
|
|
189
218
|
bullswarm workflow tui --json <shortId>
|
|
190
219
|
bullswarm workflow events --json <shortId> --after 0
|
|
191
220
|
bullswarm workflow action show --json <shortId> <actionId>
|
|
@@ -200,8 +229,8 @@ bullswarm workflow goal --resume <shortId> --json
|
|
|
200
229
|
`--orchestrator <pool>` expresses a preference and immediately falls back to
|
|
201
230
|
another eligible pool if that provider is quota-gated or unavailable. Ordinary
|
|
202
231
|
use can leave selection on `auto`. For controlled provider QA only,
|
|
203
|
-
`--strict-orchestrator <pool>` requires that exact pool and
|
|
204
|
-
|
|
232
|
+
`--strict-orchestrator <pool>` requires that exact pool and fails if it is not
|
|
233
|
+
available. Controlled comparisons can additionally pin the exact planner
|
|
205
234
|
and worker routes without changing global strategy:
|
|
206
235
|
|
|
207
236
|
```bash
|
|
@@ -210,16 +239,31 @@ bullswarm workflow goal "Implement and verify the change" --cwd . \
|
|
|
210
239
|
--worker-pool opencode2 --worker-model kaihk/gpt-5.6-luna
|
|
211
240
|
```
|
|
212
241
|
|
|
213
|
-
The worker lock covers
|
|
214
|
-
re-verification, and runtime extraction helpers. A pool that cannot guarantee
|
|
242
|
+
The worker lock covers scout, work actions, and evidence actions. A pool that cannot guarantee
|
|
215
243
|
the requested model is ineligible rather than silently substituting another
|
|
216
|
-
model.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
244
|
+
model.
|
|
245
|
+
|
|
246
|
+
The `opencode2` connector itself does not require a KaiHK provider: its base
|
|
247
|
+
spawn command carries no hardcoded model, so a plain OpenCode installation
|
|
248
|
+
dispatches with OpenCode's own configured default. When
|
|
249
|
+
`~/.config/opencode/opencode.json` has one or more KaiHK providers configured,
|
|
250
|
+
Bullswarm discovers them and pins an explicit `--model <providerId>/gpt-5.6-luna`
|
|
251
|
+
per provider — the first as the primary `opencode2` pool, each additional one
|
|
252
|
+
as its own `opencode2:<id>` pool — which is what the `--worker-model
|
|
253
|
+
kaihk/gpt-5.6-luna` example above locks onto.
|
|
254
|
+
|
|
255
|
+
`--max-agents`, `--max-actions`, and `--max-expansion-rounds` are soft V2
|
|
256
|
+
planning targets: they guide the planner toward a small program but do not
|
|
257
|
+
hard-stop useful work. `--concurrency` is the actual bound on simultaneous
|
|
258
|
+
dependency-ready dispatches. There is no default wall-clock timeout: fresh
|
|
259
|
+
semantic/transport heartbeats allow a useful worker to continue, while silence
|
|
260
|
+
is inspected rather than blindly killed.
|
|
220
261
|
Interactive setup also records a worktree-isolation
|
|
221
262
|
preference (`agent-decides`, `off`, or `required`); Bullswarm communicates that
|
|
222
|
-
policy to the
|
|
263
|
+
policy to the V2 kernel. Unless explicitly set to `off`, mutating autonomous
|
|
264
|
+
actions use isolated worktrees; the kernel checks actual changed paths against
|
|
265
|
+
declared ownership before integration. `off` serializes shared-workspace
|
|
266
|
+
writers and still enforces the changed-path boundary.
|
|
223
267
|
|
|
224
268
|
## Building a workflow from the shell
|
|
225
269
|
|
|
@@ -281,12 +325,11 @@ Values accept ISO timestamps, local `YYYY-MM-DD` dates, `today`, `yesterday`,
|
|
|
281
325
|
|
|
282
326
|
After a workflow reaches a terminal state, agents should consume
|
|
283
327
|
`workflow runs result <id> --json` instead of probing `state.json`, task files,
|
|
284
|
-
or provider-specific output.
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
surface.
|
|
328
|
+
or provider-specific output. Autonomous V2 returns the versioned
|
|
329
|
+
`bullswarm.workflow.result.v2` envelope with kernel-computed status, fresh
|
|
330
|
+
requirement evidence, action/artifact records, explicit gaps, usage, and
|
|
331
|
+
verification qualification. Fixed authored workflows retain their existing
|
|
332
|
+
result envelope. `runs show` remains the low-level debugging surface.
|
|
290
333
|
Goal launch output includes an `instructions` handoff with four named paths:
|
|
291
334
|
`agentInspect` for a machine-readable snapshot, `watch` for low-noise progress,
|
|
292
335
|
`humanTui` for the interactive browser, and `result` for the terminal delivery.
|
|
@@ -408,11 +451,11 @@ runtime value and uses its matching connector rate metadata for the attempt's
|
|
|
408
451
|
cost estimate. Unknown or provider-hidden model identity remains explicitly
|
|
409
452
|
unknown.
|
|
410
453
|
|
|
411
|
-
###
|
|
454
|
+
### Authored adaptive graphs
|
|
412
455
|
|
|
413
|
-
|
|
414
|
-
an explicit `decide` step, advisory
|
|
415
|
-
limits:
|
|
456
|
+
This is part of the separately authored fixed-graph engine, not the autonomous
|
|
457
|
+
V2 `workflow goal` path. A graph may add an explicit `decide` step, advisory
|
|
458
|
+
resource targets, and structural expansion limits:
|
|
416
459
|
|
|
417
460
|
```json
|
|
418
461
|
{
|
|
@@ -439,8 +482,9 @@ limits:
|
|
|
439
482
|
}
|
|
440
483
|
```
|
|
441
484
|
|
|
442
|
-
`maxAgents`, `maxWorkflowSeconds`, and
|
|
443
|
-
|
|
485
|
+
For an authored adaptive graph, `maxAgents`, `maxWorkflowSeconds`, and
|
|
486
|
+
`maxExpansionRounds` are advisory inputs to its decide step. Approaching them
|
|
487
|
+
strongly biases that step toward
|
|
444
488
|
consolidating existing artifacts and returning the best useful outcome;
|
|
445
489
|
crossing them is recorded but never stops a worker, skips verification, or
|
|
446
490
|
fails a run. `maxActions` and `maxItemsPerExpansion` remain hard structural
|
|
@@ -449,11 +493,17 @@ rather than discarding the run as a blanket failure. Delegates have no
|
|
|
449
493
|
implicit wall-clock timeout; set a step's `timeoutSec` (or direct-run
|
|
450
494
|
`--timeout`) only when an operator explicitly wants a hard termination timer.
|
|
451
495
|
|
|
452
|
-
|
|
453
|
-
`
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
496
|
+
Within this authored-graph engine, `complete` remains strictly verified. A
|
|
497
|
+
decide-step `stop` still
|
|
498
|
+
delivers a completed outcome when a useful delivery exists: unresolved
|
|
499
|
+
verification concerns and the stopping reason ride along as `outcome.concerns`
|
|
500
|
+
and `outcome.reason`, attributes of that completed outcome rather than a
|
|
501
|
+
separate terminal status. `stop` produces `blocked` only when no useful
|
|
502
|
+
delivery exists. `workflow runs result` treats the completed outcome as ready
|
|
503
|
+
while reporting `verified:false`. The status value `completed_with_concerns`
|
|
504
|
+
still appears on some runs — including legacy ones recorded before this
|
|
505
|
+
framing — and every consumer reads it exactly like `completed`: a delivered
|
|
506
|
+
result with concerns to review, never a failure.
|
|
457
507
|
|
|
458
508
|
The planner returns versioned JSON. It may propose `needs_more_work` with
|
|
459
509
|
bounded `run`, inline-`fanout`, or `verify` actions. The deterministic runtime
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { validateEvidenceOutput } from '../src/workflow/evidence-output.js';
|
|
5
|
+
|
|
6
|
+
function parseArgs(args) {
|
|
7
|
+
if (args.length !== 4 || args[0] !== '--contract' || args[2] !== '--value' || !args[1] || !args[3] || args[1].startsWith('--') || args[3].startsWith('--')) return null;
|
|
8
|
+
return { contractPath: args[1], valuePath: args[3] };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
12
|
+
if (!parsed) {
|
|
13
|
+
console.error('Usage: check-v2-evidence --contract <contract.json> --value <candidate.json>');
|
|
14
|
+
process.exit(2);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const contract = JSON.parse(readFileSync(parsed.contractPath, 'utf8'));
|
|
19
|
+
const value = JSON.parse(readFileSync(parsed.valuePath, 'utf8'));
|
|
20
|
+
const result = validateEvidenceOutput(value, contract);
|
|
21
|
+
process.stdout.write(`${JSON.stringify({ ok: result.ok, errors: result.errors })}\n`);
|
|
22
|
+
process.exit(result.ok ? 0 : 1);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
process.stdout.write(`${JSON.stringify({ ok: false, errors: [error.message] })}\n`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { validateV2PlannerResponse } from '../src/workflow/v2-planner.js';
|
|
5
|
+
import { deserializeV2DurableState } from '../src/workflow/v2-state.js';
|
|
6
|
+
import { extractScoutUnitIds } from '../src/workflow/goal.js';
|
|
7
|
+
|
|
8
|
+
function parseArgs(args) {
|
|
9
|
+
if (args.length !== 6 || args[0] !== '--state' || args[2] !== '--boundary' || args[4] !== '--value') return null;
|
|
10
|
+
const [, statePath, , boundary, , valuePath] = args;
|
|
11
|
+
if (!statePath || !valuePath || !['initial', 'gaps', 'steering'].includes(boundary)) return null;
|
|
12
|
+
if (statePath.startsWith('--') || valuePath.startsWith('--')) return null;
|
|
13
|
+
return { statePath, boundary, valuePath };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
17
|
+
if (!parsed) {
|
|
18
|
+
console.error('Usage: check-v2-plan --state <state.json> --boundary <initial|gaps|steering> --value <candidate.json>');
|
|
19
|
+
process.exit(2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const state = deserializeV2DurableState(readFileSync(parsed.statePath, 'utf8'));
|
|
24
|
+
const value = JSON.parse(readFileSync(parsed.valuePath, 'utf8'));
|
|
25
|
+
const scoutPath = state.preflight.scout.outputFile;
|
|
26
|
+
const requiredScoutUnits = parsed.boundary === 'initial' && scoutPath && existsSync(scoutPath)
|
|
27
|
+
? extractScoutUnitIds(readFileSync(scoutPath, 'utf8'))
|
|
28
|
+
: [];
|
|
29
|
+
validateV2PlannerResponse(value, state, { boundary: parsed.boundary, requiredScoutUnits });
|
|
30
|
+
process.stdout.write(`${JSON.stringify({ ok: true, errors: [] })}\n`);
|
|
31
|
+
process.exit(0);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
const errors = Array.isArray(error?.issues) ? error.issues : [error.message];
|
|
34
|
+
process.stdout.write(`${JSON.stringify({ ok: false, errors })}\n`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"bin": "opencode",
|
|
4
4
|
"configDirs": ["~/.config/opencode"],
|
|
5
5
|
"spawn": {
|
|
6
|
-
"cmd": ["opencode", "run", "--auto", "
|
|
6
|
+
"cmd": ["opencode", "run", "--auto", "{taskFile}"],
|
|
7
7
|
"cwdMode": "pwd",
|
|
8
8
|
"$comment-cwdMode": "QUIRK: resolves its project from $PWD, not the spawn cwd. The watcher MUST set env.PWD and spawn with cwd inside the target repo, or it will silently analyse the wrong repository and answer confidently about it."
|
|
9
9
|
},
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"format": "jsonl",
|
|
14
14
|
"args": ["--format", "json"],
|
|
15
15
|
"silenceThresholdSec": 600,
|
|
16
|
+
"failureTypes": ["error"],
|
|
16
17
|
"rules": [
|
|
17
18
|
{ "rootMatch": { "path": "type", "equals": "tool_use" }, "idPaths": ["part.callID", "part.id"], "kindPaths": ["part.tool"], "summaryPaths": ["part.state.input.command", "part.state.input.file_path", "part.state.input.path", "part.state.title"], "statusPath": "part.state.status" },
|
|
18
19
|
{ "rootMatch": { "path": "type", "equals": "text" }, "idPaths": ["part.id"], "kind": "response", "summaryPaths": ["part.text"], "status": "completed" }
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
{ "match": { "path": "type", "equals": "text" }, "path": "part.text", "mode": "concat", "separator": "\n" }
|
|
22
23
|
]
|
|
23
24
|
},
|
|
24
|
-
"$comment-auto": "--auto is required for headless workflow dispatch: task files live under ~/.bullswarm, outside the target repo, and OpenCode otherwise pauses for an interactive permission approval. --model
|
|
25
|
+
"$comment-auto": "--auto is required for headless workflow dispatch: task files live under ~/.bullswarm, outside the target repo, and OpenCode otherwise pauses for an interactive permission approval. The base connector intentionally leaves --model unset so a plain OpenCode installation uses its own default; opencode-kaihk.js adds --model <providerId>/gpt-5.6-luna only for discovered KaiHK providers, after which modelSelection can replace it for assignments and step locks.",
|
|
25
26
|
"$comment-exit1": "known failure mode: writes a complete correct answer, then dies with a Console-sync auth error and exit 1. The verdict sets contentUsableDespiteExit instead of discarding the work.",
|
|
26
27
|
"meter": { "type": "none" },
|
|
27
28
|
"costRank": 1,
|