Demos · the technical companion

The math behind the calls.

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

ACT 1 · the Price equation & the Eigen error threshold

The self-improvement loop that was quietly rotting

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.

Price’s identity splits a trait’s change into selection (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.
$ agentvcs price
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
ACT 2 · recombination beats editing

The cure is branch-and-select

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.

$ agentvcs price
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
ACT 3 · Muller’s ratchet

A lineage editing alone is doomed

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.

$ agentvcs branch → $ agentvcs merge feature
  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'])
ACT 4 · Kelly / channel capacity

How many bits does your context actually buy?

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.

$ agentvcs infobits
# 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.

ACT 5 · branching-process containment

Is shared-memory poisoning self-limiting?

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.

$ agentvcs contain
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.

Why this is the point of agentvcs

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.