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 a coding-agent binary selected from the backend registry. 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 --prompt-suggestions false --allowedTools <rule>... --name <member-name> <prompt>
codexcodex --ask-for-approval never --sandbox workspace-write <prompt>
opencodeopencode mini --standalone --agent cafleet --prompt <prompt>

Shared contract:

  • Each posture enables shell commands with no runtime permission prompts.
  • Each backend honors the leading-! shell shortcut that cafleet member exec dispatches through.
  • Every member can run its broker commands from the moment it is spawned: claude through spawn-time allow rules, codex through the rules file, and opencode through the agent preset.
  • --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 the broker commands under its spawn-time allow rules, read-only commands, and every command matching the operator's permissions.allow; a denied command routes to the DirectorA permission profile in ~/.claude/settings.json — a permission posture, not a spawn dependency (Claude)
codexkernel-enforced (Codex)no — locate the pane through cafleet member list (pane_id is ground truth)Runs commands its workspace/host rules permit; routes required denied commands~/.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-6.1-sol, gpt-6-astra, gpt-6-lunanone — 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)opencode/claude-opus-5-5, opencode/gpt-6.1-sol, opencode-go/glm-5.3, anthropic/claude-sonnet-4-6exit 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 control—Error: opencode does not support reasoning effort.

Claude

A separate evaluator checks the session condition against the transcript; native background work defers evaluation and returns a host result. Use one native Monitor task for Director inbox records, retaining its handle across separate events and renewing after observed source-task exit. The installed CAFleet skill's Claude native instructions own discovery, invocation, renewal and evidence limits; the manual lifecycle explains operation. Preserve supplied /goal state and pending user decisions; manual finite reception remains available when Monitor is unavailable or denied.

Native shell probes displayed command/stdout/stderr followed by a model turn; the trigger and any second permission check were not established. The Director authorizes each routed command under its host rules.

--permission-mode dontAsk is the reference auto-approval posture the other backends match. A member runs four kinds of call without a prompt: its spawn-time allow rules, Claude Code's built-in read-only commands, file reads inside its working directory, and every tool call matching permissions.allow. Every other call — a shell command or a file edit, including one matching permissions.ask — is denied without a prompt. A write to one of Claude Code's protected paths, such as a project's .git or .claude directory, is denied whatever the allow list holds. Beyond the broker commands, the operator's settings are therefore the member's allow list; the recommended profiles are in Claude Code configuration.

Spawn-time allow rules

cafleet passes the broker commands a claude member needs as session allow rules on its spawn command line, so the member does not depend on any Bash(cafleet ...) rule in the user's settings.json:

MemberRules
Broker capabilityBash(cafleet message *), including finite message wait and message listen
Work capabilityHost-configured read/edit/command rules

--allowedTools takes several values, so it sits before --name, which ends its value list and keeps the prompt positional. The rules are fixed at spawn: a later loss of allow rules in the user's settings does not affect a running member.

The flags do not cover these cases:

  • A deny or ask rule at any settings level, including managed policy, still blocks the command. cafleet doctor reports it before spawn.
  • The managed setting allowManagedPermissionRulesOnly makes Claude Code ignore --allowedTools. cafleet doctor reports it.
  • A blocking PreToolUse hook stops a tool call before permission rules are evaluated. cafleet doctor cannot evaluate a hook.
  • Inspect overdue member readiness/replies directly; settings can change after spawn.
  • Work commands (mise, git commit, package managers) stay under the user's own rules; a denied one is routed through cafleet member exec.

What each profile entry is for

