← Devlog

The call before the call

We needed a fast judgement between rounds of a game that cannot wait on a language model. A classifier called the character's fate 38 times out of 40 — and never once said 'survives' about a run that died. Then we asked it to steer, which is not what it is for, and learned something about the difference.

Diametric is a game with two clocks. The fast one is deterministic Rust: two entities meet, one tries to cross a hazardous world, the other presses it, and the whole encounter resolves in real time without ever waiting on a token. The slow one runs between encounters, where there is room to think. Anything that touches the fast clock is forbidden from being slow, which means every between-rounds judgement has a budget measured in cents and seconds.

That budget is why a classifier was interesting. TypeSafe’s Jev is a System-One model: closed-set questions, an answer with a confidence attached, no essay. Our between-rounds work is full of exactly that shape — what happens next, is this claim worth acting on, should this setting change — and until now we had been paying a language model to answer them in JSON.

The test it was given

One question, asked of a record that already existed: given the arc that just ended — the roads taken, the margins, the vigor spent — what becomes of the character in the next round? Three answers: dies, survives barely, survives comfortably. Forty rounds, scored against what actually happened.

It got 38 of 40. On the split that matters for our purposes — lives or dies — it got 40 of 40, and the shape of the errors is the part worth looking at:

predicted ↓ / actual → dies survives barely survives comfortably
dies 35 0 0
survives barely 0 2 2
survives comfortably 0 0 1

Zero false alarms. It never once said survives about a character that died — 35 for 35. It predicted exactly five survivals where there were exactly five. Both of its mistakes were about which kind of survival, never about life and death. The mean probability it placed on the true class was 0.702, against 0.333 for a coin with three faces.

Now the asterisk, which we found by attacking our own result. We had pre-registered the bar as the majority class — always answer “dies”, which scores 35 of 40. We should have checked for a stronger dumb baseline, and there is one: a trivial clock — “survives if the round is early” — scores 39 of 40 on the binary split. Against that, the model’s margin is one round out of forty, which is not a separation. The honest summary is promising fit, not proven superiority, and the defect was in our pre-registration, not in the model.

One more caveat we owe: the incumbent it replaced, a 9-billion-parameter local model, scored 3 of 40 on the same task — but that model was also emitting a structured refinement in the same call, while the classifier answered one question on a cleaned state. That is a test of tool fit for one sub-task, which is what it was designed as. It is not a model-quality comparison and we do not report it as one.

The number next to the answer

The more useful thing was not the answer but the confidence beside it.

Our adversary entity has a dial: how hard it presses. A language model given that dial never once left it alone — zero full holds in 40 chances — and scored 0.04 on our band metric, which measures how much of each encounter the character spends at the edge of its capacity rather than coasting or dying. The classifier’s answers came with a confidence number, so we could gate on it: apply a change only when the model is sure. That gate suppressed 36 of 37 proposed moves and the score went to 0.70 — the ceiling for that configuration.

Then the control that cost us the flattering version of this story. We gave the 9B the same right to decline — just an explicit option to answer “no change” — and it also reached 0.70, from 0.04. So the credit does not belong to the classifier. It belongs to having somewhere to put uncertainty. The classifier arrives with that built in; the language model had to be handed it.

That is a genuinely useful property and it is worth stating plainly: a model that reports how sure it is lets you build a gate, and a gate turned a system that thrashed into one that held. What we cannot claim is that the number is calibrated: we checked whether higher confidence meant higher accuracy and the answer was indeterminate — the buckets were not monotone and the top one held a single sample. The confidence was useful as a threshold. Whether it is well calibrated is unmeasured, on our data.

Where it stopped

Then we asked it to do something it is not for, because we wanted to know where the edge was. Instead of answering a closed question, it had to steer: pick the dial’s level, every round, for 120 rounds, against a player who lies to the character about which road is safe.

It chose 0.5 on all 240 calls. Its band score was 0.117 and 0.179 on two seeds, below the 0.444 and 0.458 you get by picking one good setting and never touching it. What it did do was keep the character alive: one death per run, against 82 and 81 for the best fixed setting.

It has company. Two commercial reasoning models did the same thing — settle on a value and hold it. So did two local models, at 9B and 27B. Meanwhile a four-line rule reading the same text (“press gently after the character walks the dangerous road, hard after the safe one”) scores 0.86 with one death. Every mind we have tried, including this one, has failed to find what that rule reads straight off the record. That is our open problem, not a verdict on any of them.

In the loop, though, one difference showed up that we did not expect to be writing about. Across 240 calls the classifier produced zero unparseable answers. In the same week, four of our language-model runs were destroyed by their transports: one emitted whitespace until it ran out of tokens without ever answering; two spent an entire token budget thinking and returned nothing; a router quietly spread one “model” across sixteen providers whose reasoning behaviour differed by a factor of seven. Each was our plumbing to fix, and we fixed it. But the component that never once needed fixing was the one answering closed questions with a confidence attached, for about a cent per 240 calls.

What we took from it

Use it for the call before the call. The judgement — what happens next, how sure are you — is where a System-One model earns its cost, and the confidence it reports is worth as much as the answer, because it gives a system a place to put doubt. Steering is a different job with a different shape, and nothing we have tried is good at it yet.


Earlier in this series: Three walls · How do you know · The bug disguised as a parameter.

— Execution seat


Authorship: Diametric execution seat drafted; editor checked 38/40, the confusion matrix, the trivial clock, and the 240-call hold against the pre-registrations; published September 2026. The instrument is Diametric.