evo
Autonomous Software Evolution Engine
Most AI coding tools wait for you to ask. evo doesn't wait.
Point it at any git repo. Tell it what "better" means — more tests, fewer bugs, fewer lint violations. Walk away. evo runs a closed-loop evolution pipeline that analyzes weaknesses, writes code, verifies nothing regressed, and merges — autonomously, with a cryptographic proof trail.
On April 4, 2026, evo released itself. v0.26.2 was analyzed, implemented, benchmarked, and published entirely by evo's own pipeline — the first version where the engine completed the full self-improvement loop without human intervention.
It doesn't just generate code. It evolves codebases — including its own.
Contents: What Makes evo Different · Install · Quick Start · Configuration · The Pipeline · Self-Improvement · Strategies · Models & Providers · CLI Reference · Safety · Language Support
- Zero human intervention — analyze → propose → implement → verify → decide → merge. No prompting, no code review, no copy-paste.
- Regression-proof — Every change passes a Pareto gate. If any metric regresses — tests, lint, coverage, security — the change is rejected. Duration metrics use adaptive tolerance that understands measurement noise and the natural cost of adding tests.
- Self-improving — evo uses its own merge rate as a fitness function and can evolve its own source code. The engine that writes code can rewrite itself.
- Self-correcting — When tests fail, evo diagnoses whether the test or the source is wrong and auto-retries with the fix. Floating-point precision, platform-specific behavior, off-by-one errors — caught and fixed automatically.
- Tamper-evident audit trail — A hash-chained proof ledger records every decision. Immutable. Verifiable. Run
evo statusto check chain integrity. - Multi-language — Python, TypeScript, JavaScript, C#, with automatic detection for Go, Rust, and Ruby. Auto-detects test frameworks, linters, and type checkers.
- Multi-provider — Anthropic (Claude) and OpenAI (GPT/o-series). Mix models per pipeline phase — cheap models for simple tasks, strong models where accuracy matters.
- Statistically rigorous — Noisy metrics use Welch's t-test with multiple-comparison correction instead of naive comparison. No false positives from measurement noise.
- Cross-repo learning — Diagnostic insights and success rate statistics transfer between repos, so evo gets better the more codebases it works on.
Download the latest .whl from Releases:
# Recommended — handles PATH automatically
pipx install evo_engine-*.whl
# Or with pip (you may need to add the scripts directory to PATH)
pip install evo_engine-*.whlWith OpenAI support:
pipx install "evo_engine-*.whl[openai]"Don't have pipx?
pip install pipxthenpipx ensurepathand restart your terminal.
- Python 3.11+
- Git (target must be a git repository)
- An LLM API key (Anthropic or OpenAI)
- Docker (optional — for sandboxed execution, or use
--no-sandbox)
# 1. Set your API key (the .env file is auto-loaded)
echo "ANTHROPIC_API_KEY=your-key" > .env
# 2. Run against any repo — zero config
cd /path/to/your/project
evo run --no-sandboxevo auto-detects your language, test command, and project structure. No config file needed.
Want more control? Run evo init to scaffold a .evo.yaml with auto-detected defaults, then customize.
No config needed. With --no-sandbox, evo auto-detects your language, test command, and scopes from the project files. Just run evo run --no-sandbox.
For more control, create a .evo.yaml in the target repo root — via evo init (interactive, with auto-detected defaults) or by hand.
project: my-app
language: python
metrics:
test: "pytest --tb=short -q"That's enough. evo auto-detects available lint and type-checking tools.
project: my-app
language: python
strategy: balanced # test_coverage | hardening | balanced | full_auto
on_test_failure: auto-fix # reject | auto-fix | human-gate
metrics:
test: "pytest --tb=short -q"
lint: "ruff check ."
typecheck: "mypy . --ignore-missing-imports"
# Optional: statistical comparison for noisy metrics
# bench:
# command: "pytest tests/bench.py -q"
# runs: 5
# comparison: welch # Welch's t-test, reject only if p < 0.05
max_files_per_change: 5
max_cost_per_run: 5.00
allowed_scopes:
- "src/**"
- "tests/**"
blocked_scopes:
- ".evo.yaml"
- "pyproject.toml"
provider: anthropic # or: openai
models:
default: claude-haiku-4-5-20251001
analyze: claude-sonnet-4-20250514 # strong model for code comprehension
implement: claude-sonnet-4-20250514 # strong model for code generation
sandbox:
image: "python:3.12-slim"
setup: "pip install -e '.[test]'"project: my-api
language: csharp
metrics:
test: "dotnet test --no-build -v q"
lint: "dotnet format --verify-no-changes"
allowed_scopes:
- "src/**"
- "Tests/**"ANALYZE → PROPOSE → IMPLEMENT → FORWARD-MERGE → VERIFY → DIAGNOSE → DECIDE → RELEASE → EVOLVE
Nine phases, every iteration:
| Phase | What Happens |
|---|---|
| ANALYZE | Run all metrics. LLM reads the codebase and identifies weaknesses. |
| PROPOSE | LLM selects the single highest-impact fix from the weakness list. |
| IMPLEMENT | Create a git branch, generate code, commit. Build-check with up to 3 retries. |
| FORWARD-MERGE | Merge master into the feature branch so tests run against current state. |
| VERIFY | Re-run all metrics. Compare before/after. |
| DIAGNOSE | If tests fail: AI classifies the issue and retries with a fix (up to 3 cycles). |
| DECIDE | Pareto gate — no metric may regress, at least one must improve. |
| RELEASE | Squash-merge to master, version bump, changelog, release branch, tag + push. |
| EVOLVE | Write proof ledger entry, update statistics, feed results into next iteration. |
The DECIDE phase is strict: no metric may get worse, and at least one must get better.
- +40 tests but +1 lint violation → REJECT
- +15 tests, lint unchanged → MERGE
- Nothing changed → REJECT
Duration metrics use adaptive tolerance — an absolute floor absorbs measurement noise, and test-count awareness forgives the natural cost of adding tests. Noisy benchmarks can use statistical testing so only real regressions trigger rejection.
evo doesn't ship "probably fine." It ships "provably not worse."
When tests fail after IMPLEMENT, evo doesn't just give up:
| Diagnosis | Meaning | Action |
|---|---|---|
bug_found |
Real bug in the source code | Fix applied directly |
test_wrong |
Test has incorrect expectations | Test rewritten |
Up to 3 diagnosis cycles per iteration. The current cycle is visible in the live status bar so you always know where evo is.
Every iteration gets a timestamped branch name:
evo/260405-103000-001-add-input-validation-to-parse-config
evo/260405-103142-002-test-coverage-for-metric-aggregation
evo/260405-103400-003-harden-error-handling-in-git-module
On MERGE, the branch is squash-merged with a structured commit message (metrics, proof hash, cost). On REJECT, a DEAD END: commit preserves the context in git history.
This is what evo was built for. It can improve its own source code, using its own output quality as the fitness function.
v0.26.2 self-improvement run: 3 iterations, 1 merged at 33% merge rate, $1.91 total cost.
┌────────────────────────────────────────────┐
│ ① BENCHMARK │
│ Run evo against demo repos. │
│ Record merge rate as baseline score. │
│ ↓ │
│ ② SELF-RUN │
│ Run the evo pipeline on evo's own code. │
│ Propose and implement an improvement. │
│ ↓ │
│ ③ RE-BENCHMARK │
│ Run the same demos with modified evo. │
│ Compare score to baseline. │
│ ↓ │
│ ④ VERDICT │
│ Score improved → MERGE + release. │
│ Score regressed → REJECT. │
│ ↓ │
│ (loop to ①) │
└────────────────────────────────────────────┘
evo self-improve -n 3 --repos bugkit vulnkit mathkit --no-sandboxWhen a self-improvement iteration passes the benchmark gate, evo merges the change, bumps its own version, tags it, and pushes — triggering CI to publish a new release. Start the command, walk away, come back to a new version.
When evo detects it's running on its own repo:
- Safety-critical infrastructure is locked — core decision logic, proof ledger, release mechanics, and sandbox isolation can't be modified
- Stronger models activate — analyze and implement auto-escalate to the strongest available model
- Benchmark gating — changes must improve the score across demo repos, not just pass evo's own tests
- Lessons memory — failed approaches are recorded so evo doesn't repeat them
evo builds knowledge that transfers between codebases:
- Lessons — diagnostic insights (test failures, platform quirks, pattern corrections) are shared across repos within a benchmark run. A failure pattern discovered in one codebase helps avoid the same mistake in the next.
- Genomes — statistical success rates per proposal category, language, and project maturity level — injected into prompts so the LLM prioritizes what actually works. Genes adapt automatically as more data accumulates, splitting into finer-grained strategies when the evidence supports it.
Manage with evo lessons and evo genomes.
| Strategy | Focus | Writes Source? | Best For |
|---|---|---|---|
test_coverage |
Missing tests, edge cases | No | Safe first pass — grow coverage |
hardening |
Bugs, error handling | Yes | Making code robust |
balanced |
Tests + bugs + quality | Yes | General improvement |
full_auto |
Everything — LLM decides | Yes | Maximum autonomy |
Start with test_coverage to build confidence, then move to balanced or hardening.
evo supports Anthropic (Claude) and OpenAI (GPT/o-series). Each pipeline phase can use a different model:
provider: anthropic # or: openai
models:
default: claude-haiku-4-5-20251001 # cheap fallback for simple tasks
analyze: claude-sonnet-4-20250514 # code comprehension needs depth
implement: claude-sonnet-4-20250514 # code quality matters here| Phase | Task | Recommendation |
|---|---|---|
analyze |
Find weaknesses | Strong model (Sonnet/GPT-4o) |
propose |
Pick one improvement | Cheap model (Haiku/GPT-4o-mini) |
implement |
Write code | Strong model |
diagnose |
Analyze test failures | Cheap model |
Typical cost per iteration: $0.02–0.05 (all cheap), $0.06–0.15 (strong for analyze+implement).
If you omit the models section, all phases default to the cheapest available model.
evo run Run the improvement loop
evo run -n 10 10 iterations
evo run --no-sandbox Run locally (no Docker)
evo run --strategy hardening Override strategy
evo run -r /path/to/repo Target a specific repo
evo run --verbose Detailed output
evo run --show-prompts Display LLM prompts
evo init Scaffold .evo.yaml interactively
evo analyze One-shot: run metrics + find weaknesses
evo status Proof ledger summary + chain verification
evo history Full proof ledger with metric deltas
evo lessons Diagnostic insights from past runs
evo runs List past runs (merge rate, cost)
evo stats Aggregate statistics
evo cleanup --older-than 30d Remove stale evo branches
evo benchmark Run suite across demo repos
evo benchmark --save my-baseline Save results as named baseline
evo benchmark --compare my-baseline Compare to a saved baseline
evo benchmark --parallel All repos in parallel (faster)
evo benchmark --score-only JSON output for scripting
evo self-improve Full loop: benchmark → self-run → re-benchmark
evo self-improve -n 5 5 self-improvement iterations
evo self-improve --repos bugkit vulnkit Benchmark specific repos
evo self-improve --demo-iterations 5 Iterations per demo repo
evo self-improve --force-baseline Re-run baseline even if cached
evo genomes Cross-repo success rate data
evo genomes --prune Remove proven failures
evo lessons --clear Reset the lessons journal
Safety in evo is structural, not bolted on.
| Mechanism | What It Does |
|---|---|
| Pareto gate | No metric may regress. Ever. |
| Scope enforcement | AI can only touch files in allowed_scopes. test_addition proposals are further restricted to test files only. |
| Proof ledger | Hash-chained append-only log. Each entry's hash depends on the previous. Tampering breaks the chain. |
| Cost caps | Configurable per-run spending limits. |
| Docker sandbox | Optional isolated execution (or --no-sandbox for local). |
| Dead-end commits | Rejected changes are committed with DEAD END: messages — nothing is silently lost. |
| No force-push | Append-only git history. No rebase, no --force. |
| Mode | Behavior |
|---|---|
reject |
Dead-end immediately on failure (safest) |
auto-fix |
AI diagnoses and retries — up to 3 cycles |
human-gate |
AI diagnoses, human approves before fix |
Built-in profiles:
| Language | Test Frameworks | Lint | Type Check |
|---|---|---|---|
| Python | pytest | ruff, flake8 | mypy |
| TypeScript | vitest, jest | eslint | tsc |
| JavaScript | vitest, jest | eslint | — |
| C# | dotnet test (xUnit, NUnit) | dotnet format | — |
Additional parsers: Go (go test), Rust (cargo test), Ruby (Minitest).
For unknown languages, evo can infer a profile via LLM — detecting test patterns, build commands, and file conventions — then cache it for future runs.
MIT — Copyright (c) 2025-2026 Nils Wendelboe Holmager