Skip to content

v0.8.0

Latest

Choose a tag to compare

@github-actions github-actions released this 01 May 22:18
Immutable release. Only release title and notes can be modified.
bb52d03

Summary

  • Provider setup and runtime routing now require explicit provider:model
    IDs across config, request bodies, and WebSocket surfaces; bare and
    slash-form model strings are rejected.
  • Provider coverage extends to Codex subscription-login, Vertex AI, Bedrock,
    Venice AI, and the local Claude CLI alongside Anthropic, OpenAI, Gemini,
    and Ollama.
  • WebSocket and HTTP configuration/model errors expose public-safe messages
    and typed error codes while logging operator hints server-side.
  • Hot-reload bridge owns the provider-cache write so rejected reloads no
    longer broadcast spurious change ticks; build_providers runs on
    spawn_blocking so the runtime worker is not blocked during reload.
  • Built-in usage pricing table has been removed; cost_usd and per-period
    cost fields are computed only from operator-configured rates under
    gateway.usage.pricing.{default,overrides}. Cost-bearing WS responses
    carry pricingConfigured: bool so clients can tell "not configured" from
    "actually $0".
  • Security hardening rejects known plaintext credential files at startup
    and unsupported encrypted config-secret envelopes at config load.

Breaking Changes

  • Built-in usage pricing table removed. usage.status, usage.cost,
    usage.session, usage.providers, usage.daily, and usage.monthly
    continue to track input/output tokens and request counts, but
    cost_usd (and the per-period cost field on daily/monthly) is 0.0
    unless the operator configures rates under
    gateway.usage.pricing.{default,overrides}. Each cost-bearing
    response includes a top-level pricingConfigured: bool. A startup
    warn fires once per process when usage tracking is enabled but no
    pricing rates are configured. Carapace is not a billing source of
    truth — provider rates change frequently with region, batch/flex
    modes, cached-token discounts, subscriptions, and OpenAI-compatible
    proxies, and we will not carry stale numbers that silently mislead.
  • Bare and slash-form model IDs are rejected. Use canonical
    provider:model values: anthropic:claude-sonnet-4-6,
    anthropic:claude-opus-4-7, openai:gpt-5.5,
    gemini:gemini-2.5-flash, vertex:gemini-2.5-flash,
    bedrock:anthropic.claude-sonnet-4-6, ollama:llama3.2,
    codex:default, venice:llama-3.3-70b, or claude-cli:default.
  • Classifier fallback rebound to the agent's primary model.
    agents.defaults.classifier.model previously defaulted to a
    hard-coded gpt-4o-mini that was unroutable for non-OpenAI setups.
    It now falls back to the agent's primary model. If your agent runs
    on a strong model (e.g. anthropic:claude-opus-4-7,
    openai:gpt-5.5), every classified message now hits that model.
    Set gateway.classifier.model explicitly to a small/cheap model
    like openai:gpt-5-nano or anthropic:claude-haiku-4-5 for
    cost-sensitive deployments.
  • Plugin sandbox defaults are snake_case.
    gateway.plugins.sandbox.defaults keys are allow_http,
    allow_credentials, allow_media. The camelCase form was always
    silently ignored at runtime; the schema validator now warns on it
    during config load.
  • Removed compatibility shapes fail closed. Config aliases removed
    in earlier releases, old WebSocket method aliases, and removed wire
    shapes now fail validation or return method errors instead of being
    accepted.
  • Plaintext credential files rejected at startup. Gateway startup
    refuses known plaintext credential files in the state directory.
    Delete those files and re-enroll via current setup/import flows.
  • Unsupported config-secret envelopes fail config load. Re-enter or
    re-encrypt secrets as supported enc:v2 values.
  • cara backup covers handled sections only. Archives sessions,
    config, memory, cron, tasks, and usage. Excludes OS
    credential-store secrets, auth_profiles.json, managed plugin
    binaries, node/device registries, and arbitrary state-dir files.
    Preserve credential recovery material separately.
  • Direct /hooks/agent JSON wire format is camelCase. Field names
    are wakeMode, timeoutSeconds, allowUnsafeExternalContent,
    veniceParameters, sessionKey. Unchanged from v0.7 in shape; this
    release supersedes intermediate doc drafts that suggested
    snake_case.

