The same five capabilities as the plain-English
stories, shown with the real numbers and the theory. Everything runs on real
evaluations, and every claim the narration makes is asserted against
--json — the demo fails loudly if a tool ever stops earning it.
Reproduce it: bash examples/evolution-diagnostics/run.sh
An agent tunes a router by editing one file — it never branches. All five commits pass their eval, so nothing commit-to-commit looks wrong.
Cov(w,z), choosing between branches) and transmission
(E[w·Δz], editing within a lineage). With no branches, selection is 0 by
construction — an asexual lineage — and net-negative editing is the Eigen error
catastrophe.price[score] Δz̄ = -0.1 over 4 branch points selection Cov(w,z) = +0 (contrib +0) transmission E[w·Δz] = -0.1 (contrib -0.1) → ERROR CATASTROPHE: within-lineage editing is losing trait value faster than selection recovers it — freeze or raise eval coverage ✓ d['threshold']['crossed'] is True ✓ d['selection'] == 0.0 ✓ d['transmission'] < 0
Same agent, same benchmark — now it forks two variants each round, keeps the better, and invests exploration in the winner. Selection starts doing real work.
price[score] Δz̄ = +0.133333 over 3 branch points selection Cov(w,z) = +0.033333 (contrib +0.016667) transmission E[w·Δz] = +0.233333 (contrib +0.116667) → improvement is transmission-driven (editing well within a lineage) ✓ d['threshold']['crossed'] is False ✓ d['selection'] > 0 ✓ d['transmission'] > 0 ✓ d['healthy'] is True
A feature branch evolves in isolation and slowly loses fitness. An asexual lineage can’t
purge deleterious edits — and merge --reconcile is the recombination operator.
feature 4a2019e6fbc6 ⚠ ratchet * main 3747f1d1a540 ⚠ branch 'feature' is a long unmerged lineage (5 commits, 4 deleterious step(s)) losing fitness — merge it back into 'main' to reconstitute the least-loaded class ✓ any(b['name']=='feature' and b['ratchet']=='high' for b in d['branches']) # recombine — the ratchet clears merge status: fast_forward ✓ all(b.get('ratchet')=='none' for b in d['branches'])
Two agents, 30 tool calls each. The value of context is bounded by the bits it adds to the decision — so a near-deterministic agent can’t be helped much by more of it.
# low-entropy agent — a 40k-token context feeding a near-fixed decision infobits H(action) = 0.42 bits over 30 decisions / 3 tools I(prev; next) = 0.22 bits ✓ d['action_entropy_bits'] < 1.0 # high-entropy agent — context genuinely drives the choice infobits H(action) = 2.58 bits over 30 decisions / 6 tools I(prev; next) = 2.58 bits ✓ d['action_entropy_bits'] > 2.0
The mutual information here uses the previous action as the context proxy — a
labeled lower bound on I(full-context; action). The tool never overclaims what
it measured.
A fleet reads a shared memory. If a corrupt entry fans out to n readers and each
re-propagates with probability p, it dies out iff R₀ = n·p < 1.
contain R₀ = n·p = 2.40 (n=6 via declared swarm nodes, p=0.4 via failed-eval fraction over 5 commits) NOT contained — need to verify ≥ 58% of reads → verify at least 58% of downstream reads (or cut fan-out / escape rate) to contain it ✓ d['contained'] is False and d['r0'] > 1 $ agentvcs contain --fanout 2 # a smaller fleet contain R₀ = n·p = 0.80 contained ✓ d['contained'] is True
A mean-field bound — the dispersion (tail) matters more than the mean, and the
output says so. A low average R₀ with a heavy tail can still allow rare cascades.
None of these are harness features. They’re measurements over a recorded population of
variants across time — the one object a VCS owns and a live controller doesn’t. All of it
from data agentvcs already stores, standard-library-only, with --json for agents.
Full design and the honest scope boundary:
EVOLUTIONARY_DYNAMICS.md.