EvolveSource

05 Reference · 13 min read

The operator config

If you’re the one running Evolve, this is your file. Repositories decide what counts as proof. You decide what Evolve is allowed to use: which agents, which machines, which places to deploy. This page lists every setting, so dip in when you need one.

Words this page uses

  • Agent: an AI tool that writes code; its model is the AI behind it. Attempt: one agent’s try at a goal. Run: everything Evolve does for one goal.
  • Sandbox: a sealed-off space a program runs in, cut off from the rest of the machine. Evolve’s sandboxes use bwrap (bubblewrap, a small Linux tool) or Docker (a tool that runs programs in containers).
  • Environment variable: a named setting a program reads when it starts, like PATH. Token: a long secret code that works like a password for a program.
  • API: the way programs talk to Evolve’s server. The evolve command and the web pages both use it.
  • Worker: the part of Evolve that does the jobs: running agents, checks and rollouts.
  • Policy: a project’s own rules, in its evolve.yaml (The policy file).
  • Canary: a new version tried on a small share of real traffic first. Promotion: it going fully live. Rollback: putting the old version back.
  • YAML: the plain-text format this file is written in.

Where it’s read from

Evolve reads its config from the file named by the environment variable EVOLVE_CONFIG, or from evolve.config.yaml in the current directory. config/evolve.local.yaml is the demo’s, and it’s a good one to copy from.

Basics

Field Meaning
database_url where Evolve keeps its records. Leave it out and it’s a SQLite file (a database in one file) in data_dir; give a postgres:// address of a PostgreSQL database server for a shared or busy setup
database_url_env or the environment variable holding that URL
data_dir where Evolve keeps its own copies of your repositories (mirrors), evidence and logs
listen the server’s address, such as 127.0.0.1:7070 (this machine, port 7070)
tokens who’s allowed to call the API: a name, the token itself from the environment variable token_env (or its sha256, a fingerprint of it, so the token itself isn’t in the file), and scopes, what it may do. read is enough to look; deciding on a run (approve, reject, answer, cancel) needs operate. admin can do both, and also register, change or remove projects, set up or reconcile environments, and clear out old runs (evolve gc)

agents

One entry per agent Evolve can use.

agents:
  claude-code:
    kind: command
    argv: [bin/evolve-agent, claude-code, --cli, /usr/local/bin/claude]
    ro_paths: [/usr/local/lib/claude]
    env_files: {CLAUDE_CODE_OAUTH_TOKEN: ~/.config/evolve/claude-code.token}   # from claude setup-token
    env_passthrough: [ANTHROPIC_API_KEY]
    isolation: bwrap
    network: true
Field Meaning
kind command for a real agent; fixture for the scripted demo stand-in (a script that pretends to be an agent)
argv how to run it. bin/evolve-agent knows how to drive Claude Code, Codex, opencode and Antigravity. evolve-agent patch FILE delivers a change a person wrote, applied exactly as written. A command starting ./ or ../ is relative to the config file. A later argument starting {{config_dir}} is a path from the config file’s directory, and {{workspace}}, {{input}} and {{output_dir}} are the attempt’s
isolation bwrap (the sandbox you get if you don’t say), docker, or process for no sandbox at all, which is only allowed for the demo stand-in
image with isolation: docker, the Docker image (a packaged system) the agent runs in
provider, model the company and model behind the agent, written into each attempt’s record so you can tell later who did the work
ro_paths files the sandbox may read, like the agent’s own install
home_copy files from the worker’s home that are copied into the sandbox for the attempt and deleted afterwards, like a login. Nothing else in your home directory is visible
fallback another agent for the next attempt to use, in a run that tries one attempt at a time, when this one’s isn’t eligible. The usual trick: a cheaper model first (claude-code-sonnet, with fallback: claude-code), the stronger one only when it’s needed. See attempts.sequential in the policy
env_files environment variables read from files at every attempt, and kept out of every log. For example a long-lived login token for Claude Code: {CLAUDE_CODE_OAUTH_TOKEN: ~/.config/evolve/claude-code.token}
env_passthrough, env the environment the agent gets. Nothing else leaks in
network allow the network, and only if the repository’s policy allows it too
cost_per_attempt_usd a cost to charge each attempt, for an agent that doesn’t report one
max_concurrent how many attempts may run this agent at once, across every project. Handy when an AI provider limits how much you can use it per minute

A tip for Claude Code: give it a long-lived token instead of a copy of .credentials.json. Run claude setup-token, save the token to a file, and hand it over with env_files. A copied login can run out in the middle of an attempt, and it can’t be renewed there once another session on the machine has renewed it.

