Skip to content

Backend registry reference

The agent-backend registry is warden’s persistent, machine-wide record of which coding-agent CLIs exist, how they’re billed, and which is the default. For the narrative and the mental model, see the Backend registry guide; this page is the flat reference.

One record per backend (keyed by its stable id) plus a reserved settings singleton, in an embedded ScrivaDB collection at ~/.warden/backends.

FieldTypeNotes
idstringStable id (claude, codex, aider, …)
installedboolBinary found on PATH — detection fact
binary_pathstringResolved LookPath — detection fact
detected_attimestampLast reconcile — detection fact
tierstringfree | subscription | pay_per_use | unclassified — preference
defaultboolAt most one row is true — preference
enabledboolWhether the backend may be used — preference
is_localboolDeprecated — the reserved local row is pruned; always false
limited_untiltimestampRate-limit expiry stamped on a spend / limit signal

Detection fields are reconciled by a rescan; preferences are preserved by a rescan.

FieldTypeNotes
internal_thinking_modestringDeprecated, ignored — thinking-mode was retired with the local router; internal thinking runs on Fast-Brain
allow_paid_autopilotboolThe paid-autopilot gate (migrated from autopilot.brain.allow_pay_per_use)
TierMeaning
free$0 backend (free plan)
subscriptionFlat subscription
pay_per_useMetered / pay-as-you-go
unclassifiedNot yet tiered (a newly detected CLI); treated as not free

warden’s own micro-cognition (classify, summarize, naming, commit messages, curation, digest/insights narration, REPL planning) runs on Fast-Brain (internal/fastbrain) — latency-bounded and fail-open — not on a registry walk. The former thinking-mode, the reserved local row, and the local-LLM/Ollama provider are retired; local_llm.* YAML keys still parse but are ignored.

CommandDoes
warden backend list (alias ls)Print the registry table (ID, installed, tier, default, enabled, limited)
warden backend rescanRe-detect installed CLIs, reconcile detection, preserve preferences
warden backend tier <id> <tier>Assign a tier (free|subscription|pay_per_use|unclassified)
warden backend default <id>Set the single default (rejects unknown/uninstalled/disabled)
warden backend enable <id>Enable a backend
warden backend disable <id>Disable a backend

The generated CLI reference has the full flag/help detail.

warden usage asks the daemon for provider-owned usage data from every persisted row whose tier is exactly subscription. Disabled and uninstalled rows remain in the result; the read never rescans the registry or changes routing, cooldowns, or the default backend. Use --json for the stable v1 document and --refresh to bypass the daemon’s 60-second fresh cache.

Each backend has a usage array containing zero or more distinct limits, sorted by stable id. Every limit includes id, applicability scope, a human label, nullable used_percent and resets_at, plus nullable model_families and models selectors. Multiple provider pools are never flattened: Codex primary/secondary windows remain separate, and an adapter that can safely identify Gemini and non-Gemini pools returns separate scoped entries. Unknown measurements, restore times, or model selectors remain JSON null; warden never guesses them.

Codex supplies structured percentage limits and reset times through its app-server protocol. Cursor supplies three never-flattened windows (included, auto, api) from POST https://api2.cursor.sh/aiserver.v1.DashboardService/GetCurrentPeriodUsage using the local cursor-agent login token — the same RPC as the feature-flagged CLI /usage pager. There is no cursor-agent usage subcommand; warden does not scrape the TUI or invent percents from spend cents. Antigravity supplies two pool buckets (antigravity:gemini and antigravity:non-gemini) from POST https://daily-cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary using the local agy OAuth credentials — the same RPC as the agy /usage TUI. Each bucket reports its 5-hour session limit while its weekly limit still has headroom, and flips to the exhausted weekly limit (100% used, reached, weekly duration and reset) once that pool’s weekly bucket is drained. Claude supplies a single session (five_hour) window — used_percent and resets_at — from GET https://api.anthropic.com/api/oauth/usage (the endpoint the claude CLI’s /usage pager uses), authenticated with the local Claude Code OAuth access token and degrading gracefully to one null-percentage row when the endpoint is unreachable. Warden deliberately does not substitute its local synthetic quota estimates. Account labels, credentials, raw provider output, paths, and request IDs are excluded. An API-key-only Cursor login (no auth.json access token) still emits the three Cursor limit rows with used_percent: null.

