EvolveSource

03 The pieces · 4 min read

The record

If you’re the person who gets asked “why did we ship this?” (put it live, that is), this page is for you. Six months from now, someone will ask. This page is about how Evolve makes sure there’s always an answer: what it writes down, how you ask it questions, and how the record follows your code from machine to machine.

What gets written down

Everything, as it happens: the goal, the policy (your project’s rules, locked for the run), every attempt (each agent’s try) and what it changed, every check result, the decision, each change to how traffic was split between versions, each stretch of time a version was watched, the promotion (going fully live) or rollback (going back to the old version), and everything a person did. Entries are only ever added; nothing is edited or deleted.

Asking “why is this here?”

evolve why sha256:08fe8f6a…

Every built version has a digest, a fingerprint like the sha256:… code above that changes if even one byte does. evolve why (typed in a terminal, like all evolve commands) walks backwards from a running version to the goal that asked for it: the evidence it passed, the decision that picked it, and what was seen on real traffic. If a link in that chain is missing, it says so.

Built to last

  • It’s indexed in a database: SQLite, a database kept in a single file, to begin with, or PostgreSQL, a database server, for a busy setup. The worker, the part of Evolve that does the jobs, picks up exactly where it stopped if it crashes. We test Evolve by killing its worker at nine different points while a change is going live.
  • It stays readable even if the AI model you used is long gone. Nothing in it needs a model to make sense of it.
  • evolve export writes a run out to files, and evolve export verify checks their signatures, the digital stamps that show if anything was changed. So evidence can be checked without trusting the machine that made it.

It travels with your repository

The record is kept in Git as well, under a name of its own (a ref, in Git’s words): refs/evolve/record. Each run is added when it closes, along with the goal it was for, the key that signed its evidence and the logs its checks wrote. To share it with your team, or carry on from another machine:

evolve sync

This fetches the record from your remote, the shared copy of your repository on a server like GitLab or GitHub (origin, unless you say --remote), merges it with this machine’s, brings in the runs this machine hasn’t seen, and pushes the result back. Git does the work as you, with your own keys, and your branches stay as they are.

  • No merge conflicts. Every file in the record is named after what’s in it, so records from several machines just combine.
  • Built programs stay home unless you ask. They stay on the machine that built them, since their commit (the saved snapshot of the code) can rebuild them. Set record: {binaries: lfs} in evolve.yaml and they travel over your remote’s Git LFS instead, Git’s add-on for storing big files. Evolve speaks LFS itself, so you don’t need the git-lfs tool installed.
  • Signatures still check out. Each machine’s public key, the half of its signing key that lets others check its stamps, travels with the record, so evidence checked on your laptop still verifies on the server.
  • Notes on your commits. Every change Evolve checked gets a Git note, a comment attached to the commit. git log --notes=evolve shows which checks it passed and whether it was chosen.
  • The database can be rebuilt. On a new machine, evolve init registers the project and evolve sync brings its history in. evolve reindex rebuilds the database from the record whenever you like.

One thing to watch. Pushing the record shares its logs with everyone who can read the remote. Evolve leaves out any log its redaction (the blanking out of secrets it knows about) would change, but have a look at what your tests print before you sync a private project to a public remote.

Next

Earned autonomy: how Evolve decides which agents may ship without you.