Coding engines
The factory doesn't have its own coding agent. It runs the best ones, holds each to the same bar, and shows you how each did.
The engine is the part of the Software Factory that writes the code: the Eng seat's build step. Everything around it is the factory's and is the same whichever engine runs:
- the brief (the task contract);
- the guardrails (no secrets, no human-owned files, nothing pushed on its own);
- your checks, QA's verdict and the merge gate;
- the budget and the clock;
- the record of every run.
| Engine | What it is | Runs with |
|---|---|---|
claude-cli (default) | Claude Code, Anthropic's coding agent, run headless | Anthropic models |
openhands | OpenHands, open source (MIT), run as an SDK inside the runner | any model, through LiteLLM |
codex is named in the registry and refuses to run until it's built.
Pick the engine
In order, the first that says wins:
- The task. A task that names its own engine keeps it. Nothing overrides it, and it isn't put to Jev.
- Jev, with a key. With a Jev key and a seat that lists options in
harness.routeModels, Jev picks the engine, model and effort per task from that list. Unsure, unreachable or out of the list means the next rule decides. - The seat. The workspace's engineer seat names its engine in one line:
# agents/task-engineer.yaml — an extends: core patch
harness:
engine: openhands
engineModel: claude-opus-5-5 # optional; the engine's own default otherwise
- The default. Say nothing and the workspace runs Claude Code, exactly as before.
Whatever is picked, the installation's fence applies last: VOCION_ALLOWED_ENGINES lists the engines an installation allows, and no rule routes around it. A client installation can set VOCION_ALLOWED_ENGINES=openhands and run the open runner image, which has no Claude Code in it.
How an engine runs
- The runner claims the run, clones the repo, starts its services and runs setup.
- The engine reads one brief and prints the same event stream either way.
- The runner runs the required checks, takes the final diff, pushes a branch and opens the pull request.
- Vocion scores it: cost, tokens, transcript, QA's verdict and the outcome.
Only step 2 depends on the engine. OpenHands runs inside the runner's container, which is already the sandbox: one task, a non-root user, credentials stripped. Every OpenHands tool call goes through the same guard scripts as Claude Code. An unknown tool is refused, and the model key is removed from the environment before any tool starts.
See how each engine does
Software Factory → More → Engines puts the engines side by side over 7, 30 or 90 days. You can show real factory work or eval runs. Eval and real work never mix. For each engine it shows:
- runs, pull-request rate, QA pass rate and acceptance rate;
- median time, spend and cost per landed change;
- guard violations and retries;
- how the engine was chosen (Jev or the fixed routing) and why.
Below the table, every run is listed with its seat, repo, outcome, time, cost and why that engine was chosen, linked to its pull request and feature.
Measure before you switch
The factory eval replays 48 real factory requests on two practice apps, each graded by hidden tests the engine never sees. Run it against any engine before moving a workspace:
node packages/runner/eval/run.mjs run --engine openhands --split all --tier all \
--runner-image <runner image> --fixture-repo <a sandbox repo> --max-spend 80
The results import onto the Engines page as eval runs. See the eval harness for what each case tests and how a run is scored.
Roll back
- One workspace: remove the
engineline from its engineer seat and apply. A run already in flight finishes on its own engine. - An installation:
VOCION_ALLOWED_ENGINES=claude-cli.