Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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), a verification_guidance knob (#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 in caliban config print via _env_overrides, closing the gap where env silently overrode the file. The first migrated cluster folds CALIBAN_OUTPUT_STYLE and CALIBAN_DEFAULT_PERMISSION_MODE into their settings keys and removes the ad-hoc std::env::var readers, with a CI lint (scripts/lint-env-registry.sh) banning new ad-hoc reads of migrated variables (#705, #706).
  • Settings-layer [router] section, preferred over caliban.toml and typed binary-side, with per-provider [router.provider.X] blocks for api_key_env / base_url (#540, #700; completed by #699).
  • caliban config import-router [--from <PATH>] [--dry-run] to migrate a legacy caliban.toml router 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_CONFIG file as the highest-precedence override; the walk-up / ~/.config/caliban/caliban.toml discovery was removed, so a bare repo-root caliban.toml is no longer auto-loaded (a startup warning points at caliban config import-router) (#699, #704; ADR 0060, amends ADR 0038).
  • Honor the output_style setting 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_excludes and the env-backed settings that were parsed but silently dropped on load (#694, #695).

Documentation

  • The caliban-contract router_config field carries a config-file path, not inline JSON (#690, #696).
  • Stop promising live settings reload — settings are read once at startup; the SettingsWatcher scaffolding 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 typed permission_posture (supervised default / 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 the CalibanTask CR enum. ADR 0059. (#678)
  • Tool-call input + accounting over ACP (#674): the ACP adapter now surfaces accumulated tool-call rawInput and 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 stdio caliban acp serve path is unchanged. (#681)
  • A thin caliban-contract crate (#656): caliban's launch and control-plane contract — the CalibandLaunch builder (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-supervisor re-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/*.toml is 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 with exit 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 reports model_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 /n checkpoint 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 Drain control command SIGTERMs live agents, marks them Drained, 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_session reference continues from the persisted session.json, completing the drain → resume round-trip. (#654)
  • Environment overrides for the storage substrate (#659): CALIBAN_STORAGE_SUBSTRATE, CALIBAN_STORAGE_REMOTE_URL, and CALIBAN_STORAGE_REMOTE_TOKEN_ENV override 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. The token_env indirection keeps the secret out of settings. (#667)

Fixed

  • /rewind actually restores now (#549): the CheckpointHook was never installed, so per-prompt checkpoints were never recorded and /rewind had 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-ollama provider (#634, #635), per ADR 0056. --provider ollama is no longer valid — a run configured with it fails loudly at startup (unknown provider 'ollama' — supported: anthropic, openai, google). Reach local models through --provider openai with a base_url; see Local Inference. BREAKING. (#640)

Added

  • /v1/models discovery shim for the OpenAI adapter (#632): when pointed at a local /v1 endpoint, the adapter discovers the served models and reads each one's loaded context window from meta.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_url is 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 under reasoning rather than reasoning_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 in caliban-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 / --bg reject an empty prompt instead of launching a doomed sub-agent; --continue and --resume now conflict rather than silently ignoring -c; --max-budget-usd rejects 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-mode flags when permissions.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, and stream_prefill_timeout_ms now 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_threshold never 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 import now translate Claude Code's Bash(cmd:*) command-prefix specifier to caliban's glob form, so a migrated allow/deny list is no longer silently inert — an imported deny now blocks. (#624)
  • config print / settings import accuracy (#620): config print no longer shows default allow/ask rules a rules-only config never set, now emits per-key _provenance, and settings import --dry-run validates 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::bind fail-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 uploads caliban-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_telemetry is 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, and stream_prefill_timeout_ms are 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 echoing state (RFC-noncompliant but real) is now reported instead of hanging the callback wait until the 5-minute timeout; the state-mismatch injection/DoS guard is preserved. (#603)
  • Slash-command / overlay descriptions no longer overpromise (#589): /login, /logout, and the /mcp overlay's disable/reload keys now describe their actual (stubbed) behavior rather than unimplemented features. (#600)
  • CALIBAN_KEEP_WORKTREES is 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-call keep_on_exit route 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_url is 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_NOFOLLOW writer (#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 / input contract 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 — a session/prompt call streams session/update notifications for one turn, and tool-permission prompts surface into the editor's own UI via session/request_permission (#530, #570).
    • HTTP serve (caliban http serve): drive caliban over plain HTTP/JSON from a script or curl — 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).

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_tokens on 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 named Bash(git *) and could never match. Following the printed guidance verbatim left the tool denied. Tool(<glob>) and Tool:<glob> are now interchangeable spellings everywhere patterns are parsed, including [permissions.auto] lists. This also un-breaks caliban 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 unclosed Bash(git *, an empty Bash(), a malformed glob) are now reported at startup, by caliban perms lint, and by caliban 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 curl session).
  • ADR 0055 records the driveable-server-surface design — three adapters over one core, the sequencing, and the auth/permission model (#533).
  • cargo install caliban is 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_NAME inherited 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_CA and CALIBAN_CONTROL_TLS_SERVER_NAME to 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 a failed agent 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, cargo against crates.io, npm install, gh, and curl will fail inside sandboxed commands unless you opt out with --sandbox-network=allow (or sandbox.network = "allow" in settings.json). A sandboxed command that fails while egress is blocked now says so and names the opt-out.

    Filesystem reads remain open by design — ~/.ssh and ~/.aws/credentials are 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=allow restores the exfiltration path, so use it deliberately. Per-hostname allowlists require a proxy (#477). See ADR 0054.

Added

  • sandbox section in settings.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*, plus OTEL_EXPORTER_OTLP_HEADERS) from a Bash command's environment, so ANTHROPIC_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 dumps env into a log or a file. This is a name-based filter; a secret in an innocuously-named variable is not caught. (A per-variable passthrough escape hatch to keep a matched variable is not yet configurable via settings — the scrubber currently keeps nothing back; tracked in #499.)

Fixed

  • allow_local_binding no longer grants full egress (#476): bwrap skipped --unshare-net whenever the flag was set, so a narrow, local-sounding permission ("let this command bind a test-server port") silently opened the entire internet. --unshare-net is 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-exec rejects — (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 * or localhost, 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 set allow_local_binding or a proxy port — the new fence sets the former. The generated profile is now compiled by the real sandbox-exec in 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_ai chat-generation span per model request (#378, #384) and an execute_tool span with gen_ai.tool.* attributes per tool call (#386).
  • Optional prompt/completion capture on spans (#380): gen_ai input and output messages are recorded on spans when OTEL_LOG_USER_PROMPTS is set — off by default, since they contain user content. (#387)
  • OTLP metrics pipeline (#427): a real MeterProvider with a periodic reader honoring OTEL_METRIC_EXPORT_INTERVAL, with MetricEmitter::record wired into live instruments, so emits reach the collector. session.count flows today; cost/token/active-time emits are tracked in #467 and OTLP mTLS in #465. (#468)
  • Bounded tool result_text on 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_result frames can carry a t_ms dispatch 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 caliband TCP 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_ai spans 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_commands cannot 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)
  • /rewind refuses to write through a planted symlink (#413): checkpoint restore no longer follows a symlink out of the workspace. (#448)
  • caliband control 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.toml fenced 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.*.messages span attribute size (#428): prompt capture cannot emit unbounded attributes. (#451)
  • Bump crossbeam-epoch to 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_buf cap, tool-id handling, and truncation. (#455)
  • Anthropic prompt-cache tokens land in usage (#423): cache-read/write token counts from message_start are 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)
  • /config attributes 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/show probe (#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)
  • caliband network 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/explore tools 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 + caliband ship 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 --version prints e.g. caliban 0.5.0 (<sha>, <date>), appending -dirty for 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)
  • --workspace fences 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 =BOOL value (#223): flags like --foo now also accept --foo=true / --foo=false consistently. (#293)

Security

  • Clear all cargo-audit advisories + add a CI advisory gate (#258): resolved all 6 outstanding cargo-audit findings 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 token FileStore writes through a temp file with 0600 permissions. (#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): /compact and 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): caliband now probes for an actual user namespace and runs unsandboxed (with a warning) instead of failing every tool call on runtimes that install bwrap but forbid unprivileged userns. (#371)
  • write_atomic preserves special bits + writes through symlinks (#335). (#350)
  • Write/Edit produce 0644 (or preserve mode) (#224): edited files no longer inherit the tempfile's 0600. (#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_ms is 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.rs XDG env-edge hardening (#336): relative fallbacks and non-absolute env values are handled. (#353)
  • --version -dirty ignores 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_use capability 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-json input 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-schema applied 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_models doc. (#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 logs reads 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 if filter, honor async, 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 executing command/http handlers and composed into the agent's hook chain (previously they were parsed but never fired). This completes end-to-end external [[hooks.SessionStart]] additionalContext injection via the #106 surface. disable_all_hooks is honored; allow_managed_hooks_only conservatively fires none until handler scope provenance lands (#124); mcp/prompt/agent kinds are skipped with a warning.
  • SessionStart context-injection hook surface (#106): session_start hooks can return a SessionStartOutcome whose additional_context is 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 reusable additionalContext parser; 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 delete gated 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 InputProvider mode that idles awaiting input and resumes interactively, backed by a bidirectional per-agent socket (SocketInputProvider), a worker → daemon status channel with AgentStatus::Idle, and a --interactive spawn 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_allowlist and a default permission gate; background sub-agents inherit the parent's permission policy via inherit_hooks. (#84, #85)
  • --verbose flag (#27): emit full headless tool I/O for observability.
  • --debug-file flag (#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/show instead of assuming a default. (#64)
  • Full-fidelity event stream (#78): TurnEvent now derives Serialize/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.provider instead of defaulting. (#96)
  • Workers actually launch on Spawn (#71): the supervisor launches a real worker on Spawn, fixing agents stuck in the Spawning state. (#74)
  • agents rm --force cleanup (#76, #77): --force now 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 StreamInterrupted rather 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_routing and hooks_shell races.
  • 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.