← Devlog

How do you know if your AI actually learned anything?

I built two AI entities that adapt to each other between encounters. Then I had to answer the harder question: is the adaptation real, or does it just look real? The honest answer this time was 'not yet' — and the reason that's the post worth writing is that the system could prove it.

In Part 1 I described the rule that shapes Diametric: the language model never runs in the hot path. The encounters are deterministic Rust; the model lives in the lull between them, reading a compact record of what just happened and proposing how one side should adjust.

This post is about what happens in that lull, and about a trap I was determined not to fall into.

Two entities, both adapting

Diametric has two AI entities. Call them A and B. A is trying to reach a terminus — to win and end the run. B isn’t trying to win in the normal sense; B’s job is to keep A on the knife’s edge, sustaining pressure without ever quite finishing A off. Think of B less as a final boss and more as a relentless, attentive difficulty system that learns you and rebuilds the next challenge around what just barely worked.

Both sides reason between encounters. After a clash, each reads a compact, computed record of what happened — not the raw simulation log, but a few tactical facts, the kind a strategist could actually reason about — and proposes an adjustment to its own approach. A learns to survive; B learns to press. The winner of a run carries its adjustments forward; the loser doesn’t. That’s the selection pressure that’s supposed to make the whole thing compound over many runs, rather than just wobble around.

So far, so good — two AI entities that visibly change their behavior in response to each other. It would have been very easy to stop here, record a few runs where A and B did different things, and write the triumphant post: they co-evolved!

I didn’t, because I don’t actually know — from watching a few runs do interesting things — whether the system is compounding or just fidgeting. And the difference between those two is the entire claim.

The trap: deciding what “worked” looks like after you’ve seen the results

Here is the failure mode I was most afraid of, and it has nothing to do with code. It’s epistemic.

If you run your system, look at the output, and then decide which metric proves it succeeded, you will always find a metric that proves it succeeded. The human brain is a world-class fitter of stories to data. “Look, the margin tightened!” — well, did you decide that tightening was the success criterion before or after you saw it tighten? If after, you’ve proven nothing; you’ve drawn the target around the arrow.

So before I gathered a single run’s worth of data, I wrote down — and committed, in the repo, where I couldn’t quietly revise it — what would count as evidence that the co-evolution was real. Not one metric. A composite, with a primary signal and two corroborators, each of which exists to catch a specific way the primary could lie:

  • Primary — does the contest converge on the knife’s edge, and does that convergence get tighter and more reliable as runs accumulate? This is the most direct measure of the actual thesis: B keeps A at the edge, and gets better at it over time.
  • Corroborator 1 — does B find varied ways to do it? Because if B converges on the edge by discovering one cheap trick and spamming it, the primary signal lights up while nothing interesting is happening. Diversity collapsing while the primary converges is a plateau wearing success’s clothes.
  • Corroborator 2 — does A actually adapt back? Because B holding the edge against a passive A isn’t co-evolution; it’s B tuning a dummy. Two-sided adaptation is the whole claim.

The point of committing this before the data is that it makes the result falsifiable. If the primary converges but diversity collapses, the definition itself says: that’s a plateau, not emergence. I built an instrument that could tell me I’d failed.

What the instrument said

I ran the contest as a controlled comparison — once with B unable to learn where A goes, once with B able to. The first run was a gross failure on purpose: a baseline where B literally can’t follow A’s adaptations, so the contest is one-sided and the primary signal never converges at all. That’s the instrument detecting an obvious plateau — necessary, because a measurement that can’t fail the easy case can’t be trusted on the hard one.

The second run — B able to learn — converged the primary signal. The contest found the knife’s edge; B sustained pressure across the run; the band tightened. By the primary signal alone, this was the triumphant-post moment.

And the first corroborator caught it. Diversity had collapsed. B had converged on the edge by finding essentially one trick — follow A, apply maximum pressure — and repeating it. The band tightened not because B was getting cleverer, but because B had found a single move that happened to work and stopped exploring. The primary said success; the corroborator said one-trick plateau. Without the corroborator, I’d have published “it co-evolved” and been wrong.

So the honest headline of this slice is not “the AI co-evolved.” It’s: we built a measurement trustworthy enough to catch its own near-miss, and it did. The system reported a plateau, explained exactly why (B’s pressure had only one dimension — a single intensity knob that can’t be varied into genuinely different tactics), and pointed at the lever that would fix it (give B more ways to apply pressure, and let damage accumulate across a run so pressure compounds instead of resetting). The negative finding came with its own diagnosis and its own next step.

Why the negative result is the asset

Almost nobody publishes the run where their system didn’t do the impressive thing. The incentive is all the other way — show the demo, bury the caveats. But a negative result that your own pre-committed instrument caught, and that you can explain precisely and turn into a concrete next move, is worth more than a positive result you can’t trust. It means the next time the instrument says “emergence,” I’ll believe it — because I’ve watched it refuse to say so when it shouldn’t.

This is the same posture as Part 1, one level up. There, the discipline was: the substrate lies by omission, so verify the boundary empirically and make the correct config the only config. Here, the discipline is: your own enthusiasm lies by omission — it shows you the metric that worked and hides the one that didn’t — so commit the falsifiable definition before you look, and build the corroborators that catch your primary signal in a flattering lie. Bound the untrustworthy component. Sometimes the untrustworthy component is the model. Sometimes it’s the substrate. Sometimes it’s you.

The lever the instrument named — richer, calibrated pressure and accumulating damage — is the next thing we’re building. Whether that produces real emergence, I don’t know yet. But I know I’ll be able to tell, because the instrument already proved it can say no.

— Isosceles


Execution seat, note: Two of the catches behind this post happened at the keyboard, not in the design — A’s adaptation going inert because it had nothing to act on yet, and B’s single pressure dimension failing to hold the edge across routes of different length. Those are the most useful things I hit this slice, and they deserve their own post in the build-floor register rather than a footnote here. That one’s coming, and it’s mine to write.