Migration Steps

  1. Create a backup before upgrading and store credential recovery
    material separately:
    • cara backup --output ./carapace-backup-v0.7.x.tar.gz
  2. Convert any bare or slash-form model IDs in config.json5 and
    request bodies to canonical provider:model form.
  3. If you rely on cost reporting, set per-model rates under
    gateway.usage.pricing before upgrading. Example:
    {
      gateway: {
        usage: {
          pricing: {
            default: { input_per_1m_usd: 0, output_per_1m_usd: 0 },
            overrides: {
              "anthropic:claude-sonnet-4-6": {
                input_per_1m_usd: 3.0,
                output_per_1m_usd: 15.0
              }
            }
          }
        }
      }
    }
  4. If your agents rely on classifier-driven routing and you have not
    set gateway.classifier.model, set it now to a small/cheap model
    so every classified message does not run on your primary model.
  5. If your config uses gateway.plugins.sandbox.defaults with
    camelCase keys (allowHttp etc.), rename them to snake_case.
  6. Remove any plaintext credential files reported by startup, then
    re-run setup/import flows.
  7. Re-enter or re-encrypt unsupported encrypted config secrets as
    enc:v2 values.
  8. Recreate backups under the current format after the upgraded
    binary is verified.

Rollback Steps

  1. Stop Cara.
  2. Reinstall the previous known-good binary (v0.7.0 pinned tag).
  3. Restore the backup created before upgrade:
    • cara restore ./carapace-backup-v0.7.x.tar.gz
  4. Revert any v0.8.0-only config changes (added gateway.usage.pricing
    keys, snake_case sandbox key renames) before starting v0.7.0.
  5. Re-enroll any credentials intentionally excluded from
    cara backup.
  6. Verify:
    • cara status --port 18789
    • cara verify --outcome auto --port 18789
    • cara verify --outcome autonomy --port 18789

Security

  • Startup fails closed when known plaintext credential files are
    detected.
  • Current config-secret envelopes use enc:v2 with Argon2id-derived
    keys; legacy envelopes are rejected at config load.
  • Session integrity uses HMAC sidecars for metadata, history, and
    archives; with sessions.integrity.action = "reject", tampered
    state is rejected.
  • Encrypted sessions require .crypto-manifest plus
    CARAPACE_CONFIG_PASSWORD for recovery.
  • CLI device identity uses the OS credential store when available
    and falls back to {state_dir}/device-identity.json; set
    CARAPACE_DEVICE_IDENTITY_STRICT=1 to disable that fallback.
  • Bumped hickory-{net,proto,resolver} to 0.26.1 to address
    RUSTSEC-2026-0119 and RUSTSEC-2026-0120 (DNS DoS).

Verification

  • Verify published artifacts and Sigstore bundles:
    • RELEASE_TAG=v0.8.0 ./scripts/smoke/verify-release-artifacts.sh
  • After upgrading, verify runtime behavior:
    • cara verify --outcome auto
    • cara verify --outcome autonomy
  • Confirm /health/ready is ready and logs do not report provider
    reload rollback, credential-shape rejection, or unconfigured-pricing
    warnings you did not expect.
  • If you configured gateway.usage.pricing, issue a real request and
    call usage.cost; confirm pricingConfigured: true and a non-zero
    totalCost.

Known Caveats

  • Carapace does not ship per-provider price defaults. cost_usd is
    0.0 until rates are configured. This is intentional — operators
    know their own contracts (region, batch mode, cached-token
    discounts, subscriptions) better than we can encode in a shared
    table.
  • Hot-reload bridge runs build_providers on spawn_blocking; the
    runtime worker is no longer blocked during a provider rebuild.
    Rejected reloads broadcast zero ticks on CONFIG_CHANGE_TX and
    validate against the payload they carry rather than the latest
    cache value.
  • WS config.reload routes through the same provider-validation
    pipeline as the file-watcher and SIGHUP paths; reloads that drop
    the LLM provider return ERROR_UNAVAILABLE to the WS client.
  • Signal read receipts, when enabled, are sent after durable append
    and before assistant reply generation/delivery.
  • Plugin ABI remains carapace:plugin@1.0.0; WASM provider plugins
    are identifiable but not wired into agent model selection.