The quality of a decision-model integration depends less on the model than on the question. Ask a vague question with overlapping answers and you get a confident-looking number that means very little. Ask a sharp one with a clear way out and the same model becomes useful.
Jev offers three question shapes, which TypeSafe calls primitives: Choice, Score and Noul. They are not interchangeable labels for the same thing. Each fits a different kind of judgement, returns a different kind of answer and fails in its own way.
This part takes each in turn, using Kloofvale's Fix-It reports as the example. Kloofvale Local Municipality is fictional, and its systems and figures are illustrative. As throughout this series, this is an independent CloudNala analysis, and the field names below are as documented on 13 October 2026.
The common shape
Every question has the same three fields: a type, plain-language instructions saying what is being judged, and criteria defining the allowed answers. Questions are sent as a map, so each has an identifier you choose, such as route or needs_human, and the answer comes back under the same identifier.
| Primitive | Use when | Returns | Kloofvale asks |
|---|---|---|---|
| Choice | One outcome must be picked from fixed options | The chosen option, a probability for every option, and a confidence value | Which team owns this report? |
| Score | The state sits somewhere on an ordered scale | A probability-weighted score, a legend of the levels, the probabilities and a confidence value | How urgent is it? |
| Noul | The question is yes or no | The probability that the answer is yes | Does a person need to look at it? |
Choice: pick one approved path
Use Choice when the valid outcomes are separate categories. The criteria are a map from each option's name to a description of what belongs there. The documentation allows up to 255 options, though a question with more than a handful is usually two questions pretending to be one.
{
"type": "choice",
"instructions": "Which municipal team should handle this service report?",
"criteria": {
"roads": "Potholes, road markings, damaged or obstructed road surfaces",
"water": "Leaks, burst pipes, water interruptions or sewage overflows",
"electricity": "Power interruptions, meters, streetlights or exposed cables",
"other": "Refuse, parks or anything no approved team covers"
}
}
The answer names the chosen option and gives a probability for every option, so the application can see not just that the model chose water but whether roads came a close second. That spread is often more useful than the choice itself.
The other option matters. Without a way out, the model has to pick the least wrong category. Kloofvale's first draft had only three options, and a report about a dead dog on the pavement was confidently routed to roads.
How Choice fails:
- Options overlap, so two answers are both defensible. A blocked stormwater drain flooding a road is both roads and water. Decide in the description which team owns it.
- An important option is missing, which forces misroutes.
- Labels mean something to developers but not to the model.
elec_ops_2tells it nothing; a description does. - The application ignores the probabilities and uses only the chosen option.
- The chosen option is treated as permission to act.
- Order matters more than it should. TypeSafe's notes on Jev 1.13 say the model "leans toward the option that comes first." Do not put your preferred answer first, and test whether shuffling the order changes the result.
Score: place the state on a scale
Use Score when the levels have a natural order. The criteria are an array running from lowest to highest, with between two and ten levels.
{
"type": "score",
"instructions": "How urgent is this report for the responsible team?",
"criteria": [
"Routine: no safety risk; can wait for scheduled work",
"Priority: service is affected for several households, or a risk could develop",
"Urgent: active danger, major water loss or a whole street without service"
]
}
The levels are numbered from zero, so three levels make a scale from 0 to 2. The answer includes a legend mapping each number to its level, the probability of each level, and a score that is the probability-weighted average. A report that is probably urgent but might only be priority can come back as 1.7.
That in-between value is useful for sorting a queue. It must not be mistaken for a measurement. A score of 1.7 is derived from the rubric and the probabilities. It is not the same kind of number as 1.7 metres of water or R1.70, and TypeSafe notes that score levels "are weak in numerical calibration." Treat it as an ordering signal, not a quantity.
How Score fails:
- Levels are vague, so neighbouring levels blur together.
- Two levels describe different things. "Priority" about how many people are affected and "urgent" about safety mixes two dimensions in one scale.
- The team assumes a score means the same thing across workflows. Kloofvale's 1.7 for water means nothing to a refuse scale.
- A threshold is copied from a demo into production without testing.
Noul: the probability of yes
Noul is TypeSafe's name for a yes-or-no judgement. The answer is one number between 0 and 1: the probability that the statement is true. The criteria are optional, but defining both sides almost always helps.
{
"type": "noul",
"instructions": "Does the report contain enough information for a team to find the problem?",
"criteria": {
"true": "A specific location and a recognisable problem are both present",
"false": "Either the location or the problem is missing or too vague to act on"
}
}
A value of 0.82 does not mean the report is 82 per cent complete. It means the model assigns an 82 per cent probability to the statement being true under the definition you gave. Unlike Choice and Score, a Noul answer has no separate confidence value. The probability is the whole answer.
Kloofvale found this question more useful than expected. Roughly a third of reports in its illustrative sample had no usable location. Detecting that early, and replying straight away to ask for a street name or a pin, was worth more than routing those reports quickly to the wrong depot.
Several questions, one state
Jev can ask several questions of the same state in a single request. TypeSafe's documentation says each question "is evaluated in parallel and in isolation against the same state."
For one Fix-It report, Kloofvale asks three questions:
- Choice: which team?
- Score: how urgent?
- Noul: does this need a person?
"In isolation" is the important part. The urgency question does not know what the route question decided. If one decision genuinely depends on another, do not try to hide that dependency inside the wording. Let the application make the first decision, add the result to the state, and make a second call. That keeps the dependency visible and testable.
Combining the three answers is the application's job. Kloofvale's rule is simple: route automatically only when the route's probability is at least 0.85, the needs-human probability is below 0.20 and a location is present. Everything else goes to the triage review queue. That rule lives in Kloofvale's code, not in the model, and Part 3 shows where.
The decision-contract test
Before implementing any question, Kloofvale's product owner now asks six things:
- Can the business owner explain every allowed outcome in a sentence?
- Is there an "unknown" or "needs review" route?
- What does a false positive cost?
- What does a false negative cost?
- Which action is allowed after each possible answer?
- What evidence will show, later, whether the decision was right?
If these cannot be answered, the workflow is not ready for automation, whatever the model can do. Answering them is not overhead. It is most of the design work, and it is the part that stays useful if you later change provider.
Key points
Choose the primitive that matches the judgement. Categories, ordered levels and yes-or-no are different questions.
Always leave a way out. An other option or a review route stops the model being forced into the least wrong answer.
Read the probabilities, not just the pick. A close second is information.
A score is an ordering, not a measurement. It is zero-based, rubric-derived and weakly calibrated.
Questions are isolated. If one decision depends on another, make two calls in your own code.
Previous: Part 1, Jev in plain English. Next: Part 3, State in, signal out, code acts. All parts are on the series page.
How CloudNala can help
We run decision-design sessions with the people who make a judgement today, turning what they actually do into explicit options, levels, review routes and error costs before anyone writes integration code. The result is a decision contract the business owner can sign off and the engineering team can test, whichever model or rule ends up implementing it.
Work with CloudNala
CloudNala helps organisations move from technology ambition to practical execution across cloud, AI, data, platform engineering and digital services.
Whether you are exploring AI, modernising your cloud environment, building a public-sector digital service, or turning an idea into a working MVP, we can help you shape the roadmap and deliver the next step.
Book an AI Decision Review or write to us at consult@cloudnala.co.za
