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-operator 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.

The operator is not published to crates.io (publish = false). A release is a container image: tagging a merge commit v* fires release-image.yml, which publishes ghcr.io/caliban-ai/caliban-operator:<version> for linux/amd64 and linux/arm64.

Entries before v0.6.0 were back-filled from the release: commit messages that were, until this file existed, the only record of what each tag contained. They are therefore summaries at the granularity those commits recorded, not the per-change detail used from v0.6.0 onwards.

Unreleased

0.7.0 - 2026-10-06

The release that makes a second replica safe, and moves the agent's posture out of untyped env and into the API.

Leader election is on by default, so replicas: 2 is a standby rather than a race. A Workspace now declares its agent policy as typed fields the operator validates and projects — and the settings that leave an agent unsupervised are admitted only where the Workspace authorizes them, extending ADR 0006's rule to the policy itself. A task can override just the model. The sandbox pod runs as the agent's own uid, so clones it writes are usable.

Needs caliban-crds >= 0.2.9 for the agentPolicy fields, model.name and the
state.mode enum, and the Lease RBAC from caliban-operator chart >= 0.2.11.
Upgrading begins enforcing the unsupervised-policy gate: a Workspace that sets
permissionMode dontAsk/bypassPermissions or noPermissions without
agentPolicy.allowUnattended is refused, fail-closed, where v0.6.0 ignored it.

