Jev Choice vs Score vs Noul
Choose the right Jev question type: Choice for named alternatives, Score for ordered levels, and Noul for one true-or-false proposition.
Choice: select one named alternative
Use Choice for routing, labels, policy branches, or tool selection. Make criteria mutually understandable and include an explicit fallback when the real world can fall outside the listed options.
Score: place a case on an ordered scale
Use Score for severity, priority, quality, or risk bands. Every level needs a concrete rubric; vague numbers create inconsistent decisions.
Noul: estimate whether one statement is true
Use Noul for a single factual or policy proposition. It returns P(true). Do not combine two conditions with “and” unless they genuinely form one proposition.
Compose decisions from small questions
Ask independent questions in parallel, then combine their typed answers in code. This keeps business policy visible, testable, and separate from model judgment.
Work through a complete example and its failure paths
The complete file below has no placeholder functions. It prints a suggestion or review state; it does not update tickets, spend money, or publish content.
This is a site-authored experiment with synthetic inputs and fixture responses. It uses only the Python 3.11+ standard library, no key or network. Passing tests establishes application behavior for these cases, not Jev accuracy, latency or real-provider retries.
One ticket, three different questions
route selects a queue; severity rates impact on three ordered levels; urgent checks ongoing disruption. They share evidence but are independent. Do not refer to an uncomputed route answer in severity instructions.
Three Score levels occupy 0–2. An illustrative distribution {0:0, 1:0.2, 2:0.8} has weighted position 1.8, not 1.8% risk or 1.8 hours of downtime. A Noul value of 0.9 is its probability output, not a separate confidence field.
| Question | Synthetic answer | How the application uses it |
|---|---|---|
| Choice · route | technical / confidence 0.8 | Propose one mutually exclusive queue; read confidence 0.8 separately from winning probability 0.85. |
| Score · severity | 1.8 / [0, 2] | Compare impact on the declared scale; this is not a probability, downtime or recovery cost. |
| Noul · urgent | 0.9 / [0, 1] | Read the probability output for the ongoing-disruption proposition; calibrate policy using labeled outcomes. |
Exercise: change fixture route.choice to invented or severity.score to 3; the program must reject it. Then set urgent to 0.2: the proposed queue can remain technical because urgency and ownership are different questions. Use one Choice for mutually exclusive queues; separately asked technical/non-technical Nouls need not complement each other.
typed_questions_lab.py
"""Synthetic answer-reading lab. Python 3.11+, standard library, no network.
The fixture is written by this site, not an observed Jev response. The lesson is
how to read three different answer types, not how accurately Jev classifies.
"""
import json
from math import isfinite
STATE = {
"message": "Checkout fails for every customer; invoices are still accessible.",
"scope": "all customers",
}
QUESTIONS = {
"route": {"type": "choice", "instructions": "Which team owns this incident?",
"criteria": {"technical": "Bugs or integrations", "billing": "Invoices", "human": "Unclear ownership"}},
"severity": {"type": "score", "instructions": "How blocked are customers?",
"criteria": ["Unaffected", "Workaround available", "Core workflow blocked"]},
"urgent": {"type": "noul", "instructions": "Does the message describe an ongoing service disruption?"},
}
FIXTURE = {
"route": {"type": "choice", "choice": "technical", "confidence": 0.8,
"probabilities": {"technical": 0.85, "billing": 0.10, "human": 0.05}},
"severity": {"type": "score", "score": 1.8},
"urgent": {"type": "noul", "noul": 0.9},
}
def bounded_number(value, low, high):
return (isinstance(value, (int, float)) and not isinstance(value, bool)
and isfinite(value) and low <= value <= high)
def interpret(answers):
route, severity, urgent = (answers[key] for key in ("route", "severity", "urgent"))
if route.get("type") != "choice" or route.get("choice") not in QUESTIONS["route"]["criteria"]:
raise ValueError("Unexpected Choice option")
if not bounded_number(route.get("confidence"), 0, 1):
raise ValueError("Invalid Choice confidence")
probabilities = route.get("probabilities", {})
if (set(probabilities) != set(QUESTIONS["route"]["criteria"])
or not all(bounded_number(p, 0, 1) for p in probabilities.values())
or abs(sum(probabilities.values()) - 1) > 1e-6):
raise ValueError("Invalid Choice distribution")
if severity.get("type") != "score" or not bounded_number(severity.get("score"), 0, 2):
raise ValueError("Score must be a position in the declared 0–2 scale")
if urgent.get("type") != "noul" or not bounded_number(urgent.get("noul"), 0, 1):
raise ValueError("Noul must be a probability")
return {
"fixture_only": True,
"proposed_team": route["choice"],
"choice_confidence": route["confidence"],
"winning_option_probability": probabilities[route["choice"]],
"severity_position_0_to_2": severity["score"],
"ongoing_disruption_probability": urgent["noul"],
"action": "review_before_any_ticket_update",
}
if __name__ == "__main__":
print("SYNTHETIC FIXTURE — no API request or model measurement")
print(json.dumps(interpret(FIXTURE), indent=2))
print("Score illustration only: 0*0 + 1*0.2 + 2*0.8 = 1.8; not 1.8% or hours.")
print("One Choice holds mutually exclusive queues; independent Noul answers need not sum to 1.")
Download this fileRun
python3 typed_questions_lab.pyHow to verify the run
The output must say SYNTHETIC FIXTURE and fixture_only=true. The technical queue, 0.8 confidence, 0.85 winning probability, 1.8 scale position and 0.9 proposition probability remain distinct fields. None was measured from the API.