Skip to content

v3.18.0

A release cut from watching unattended runs: what they merge, what they refuse, and how they account for themselves afterwards.

The run accounts for itself

Asking what came of a batch of runs meant reading .sdd/ by hand once the orchestrator had exited. bernstein runs report projects the work ledger into one row per finished run — pr-opened, gate-failed, no-changes, infra-error or wedged — each carrying the line of evidence it was classified from (#4465).

Pull requests are described from the change, not from the session. The title names the commit that changed the most under src/, skipping upkeep; the body is composed from the issue's problem statement, the touched files and the gates that ran, and carries a Provenance block the review-receipt machinery verifies against the diff (#4484).

Journal payload hashing excludes the wall-clock envelope by design, so ts and elapsed_s on stored rows are not covered by chain verification — and nothing said so. replay --verify and the receipt manifest now name the unauthenticated field set, machine-readably (#4209).

Plan approval binds to the rendering the reviewer saw: a plan carries the SHA-256 digest of its deterministic rendering, and approve or reject answers 409 when the stored plan no longer matches it (#3839).

Gates that refuse

Reap-and-merge landed an agent's branch without running the configured quality gates. They now run on the still-alive worktree before the merge commit; a blocking failure — or a gate runner that errors — leaves the branch unmerged and records the refusal (#4393).

A merge-gate failure gets one bounded repair attempt seeded with the exact failure output, then falls back to the existing handling; no second attempt either way. Off switch: gate_repair_enabled (#4463).

A run used to pin its overrides into the tracked bernstein.yaml, so an agent that committed with a staged tree proposed rewriting the repository's configuration for everyone. Overrides now resolve from an untracked overlay merged at load time, and a new required run_config gate refuses any diff touching a run-configuration path (#4485).

agent_test_mutation is in VALID_GATE_NAMES, so a seed naming it parses instead of failing; a structural test keeps every default gate spec listed (#4488).

Keys that stay apart

Installing an Agent Plugins directory containment-checked the manifest's skills field but followed whatever the entries under it pointed at: a skill directory, a bucket or a nested file symlinked out of the pack was copied into the install scope. Every walked path now has to resolve inside the pack; an escaping skill directory is skipped and reported, an escaping file refuses the skill's install (#4448).

Every HMAC-chained store signed with the same raw key. New audit entries carry scheme v2 — an HKDF-SHA256 per-store key and a domain-tagged preimage — resolved in one place, so the log verifier, the local record check and the startup guard reach the same verdict. v1 chains verify unchanged; an unknown scheme fails hard everywhere (#4212).

Also

A board carrying a dependency cycle drains instead of wedging (#4287). The legacy /dashboard route is gone; bernstein dashboard points at bernstein gui serve (#4395). The watchdog no longer restarts a run that already finished (#4445). The nightly dependency audit is green again on pip 26.2.1. A release-notes entry can ship as its own fragment file instead of a line in the shared page, so parallel PRs stop colliding in the merge queue (#4474).

Contributors

  • Chirag Honnyal — the gate-name fix that lets a seed naming agent_test_mutation parse (#4493), the cycle-forming dependency rejected before persistence rather than after (#4431), the legacy /dashboard route removal (#4430), quality gates running in reap-and-merge before an agent branch lands (#4429), and the staleness-clock reset for the curated context files (#4477).
  • Louis20060723 — Agent Plugins directory layout in skills install, including the containment walk that refuses a skill escaping its pack (#4448).
  • Aditya Pathak — the mypy configuration and its preview follow-up (#4434, #4432).
  • Vaibhav Srivastava — the CI canary proposal branch now builds on the fetched default branch, not on whatever the runner had checked out (#4497).