Agent Swarmdocs

09 -Build your own

Harnesses & backends

Agent Swarm separates the run-level backend dial from the per-agent dispatch surface. Understanding the difference lets you mix harnesses in a single swarm, pin a specific agent to a specific CLI, and know exactly what agent-swarm doctor is checking.

Two concepts, two schemas

The codebase uses two distinct types for dispatch. They look similar but control different things:

Type Values What it controls
BackendId claude | codex The run-level dial set by --backend or config.backend. Used for run metadata and the wrapperName field; does not directly shell out.
HarnessId claude | codex | opencode | rovo The per-agent dispatch surface - the CLI that actually shells out for a given agent. Set by agent.harness in the agent definition.

BackendId and HarnessId share two values (claude and codex) but they are separate schemas. Do not conflate them: opencode and rovo are valid harnesses but are not valid backends. A run-level --backend codex does not prevent an individual agent from dispatching via the opencode harness.

Note

BackendId is defined in src/schemas/backend-id.ts; HarnessId is defined in src/schemas/harness-id.ts. Both are Zod z.enum schemas - the source of truth for valid values.

How a harness is resolved for each agent

When a round runs, every agent gets its own harness resolved independently. The resolver walks this priority order - first that is set wins:

  1. agent.harness - a HarnessId set directly in the agent definition file. This is the strongest override and bypasses the run-level backend entirely.
  2. Run-level --backend / config.backend - the BackendId from the CLI flag or project config, mapped to the matching harness.
  3. agent.backend - a BackendId set in the agent definition. Weaker than a run-level override; mapped to the matching harness when neither of the above is set.

If none of the three is set, the agent dispatches via the claude harness (the default). An agent with an explicit harness field always uses that harness regardless of what --backend is passed at the command line.

Tip

Prefer harness over backend in agent definitions when you want to pin a specific CLI. The harness field is unambiguous and does not depend on how BackendId maps to HarnessId.

Per-harness model flags

Every agent definition accepts an optional model string. When set, it is passed to the harness CLI using that harness's own flag. The mapping is:

Harness CLI binary Model flag Example
claude claude --model claude --print --model claude-opus-4-5 -
codex codex -m codex exec ... -m o3-mini -
opencode opencode --model opencode run --model anthropic/claude-sonnet-4-5
rovo acli --model acli rovodev run --shadow -y --model rovo-default

When model is omitted from the agent definition, the harness uses its own default model. The model string is harness-specific - check the documentation for each CLI to see valid model identifiers.

Pinning a harness in an agent definition

The bundled principal-engineer-opencode agent shows the pattern: set harness: opencode in the agent definition and the agent will always dispatch via OpenCode, regardless of the run-level --backend flag.

# .agent-swarm/agents/principal-engineer-opencode.yml
name: principal-engineer-opencode
description: Engineering agent that dispatches via OpenCode.
persona: You are a principal engineer optimizing for correctness, maintainability, and practical execution.
harness: opencode
model: anthropic/claude-sonnet-4-5
prompt: |
  You are the principal-engineer-opencode agent in a swarm.
  Focus on implementation approach, system boundaries, and delivery feasibility.
  Return only the shared swarm JSON contract.

You can also use backend: codex instead of harness: codex if you want the agent-level preference to participate in the run-level backend mismatch checks that agent-swarm doctor reports. Use harness when you want to pin opencode or rovo, since those are not valid BackendId values.

To run a mixed-harness swarm - for example, two Claude agents and one OpenCode agent - select all three agents in your preset or config. Each dispatches independently via its own harness:

# agent-swarm run against a mixed preset
agent-swarm run 2 "Should we adopt the new data layer?" \
  --agents product-manager,principal-engineer,principal-engineer-opencode

What doctor checks

agent-swarm doctor always probes all four harnesses - Claude, Codex, OpenCode, and Rovo - for availability and authentication, even when no project config exists. This is the Harness inventory section of the doctor report.

Each harness probe produces one of three outcomes:

Status Condition
OK The harness CLI is found on PATH and authentication probes succeed.
WARN The harness is missing or unauthenticated, but it is not required by any agent in your current config. The run can still proceed without it.
FAIL The harness is missing or unauthenticated, and at least one configured agent requires it. The detail line shows required by: <agent-name>.

Agent Swarm does not globally require any harness. A single-harness setup passes doctor as long as the one harness its agents use is working - the other three will show as WARN, not FAIL.

# probe all four harnesses and check your config
agent-swarm doctor

# example output (Harness inventory section)
Harness inventory
  [OK]   Claude Code: authenticated (claude 1.x.x)
  [WARN] OpenAI Codex: not found (not required by current config)
  [WARN] OpenCode: not found (not required by current config)
  [WARN] Rovo Dev: not found (not required by current config)

Doctor exits 0 when all checks pass (warnings are non-fatal), 1 when any check fails, and 2 on an internal error.

Note

Run agent-swarm doctor after adding a new agent that pins a different harness - it will tell you immediately whether that harness is installed and authenticated, and which agents depend on it.

Where next

  • Agents & roles - the full agent definition schema, including the harness, backend, and model fields.
  • Quickstart - install a harness CLI and verify it with doctor before your first run.
  • CLI reference - the --backend flag and all other run options.
  • Architecture - the harness adapter layer and how dispatch is wired through the pipeline.