EntryProfileNeeded byWhy
Bash(cafleet *)Other modesThe DirectorOne pattern pre-approves every subcommand the Director runs.
Skill(cafleet), Skill(cafleet-design-doc)BothThe Director and every memberEach loads the installed skills through the Skill tool.
Read(~/.claude/skills/**)BothThe Director and every memberRole and reference pages of an installed skill sit outside the working directory.
Edit, WriteBothEvery member that writes filesA member's file edit is denied unless an entry matches it. No entry covers a protected path.
Bash(cafleet member prompt *), Bash(cafleet member exec *) under askBothThe DirectorThe operator confirms each dispatch; a member's own attempt is denied.

The auto mode profile carries no Bash(cafleet ...) allow entry: the classifier reviews each Director command that no rule matches, auto mode approves the Director's file edits inside the working directory, and members receive their broker commands as spawn-time allow rules.

cafleet member prompt and cafleet member exec stay under ask in both profiles because the first keystrokes arbitrary text into a member's pane and the second runs an arbitrary command there. An ask rule outranks every allow rule, so the entries hold beside Bash(cafleet *).

Edit and Write apply to every session that reads the settings file, so they also pre-approve file edits in your own sessions. To confine the approval, replace both with a path rule such as Edit(~/work/**), which covers every file-editing tool. No entry reaches a protected path: a member's edit under a project's .git or .claude directory is always denied, and the Director session makes that edit instead. When CLAUDE_CONFIG_DIR relocates the config directory, write the Read entry against that directory's skills/**.

What members can run

A member whose shell command is denied asks its Director to run it. The Director runs it with cafleet member exec, which is under ask, so each routed command costs the operator one confirmation. Add an allow entry for every project command members run as part of their work — a test or lint task, for example, as Bash(npm test *) — so those commands run without routing. Routing carries shell commands only: a denied file edit needs a matching Edit entry, or, on a protected path, the Director to make the edit.

SymptomCauseResolution
A member reports a denied shell commandThe command is outside the spawn-time allow rules, the read-only set, and the allow listAdd an allow entry for the command. Until then, each Director dispatch of it asks the operator to confirm.
A member reports a denied file editNo Edit entry matches the file's path, or the path is protectedAdd Edit and Write, or widen the Edit path rule to cover the member's working directory. For a protected path, the Director makes the edit.
The Director is prompted for every cafleet commandThe session runs in a non-auto mode with the auto mode profileSwitch the session to auto mode, or use the other-modes profile
The classifier blocks a Director cafleet commandAuto mode judged the action outside the requestAdd a pattern for that subcommand per permissions.allow coverage
defaultMode: "auto" has no effectIt is set in a project or local settings file, or auto mode is unavailable for the organization or modelMove it to ~/.claude/settings.json, removing it from the project file. When auto mode is unavailable, use the other-modes profile.

Verify native Monitor authorization separately from Bash broker rules. Monitor events remain broker events during an open user decision. Actual expiry, cancellation, child cleanup and independently observed continuation preservation require acceptance evidence.

Codex

The objective belongs to the thread, with model-callable lifecycle tools and optional token-budget accounting. Retain one native execution session handle for Director inbox reception and explicitly read it while delegated work remains, independently of whether a host goal exists. The installed CAFleet skill's Codex native instructions own tool calls, bounded reads, leases and recovery; the manual lifecycle explains operation. Preserve supplied goal activation, pause, completion and budget authority. A background process alone supplies no unsolicited per-line wake after a model turn ends; fully idle Codex reconciles its inbox on the next user/native activation.

A native shell probe displayed the actual command, exit code, duration and output. Installed protocol metadata describes unsandboxed dispatch while public CLI guidance describes current approval/sandbox settings; the TUI's effective boundary and protocol path were not established. Treat native input as a Director-authorized action rather than assume a second member-tool permission check.

--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 into a member pane",
)

prefix_rule(
    pattern = ["cafleet", "member", "exec"],
    decision = "prompt",
    justification = "cafleet member exec runs an arbitrary shell command in a member pane",
)

Codex applies the strictest decision when more than one rule matches (forbidden > prompt > allow): cafleet member prompt and cafleet member exec each match the broad allow and their own rule, so the 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.

Minimum rule set

A rules directory maintained without the installed file — for example one managed from a dotfiles repository — needs at least these rules:

prefix_rule(
    pattern = ["cafleet", "message"],
    decision = "allow",
    match = ["cafleet message poll 5", "cafleet message send --from-member-id 1 --to-member-id 2 ready"],
    not_match = ["cafleet member list 1", "cafleet doctor"],
)

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

prefix_rule(
    pattern = ["cafleet", "member", "exec"],
    decision = "prompt",
    justification = "cafleet member exec runs an arbitrary shell command in a member pane",
)

The allow rules cover the broker commands members run themselves — the same commands a claude member receives as spawn-time allow rules; the prompt rules keep cafleet member prompt and cafleet member exec under operator approval.

The set is sufficient for members and is not the recommendation for a Director session. Codex has no classifier to review what these rules leave unmatched, so every other cafleet command a Director runs follows that session's own approval policy and sandbox instead of running pre-approved outside it. Keep the installed file for a Director session; it is a superset of these rules, so they add nothing when it is also present.

Opencode

OpenCode members perform supplied assignments with their selected provider/model, workspace reads/edits, permitted tools and broker communication. The Director coordinates next steps and routed native shell commands. Leading-! input runs a native shell command in mini. The native path's effective permission boundary and any second member-tool permission check remain unestablished; preserve the preset's member-tool permissions and the Director's command authorization.

The pane runs opencode mini --standalone, the long-lived minimal interactive interface with a private server per pane. The prompt travels through --prompt because mini takes no positional 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.

Preset discovery includes the relocated directory and default home configuration. Agent definitions with the same name can merge across those sources; inspect the effective configuration when customizing a preset.

The preset's shell ruleset is deny-by-default: a "*": "deny" base first, then an explicit allowlist translated from the operator's Claude Code permissions.allow set (cafleet *, its declared Git commands, 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. Explicit cafleet member prompt * and cafleet member exec * deny entries follow the cafleet * allow, so they win: the preset configures members, and dispatching a command into another pane is the Director's act. A member's denied command receives no permission prompt, while permitted broker commands run normally. Tool permission and assignment authority are separate: the assigned role and Director instructions determine which allowed operations a member may perform. 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. Apply these limits when choosing tools and authorizing commands:

SurfaceExampleUsage limit
MCP-contributed tools—Their participation in preset permission evaluation is unverified on opencode 2.1.4. Keep loaded configurations free of MCP servers.
Compound shell commandsgit log --stat; curl … | shPermission matching for compound lines is unverified on opencode 2.1.4. Submit one command per invocation and authorize each actual command.
Interpreter or hook execution via allowed toolingmise //cafleet:test * executes workspace-writable test code; git commit * runs .git/hooksAuthorize the code and hooks that an allowed command can execute.

cafleet ships no MCP stanzas. Operators MUST keep every loaded opencode configuration free of MCP servers.

For kernel-enforced isolation, use the codex backend.

Spawn, preset loading, broker input and native shell input are validated against opencode 2.1.4; opencode 2 is the minimum supported version.