The command exits 0 when every row is ok or truthfully unsupported, 2 after rendering a partial result with an operational provider failure, and 1 when no consolidated document can be produced.

{
"id": "cursor",
"status": "rate_limited",
"usage": [
{"id": "cursor:api", "scope": "api", "label": "API", "model_families": ["claude", "gemini", "glm", "gpt", "kimi"], "models": null, "used_percent": 100, "resets_at": "2026-10-01T18:31:27Z"},
{"id": "cursor:auto", "scope": "auto", "label": "Auto", "model_families": null, "models": ["auto"], "used_percent": 4.09, "resets_at": "2026-10-01T18:31:27Z"},
{"id": "cursor:included", "scope": "included", "label": "Included", "model_families": ["composer", "cursor-grok"], "models": null, "used_percent": 8.87, "resets_at": "2026-10-01T18:31:27Z"}
]
}

status is ok when every bar is below 100, or rate_limited when any window is at the cap (recovery still ranks Composer/Grok/auto on their own headroom). Omitted percents stay JSON null — they are never defaulted to 0.

{
"id": "antigravity",
"status": "rate_limited",
"usage": [
{"id": "antigravity:gemini", "scope": "gemini", "label": "Gemini", "model_families": ["gemini"], "models": null, "used_percent": 100, "duration_minutes": 300, "resets_at": "2026-09-05T21:40:45Z", "limit_state": "reached"},
{"id": "antigravity:non-gemini", "scope": "non-gemini", "label": "Non-Gemini", "model_families": null, "models": null, "used_percent": 0, "duration_minutes": 300, "resets_at": "2026-09-06T01:04:38Z"}
]
}

The Antigravity adapter maps retrieveUserQuotaSummary buckets into two pool buckets (antigravity:gemini and antigravity:non-gemini). Each bucket reports its 5-hour session limit (usage % + reset) while its weekly limit still has headroom; once the pool’s weekly limit is exhausted the bucket reports the weekly limit fully consumed (100% used, reached, duration_minutes: 10080, weekly reset) — matching how agy /usage gates the 5-hour window under the weekly cap.

ToolArgsReturns
list_backends—{backends[], settings} (read-only)
rescan_backends—The refreshed {backends[], settings}
set_backend_tier{id, tier}The updated backend
set_default_backend{id}The refreshed {backends[], settings}
set_thinking_mode{mode}Deprecated no-op — returns the current settings

Enable/disable is not an MCP tool — use the CLI, web, TUI, or REST PATCH /api/v1/backends/{id}.

Method + pathPurpose
GET /api/v1/backendsThe registry + settings (read-only)
GET /api/v1/usage?refresh=trueProvider usage for exact subscription-tier rows (read-only)
POST /api/v1/backends/rescanRe-detect and reconcile; returns the registry + settings
PUT /api/v1/backends/default{id} → set the default; returns the registry + settings
PUT /api/v1/backends/thinking-mode{mode} → deprecated 200 no-op; returns settings
PATCH /api/v1/backends/{id}{tier?, enabled?} → update one backend (both fields optional)

See the OpenAPI reference (/api/docs) for the full schemas.

KeyDefaultDescription
backends.limit_retry15mGo duration — how long a free CLI backend is skipped after a rate-limit / spend signal, before retrying it

Tiers, the default, and enabled flags live in the store, not the config file — edit them via the surfaces above.

Autopilot’s cost-tier ladder and paid-autopilot gate derive from the registry: only installed, enabled rows are eligible, bucketed by tier. The deprecated autopilot.brain.backends.{free,subscription,pay_per_use} ladder and autopilot.brain.allow_pay_per_use gate are imported once on the first boot after upgrade (sentinel-guarded, idempotent) and then ignored — the store is authoritative, and the daemon logs a deprecation warning if the config still carries them. See the Autopilot concepts page.