For AI agents: the complete documentation index is available at /cafleet/llms.txt, the full documentation bundle is available at /cafleet/llms-full.txt, and this page is available as Markdown at /cafleet/spec/coding-agent-backends.md.

Coding-agent backends

Every member pane runs one of three coding-agent binaries: claude (Claude Code), codex (OpenAI Codex CLI), or opencode. The backend is recorded per member in member_placements.coding_agent; selection and inheritance via --coding-agent, mixed-backend teams, and identity delivery are covered in Coding agents. This page specifies each backend's spawn argv, auto-approval posture, model-flag format, and version/config requirements.

Spawn argv

BackendSpawn argv
claudeclaude --permission-mode dontAsk --name <member-name> <prompt>
codexcodex --ask-for-approval never --sandbox workspace-write <prompt>
opencodeopencode --agent cafleet --prompt <prompt>

Shared contract:

  • All three postures enable the Bash tool with no runtime permission prompts.
  • All three honor the leading-! shell shortcut that cafleet member prompt --shell uses.
  • --model <m> from cafleet member create is inserted immediately before the prompt. The value passes through verbatim — the binary rejects unknown models, so newly released models need no cafleet release. Omitted, no model tokens are emitted and the binary uses its configured default. Per-backend formats and create-time validation are in Model selection.
  • --effort <level> from cafleet member create forwards a reasoning-effort level, emitted immediately after the model tokens (before the prompt). Create-time validation uses the backend-specific accepted set before registration or multiplexer effects. Omission emits no effort tokens, leaving argv byte-identical to the no-effort form. Levels and exact errors are in Reasoning effort.
  • A missing binary fails the spawn: exit 1 with Error: binary <name> not found on PATH.

Per-backend capabilities:

BackendOS-level sandboxSets the pane titleShell-command posturePreset / config prerequisite
claudenoneyes, via --name <member-name>Runs cafleet and any shell command directlynone
codexkernel-enforced (Codex)no — locate the pane through cafleet member list (pane_id is ground truth)Runs cafleet and any shell command directly~/.codex/rules/cafleet.rules (CODEX_HOME relocates it), plus the ~/.codex/config.toml settings and a trusted working directory — a permission posture, not a spawn dependency (the rules file)
opencodenoneno — locate the pane through cafleet member listDeny-by-default allowlist; everything outside it routes to the Director~/.opencode/agents/cafleet.md (OPENCODE_CONFIG_DIR relocates it) — a spawn precondition (the agent preset)

Model selection

BackendAccepted value formatExample valuesCreate-time validation
claudePasses through verbatimhaiku, sonnet, opus, fablenone — the binary rejects unknown models
codexPasses through verbatimgpt-5.6-sol (default), gpt-5.6-terra, gpt-5.6-luna, gpt-5.5none — the binary rejects unknown models
opencode<provider-id>/<model-id>, split on the first / into two non-empty segments (model ids may contain further slashes)anthropic/claude-sonnet-4-6, openai/gpt-5.5exit 2 with Error: --model for the opencode backend must be '<provider-id>/<model-id>' (got '<value>').

Reasoning effort

BackendAccepted levelsForwarded asRejected with (exit 2)
claudelow, medium, high, xhigh, max--effort <level>, immediately after the model tokensError: --effort for the claude backend must be one of low, medium, high, xhigh, max (got '<value>').
codexminimal, low, medium, high, xhighthe single token --config=model_reasoning_effort=<level>, immediately after the model tokensError: --effort for the codex backend must be one of minimal, low, medium, high, xhigh (got '<value>').
opencodenone — the backend exposes no reasoning-effort controlError: opencode does not support reasoning effort.

Claude

--permission-mode dontAsk is the reference auto-approval posture the other backends match.

Codex

