Products that act on a model's judgment mostly handle this two ways: hide the uncertainty and let the feature be quietly wrong, or hand the user a chat box and make the uncertainty their problem. There is a middle, and it has patterns. This library is eight places software acts on a judgment, each one wired to real answers from a calibrated model — including the three where that model was confidently wrong.
Every team that puts a model in front of a user reaches the same afternoon. The feature works. It works about nine times in ten. And nobody can agree on what it should do the tenth time.
The two answers that ship are both bad. The first is to hide it: fill the field, categorise the row, merge the records, and say nothing, because surfacing doubt would make the feature feel weak. That works until the tenth case, which is now a wrong number in a ledger that nobody is checking any more — the whole promise of autofill is that people stop looking. The second is to hand it back: put a chat box on the screen and let the user sort it out. That is not a design decision. That is the absence of one, shipped.
What is missing between them is a pattern language. Interfaces have had one for loading, for errors, for empty states — shared, argued-over, reusable answers to a recurring problem. For acting on a judgment that might be wrong, there is nothing. Every team rebuilds it from scratch, badly, in a sprint, and calls the result a confidence score in a tooltip.
This is an attempt at that language. Eight places software acts on a model's judgment, each one wired to a real answer from a model that reports how sure it is. The claim underneath is small and has consequences: how assertive an interface should be is a function of two numbers, and only one of them comes from the model. The model knows how certain it is. It has no idea what happens if it is wrong. That second number is yours, it is a design decision, and almost every product that gets this wrong gets it wrong by forgetting it exists.
Below: the two numbers and the five things you can do with them, then the eight surfaces, then what actually came back when I ran it. That last part matters most. Three of the twenty-five judgments here are wrong, and two of them are wrong at maximum certainty — a valid email address silently rewritten, a paid receipt producing a sum to pay. No threshold catches those. They cleared every threshold there is. Which is the clearest argument I can make for why the second number has to exist.
Almost every team treats this as a single dial: make the model better, then let it do more. That is the wrong shape. How assertive an interface should be is a function of two independent things, and only the first of them is on the model's side of the wire.
How sure the model is. A generating model cannot tell you this — ask it and you get prose about being an AI. A calibrated one returns the number directly, which is the entire reason this library is built on one.
What it costs to be wrong in silence. Nothing in the model knows this. Reordering a list and merging two customer records can arrive at identical certainty and must not produce the same interface.
Every card holds one real product moment and three cases: one easy, one genuinely ambiguous, one where the right answer is absent. The numbers are what Jev actually returned, three runs each. Drag the stakes slider and the interface changes without a single new request — the policy was never part of the inference.
A pattern library where every case works is a screenshot. These are the four things this run turned up that changed how I would build the surfaces.
Judgments come from Jev, a calibrated model that returns typed answers and
probabilities instead of text. Three primitives are in play: a Choice picks one
option and reports the distribution, a Noul returns the probability a condition
holds, and a Score places something on an ordered scale. The three do not hand back
the same shape, so each card names how its one number was derived rather than flattening them
and hoping nobody asks.
Answers are generated at build time by generate.py and read from a static JSON file.
Two reasons: an API key belongs on a machine I control, not in a browser bundle, and a pattern
library should open instantly. The policy in ladder.py is about forty lines of
arithmetic with no model in it at all — which is the point the slider is making.
Every case was asked three times. The spread under each number is the honest width of it, and it is why a threshold needs air rather than a decimal point.