When an agent can’t log in, or hits its plan’s usage limit, the run closes as blocked (operator action needed), with the reason and any reset time, so nobody mistakes it for a problem with the code.

The reviewer

reviewer: claude-code     # one of your agents

A reviewer is a second pair of eyes: an agent whose only job is judging.

With one, a run is planned before any attempt (see the plan in the policy), and no attempt is accepted on its own say-so. An attempt that passes the checks gets reviewed first. The reviewer can:

  • accept it;
  • say what to fix, in which case the agent is asked to carry on (an intervention);
  • call its approach a dead end, so nothing more is spent on it;
  • choose between several that passed. It looks hardest at behaviour the checks don’t pin down;
  • with spec.tests, adopt a goal’s tests or send them back.

It reads the goal, the shared context, each candidate’s patch, the agent’s own account and the evidence, in a read-only copy of the project. Its choice and its reasons go into the decision, where a person can later say it got it wrong.

Sometimes it needs something only a person knows, or the choice is really yours. Then it asks, and the run waits. You’ll see the question on the run’s page and in evolve run show. Answer on the page, or with evolve run answer <run> "…", which also adds your answer to the project’s shared context for next time. Then it decides again.

Its cost is part of the run’s. Without a reviewer, the policy’s rank decides.

A strong model with cheap workers

For Claude Code, --subagent-model MODEL (before the -- in argv) lets the attempt’s model hand the boring jobs to helpers, called subagents, on a cheaper model: bulk edits, searches, running tests and reading the results. It keeps the design and the review for itself:

  claude-code-delegating:
    kind: command
    argv: [../bin/evolve-agent, claude-code, --subagent-model, claude-haiku-4-5, --cli, ~/.local/share/mise/installs/claude/latest/claude, --, --model, claude-sonnet-5]

The helpers run in the same process and sandbox as the attempt, under the same tool rules, and their cost is part of the attempt’s. The Live page (the page in Evolve’s web interface where you watch agents work) marks their steps with ↳.

Agents check their own work

Agents run through bin/evolve-agent are asked to run evolve-agent check before they finish. It runs the project’s required checks in the attempt’s work tree, the way the verifier will afterwards: the build, the commands, and the cli transcript, service examples, browser and gui scenarios up to the current goal. (Speed is only ever measured by Evolve.)

It prints what fails and why, so the agent can fix it while the change is still fresh in its mind. But its results count for nothing as evidence. Evolve checks everything again itself, from the locked checks.

An agent on another machine

evolve-agent remote runs an agent on another machine over SSH (the usual way to log in to another machine and run things there), with that machine’s logins, memory and usage limits. The attempt’s copy of the code goes there as a git bundle, a single file holding a Git repository. The agent runs in bwrap in a throwaway directory, its steps stream back to the Live page, and only a patch comes home, judged here like any agent’s change.

The other machine needs bwrap, git and the agent’s CLI. It has to be Linux, on the same kind of processor as this machine, because Evolve copies its own evolve-agent over (once per build). If the agent runs out of time over there, its work so far and what it cost still come back, so the attempt can be carried on.

agents:
  opencode-build-box:
    kind: command
    argv: [../bin/evolve-agent, remote, --host, you@build-box,
           --ro, .local/share/mise, --ro, .config/mise, --ro, .config/opencode,
           --rw, .cache/opencode, --copy, .local/share/opencode/auth.json,
           --, opencode, --cli, /home/you/.local/share/mise/installs/opencode/latest/opencode,
           --, --model, openrouter/openrouter/auto]
    ro_paths: [~/.ssh]          # this machine's key for that host
    isolation: bwrap
    network: true

On the other machine, the agent sees nothing of the home directory except what you name: --ro (read-only: toolchains, config), --rw (writable: caches) and --copy (a private copy: a login it’s allowed to renew). Do name the model. A model the agent remembers from being used by hand isn’t visible to it there.

If the machine can’t be reached, the run is left blocked (operator action needed) until you sort the machine out.

environments

Where changes get deployed. The name is what a policy’s deployment.environment points at. Each one’s adapter says what kind of place it is: local, argo or orchy, the three below.

environments:
  local:                    # the name a policy points at
    adapter: local
    url: http://127.0.0.1:7080
    admin_token_env: EVOLVE_LOCALENV_TOKEN

local: the demo’s built-in environment.

Field Meaning
url, admin_token_env where it listens and the token to control it

argo: Kubernetes (a popular system for running software across many machines) with Argo Rollouts, its add-on for moving traffic to a new version step by step.

