Jev and System One models: a plain guide / How it works
What Jev returns: Choice, Score and Noul
Jev answers three kinds of question. Choice picks one option from a list of up to 255 and returns a probability per option plus a confidence number. Score places the text on an ordered scale of 2 to 10 levels you describe in words and returns a probability-weighted value that can land between levels. Noul is a yes/no statement that returns a single probability from 0 to 1 with no separate confidence number. Each maps to a structure your code already has: a switch, a threshold, an if.
Published September 22, 2026. Editorial.
Key takeaways
- Choice returns the chosen option, a probability for every option, and a confidence number, for lists of up to 255 options.
- Score returns each level number multiplied by its probability and added up, so a scale of 0 to 2 can return 1.43, and the docs' own example does exactly that with confidence 0.35.
- Noul returns one probability that a statement is true, and nothing else: no confidence number, because with two outcomes the probability already says how sure the model is.
- Name each question as the thing you will do with the answer, in one clause, with no negation, so the code that reads the result and the person who reads the code agree on what it means.
- Reveneau grades its eval suite with Noul and Score questions: Noul for pass or fail criteria, Score for the checks where partial credit matters.
Every request to Jev carries a state and a map of named questions, and every question is one of three types, which TypeSafe's docs call primitives [1]. Getting the type right is most of the work of using the model well, because each type returns a different shape and each shape fits a different structure in code. This page goes through the three, with the exact limits from the docs, and ends with how to name them.
Choice: one option from a list
A Choice question gives the model a list of options and asks it to pick one. The list can hold up to 255 options. The answer has three parts: the chosen option, a probability for every option in the list, and a confidence number from 0 to 1 [2].
The probability per option is the part most teams under-use. If you ask which of five support queues a ticket belongs to and the answer comes back as billing at 0.51 and technical at 0.46, the chosen option is billing, and the probabilities tell you the model could barely separate the two. That is a different situation from billing at 0.97, and your code should treat it differently. The confidence number summarises that spread in one figure, and calibrated probabilities and confidence, explained covers how it is computed and how to set thresholds on it.
In code, a Choice question is a switch statement. Each option is a case, and the probability is the guard that decides whether to take the case automatically or hand it to a person. Two rules make the list work. Every option should be something your code can act on, because an option nobody handles is a branch to nowhere. And the options should be mutually exclusive, because if two of them overlap the model will split its probability between them and the confidence number will drop for a reason that has nothing to do with the text.
Score: a position on an ordered scale
A Score question describes a scale of 2 to 10 levels in words and asks where the text sits. The answer is a probability per level, and the score itself is each level number multiplied by its probability, added together [3]. That means it can land between levels.
The docs' own example makes this concrete. A three-level scale, numbered 0, 1 and 2, returns probabilities of 0.0 for level 0, 0.57 for level 1 and 0.43 for level 2. The score is 0 x 0.0 + 1 x 0.57 + 2 x 0.43, which is 1.43, and the confidence is 0.35 [3]. Read that as: the model is sure the text is above level 0, and it leans towards level 1 while giving level 2 a real chance. A score of 1.43 with confidence 0.35 carries more information than a hard label of 1 would.
In code, a Score question is a threshold on a number. TypeSafe's guardrails cookbook shows the shape: a severity scale of 0 to 3, with a review threshold of 0.35 and an action threshold of 0.70 under a strict policy or 0.85 under a permissive one [4]. Below the first threshold the message passes, between the two it goes to review, above the second the system acts. The levels are described in words in the question, so the scale means what you wrote it to mean.
One limit from TypeSafe's own list of weaknesses applies here: Score levels "are weak in numerical calibration" [5]. The ordering is reliable, so a 2.1 is above a 1.4. The exact distance between them is less reliable than the ordering, so a threshold should be set from your own labelled data rather than read off the scale as if the numbers were measurements. Where Jev is weak says more.
Noul: one probability that a statement is true
A Noul question is a statement, and the answer is one probability from 0 to 1 that the statement holds for the state. There is no separate confidence number [6]. That is by design: with two outcomes, the probability already says how sure the model is. A 0.95 is a confident yes, a 0.05 is a confident no, and a 0.5 means the model cannot tell.
In code, a Noul question is an if with a threshold. The statement should be written so that a yes means the same thing to the model, to the code that reads the answer, and to the person who reads the code six months later. "The response answers the question the user asked" is a good Noul. "The response is not off topic" is a worse one, because it contains a negation, and TypeSafe's jaggedness page says negations are read at face value and double negatives are answered less reliably [5].
Noul is the type we use most. Reveneau grades its eval suite with Jev, and most acceptance criteria are yes/no statements: the change adds the field the specification names, the diff touches only the files the plan listed, the generated text follows the instruction. Each is a Noul question with the criterion as the statement, and a probability below the threshold fails the change. How Reveneau uses Jev describes the thresholds, and evals with Jev is the how-to.
Which type for which decision
A short rule covers most cases. If the answer is one item from a list, use Choice. If the answer is a degree of something, use Score. If the answer is yes or no, use Noul.
The mistakes are predictable. Teams write a two-option Choice where a Noul would do, which works but gives up the simplicity of a single probability. Teams write a Score where the levels are categories rather than an ordered degree, which confuses the model because a Score assumes level 2 is more of something than level 1. And teams write one Choice with 40 options where four Nouls asked in parallel would be clearer, because each Noul gets a probability on its own terms rather than sharing one distribution across 40 options. TypeSafe's design guidance is to break a broad judgment into atomic questions asked in parallel and combine them in code [7], and many questions in one call covers the mechanics.
What every answer carries
Whatever the type, three things come back with the answer and all three are worth keeping.
The probabilities are the model's belief about each outcome. Log them. When you review the cases the model got wrong, the probabilities tell you whether it was confidently wrong, which is a question-writing problem, or uncertain, which is a threshold problem.
The shape is fixed. The docs describe the answer as always matching the schema of the question, which TypeSafe calls not hallucinating. What that means is that a Choice always returns one of your options, a Score always returns a value on your scale, and a Noul always returns a number between 0 and 1 [1]. The answer can still be wrong: DataCamp reports TypeSafe's own evaluation at 0 percent structured-output errors for Jev and 67.8 percent agreement with the reference answer [8], and the gap between those two numbers is why you need the probabilities.
The independence from other questions. TypeSafe's batching cookbook found that answers did not depend on what else was in the request, with a standard deviation of 0.0 across five repeats for 11 of 13 questions [9]. So you can add a question to a request without changing the answers to the others, which is what makes fan-out safe.
How to name the questions
The questions are a map, so each has a key, and the key is what your code reads. A few habits make the map readable.
Name the question as the thing you will do with the answer. "route_queue" for a Choice that picks a queue, "severity" for a Score, "in_scope" for a Noul. The name should tell a reader what branch, threshold or if the answer feeds.
Write the question text as one clause with no negation and no implied condition. TypeSafe's jaggedness page is explicit that the model "answers the question you wrote, not the one you meant" and that scoping words, negations and implied conditions are read literally [5]. "The diff modifies only files listed in the plan" is one clause. "The diff does not touch anything it should not" contains a negation and an implied standard, and it will be answered literally against whatever the model takes "should not" to mean.
Put the option list or the scale description in words the state uses. If your tickets say "refund" and your options say "reimbursement", you have added a translation step the model has to guess at.
Keep one decision per question. "Is this spam and is it urgent" is two questions wearing one name, and TypeSafe names "Is this spam?" on its own as too broad [7]. Ask four narrow Nouls about what the message contains and combine them in code.
A worked example
Take an incoming support message. One request, four questions. A Choice named route_queue with the options billing, technical, account and other. A Score named urgency on a scale of 0 to 3 described as: can wait a week, should be answered today, needs a reply within the hour, service is down for the customer. A Noul named contains_pii with the statement "The message contains a personal identifier such as a full name with an address, a card number, or a government ID number." A Noul named is_abusive with the statement "The message contains threats or abuse directed at a person."
The answers come back together in one response. Code reads route_queue and takes the branch if confidence is above the threshold for that queue, or sends it to triage if below. Code reads urgency and sets the priority flag from the score. Code reads contains_pii and, above 0.7, masks the message before it is stored. Code reads is_abusive and, above 0.85, routes to the safety team ahead of everything else. Four decisions, one request, and the response time is the same as for one question, because TypeSafe evaluates every question in parallel [10].
That is the whole shape of building with Jev: a state, a handful of well-named questions of the right type, and code that reads the probabilities and acts. The pillar, Jev and System One models, puts it in context, and how to write the state and the questions is the next page to read.
Best for
- Choice when the answer is one item from a fixed list your code can act on
- Score when the answer is a degree of something on an ordered scale you can describe in words
- Noul when the answer is yes or no and you want one probability to threshold
Avoid if
- Do not use Score for categories that have no natural order, because the model assumes level 2 is more than level 1
- Do not use one Choice with dozens of overlapping options when several Nouls in parallel would each get a clean probability
- Do not write a Noul statement with a negation in it, since TypeSafe documents negations as read literally
Check before you decide
- Confirm every Choice option is handled by a branch in code, and that no two options overlap
- Confirm each Score threshold against your own labelled cases rather than reading it off the scale
- Confirm the Noul statement means the same thing to the model, to the code, and to a reader of the code
Common questions
What are Jev's three question types?
Choice picks one option from a list of up to 255 and returns the choice, a probability per option and a confidence number. Score places the text on an ordered scale of 2 to 10 levels described in words and returns a probability-weighted value. Noul is a yes/no statement and returns one probability from 0 to 1. In code they are a switch, a threshold and an if, and the probabilities decide whether code acts or a person does.
How many options can a Choice question have?
Up to 255, according to TypeSafe's Choice documentation. In practice a long list works against you: the model spreads one probability distribution across every option, so overlapping or near-duplicate options lower the confidence number for reasons unrelated to the text. If you have 40 categories, check whether several narrow Noul questions asked in parallel would give cleaner probabilities, since each Noul is scored on its own terms.
How is a Score computed?
Each level number is multiplied by the probability the model assigns to that level, and the products are added. The docs' example uses levels 0, 1 and 2 with probabilities 0.0, 0.57 and 0.43, giving 0 + 0.57 + 0.86, which is 1.43, with a confidence of 0.35. A score between levels means the model is split, and that split carries more information than a hard label would.
Why does a Noul answer have no confidence number?
Because a yes/no question has two outcomes and one probability already describes both. A Noul of 0.95 is a confident yes, 0.05 a confident no, and 0.5 means the model cannot tell. TypeSafe's Noul docs state that no separate confidence number is returned. Choice and Score need one because their probability is spread over several options, and the confidence number summarises how concentrated that spread is.
When should a team use Score instead of Choice?
Use Score when the levels are degrees of one thing, such as severity from 0 to 3 or completeness from 1 to 5, because the model assumes level 2 is more of that thing than level 1. Use Choice when the options are categories with no order, such as billing, technical and account. A Score over unordered categories confuses the model, and a Choice over ordered degrees throws away the between-level value that Score would have given you.
How should Score thresholds be set?
From your own labelled cases, and never by reading the scale as if its numbers were measurements. TypeSafe's jaggedness page says Score levels are weak in numerical calibration: the ordering is reliable, and the exact distance between values is less so. TypeSafe's guardrails cookbook shows the shape of a working policy on a 0 to 3 severity scale: review at 0.35 and act at 0.70 under a strict policy or 0.85 under a permissive one.
Does adding a question change the other answers?
TypeSafe's batching cookbook says no: answers do not depend on what else is in the request. On jev-1.12, 13 questions against the Wikipedia GDPR article repeated five times each gave a standard deviation of 0.0 for 11 of the 13 questions. That independence is what makes it safe to add a question to a request without re-checking the thresholds on the questions already there.
How should questions be named?
Name each question as the thing your code will do with the answer: route_queue for a Choice that picks a queue, severity for a Score, in_scope for a Noul. Write the question text as one clause with no negation and no implied condition, because TypeSafe documents that scoping words, negations and implied conditions are read literally. Use the words the state uses, so the model does not have to translate between your vocabulary and the text's.
What does it mean that the answer always matches the schema?
A Choice always returns one of your options, a Score always returns a value on your scale, and a Noul always returns a number between 0 and 1. TypeSafe calls this not hallucinating, and DataCamp reports 0 percent structured-output errors on TypeSafe's own evaluation. The answer can still be wrong: on that same evaluation Jev agreed with the reference 67.8 percent of the time. The probabilities are how you tell a confident answer from a guess.
Can one request mix all three types?
Yes. A request carries a map of named questions and each entry can be a Choice, a Score or a Noul. TypeSafe evaluates every question in parallel and states that adding questions barely changes the response time. A support-triage request might carry one Choice for the queue, one Score for urgency and two Nouls for personal data and abuse, and all four answers return together in one response.
Which type does Reveneau use for eval grading?
Mostly Noul, because most acceptance criteria are yes/no statements: the change adds the field the specification names, the diff touches only the files the plan listed, the generated text follows the instruction. Each criterion is the Noul statement and a probability below the threshold fails the change. Score is used where partial credit matters, such as how completely a response covers a rubric with several parts.
References
- [1] TypeSafe docs, System One concept: a state plus a map of named questions; a typed answer per question with probabilities; the answer always matches the schema.
- [2] TypeSafe docs, Choice primitive: up to 255 options; returns the choice, a probability per option, and a confidence number.
- [3] TypeSafe docs, Score primitive: 2 to 10 levels described in words; score is each level multiplied by its probability, added up; example score 1.43, confidence 0.35, probabilities {0: 0.0, 1: 0.57, 2: 0.43}.
- [4] TypeSafe docs, LLM guardrails cookbook: one request screens a message with questions such as jailbreak, harmful_request, medical_advice, self_harm and a 0 to 3 severity score; review threshold 0.35 and action threshold 0.70 (strict) or 0.85 (permissive); route precedence support, block, review, pass.
- [5] TypeSafe docs, Model jaggedness for jev-1.13: "answers the question you wrote, not the one you meant. Scoping words, negations, and implied conditions are read at face value"; Score levels "are weak in numerical calibration"; double negatives answered less reliably.
- [6] TypeSafe docs, Noul primitive: a yes/no statement; returns one probability from 0 to 1; no separate confidence number.
- [7] TypeSafe docs, How to build with System One: break a broad judgment into atomic questions asked in parallel and combine them in code with weighted arithmetic; "Is this spam?" named as a broad-question anti-pattern.
- [8] DataCamp, Jev: TypeSafe's System One model explained: 0% structured-output errors for Jev on TypeSafe's own evaluation; 67.8% agreement with the reference answer.
- [9] TypeSafe docs, Parallel questions cookbook: answers do not depend on what else is in the request; standard deviation 0.0 across five repeats for 11 of 13 questions on jev-1.12.
- [10] TypeSafe docs, Introduction: every question in a request is evaluated in parallel; "Adding questions barely changes the response time."
Related reading
Our eval suite now runs ten times faster. Here is what we changed.
This month we replaced the language model that graded the judged checks in our eval suite with Jev. The deterministic checks did not move, every rubric is now written inside the check, and the suite runs ten times faster.
How to write an acceptance test a machine can run
Most acceptance criteria are written for a human reader who will add the missing details. A machine adds nothing. Here is how to write the sentence so an automated check can enforce it.
Never let the model grade its own work
When the same run writes the code and the tests, a passing build proves only that the code is consistent with itself. That is not verification, and it is the most common way an AI-built codebase becomes confidently wrong.
What to do with a grader that gives no reason
A Jev grade is a probability with no paragraph. That is enough for a check you wrote and calibrated yourself, and wrong for a new kind of failure, a design judgment, or anything a regulator wants explained in words.
More in How it works
Calibrated probabilities and confidence, explained
A calibrated probability is one you can read as a frequency: when the model says 0.8, it should be right 8 times in 10 across many such answers. TypeSafe trains Jev for this with a method it calls Reinforcement Learning for Calibrated Decisions. Confidence is a separate number, for Choice and Score only, computed from how spread out the probabilities are. TypeSafe suggests acting automatically at 0.9 and above and routing to a person below 0.5, and says different actions in the same system should be gated at different levels depending on the consequences.
How to write the state and the questions
A Jev request has two parts: the state, which is the text the model reads, and the questions, which are what you ask about it. The state can be a string, a JSON object, or an array of text values, text only, up to 32k tokens inside a 64k-token request. The questions should each ask one thing, in one clause, with no negation, because TypeSafe documents that Jev answers the question you wrote rather than the one you meant. This page is the practical guide to both.
Many questions in one call: speculative fan-out
Every question in a Jev request is evaluated in parallel, and TypeSafe's docs state that adding questions barely changes the response time. Its batching cookbook measured 13 questions against the Wikipedia GDPR article on jev-1.12: one batched request cost $0.000497 and took 0.27 seconds, while 13 single requests cost $0.006090 and took 2.71 seconds. TypeSafe reports that as 12.2 times cheaper and 10.0 times faster, and says the answers did not depend on what else was in the request. This page explains the pattern, called speculative fan-out, and when it wastes tokens.