Skip to content

Backend registry

Picking a backend per spawn with --backend is the foreground choice. The backend registry is the durable background picture behind it: warden detects the coding-agent CLIs installed on this machine and remembers, per backend, how it’s billed, whether it’s enabled, and which one is the default — plus a machine-wide internal-thinking mode.

That store is warden’s single source of truth for backends. Two subsystems read from it:

  • Autopilot’s cost-tier ladder — cheapest-first backend selection for the manager and guardian.
  • The internal free/local thinking router — warden’s own thinking (task classification, agent naming, digest narration, memory curation) routed strictly through free and local backends, never a paid call.

The mental model: detection is a fact, tiering is a preference

Section titled “The mental model: detection is a fact, tiering is a preference”

The registry keeps two kinds of data per backend, and a rescan treats them differently:

KindFieldsOn rescan
Detection (fact)installed, binary_path, detected_atReconciled — newly installed CLIs are added; vanished ones are marked uninstalled
Preference (yours)tier, default, enabledPreserved — a rescan never overwrites your choices

So you can warden backend rescan freely: it refreshes what’s on disk without ever resetting how you tiered things.

The store lives in an embedded ScrivaDB collection at ~/.warden/backends and is managed by the daemon — every surface below is a thin caller of the same /api/v1/backends* endpoints.

Alongside the detected CLIs, the registry always carries a reserved local row — a $0, never-rate-limited class representing warden’s local model. It is special:

  • Its tier is the system-set local (you can’t re-tier it).
  • It can never be a user-agent default.
  • It is the terminal candidate of the internal-thinking walk — the fallback that always answers.

Every detected backend carries a billing tier:

TierMeaning
freeA $0 backend (you run it on a free plan). The only CLI tier the internal-thinking router calls.
subscriptionCovered by a flat subscription.
pay_per_useMetered / pay-as-you-go.
unclassifiedNot yet tiered. A newly detected CLI starts here, treated as not free.
localReserved, system-set — the local row only.

A newly detected CLI is unclassified until you tier it, so warden never assumes a backend is free (and never routes internal thinking to it) without you saying so.

warden does a fair amount of its own “thinking” — classifying a task, summarizing activity, naming an agent, narrating a digest, curating project memory. This is internal, non-user-facing work, and warden routes it only through free and local backends. It never makes a paid call. The thinking-mode picks the walk:

ModeWalk
local_onlyThe local model only.
free_plus_local (default)Eligible free CLI backends first (default-first, then stable id order), then the never-limited local model.

A free CLI backend is eligible only when it is installed, enabled, tier free, and not currently rate-limited. On a rate-limit / spend signal warden stamps that backend limited (config backends.limit_retry, default 15m) and moves to the next candidate. When the walk is exhausted, the caller degrades gracefully — a deterministic slug, a skipped narration, the default task bucket, no memory proposal — rather than escalating to a subscription / pay_per_use backend.

Terminal window
warden backend list # full table incl. the reserved local row (alias: ls)
# ID INSTALLED TIER DEFAULT ENABLED LIMITED
# aider ✓ unclassified - ✓ -
# claude ✓ subscription ✓ ✓ -
# codex ✓ free - ✓ -
# local - local - ✓ -
#
# internal thinking mode: free_plus_local
warden backend rescan # re-detect installed CLIs (preferences preserved)
warden backend tier codex free # free | subscription | pay_per_use | unclassified
warden backend default claude # set the single default (rejects local)
warden backend enable codex # / warden backend disable aider
warden backend thinking-mode local_only # or free_plus_local

warden backend default <id> is rejected for an unknown, uninstalled, disabled, or reserved (local) target — the same rules the daemon enforces.

Open the 🧩 backends button in the web AttentionBar (Esc closes it). It’s a table with a Tier dropdown, a Default radio, an Enabled checkbox, and a live Limited countdown per row, plus a header thinking-mode selector and a ⟳ Rescan button. The reserved local row shows a static “Local” tier and a disabled default radio.

Press b in the TUI cockpit to open the Backends page:

KeyAction
tCycle the focused backend’s tier
d / enterMake it the default
e / spaceToggle enabled
mFlip the internal-thinking mode
rRescan
esc / bBack

For an orchestrating agent:

ToolDoes
list_backendsThe whole registry + settings (read-only)
rescan_backendsRe-detect and reconcile, return the refreshed registry
set_backend_tierAssign a billing tier
set_default_backendSet the single default
set_thinking_modeSet local_only / free_plus_local

Enabling/disabling a backend is intentionally not an MCP tool — it is available on the CLI, web, and TUI, and over REST as PATCH /api/v1/backends/{id}.

Autopilot’s cost-tier backend ladder and its paid-autopilot gate are derived from this registry: only installed, enabled, non-local backends are eligible, bucketed by tier, cheapest first. So the way you steer autopilot’s spending is simply how you tier backends here.