Added

  • Leader election, on by default. The controller acquires a coordination.k8s.io Lease before running either reconciler and returns to standby if it loses it, so running more than one replica is safe rather than a race between two writers. Configured by CALIBAN_LEADER_ELECTION (default on), CALIBAN_LEASE_NAME, CALIBAN_LEASE_NAMESPACE, CALIBAN_LEASE_DURATION_SECONDS and CALIBAN_LEASE_GRACE_SECONDS; the holder identity comes from POD_NAME. Needs the Lease RBAC added in caliban-charts (#48, PR #96)

  • Typed agent permission posture on Workspace. spec.agentPolicy gained permissionMode, autoAllow and noPermissions, projected into the agent's environment instead of travelling as untyped env entries. The settings that leave an agent unsupervised — permissionMode: dontAsk or bypassPermissions, noPermissions — are admitted only on a Workspace whose agentPolicy.allowUnattended is true, which extends ADR 0006's existing authorization rule to the Workspace's own policy (recorded as decision 7 in that ADR) (#51, PR #88)

  • Typed agent extension posture on Workspace. spec.agentPolicy also gained noMcp, noHooks, noSkills, noSubAgent, strictKnownMarketplaces, enabledPlugins, blockedMarketplaces and parallelToolLimit. Typed fields take precedence over any same-named env entry, and list fields project even when empty — an empty enabledPlugins means enable none, which is a different instruction from leaving it unset (#87, PR #89)

  • Per-task model override. CalibanTask.spec.model.name overrides the resolved workspace provider's model for one task, applied at the resolve-and-pin step so the override is recorded in status.resolvedWorkspace like every other pinned value (#52, PR #91)

Fixed

  • The sandbox pod runs as the agent's uid. The pod spec now carries a securityContext with runAsUser/runAsGroup/fsGroup set to the agent uid (default 10001, configurable via CALIBAN_AGENT_UID / CALIBAN_AGENT_GID) and runAsNonRoot. Before this, clones written by the agent were owned by a different uid than the one that had to use them (#79, PR #85)

  • An invalid state.mode is refused at admission. The CRD schema now carries enum: [remote, local], so the apiserver rejects a bad mode on write — the same moment permissionPosture already failed. The enum is in the schema and deliberately not in the Rust type: a task stored before the enum existed may hold any value, and a typed enum would make such an object fail to deserialize entirely, which is worse than the clear Failed status it gets now. The reconcile-time cross-field checks (remote needs an endpoint, local must not have one) are unchanged (#94, PR #97)

Internal

  • The Rust toolchain now lives in exactly one place. rust-toolchain.toml moved to 1.99.0 and is the only pin: ci.yml installs with dtolnay/rust-toolchain@stable and the Dockerfile uses FROM rust:1-bookworm, both deferring to the file, which rustup honours when cargo runs. Previously the version was written in three places that could drift (#90, PR #98)

  • caliban-contract pinned to =0.15.0, in lockstep with prospero (caliban-ai/prospero#266) so the contract's two downstream consumers never disagree about its version. Nothing the operator compiles against changed — launch.rs is the only file differing between the versions. Worth knowing downstream: CalibandLaunch.router_config kept its type but changed meaning, from inline config JSON to a filesystem path, so a caller passing JSON still compiles and silently has it read as a path. The operator passes the mounted ConfigMap path (#95, PR #99)

  • Documentation audit against the shipped code: CRD and deploying references brought current, README moved to v0.6.0, and the missing ADR template restored (PR #86)

  • This file, and an mdBook guide published from docs/guide/. The operator was the only repo in the suite with neither. The guide ingests the ADR log, this changelog and the three reference docs at build time, so each has exactly one editable copy (#92, PR #100)

  • Six append-only notes recording where the code has overtaken ADRs 0001, 0002 and 0003 — the volumeClaimTemplates type, two Sandbox fields that were never declared, the control-plane TLS environment variables removed in #59, the now-configurable cluster DNS domain, serde_yaml → serde_norway, and the target cluster moving to k3s v1.36. No decision prose was altered (#93, PR #101)

  • The guide's published links are now checked. Crawling the newly published site found three 404s on the ADR 0000 page — template.md, README.md and a bootstrap-spec reference — each correct as a file on GitHub and dead once rendered, because only files listed in SUMMARY.md become pages. The ADR ingest now rewrites links that leave the book to absolute URLs, protecting the ingested chapters so an in-book ../<chapter>.md still resolves, and covering both the inline ](url) and reference [label]: url forms. The bootstrap reference points at caliban, where that document actually lives — it had never resolved in this repo. check-links.sh runs in docs.yml and resolves every internal href, plus any link back into this repository, against what the build produced; it was proven to fail by re-introducing a dead link. mdBook validates no markdown links, so all three had published with zero build warnings (PR #103, PR #104)

  • Changelog catch-up: #100 and #101 were missing from the file #100 created (PR #102)

0.6.0 - 2026-09-19

Per-session permission posture, and caliband's launch surface sourced from the contract crate rather than hand-written strings.

Added

  • CalibanTask.spec.task.permissionPosture (supervised | unattended), admitted only under a Workspace whose agentPolicy.allowUnattended is true. The effective posture is reported in status and shown as a Posture printer column. Recorded as ADR 0006 (#81)

Changed

  • caliband's flags and environment variable names now come from caliban-contract 0.14.0, and provider credential environment names from ProviderKind, so the operator no longer carries its own copy of caliband's launch surface (#83)

  • CRD documentation fixes: tokenRef principal guidance, and an egress example using an RFC 5737 documentation address (#77)

Requires caliban-crds >= 0.2.5 for the permissionPosture / agentPolicy fields.

0.5.0 - 2026-09-16

Terminal phases, workspace egress control, storage settings and Kubernetes Events — 17 PRs.

Added

  • AgentsSettled resolves to a terminal phase (#75)
  • Workspace egress allow-list (#74)
  • spec.state storage settings plus a gonzalod token (#76)
  • Kubernetes Events for reconcile outcomes (#73)
  • Sandbox resource requests and limits (#62)
  • Configurable cluster DNS domain (#71)
  • Server-side-apply status writes (#67)
  • A watch on owned Sandbox objects (#68)

Fixed

  • Reconcile, config, RBAC and CRD fixes (#60, #61, #63, #65, #69, #70, #72)
  • Documentation corrections (#66, #77)

0.4.0 - 2026-09-13

Interactive tasks, sandbox reachability fixes, and the removal of Ollama.

Added

  • CalibanTask.spec.task.interactive (#28, PR #29)

Fixed

  • Project the provider base URL and API key under provider-native environment variable names (#31)
  • Pass the session-plane CA to caliband (#33)
  • Make Workspace.spec.sources optional (#34)
  • Pass --tls-server-name so workers verify against the certificate SAN (#36)

Removed

  • Ollama support. Samples, CRDs and tests migrated to kind: openai with an explicit baseUrl, which covers the same deployments without a dedicated provider kind (#39)

0.3.1 - 2026-07-19

Fixed

  • Per-agent stream reachability in Kubernetes. build_sandbox passes --advertise-host <sandbox>.<ns>.svc.cluster.local and pins --agent-port-base, and the sandbox NetworkPolicy opens the per-agent stream window (7100–7999) alongside 8443. Without this, prosperod could not attach to a k8s agent's output because caliband advertised tcp://0.0.0.0:7100 (#24, #25, PR #26)

0.3.0 - 2026-07-18

Fixed

  • build_sandbox launches caliband with the shared session-plane bearer token and TLS, so the pod binds instead of crash-looping on "a non-empty bearer token is required" (#22, PR #23)

0.2.0 - 2026-07-12

The configuration plane: a Workspace custom resource, and resolve-and-pin.

Added

  • Workspace CRD (v1alpha1), with CalibanTask.workspaceRef / providerRef resolve-and-pin (#11, PR #12)

Changed

  • Breaking (pre-v1). Inline CalibanTask.spec.workspace removed in favour of workspaceRef (#11, PR #12)
  • Gate the CalibanTask pin on Workspace readiness (#13, PR #18)

Fixed

  • CRD schema validation, graceful shutdown, and serde_yaml → serde_norway (#2, PR #10)

Removed

  • Dead WorkspacePhase::Reconciling variant (#14, PR #17)
  • Orphaned CalibanTaskStatus.workspace field (#15, PR #16)

0.1.1 - 2026-07-05

First release that reconciles end to end.

Fixed

  • volumeClaimTemplates TypeMeta, so a CalibanTask reconciles into a Sandbox that agent-sandbox v0.5.0 accepts (#7, PR #8)

0.1.0 - 2026-07-05

Added

  • The container image and its multi-arch release workflow. A two-stage Dockerfile (rust:1.95-bookworm → debian:bookworm-slim + ca-certificates) builds the controller and runs it non-root as uid 10001, matching the Helm chart's securityContext; the controller writes nothing to disk, so it runs under a read-only root filesystem. release-image.yml builds both arches and publishes ghcr.io/caliban-ai/caliban-operator on v* tags (caliban-ai/caliban#358, PR #5)