Bernstein — Multi-Agent Orchestration
Version updated for https://github.com/sipyourdrink-ltd/bernstein to version v3.8.4.
- This action is used across all versions by 5 repositories.
Action Type
This is a Composite action.
Go to the GitHub Marketplace to find the latest changes.
Action Summary
Bernstein is a deterministic orchestrator for CLI coding agents that schedules tasks in plain Python and ensures reproducibility and auditability. It uses an always-on lineage spine to track changes and an HMAC-chained audit log to verify results offline, making it suitable for environments with strict requirements on transparency and repeatability.
What’s Changed
A bug-fix release. This wave closes the defects surfaced by running 3.8.2/3.8.3 end to end across cluster mode, the task lifecycle, and the verifiability core: multi-machine setups that could never complete a task, runs that declared success without a deliverable, and audit/lineage surfaces that verified less than they claimed. Nothing here changes a public API; upgrade in place.
Cluster mode
- Worker registration works with a single credential: the raw cluster secret (or the operator API token) now clears both auth layers, which previously accepted disjoint credentials with no issuance surface for the inner one (#2805). The cluster secret is deliberately barred from operator-only admin endpoints.
- A tokenless or misconfigured worker join now fails fast with an actionable message naming
--token,BERNSTEIN_AUTH_TOKEN, and the auto-generated token path, instead of silently retrying a 401 every 5 seconds forever; the deployment docs document the real join flow (#2802). - Remote task completion is possible: the completion URL respects
BERNSTEIN_SERVER_URLinstead of hardcoding localhost, and the worker loop reports terminal state for every reaped process (#2808). - Dead workers are detected and their claimed tasks requeued: the node reaper now always runs, and each claim records the owning node (#2801).
- Workers honor the task’s model/adapter selection instead of discarding it and refusing non-Claude adapters; a
--modelflag plus adapter profiles resolve sensible defaults (#2804).
Task lifecycle and run correctness
- A suspiciously fast clean agent exit is no longer auto-completed into “done” with an empty diff; it routes to retry and surfaces as
clean_exit_unverified(#2810). - Retry storms are capped: backoff and fail-counts follow the retried task lineage, so a structurally dead spawn terminates within the cap instead of ballooning a 5-step plan into ~97 task records (#2806).
- Resume after stop no longer declares a run complete while dropping open tasks: stopped sessions persist their open work and re-plan on resume (#2798).
- A supervisor watching an agent stuck at spawn-time “starting” now escalates through SIGTERM/SIGKILL and requeues the task instead of rewriting the shutdown signal forever (#2796).
- The CLI no longer opens a browser dashboard that will greet the operator with a 401; it probes first and prints the working alternatives (#2794).
- A manager/planning spawn that would run unsandboxed in the operator checkout is refused up front, and writes that escape the worktree are contained at reap time instead of landing untracked in the operator’s checkout (#2793).
- An explicit
--sandboxoverride that cannot be honored fails loudly instead of degrading to host execution (#2847). --dry-runvalidates the seed through the same parser as a real run and warns on unparseable backlog files (#2849).
Audit chain, lineage, and replay
- The task server and spawner now resolve the same audit HMAC key, and appends hold a cross-process lock, so a mixed-writer chain verifies instead of failing on key mismatch; concurrent writers serialize into one verifiable chain (#2791).
- Ambient host
BAGGAGE/TRACEPARENTenv (foreign Sentry/OTEL ids) is no longer sealed into lineage hashes; only orchestrator-owned context is recorded (#2787). - A lineage chain that contains only the journal seal no longer passes verification silently:
bernstein lineage verifyreports SEAL ONLY and exits non-zero when no artifact provenance exists (#2789). - Deterministic replay refuses to run live: activating replay for a run with no recording aborts before any agent spawns instead of silently executing against the world (#2790).
- Nightly adapter-canary receipts are anchored into the HMAC audit chain as documented (#2850), chronic skip verdicts escalate to issues, and a stale or absent last-green is surfaced (#2845).
- Qwen CLI-adapter runs record real token usage in the cost ledger (#2851).
Cloud and Cloudflare adapter surfaces
- The
cloudflareandcodex_cloudflareadapters refuse fast with actionable errors instead of pretending: one had no worker-trigger path (every task timed out with zero artifacts), the other targeted a REST API that does not exist; both are marked experimental in docs (#2782, #2783). bernstein cloud initscaffolds a runnable free-tier worker,cloud deployno longer points at a template the wheel does not ship, dead-endpoint errors are actionable instead of raw tracebacks, and the template declares no paid bindings (#2784).
CLI and dashboard
- Operator-surface defects from 3.8.2 testing: no more
.claude/mcp.jsonchurn on every run,--freshworks onrun,stop --forcereports only confirmed-terminated processes,pssees a live leaf process, dry-run previews are populated, and the dashboard stops mislabeling models (#2800). worker --adapteraccepts every registered adapter (same registry asrun --cli),--idledocuments that it forces the mock backend internally,startappears in--help, and container worker health is documented (#2807). Remaining wiring-level items are tracked in #2874.
CI and maintenance
- The post-CI dispatcher boots again: the auto-release call granted less than the callee requested and every dispatcher run since 2026-07-19 ended as a silent startup_failure — auto-release, auto-heal, CI-fix, and bisect were all dead (#2866). A regression test now asserts caller grants cover every callee job request (#2867).
- Hosted SonarQube, GlitchTip, Dependency-Track, and the operator Telegram alert integrations are retired to simplify operations (#2859, #2863); the observability snapshot runs on manual dispatch only (#2856).
Thanks
Thanks to the external contributors in this release:
- @AnayGarodia — centralized the artifact constants and typed the wire payloads so the task and adapter surfaces share one definition (#2838)
Full Changelog: https://github.com/sipyourdrink-ltd/bernstein/compare/v3.8.3...v3.8.4