Changelog
All notable changes to caliban are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. While the project is pre-1.0, the minor version is bumped for new features and the patch version for fixes.
Unreleased
0.15.0 - 2026-09-21
The config-layer release. Two threads land together: the agent-loop policy
surface (ADR 0058 B-series) gives
the loop model-adaptive turn/time/cost budgets, verification guidance, and named
profiles; and a broad push makes configuration actually flow through the
settings layer — an environment layer with provenance, router config unified
onto settings (retiring caliban.toml discovery), and several keys that were
parsed-but-ignored now honored, with the doc drift around all of it corrected.
Added
- Agent-loop policy surface (ADR 0058):
a
[agent_loop]config surface (#661, #687), a wall-clock time budget (#662, #688), a cost budget via an injected cost model (#663, #691), averification_guidanceknob (#665, #692), and adaptive local/cloud defaults with named profiles (#666, #693). - Environment settings layer with provenance (#538, #702):
CALIBAN_*overrides fold into the loaded settings (env > file) through a single aggregation point and are attributed incaliban config printvia_env_overrides, closing the gap where env silently overrode the file. The first migrated cluster foldsCALIBAN_OUTPUT_STYLEandCALIBAN_DEFAULT_PERMISSION_MODEinto their settings keys and removes the ad-hocstd::env::varreaders, with a CI lint (scripts/lint-env-registry.sh) banning new ad-hoc reads of migrated variables (#705, #706). - Settings-layer
[router]section, preferred overcaliban.tomland typed binary-side, with per-provider[router.provider.X]blocks forapi_key_env/base_url(#540, #700; completed by #699). caliban config import-router [--from <PATH>] [--dry-run]to migrate a legacycaliban.tomlrouter config into.caliban/settings.toml[router], relocating top-level[provider.X]blocks to[router.provider.X](#699, #704).
Changed
- Breaking: router config now resolves through the settings layer with an
explicit
--config/CALIBAN_ROUTER_CONFIGfile as the highest-precedence override; the walk-up /~/.config/caliban/caliban.tomldiscovery was removed, so a bare repo-rootcaliban.tomlis no longer auto-loaded (a startup warning points atcaliban config import-router) (#699, #704; ADR 0060, amends ADR 0038). - Honor the
output_stylesetting and mark the remaining parsed-but-inert settings keys as reserved, rather than implying they take effect (#620, #703). - Prune inert telemetry knobs from
[telemetry]and correct the observability documentation that oversold them (#499, #697).
Fixed
- Honor
claude_md_excludesand the env-backed settings that were parsed but silently dropped on load (#694, #695).
Documentation
- The
caliban-contractrouter_configfield carries a config-file path, not inline JSON (#690, #696). - Stop promising live settings reload — settings are read once at startup; the
SettingsWatcherscaffolding is unwired (#617, #698).
0.14.0 - 2026-09-19
The ACP-over-network release. Following ADR 0059,
a per-agent worker can now be driven over the Agent Client Protocol on its
existing TLS + bearer-token listener, with a per-session permission posture the
operator chooses — so a control plane like prospero can drive in-cluster agents
over ACP on the path it already secures. A new thin caliban-contract crate
publishes caliban's launch and control-plane contract so out-of-tree components
stop hand-copying flag names and wire types. Two robustness fixes from a
dogfooding round round it out: a malformed repo-committed config no longer bricks
every run, and an undiscoverable model context window is shown honestly instead
of a fabricated default.
Added
- A per-session permission posture on
SpawnSpec(#676): the worker honors a typedpermission_posture(superviseddefault /unattended), constructing its permission gate from it — fixing the in-cluster "every tool denied" blocker and giving the operator a real, audited lever. Wire values match theCalibanTaskCR enum. ADR 0059. (#678) - Tool-call input + accounting over ACP (#674): the ACP adapter now surfaces
accumulated tool-call
rawInputand threads token-usage/turn accounting into the prompt result's_meta(caliban/usage,caliban/turns), closing data-parity gaps with the NDJSON drive wire. (#680) - The worker speaks ACP on its network listener (#675): per ADR 0059
(transport Option 2), a spawn may select
drive_protocol = acp, and the worker serves the Agent Client Protocol (JSON-RPC) as an alternative to the NDJSON session plane on the same TLS + bearer-token listener (#527 gate), reusing the ADR 0055 drive core. The stdiocaliban acp servepath is unchanged. (#681) - A thin
caliban-contractcrate (#656): caliban's launch and control-plane contract — theCalibandLaunchbuilder (flag/env names +.args()/.env()), provider credential-env helpers, and the supervisor wire types — now live in a dependency-light crate (serde only, no daemon internals) that out-of-tree drivers (prospero, caliban-operator) can depend on directly instead of hand-copying names and types.caliban-supervisorre-exports the wire types, so there is a single definition, and a drift test fails if caliband's CLI and the builder disagree on a flag. (#682)
Fixed
- A malformed untrusted-scope config no longer bricks startup (#670): a syntax
error in a project- or local-scope
.caliban/*.tomlis now warn-and-skipped (the scope is dropped with a clear, file-naming warning) instead of hard-failing every non-bare caliban run in the repo withexit 78. Trusted (user/managed) scopes stay fail-loud, preserving the #410 guarantee. (#683) - An undiscoverable context window is shown honestly, not fabricated (#669):
when a model is absent from the static table and its server exposes no
meta.n_ctx(e.g. llama-swap, mlx-lm), caliban now reports the context window as unknown — the status bar omits the utilization segment (no "0% of 128K"), headless reportsmodel_context_window: null, and context-based autocompaction stays off — rather than presenting a hardcoded 128K as fact. (#685)
Docs: ADR 0059 records the ACP-over-network transport choice, auth reuse, and permission-posture model, amending ADR 0055 (#677).
0.13.0 - 2026-09-16
The daemon-lifecycle release. Long-running daemon-managed agents gain a full
drain → checkpoint → resume path; /rewind finally works end to end; and a new
fork-from-checkpoint branches a session without disturbing the original. The
caliband network transport is hardened, and three storage environment overrides
let an operator point an agent at a remote gonzalo daemon without hand-authoring
a settings file.
Added
- Fork from a checkpoint (#37): from the
/ncheckpoint overlay,[f]branches a new session from the selected checkpoint — written to disk and seeded with the conversation truncated at that point — leaving the current session, its checkpoint history, and the working tree untouched. (#655) - Graceful drain of daemon agents (#650): a
Draincontrol command SIGTERMs live agents, marks themDrained, and returns their session directories as resume references — the checkpoint half of ADR 0057. (#653) - Resume a daemon agent from a persisted session (#651): a worker given a
resume_sessionreference continues from the persistedsession.json, completing the drain → resume round-trip. (#654) - Environment overrides for the storage substrate (#659):
CALIBAN_STORAGE_SUBSTRATE,CALIBAN_STORAGE_REMOTE_URL, andCALIBAN_STORAGE_REMOTE_TOKEN_ENVoverride the[storage]settings (env wins), so caliban can be pointed at a remote gonzalo daemon — and handed its token by name — without a settings file. Thetoken_envindirection keeps the secret out of settings. (#667)
Fixed
/rewindactually restores now (#549): theCheckpointHookwas never installed, so per-prompt checkpoints were never recorded and/rewindhad nothing to restore. It is now wired as the last hook layer, so all five rewind actions — code, conversation, both, summarize-forward, summarize-backward — work. (#649)- caliband network mode hardened (#319): the agent registry no longer aborts on a single un-deserializable manifest, a wildcard advertise host is flagged, and the network control endpoint is honored only in network mode. (#648)
- caliband TLS pinned to aws-lc-rs, with negative-path tests (#320): the crypto provider is pinned per-config instead of relying on the process-wide ambient default (so a future dependency cannot silently flip the TLS backend), and the suite now proves an untrusted CA and a hostname mismatch are rejected. (#657)
Security
- rustls upgraded to 0.23.45 for RUSTSEC-2026-0285 — TLS 1.3 handshake messages were incorrectly accepted across encryption-level boundaries. caliband's network transport rides on rustls, so the patched crypto stack (aws-lc-rs 1.18, rustls-webpki 0.103.15) is shipped in this release.
Observability: the caliband supervisor now logs a worker's spawn-death cause to its stdout, so a worker that dies during spawn is diagnosable (#646, #647).
Docs: ADR 0057 records the drain/checkpoint/resume design (#652); ADR 0058 records the agent-loop policy surface — model-adaptive budgets, spiral + wrong-path containment, and verification guidance, grounded in the eval finding that self-verification helps strong models but hurts weaker ones (#660); and the user guide + README were refreshed for v0.12.0 and the drain/resume/fork work (#658).
0.12.0 - 2026-09-13
The Ollama release. caliban's bespoke ollama provider is removed in favor
of reaching local inference engines through the OpenAI-compatible provider
pointed at a base_url — the same seam that reaches OpenAI itself. This is
governance-motivated (see ADR 0056)
and architecturally cheap: the OpenAI adapter already speaks to any local engine
(llama.cpp, mlx-lm, LM Studio, llama-swap), and the one genuine loss —
context-window discovery — is recovered by a /v1/models shim. Benchmark and
conformance evidence gathered on Apple M5 Pro back the decision.
Removed
- The
caliban-provider-ollamaprovider (#634, #635), per ADR 0056.--provider ollamais no longer valid — a run configured with it fails loudly at startup (unknown provider 'ollama' — supported: anthropic, openai, google). Reach local models through--provider openaiwith abase_url; see Local Inference. BREAKING. (#640)
Added
/v1/modelsdiscovery shim for the OpenAI adapter (#632): when pointed at a local/v1endpoint, the adapter discovers the served models and reads each one's loaded context window frommeta.n_ctx— recovering the dynamic capability discovery the removed provider offered, now on the OpenAI seam. (#639)- Keyless OpenAI adapter for local endpoints (#641): when a
base_urlis set, no API key is required, so local inference is as frictionless as the removed provider was — no throwaway key. (#642)
Fixed
- MLX reasoning traces are captured (#627): MLX-based servers (e.g.
mlx_lm.server) stream the thinking trace underreasoningrather thanreasoning_content; a serde alias now accepts both, so their thinking is no longer silently dropped. (#628)
Docs: ADR 0056 accepted with benchmark + conformance eval harnesses (#629, #636);
the local-model path reframed around the OpenAI adapter + base_url (#631, #633,
#638); a full sweep of stale Ollama references from the user guide and code
comments, keeping the decision history in the ADRs (#643, #644). A one-time
deprecation notice + doctor hint shipped mid-cycle (#630, #637) and is
superseded by the removal above.
0.11.0 - 2026-09-10
A QA-driven correctness release. A declarative tool-assembly refactor unblocks the tool backlog; a full-CLI QA sweep surfaced and fixed a cluster of permission and sub-agent gaps (a driven-serve enforce fail-open, sub-agent settings that never reached the child, imported Claude Code rules that silently matched nothing); the session plane gains inbound-size and fail-closed-bind hardening; and the CLI gets argument-validation polish. Plus a test-flake cleanup and CI modernization.
Added
- Declarative built-in tool registry (#541):
build_registry's hand-wired block is replaced by a descriptor table incaliban-tools-builtin— each built-in declares its own availability predicate and factory, so adding one no longer means editing the composition root. Cheapens the whole tool backlog (#16–#22). (#616)
Changed
- CLI argument validation hardened (#621):
agents spawn/--bgreject an empty prompt instead of launching a doomed sub-agent;--continueand--resumenow conflict rather than silently ignoring-c;--max-budget-usdrejects negative / non-finite values at parse. (#623)
Fixed
- Permissions enforce gate applies to driven serve runs (#586): the MCP /
ACP / HTTP serve modes now refuse
--no-permissions,--auto-allow, and weakening--permission-modeflags whenpermissions.enforce = true, matching the interactive path — closing a fail-open on the driven surface. (#613) - Spawned sub-agents honor context-management + stream-watchdog settings
(#584):
auto_compact_threshold,micro_compact_enabled,tool_result_cap_chars,min_cache_block_tokens,stream_idle_timeout_ms, andstream_prefill_timeout_msnow reach spawned sub-agents instead of silently falling back to defaults. (#615) - Spawned sub-agents actually auto-compact (#619): sub-agents were built with
a no-op compactor, so
auto_compact_thresholdnever fired and a long-running sub-agent could overflow its context window; they now get the configured compactor. (#622) - Imported Claude Code Bash rules actually match (#618):
settings import/perms importnow translate Claude Code'sBash(cmd:*)command-prefix specifier to caliban's glob form, so a migrated allow/deny list is no longer silently inert — an importeddenynow blocks. (#624) config print/settings importaccuracy (#620):config printno longer shows default allow/ask rules a rules-only config never set, now emits per-key_provenance, andsettings import --dry-runvalidates its source instead of reporting success for a missing file. (#625)
Security
- Session-plane hardening (#593): the per-agent inbound reader now bounds
line length (a post-auth client can no longer OOM a worker with one
newline-less line),
Listener::bindfail-closes a network bind that lacks a token + TLS, and TLS uses the workspace-standard aws-lc-rs provider. (#614)
Testing: hardened flaky test sites — ETXTBSY-safe write-then-exec in
telemetry/settings (#580, #609), a deterministic registry-poll drain in serve
(#599, #610), race-free worktree-cleanup assertions in the supervisor (#602,
#611), and host-independent finalize_bwrap branch coverage via an injected
userns bool (#397, #612). Internal: GitHub Actions bumped off the deprecated
Node.js 20 runtime to Node 24-native majors (#607, #608).
0.10.0 - 2026-09-09
A hardening-and-polish release on top of v0.9.0's driveable server surface: three security fixes (a plaintext token-leak guard, https-only OAuth endpoints, and a symlink-safe checkpoint restore), a batch of config-schema and settings corrections, supervisor and OAuth robustness fixes, and the first prebuilt macOS arm64 binary attached to tagged releases so Apple Silicon users can install without a Rust toolchain.
Added
- Prebuilt macOS arm64 binary attached to tagged releases (#575): a
version-tagged release (
v*) now builds and uploadscaliban-aarch64-apple-darwin.tar.gz(+ a.sha256) for Apple Silicon, so M-series users can install a release without a local Rust toolchain. Tag-gated and repo-guarded; it uploads onto the Release the cut-release flow creates. (#576)
Fixed
enable_telemetryis honored, not just the env var (#494): the setting is now respected on its own, matching the documented config surface. (#578)- Worker spawn survives a spurious
ETXTBSY(#441): exec of a just-written worker binary no longer fails a real launch (errno 26) — it retries briefly; and that retry now runs on the blocking pool so it can't wedge a tokio runtime worker thread (#590). (#579, #604) - Driven MCP runs get the full layered permission setup (#566): a programmatically-driven MCP run is routed through the same permission layering as an interactive one, so Permissions v2 is enforced by construction. (#581)
- Settings-schema drift corrected; permission-rule reloads surface (#498): previously-unschematized keys are now type-checked and the reload path is wired through. (#582)
- JSON→TOML migration nudges are no longer dropped (#587): they now surface
via
validation_warnings, so a migration hint survives even before tracing is initialized. (#591) - Four honored settings added to the JSON schema (#588):
allow_local_http_hook_targets,compact_strategy,stream_idle_timeout_ms, andstream_prefill_timeout_msare now schema-checked — a wrong type warns instead of being silently ignored. (#592) - State-less OAuth error redirects surface promptly (#595): an auth server
that returns
?error=…without echoingstate(RFC-noncompliant but real) is now reported instead of hanging the callback wait until the 5-minute timeout; thestate-mismatch injection/DoS guard is preserved. (#603) - Slash-command / overlay descriptions no longer overpromise (#589):
/login,/logout, and the/mcpoverlay's disable/reload keys now describe their actual (stubbed) behavior rather than unimplemented features. (#600) CALIBAN_KEEP_WORKTREESis actually honored (#585): the documented debug escape hatch to keep sub-agent worktrees now prevents removal (it was a silent no-op); the never-built per-callkeep_on_exitroute is retired from the docs. (#605)
Security
- Bearer token no longer leaks over plaintext; session accept loop slowloris-hardened (#495): the per-agent status client refuses to dial when a token would travel without TLS, and the session accept loop bounds a stalled pre-auth peer with a handshake timeout so it can't wedge the loop. (#594)
- Manual-mode OAuth endpoints require https (#496): a non-loopback
http://auth_url/token_urlis rejected — it would send the code, PKCE verifier, and secret in cleartext — matching the discovery-hop guard; the DCR error body is also truncated. (#596) - Checkpoint restore routed through the confined
O_NOFOLLOWwriter (#497): restore writes now go through the same symlink-refusing atomic path as Write/Edit, closing a symlink TOCTOU in the restore step. (#598)
Docs & internal: re-rated the Claude Code parity-matrix worktree-isolation row
(#562); qualified the checkpoint-restore durability wording (#597); added the
lifecycle/do-not-merge label to labels.yml (#577).
0.9.0 - 2026-08-22
This release makes caliban driveable. Until now caliban was a first-class MCP client but exposed no server surface, so nothing could steer it programmatically. Now an external program can start an agent run, stream its turn events, read its status, feed it follow-up input, and answer the permission prompts it raises — with no TUI in the loop — through three protocol surfaces built over one shared, transport-agnostic drive core (ADR 0055): an MCP server for another agent, ACP for an editor, and plain HTTP for a script. Every surface inherits the same auth model and Permissions v2 enforcement by construction.
Added
- Driveable server surface — MCP server, ACP, and HTTP serve over one core
(#503): caliban can now be driven as a backend. A transport-agnostic drive
core exposes a
run/stream/status/inputcontract factored out of the headless and attach internals (#525, #552), and three thin protocol adapters ride it — each holding no agent logic:- MCP server (
caliban mcp serve): drive caliban as an MCP server from another agent, over stdio with poll-based tools (caliban_run→caliban_poll→ …) and a versioned{v, event}envelope around each turn event (#526, #565). - ACP (
caliban acp serve): an Agent Client Protocol agent over newline-delimited JSON-RPC for editor drive-in (Zed / OpenCode / Grok Build). Push/streaming — asession/promptcall streamssession/updatenotifications for one turn, and tool-permission prompts surface into the editor's own UI viasession/request_permission(#530, #570). - HTTP serve (
caliban http serve): drive caliban over plain HTTP/JSON from a script orcurl—POST /runs,GET /runs/:id/events?cursor=N,/status,/input,/permit(#531, #569). - Shared auth gate across all three (#527, #563): loopback is open;
a non-loopback peer must present a bearer token matching
CALIBAN_DRIVE_TOKEN(constant-time compared), and binding a surface to a non-loopback address with no token configured is refused — caliban never serves unauthenticated on the network. - Permission-elicitation bridge (#528, #564): a driven run still enforces Permissions v2 — a tool call that would prompt is surfaced back over each surface's own channel and its decision routed into the run, so a headless run never deadlocks or fails open. Covered end-to-end by a no-TUI test that drives a run start-to-finish over MCP (#529, #567, #568).
- MCP server (
Fixed
- Prompt-cache tokens are no longer double-counted in telemetry (#553):
cache-read and cache-creation tokens were being added into
gen_ai.usage.input_tokenson top of their own dedicated fields, inflating the reported input-token count on cached turns. They are now counted once. - Permission patterns accept the
Tool(<glob>)form (#518): the matcher split rule patterns on:only, so the rule caliban itself prints on a headless denial —--allow 'Bash(git *)'— parsed as a tool literally namedBash(git *)and could never match. Following the printed guidance verbatim left the tool denied.Tool(<glob>)andTool:<glob>are now interchangeable spellings everywhere patterns are parsed, including[permissions.auto]lists. This also un-breakscaliban perms import: Claude Code writes the parenthesised form and the importer copies patterns through verbatim, so every rule in a migrated config was previously inert. Rules that can never match (an unclosedBash(git *, an emptyBash(), a malformed glob) are now reported at startup, bycaliban perms lint, and bycaliban perms add, instead of failing closed and silently.
Changed
- New "Driving Caliban" guide section (#532): an overview of the
run/stream/status/input contract, the auth model, and how permission prompts
surface, plus one how-to page per surface with a copy-pasteable example (an MCP
client config, an ACP handshake, a
curlsession). - ADR 0055 records the driveable-server-surface design — three adapters over one core, the sequencing, and the auth/permission model (#533).
cargo install calibanis taught as the primary install path in the guide (#524, #534).- Competitor parity matrices swept under a production-call-path rule (#519, #557): a row is scored only against a real call path in the shipped binary. Applied across the Claude Code (#516, #522), Codex (#555), Grok Build (#548), OpenCode (#548), Antigravity (#554), and Pi (#515, #523) readouts, correcting overclaimed and duplicate-scored rows; the driveable-server-surface work ticks the MCP/ACP/HTTP rows those matrices had tracked as gaps.
0.8.0 - 2026-08-02
Two threads define this release. Storage moves behind the gonzalo facade —
sessions, auto-memory, and configuration now persist through a pluggable storage
substrate that can be backed by a local store or a remote gonzalo daemon, laying
the groundwork for multi-host and cluster deployments. And the sub-agent
control plane is fixed end-to-end: interactive sub-agents launched over the
Kubernetes TLS session-plane could never report their status back to the daemon —
every Idle/Running report was silently dropped, stranding an agent in Running
forever. Three fixes close that gap and make the failure observable if it ever
recurs.
Added
- Sessions persist through the gonzalo facade (#471): session state is now written via the gonzalo storage facade with an async debounce-writer, decoupling session persistence from the local filesystem and smoothing bursty writes. (#506)
- Storage substrate selection + remote gonzalo daemon config (#473): choose
where caliban persists its state, including pointing at a remote gonzalo
daemon, configured through
settings.json. (#502) - Auto-memory routed through the gonzalo facade (#470, pilot): auto-memory topics now flow through the same storage substrate as sessions — the first consumer of the shared facade beyond sessions. (#484)
Fixed
- Interactive sub-agents report status over the TLS control plane (#512):
the daemon no longer derives the worker's TLS verification identity from the
advertise host — the dial name and the cert's SAN are different things, and
defaulting one to the other made the worker verify against a name the serving
cert could not prove. An explicitly-set
CALIBAN_CONTROL_TLS_SERVER_NAMEinherited from the pod environment is now preserved instead of being clobbered by a derived value, and the daemon warns at startup when control TLS is configured with no resolvable server name. (#513) - Workers receive the control-plane TLS material they need to dial the
daemon (#510): the launcher now forwards
CALIBAN_CONTROL_TLS_CAandCALIBAN_CONTROL_TLS_SERVER_NAMEto workers, so a worker on a TLS control listener can complete the handshake instead of dialing plaintext and having every status report silently dropped. A dropped status report is now logged once so the failure is observable. (#511) - Worker stdout/stderr is captured instead of discarded (#509): a worker
that dies during preflight now leaves its output in the session directory
(
worker.log) instead of an empty container log, so the cause of afailedagent can be read rather than reconstructed by hand.
Docs: user guide + README refreshed for the 0.2.0–0.7.0 span (#500); competitor evaluation refreshed with Codex, OpenCode, OpenClaw, Grok Build, and Google Antigravity areas plus a primary-source pass (#488, #489, #490, #491, #505); Discord badge and community section added to the README (#492).
0.7.0 - 2026-07-15
This release makes the --workspace sandbox a real confinement boundary.
Where 0.6.0 had to disclose that the sandbox was not a secrets boundary — it
conceded filesystem reads, network egress, and the full process environment all
at once — 0.7.0 closes egress by default and scrubs secrets from the child's
environment. A sandboxed Bash command can now read the disk but cannot send
anything off the machine. Review before upgrading: this is a breaking
change — --workspace now also means "no network", so git fetch, cargo
against crates.io, npm install, and gh fail inside sandboxed commands until
you opt out with --sandbox-network=allow. Reads stay open by design (see ADR
0054), which is safe only because egress is now shut.
Not in this release — a known, deliberate gap. The egress opt-out is
all-or-nothing: --sandbox-network=allow re-opens the entire network, and there
is no per-hostname allowlist yet (e.g. "allow github.com so a run can open
a PR, and nothing else"). That is not a small feature — neither sandbox backend
can filter egress by hostname, so it requires a loopback proxy running outside
the sandbox. It is designed and tracked as a follow-up in #477. A
complementary read-side control (denying reads of the canonical credential
stores) is tracked in #481.
Changed
-
Sandboxed Bash commands can no longer reach the network (#406) — BREAKING. Under
--workspace(or--restrict-paths), the OS sandbox now denies egress by default: a command may read the disk but cannot phone home. Loopback is unaffected, so localhost test and dev servers keep working.git fetch,cargoagainst crates.io,npm install,gh, andcurlwill fail inside sandboxed commands unless you opt out with--sandbox-network=allow(orsandbox.network = "allow"insettings.json). A sandboxed command that fails while egress is blocked now says so and names the opt-out.Filesystem reads remain open by design —
~/.sshand~/.aws/credentialsare still readable, as in every comparable agent. That is defensible only because egress is now closed: a command can read a credential file but has nowhere to send it. Re-opening the network with--sandbox-network=allowrestores the exfiltration path, so use it deliberately. Per-hostname allowlists require a proxy (#477). See ADR 0054.
Added
sandboxsection insettings.json(#406):sandbox.network = "deny"|"allow"configures the egress posture. This is the first user-reachable sandbox configuration — the[sandbox]table previously documented in the sandbox crate was never wired to anything.- Sandboxed commands run with a scrubbed environment (#405): under
--workspace, the OS sandbox now drops secret-named variables (*KEY*,*SECRET*,*TOKEN*,*PASSWORD*,*CREDENTIAL*, plusOTEL_EXPORTER_OTLP_HEADERS) from a Bash command's environment, soANTHROPIC_API_KEY,CALIBAN_*tokens, and the like are no longer visible to commands the model runs. Matches Codex's default. Defense-in-depth on top of the closed egress (#406) — and it keeps secrets out of anything that dumpsenvinto a log or a file. This is a name-based filter; a secret in an innocuously-named variable is not caught. (A per-variablepassthroughescape hatch to keep a matched variable is not yet configurable via settings — the scrubber currently keeps nothing back; tracked in #499.)
Fixed
allow_local_bindingno longer grants full egress (#476): bwrap skipped--unshare-netwhenever the flag was set, so a narrow, local-sounding permission ("let this command bind a test-server port") silently opened the entire internet.--unshare-netis the loopback-only posture on Linux, so the flag must not suppress it. (#479)- The macOS Seatbelt generator emitted invalid profiles (#406): three rules
used syntax
sandbox-execrejects —(local ip "*:0")for local binding, and(remote tcp "127.0.0.1:<port>")for both proxy modes (Seatbelt requires the host to be literally*orlocalhost, and the port to be a number or*). An invalid rule makes Seatbelt refuse the whole profile, so every sandboxed command fails to launch. These never fired because no production policy setallow_local_bindingor a proxy port — the new fence sets the former. The generated profile is now compiled by the realsandbox-execin tests, which the previous string-matching tests could not catch.
0.6.0 - 2026-07-12
This release makes caliban observable and closes a broad security-hardening
sweep. OpenTelemetry support graduates from feature-gated stubs to a working
OTLP pipeline: gen_ai.* spans per model request and tool call, following the
OTel GenAI semantic conventions (ADR 0053), plus an OTLP metrics pipeline. It
also lands QA sweep epic #399 — 28 fixes, a dozen of which close security
fail-opens shipped in 0.5.0, where a permission or sandbox control was
configured but silently inert. Review before upgrading: several
permissions/sandbox paths now fail closed — a malformed permissions config, an
unusable sandbox, or an unparseable domain ACL is now an error rather than a
silent no-op, so a config that "worked" in 0.5.0 may now refuse to start.
The sandbox is not a secrets boundary in this release. Sandboxed commands
still inherit the full parent environment, so provider credentials
(ANTHROPIC_API_KEY, GH_TOKEN, …) are readable by any command caliban runs,
and the default fence leaves network egress open — a sandboxed command can
exfiltrate them. Do not rely on the sandbox to contain a command you would not
trust with your API keys. Tracked in #405.
Added
- OTel GenAI tracing over OTLP (#375, ADR 0053): the OTLP span exporter is
real rather than a feature-gated stub (#383), and caliban emits a
gen_aichat-generation span per model request (#378, #384) and anexecute_toolspan withgen_ai.tool.*attributes per tool call (#386). - Optional prompt/completion capture on spans (#380):
gen_aiinput and output messages are recorded on spans whenOTEL_LOG_USER_PROMPTSis set — off by default, since they contain user content. (#387) - OTLP metrics pipeline (#427): a real
MeterProviderwith a periodic reader honoringOTEL_METRIC_EXPORT_INTERVAL, withMetricEmitter::recordwired into live instruments, so emits reach the collector.session.countflows today; cost/token/active-time emits are tracked in #467 and OTLP mTLS in #465. (#468) - Bounded tool
result_texton the agent stream (#391): tool results are surfaced on the stream with a size bound. (#394) - Opt-in tool-dispatch timing (#28): stream-json
tool_resultframes can carry at_msdispatch duration. (#398) - Per-turn thinking cap (#62): a per-turn thinking-character cap bounds runaway extended-thinking spirals. (#396)
- Fail-closed token + TLS on the
calibandTCP session plane (#288): the networked session plane requires a bearer token and TLS rather than accepting unauthenticated plaintext. (#395)
Changed
- Permissions and sandbox controls fail closed (#410, #403, #404): an unparseable permissions config surfaces its parse error instead of silently dropping rules, v2 rule sets concatenate rather than overwrite, and an unusable sandbox or malformed domain ACL is an error rather than a silent no-op. (#438, #440, #437)
- Run span covers polling (#385):
gen_aispans nest under the run span rather than escaping it. (#389)
Security
Twelve of these close controls that were configured but inert in 0.5.0 — the policy was accepted and then not enforced. Known gap: the sandboxed child environment is still unscrubbed (#405) — see the note above. These fixes harden the write and egress fences; they do not make the sandbox a secrets boundary.
- Sandbox domain ACLs no longer no-op or invert egress (#403): a malformed or unsupported domain ACL silently allowed all egress, and in one path inverted allow/deny. Now fail-closed. (#440)
allow_unsandboxed_commandscannot be bypassed by chaining (#402): a chained command (allowed && evil) escaped the sandbox via the allowlisted prefix. (#434)- bwrap deny-masks apply to files and actually block writes (#407): masks covered directories only and did not prevent writes. (#450)
- Workspace-fence TOCTOU closed on the write path (#415): writes now go through a confined path, so the fence cannot be raced between check and open. (#459)
/rewindrefuses to write through a planted symlink (#413): checkpoint restore no longer follows a symlink out of the workspace. (#448)calibandcontrol plane and transport fail closed (#400, #401): the control-plane listener no longer serves unauthenticated clients, and the transport is hardened against pre-auth DoS and token-comparison timing leaks. (#433, #436)- MCP OAuth hardening (#431, #430): fixes a callback DoS and a cross-process token-store race, and enforces https on every OAuth discovery hop and bearer attach. (#456, #443)
- Legacy
hooks.tomlfenced from HTTP-hook allowlists (#409): a legacy hooks file can no longer inject entries into the user-managed HTTP-hook allowlist. (#435) - No false macOS per-host egress rule; fence root canonicalized (#408): the Seatbelt profile no longer emits a per-host egress rule it cannot enforce, and the fence root is canonicalized before comparison. (#462)
- Bound
gen_ai.*.messagesspan attribute size (#428): prompt capture cannot emit unbounded attributes. (#451) - Bump
crossbeam-epochto 0.9.20 (RUSTSEC-2026-0204). (#457)
Fixed
- Large Bash output can no longer deadlock (#416): stdout/stderr are drained past the output cap, so a command producing more than the cap no longer hangs. (#439)
- Checkpoint durability (#412): restore aborts before any mutation on a blob-integrity or missing-blob failure (the dominant case; a rarer phase-2 filesystem write error can still leave a partially-applied tree), correct eviction ordering, and an atomic index write. (#444)
- Deferred session-write failures surface; debounce is bounded (#414): a failed deferred write is reported rather than swallowed. (#461)
- Extended-thinking signatures survive streaming (#419): thinking-block signatures are preserved through the stream, so thinking blocks remain valid on replay. (#442)
- Streaming robustness (#424): usage deserialization, a
line_bufcap, tool-id handling, and truncation. (#455) - Anthropic prompt-cache tokens land in usage (#423): cache-read/write token
counts from
message_startare carried into the usage totals. (#446) - Compaction shrinks oversized
tool_use/thinking blocks (#421): caps are taken from the active model rather than a fixed constant. (#449) - No duplicate assistant message on surrender; empty content blocks dropped (#422). (#452)
- No-edit nudge cannot preempt a terminal stop reason (#420). (#447)
- Stable parallel-tool conflict key; new files respect umask (#417). (#453)
/configattributes each key to its true source scope (#411): keys are no longer misattributed to the wrong config file. (#463)- Pre-flight fatals route through the output encoder (#429): a fatal before the stream opens is emitted in the requested output format rather than as bare text. (#464)
- OTLP gRPC auth headers are applied (#426): headers configured for the gRPC exporter are attached via tonic metadata, and the headers helper is applied at startup. mTLS client certs remain unwired (#465). (#466)
- MCP robustness (#432): utf8-safe template handling, bounded elicitation, and truncated error bodies. (#454)
- Warm Ollama turns skip the static
/api/showprobe (#425): the capability probe no longer re-runs on every turn. (#458)
Docs: adopt OTel GenAI semantic conventions, semconv-only (ADR 0053, #376, #382);
reconcile ADR 0033 headers-helper drift to env-only reality (#381, #388); publish
CHANGELOG.md to the Pages site (#373).
0.5.0 - 2026-07-05
This release turns caliban from a single-process CLI into the base of a
distributed, self-hostable agent supervisor. caliband gains a networked
control plane, workspace-scoped multi-repo supervision, and multi-arch container
images; caliban learns to consume gonzalo's code-graph over MCP; and
config/data relocate to XDG-first locations. It also lands a broad reliability,
OAuth, and security-hardening pass. Behavior changes to review before
upgrading: config/data/cache/state now live in XDG locations (previously the
platform GUI dirs on macOS), and --workspace now fences file writes by
default. The caliband network transport is beta (hardening tracked in
#319/#320).
Added
- Workspace-scoped
caliband(#281): the supervisor now manages a workspace spanning multiple sources, with per-source worktree isolation wired end to end. (#325) calibandnetwork transport (#280) — beta: the daemon can serve its control plane over NDJSON on TCP with rustls TLS + a bearer token (--listen/CALIBAN_DAEMON_LISTEN), so a remote client (e.g. prospero) can drive it across the network rather than only a local Unix socket. (#321)- Consume the gonzalo code-graph MCP server (#308): a config entry wires
gonzalo's
search/node/callers/callees/impact/exploretools into the agent, over stdio or HTTP. (#310) - Dynamic Ollama model discovery (#316): the Ollama provider builds its model list and capabilities from the runtime API rather than a static table. (#322)
- OAuth Dynamic Client Registration (RFC 7591) (#313):
oauth="auto"MCP servers self-register a client when the provider supports DCR. (#315) - Multi-arch container image (#279):
caliban+calibandship as a single linux/amd64 + linux/arm64 image on GHCR. (#298) - Build commit in
--version(#303): binaries built from a git checkout now report the commit they were built from —caliban --versionprints e.g.caliban 0.5.0 (<sha>, <date>), appending-dirtyfor an uncommitted tree. Builds without git metadata (release tarballs, crates.io installs) fall back to the bare semver. (#305)
Changed
- XDG-first config/data/cache/state on all platforms (#295): caliban now
stores its config, data, cache, and state under XDG locations everywhere — on
macOS this moves them out of
~/Library/Application Support(ADR 0050). Existing files in the old locations are not migrated automatically. (#297) --workspacefences file writes by default (#237): under--workspace, file writes are restricted to the workspace unless you pass--no-restrict-paths. (#273)- Streaming-timeout policy raised above the transport layer (#330): connect,
first-byte, and total-exemption timeouts are applied uniformly above the
provider transport, so a hanging
stream()call is bounded like a silent stream. (#364) - Boolean CLI flags accept an optional
=BOOLvalue (#223): flags like--foonow also accept--foo=true/--foo=falseconsistently. (#293)
Security
- Clear all cargo-audit advisories + add a CI advisory gate (#258): resolved
all 6 outstanding
cargo-auditfindings and added a CI gate that fails on new advisories. (#260) - OAuth discovery enforces https + issuer match (#339): MCP OAuth discovery rejects non-https endpoints and mismatched issuers. (#357)
- OAuth token store writes are atomic +
0600(#341): the OAuth tokenFileStorewrites through a temp file with0600permissions. (#355) - Collapse
..before the workspace fence check (#327): path traversal is normalized before the workspace boundary is enforced. (#346) - Fence Bash writes via the OS sandbox under
--workspace(#328): background and foreground Bash writes are confined by the OS sandbox when a workspace fence is active. (#348)
Fixed
- Real compactor wired for
/compact+ autocompact (#292):/compactand automatic compaction now run an actual compaction pass. (#294) - Compactor strategy correctness (#329): fixes orphaned blocks, summarizer input, usage accounting, and the in-window tail. (#349)
- Prefill-aware stream watchdog + total-timeout exemption (#263, #254): a slow first chunk within the prefill budget no longer trips the idle watchdog, and the stream path is exempt from the total timeout. (#269)
- Sandbox degrades gracefully when user namespaces are denied (#345):
calibandnow probes for an actual user namespace and runs unsandboxed (with a warning) instead of failing every tool call on runtimes that installbwrapbut forbid unprivileged userns. (#371) write_atomicpreserves special bits + writes through symlinks (#335). (#350)Write/Editproduce0644(or preserve mode) (#224): edited files no longer inherit the tempfile's0600. (#291)- Result frame = final message + additive CC-contract fields (#222): the headless result frame carries the final message and the additive Claude-Code-contract fields. (#276)
duration_msis whole-session in multi-frame stream-json (#331). (#351)- Per-tool dispatch records + ignore/globset spam filtered (#256). (#257)
- MCP OAuth: cache before discovery, persist DCR
client_secret(#333). (#352) - Wire the MCP OAuth auto/manual flow into the connection path (#300). (#304)
- Complete settings-path MCP config plumbing (#309, #311): env expansion and the OAuth callback port are honored for settings-file MCP servers. (#312)
- Windows OAuth browser opener no longer truncates the auth URL (#338). (#356)
- Settings
${VAR}expander preserves non-ASCII text (#340). (#354) paths.rsXDG env-edge hardening (#336): relative fallbacks and non-absolute env values are handled. (#353)--version -dirtyignores untracked files (#306). (#307)
Testing: hermetic gonzalo code-graph contract test via an in-tree mock MCP
server, with the live round-trip honestly #[ignore]d (#344, #367); positive
prefill-grace assertions (#334, #368); closed the no_bare_platform_dirs guard
coverage holes (#337, #369).
Docs: introduced docs/evaluation/ and reorganized the probe + competitor docs
(#361, #362); corrected the container.md sandbox-fallback caveat (#345, #370).
Internal: migrated helper scripts from Python to bash (#360, #365); tracked
rebuild.sh and gitignored the Python bytecode cache (#359); container images
now build each arch natively on GitHub arm64 runners, dropping QEMU (#302).
0.4.0 - 2026-06-21
This release is a security and protocol-correctness pass on top of a completed
architecture-refactor sprint. It tightens permission resolution, hook egress, and
tool sandboxing across the board; aligns the headless result frame and terminal-stop
reporting with ADR 0025; hardens the model-router circuit breaker; and adds two TUI
input conveniences. Behavior change: several permission fixes are intentionally
stricter than v0.3.0 — actions that were previously allowed (broad MCP allows, ../
workspace escapes, mode-weakening flags under lockdown) are now denied. Review the
Security section before upgrading if you depend on the looser behavior.
Added
- Fuzzy slash-menu typeahead (#15): the slash-command menu now matches on fuzzy subsequences instead of prefix-only. (#146)
- Backslash-continuation for multi-line input (#101): end a line with
\then Enter to continue input across lines. (#136)
Changed
- Plan mode gates on tool capability, not a name allowlist (#162): read-only
enforcement now keys off
Tool::is_read_only, so plan mode correctly blocks any mutating tool rather than a hard-coded set. (#207) - One resettable wakeup per watched stream (#117): replace the per-poll wakeup with a single resettable timer, cutting stream-polling overhead. (#139)
Security
deny:mcp__*outranks server allows (#213): global rules are partitioned by action so a deny rule can no longer be overridden by a more specific server allow. (#228)- Block
../workspace escape (#216): relative path traversal out of the workspace is rejected, and a reason sentinel can no longer flip a static Deny. (#231) - SSRF guard + scoped HTTP-hook allowlists (#217): http-hook allowlists are scoped to user/managed, URLs are matched by component, and an SSRF guard blocks internal-address egress. (#232)
- Preserve static Deny under acceptEdits (#169): acceptEdits mode no longer weakens an explicit Deny rule. (#188)
- Lockdown refuses mode-weakening flags (#178): enforce-lockdown rejects CLI flags that would relax the active permission mode. (#191)
- Workspace-scope relative file-edit patterns (#177): relative edit patterns are resolved against the workspace root rather than matching loosely. (#189)
- OS sandbox applied to background Bash (#160): background Bash commands now run under the same OS sandbox as foreground ones. (#190)
- Marketplace downloads use the hardened HTTP client (#158): plugin marketplace fetches route through the SSRF-guarded client. (#187)
- Checkpoint byte-cap + integrity hardening (#220): enforce the checkpoint byte-cap, restore integrity checks, and prompt the index before the hook is wired. (#235)
Fixed
- Model router — circuit-breaker recovery (#215, #183): fix recovery concurrency, the recovery state machine, and hedge bugs; wire recovery to use a single probe and require N successes before closing. (#230, #200)
- Model router — route-resolved reasoning effort applied (#173): the effort resolved by the route is now applied to outgoing calls. (#198)
- Model router — tool-use capability parsing (#172): parse the
tool_usecapability requirement as a string enum. (#196) - Model router — router-debug default model (#144): derive the router-debug default model from CLI args. (#150)
- Headless result frame stays terminal (#218): the result frame is kept terminal
and
stream-jsoninput now activates headless mode. (#233) - Headless protocol parity (#184): budget no longer masks success, max-turns reporting reaches parity, and EventKind drift is corrected. (#208)
- Headless text mode surfaces non-success stops (#175): text output now reports non-success terminal stops instead of swallowing them. (#203)
--json-schemaapplied reliably (#214, #174): the directive applies even when a system message exists, instructs the model, and ships three validator fixes. (#229, #204)- Generation-agnostic Anthropic rate-card globs (#142): rate-card matching no longer pins to a specific model generation. (#148)
type:"text"on Anthropic system blocks (#141): emit the explicit block type. (#147)- Provider stream-interruption retry (#245): retry stream interruptions that occur before any content is produced. (#248)
- Google 400 bodies no longer trip fault markers (#221): classify Google 400
bodies correctly and fix the Vertex
list_modelsdoc. (#238) - Sub-agent no-edit nudge resets on edits (#244): the no-edit nudge resets on actual file edits, not on any side-effecting tool. (#246)
- AgentTool prompt truncation on a char boundary (#219): truncate the AgentTool Debug system prompt on a UTF-8 char boundary to avoid a panic. (#234)
- Sub-agent signal races (#115, #138): serialize Kill/Respawn on the registry
lock and close the
Rm --force/Respawn signal race. (#137, #145) agents logsreads the worker transcript (#143): read the worker's transcript file instead of the wrong source. (#149)- Hooks — filter/async/exit-2 handling (#171): apply the
iffilter, honorasync, and stop swallowing exit-2 denials. (#195) - Hooks — validation hardening (#185): event↔kind validation,
${VAR}header expansion, UpdatedInput validation, and a truncation panic fix. (#209) - Checkpoint byte-cap sweeper (#180): implement the per-project blob byte-cap sweeper. (#205)
- Checkpoint rewind correctness (#181): rewind keeps the prompt's assistant turn and uses a deterministic cwd hash. (#206)
- Agent-core — degenerate reasoning-only turns (#249): nudge reasoning-only turns instead of ending the run empty. (#253)
- Agent-core — MicroCompactor result ordering (#170): a failed result no longer supersedes a good one. (#193)
- Agent-core — ToolResultCap window clamp (#182): clamp head/tail windows to avoid overlap. (#199)
- Eval follow-ups (#240, #241): whitespace-tolerant Edit and transient-5xx retry. (#242)
- Config migrate detects legacy
permissions.toml(#176). (#202) - Perms CLI predictors mirror runtime (#179): plus lossless ordered export. (#201)
Internal: completed the architecture-refactor sprint (#152–#168) — extracted
RecoveryState and pure helpers from the turn-loop, segregated the Hooks trait,
decomposed the plugins-manager and TUI startup modules, converged provider transport
plumbing and error classification, centralized frontmatter/path helpers, and migrated
/usage, /context, /compact onto the slash-command registry.
0.3.0 - 2026-06-17
This release pairs extensibility — config-defined hooks that now fire at runtime, a SessionStart context-injection surface, and a proactive skill nudge — with a reliability pass on the background sub-agent supervisor, hardening the EventHub and worker channels against panics, unbounded memory, blocked readers, and idle-timeout overshoot. It also adds a user-facing extended-thinking toggle and tightens the Google provider's fault classification.
Added
- Config-defined hooks execute at runtime (#121):
[[hooks.*]]handlers in settings are now built into executingcommand/httphandlers and composed into the agent's hook chain (previously they were parsed but never fired). This completes end-to-end external[[hooks.SessionStart]]additionalContextinjection via the #106 surface.disable_all_hooksis honored;allow_managed_hooks_onlyconservatively fires none until handler scope provenance lands (#124);mcp/prompt/agentkinds are skipped with a warning. - SessionStart context-injection hook surface (#106):
session_starthooks can return aSessionStartOutcomewhoseadditional_contextis spliced into the system prompt before turn 1 (via a<session-context>block), letting skill packs / plugins ship their own activation preambles. The #56 built-in skills nudge remains an independent fallback. Ships a reusableadditionalContextparser; runtime execution of config-defined hooks is tracked in #121. (#122) - Proactive skill-invocation nudge (#56): the system prompt now lists loaded
skills and instructs the model to invoke a matching skill before improvising,
gated by
tools.skill_guidance. (#105) - User-facing extended-thinking toggle (#100): control extended thinking independently of the effort level. (#110)
- Shared cross-cutting area labels (#109): a shared "area core" label set spanning the caliban-ai repos. (#123)
Changed
- Immediate slash commands (#13): 19 eligible slash commands now execute immediately instead of requiring a confirmation step. (#104)
Fixed
- Inbound frame reader no longer blocks on a full worker channel (#118): the reader no longer stalls when the worker channel is full. (#134)
- Worker idle timeout uses a deadline (#119): switch to a deadline to remove idle-timeout overshoot. (#133)
- EventHub history is bounded (#116): cap EventHub history to bound worker memory. (#132)
- Inherited workers honor parent allow/deny rules (#114): propagate the parent runtime's allow/deny rules to inherited workers. (#131)
- Poisoned EventHub history lock recovers (#113): recover the lock instead of panicking. (#130)
- Google provider fault classification (#111): classify 400 context-overflow and in-band SSE faults. (#129)
/memory deletegated behind--force(#112): destructive memory deletion now requires explicit confirmation. (#120)- Skipped skills surfaced (#107): skills that fail to load are now reported instead of being silently dropped. (#108)
Docs: adopted the docs/adr/ convention to match prospero + gonzalo (#125), and
centralized GitHub Pages — ADR ingestion, shared theme, rustdoc (#128).
0.2.0 - 2026-06-13
This release centers on interactive background sub-agents and the supervisor machinery behind them: you can now spawn workers, attach to a live sub-agent's transcript, send it input, and have it idle while awaiting more — all under an inherited permission policy. It also adds observability flags, smarter Ollama context detection, and a more robust streaming/permissions layer.
Added
- Interactive background sub-agents (#81): sub-agents can now run in an
InputProvidermode that idles awaiting input and resumes interactively, backed by a bidirectional per-agent socket (SocketInputProvider), aworker → daemonstatus channel withAgentStatus::Idle, and a--interactivespawn path. Interactive workers bound their idle time when no client is attached. (#87, #89, #90, #91, #92) caliban agents attach(#79): stream a running sub-agent's transcript live, with a send path to feed the attached agent input. (#82)- Worker permission gating (#75): a spawned worker applies its
tool_allowlistand a default permission gate; background sub-agents inherit the parent's permission policy viainherit_hooks. (#84, #85) --verboseflag (#27): emit full headless tool I/O for observability.--debug-fileflag (#26): redirect the debug log to a chosen file.- Ollama context-window detection (#60): detect a model's real context
window via
/api/ps+/api/showinstead of assuming a default. (#64) - Full-fidelity event stream (#78):
TurnEventnow derivesSerialize/Deserialize, enabling complete event-stream capture and replay. (#80)
Changed
- Permissions "Ask" modal UX overhaul (#58): reworked the Ask modal and fixed a double-prompt so a decision is requested once. (#61)
Fixed
- Daemon-spawned workers honor a provider (#93): the daemon now threads the
requested provider through
SpawnSpec.providerinstead of defaulting. (#96) - Workers actually launch on Spawn (#71): the supervisor launches a real
worker on
Spawn, fixing agents stuck in theSpawningstate. (#74) agents rm --forcecleanup (#76, #77):--forcenow signals the worker and the per-agent socket is cleaned up on exit. (#83)- Mid-stream failures classified correctly (#63): body/decode failures that
occur mid-stream are now classified as
StreamInterruptedrather than a generic error. - Live permission rules (#55): "Always allow" / "Always deny" rules now take effect immediately, in-session. (#57)
Internal
- CI: resumable, rate-limit-aware crates.io publisher (#59) and a minimum-coverage gate with coverage tracking (#67).
- Testing: covered CLI subcommands and ratcheted the coverage floor 75 → 80 → 85
(#68, #72, #73); de-flaked the
strict_routingandhooks_shellraces. - Project: Kanban foundation — Kubernetes-style labels and board automation (#53).
- Docs: ADR 0047 for interactive background sub-agents (#86) and ADR hygiene pass (#98).
0.1.0 - 2026-06-06
Initial public release.