Field Meaning
kubectl, kubeconfig, context how to reach the cluster (the group of machines Kubernetes runs): the Kubernetes command, its settings file, and which of its clusters to use
namespace, rollout, container the Rollout Evolve drives: Argo’s record of your app and how to move traffic to a new version, found by its namespace (a named area of the cluster) and container (the program inside it)
image_repository where candidates’ images (packaged programs Kubernetes can run) are uploaded
metrics_url, metrics_token_env the Prometheus (a tool that collects numbers about running software) Evolve judges the canary from
requests_query, errors_query, p95_query the questions asked of Prometheus, in its own query language, if yours differ from the defaults

orchy: a fabric, the set of machines orchy runs your apps on.

Field Meaning
endpoint where to reach orchy: the socket (a local connection point) of the orchy program running on this machine, or the https address of your fabric, orchy’s name for a set of machines it manages
token_env or token_file a deployer token (orchy tools token create --role deployer), from an environment variable or from a file only the worker can read
local_token_file the local.token file of the orchy program on this machine, when endpoint is its socket
app, tenant, session the application, the account it belongs to in orchy, and its orchy.json settings file. A change to that file on its own gets deployed too. If the version Evolve puts live is already serving but its settings differ from the file, Evolve deploys the same version again and orchy rolls out a new revision, a fresh copy of the app running with the new settings. Route ports and the rollout settings aren’t compared, and a setting you delete from the file isn’t noticed
via api to deploy directly, or pipeline to go through an orchy pipeline (a list of steps orchy runs to put a version live) named by pipeline
canary allow canary steps on orchy’s traffic split. Without it, the switch from old to new is all at once (that’s called blue-green)
identity_url, identity_host, domain how Evolve asks the running application what it is
identity_token_env or identity_token_file a token Evolve sends when it asks, for an application that only tells its operator what it is. Evolve’s own site does this: set OPERATOR_TOKEN in its environment and its /identity and /metrics pages answer only to that token
metrics_url where the canary’s numbers (requests, errors, speed) come from

verifier

Field Meaning
isolation the checks’ sandbox: bwrap, docker or process
image with isolation: docker, the Docker image the checks run in. Docker needs one
ro_paths extra files and directories the checks’ sandbox may read
evidence_ttl_hours how long a check result stays fresh enough to put a change live on: 72 unless you change it. Older evidence can’t promote anything
max_log_bytes cap on one check’s log
memory_mb, cpus what one check may use: 2048 MB and 2 CPUs unless you change them. They’re enforced, so a check that needs more will be stopped
build_timeout_seconds how long a build may take: 600 unless you change it
browser the headless browser for browser checks. If you don’t name one, it’s the first of chromium, chromium-browser or google-chrome that’s found

confidence

How agents earn, and lose, the right to ship without your approval. See earned autonomy.

confidence:
  window_days: 30
  objectives:
    - {indicator: check_escape_rate, objective: 0.05, threshold: 0.20}
    - {indicator: regret_rate, objective: 0.01, threshold: 0.05}
  autonomy:
    initial: supervised
    earn_after: 3
    agents: {fixture: autonomous}
Field Meaning
window_days how far back indicators are measured: 30 days unless you change it
objectives for each indicator, the level you’re aiming for (objective) and the level where Evolve steps in (threshold). There are 13 indicators, each explained in earned autonomy: check_escape_rate, regret_rate, unknown_rate, interaction_load, unattended_rate, time_to_safe_seconds, wrong_pick_rate, escaped_defect_rate, first_attempt_rate, wasted_spend_rate, stuck_rate, plan_calibration, escalation_load
autonomy.initial where a new agent starts: supervised (unless you say otherwise) or autonomous
autonomy.agents a different starting level for particular agents
autonomy.earn_after how many clean promotions in a row earn autonomy: 3 unless you change it
autonomy.keep_on_escape keep autonomy even when a change is caught in production. Off unless you turn it on

The rest

Section Meaning
secrets.env environment variables whose values are scrubbed out of every log and piece of evidence. Tokens and agent logins are scrubbed too
alerts.file, alerts.webhook_url where alerts go: a file, or a webhook (an address Evolve sends a message to, like a chat channel’s). Alerts are sent for a rollback, a run that’s closed, or a run that’s now waiting on you
worker.concurrency, worker.lease_seconds, worker.poll_ms how the worker runs jobs: how many at once, how long it holds a job before another worker may take it over, and how often it looks for new ones
worker.max_per_repository how many attempts of one project may have an agent running at once, so one project can’t hog every worker