EvolveSource

03 The pieces · 3 min read

Goals and the rules of the game

This page is for whoever tells the agents (the AI tools that write code changes) what to do, which is probably you. Before an agent writes a line, two things have to be settled: what you want, and how anyone will know you got it. This page covers both. Once you’ve read it you’ll know what a goal looks like to Evolve, where the rules live, and why an agent can’t bend them.

A goal you can check

Evolve calls a goal an objective. It has three parts:

  • a target: one measurement that has to reach a level, like “p95 latency under 150 ms” (the slowest 5% of requests answer within 150 milliseconds), or one check that has to pass. A check is one of the tests Evolve runs on every change. For a command-line program, for example, the target can be its transcript: a list of ways to run it and what each should print (target: {check: cli});
  • invariants: checks that must keep passing, like “the price tests” and “the checkout contract” (a list of requests and the answers they must get);
  • instructions for the agents, in plain words.

Compare “make it better” with “p95 under 150 ms while every price test passes”. Only the second one can be checked, and anyone, or anything, can check it.

You’ll rarely write one by hand. Evolve comes with a command, evolve, that you type in a terminal. evolve run "make checkout faster, under 150 ms" reads your sentence, finds the check that measures it, makes every other required check an invariant, and shows you the objective before anything starts. Written out, in the YAML format most settings files use, it looks like this. You can record one yourself with evolve objective create --file:

schema_version: 1
name: faster-checkout
statement: p95 under 150 ms while checkout stays correct
target: {check: latency, metric: p95_ms, maximum: 150}
invariants: [build, tests, contract]
instructions: |
  Checkout is slow. Find out why and fix it without changing any price.

The policy: the rules, kept in your repository

The rules for judging are called the policy. They live in a file called evolve.yaml in your repository, the place your project’s code and its history are kept. It says:

  • which files agents may and may not touch (tests, the policy itself, the settings for putting your software live);
  • what the checks are, and how to run them;
  • how to rank the attempts that pass;
  • how carefully to roll a change out to real users. It starts with a canary, a small share of real traffic, then grows in steps; the policy sets the steps, the limits and how long to watch.

Locked at the start

When a run begins (a run is everything Evolve does for one goal), it copies the policy, and every file it points to, from your main branch, the version of your code everyone works from. Then it locks that copy for the whole run.

So what if an agent edits the tests, or the policy? It only changes its own copy. The run is still judged by the locked rules, and touching those files gets the attempt thrown out.

This is the most important safety rule in the whole thing: whoever is being judged never gets to change the judge. We learned how much it matters the hard way, from a real run where an agent edited a test so its own change would pass.

Next

Agents and their sandboxes: who writes the attempts, and how they’re kept apart.