--sandbox workspace-write confines writes to the workspace under a kernel-enforced sandbox — codex is the only backend with one. --ask-for-approval never disables interactive approval prompts (upstream write-up: https://developers.openai.com/codex/agent-approvals-security).

Three ~/.codex/config.toml prerequisites must be in place before the first codex spawn, covered in Codex configuration and Trust the working directory:

SettingRequired valueWhy
network_accesstrueThe multiplexer socket counts as network access
writable_rootsIncludes the cafleet DB directory
trust_level"trusted"The working directory must be trusted before spawning

trust_level is keyed by absolute workspace path:

[projects."/abs/path/to/workspace"]
trust_level = "trusted"

The cafleet rules file

~/.codex/rules/cafleet.rules grants the auto-approval posture for cafleet commands (CODEX_HOME relocates the ~/.codex base — see Config-dir resolution). It ships as an embedded static asset (presets/codex/cafleet.rules) in the released binary and is installed offline by cafleet setup:

prefix_rule(pattern = ["cafleet"], decision = "allow")

prefix_rule(
    pattern = ["cafleet", "member", "prompt"],
    decision = "prompt",
    justification = "cafleet member prompt keystrokes arbitrary text or shell commands into a member pane",
)

Codex applies the strictest decision when more than one rule matches (forbidden > prompt > allow): cafleet member prompt matches both rules, so its prompt wins and each invocation keeps requiring approval, while every other subcommand matches only the broad ["cafleet"] allow — for every fleet, since every id rides past the matched prefix as a positional or trailing argument.

The file is owned by cafleet setup: it is overwritten on every install, so operator customizations belong in a separate rules file under ~/.codex/rules/ — Codex loads every *.rules file in that directory at startup and applies the strictest decision across all of them. The rules file is a permission posture, not a spawn dependency: cafleet member create --coding-agent codex requires only the codex binary on PATH.

Opencode

The pane runs the bare opencode TUI (not opencode run), so it stays a long-lived, observable pane like the other backends. The prompt is passed via --prompt — bare opencode's positional is a project path, not a message.

The cafleet agent preset

--agent cafleet binds the member to ~/.opencode/agents/cafleet.md (OPENCODE_CONFIG_DIR relocates the ~/.opencode base — see Config-dir resolution; the spawn precondition checks the same resolved path setup installs to). The preset is embedded in the released binary (presets/opencode/cafleet.md). cafleet setup installs it offline, replacing any existing copy; rerun setup after upgrading CAFleet to refresh it. The preset is a spawn precondition: the spawn argv references --agent cafleet, so cafleet member create --coding-agent opencode fails with opencode agent preset not found at <preset>; run 'cafleet setup --coding-agent opencode' first when the file is missing.

The preset's bash ruleset is deny-by-default: a "*": "deny" base first, then an explicit allowlist translated from the operator's Claude Code permissions.allow set (cafleet *, non-destructive git subcommands, file-inspection utilities, and the project's cargo-backed mise tasks). opencode selects the last matching rule, so this order is the safety floor — every check resolves to allow or deny, never ask. A permission popup in an opencode pane is therefore a regression escape, not a runtime decision: capture the pane, escalate, and extend the allowlist by operator decision — do not answer the popup ad hoc.

Safety-floor caveats

The posture is a deny-by-default allowlist, with no OS-level sandbox. Standalone un-enumerated commands fall to the "*": "deny" base, but three classes of bypass under allowed globs persist:

Bypass classExampleWhy the allowlist misses it
MCP-contributed toolsThey bypass the permission evaluator entirely
Shell chaining or argument-space abuse inside an allowed cmd * matchgit log --stat; curl … | sh matching git log *The compound line's leading tokens match the allowed glob
Interpreter or hook execution via allowed toolingmise //cafleet:test * executes workspace-writable test code; git commit * runs .git/hooksThe allowed command is itself the execution vector

cafleet ships no MCP stanzas, and operators MUST NOT add MCP servers to any opencode config their machine loads.

For kernel-enforced isolation, use the codex backend.

Validated against opencode 1.15.5 (the minimum supported version).