judgevet.domain.answers

Status: draft.

judgevet.domain.answers

Answer types returned by the Jev API.

The domain checks noul and confidence against [0,1] on construction. It checks that probabilities sum to 1 and contain the selected choice. It also checks that score lies in legend range and legend/probability keys match. Frozen dataclasses prevent attribute reassignment; nested dictionaries remain mutable. All numeric answer values must be finite integers or floats, excluding booleans. Public policy evaluation also checks values when it consumes an answer.

Examples:

from judgevet.domain.answers import NoulAnswer, ChoiceAnswer, ScoreAnswer

noul = NoulAnswer(noul=0.75)
choice = ChoiceAnswer(
    choice="yes", confidence=0.8, probabilities={"yes": 0.8, "no": 0.2}
)
score = ScoreAnswer(
    score=2.5,
    confidence=0.9,
    legend={1: "poor", 2: "fair", 3: "good"},
    probabilities={1: 0.1, 2: 0.2, 3: 0.7},
)
See Also

Answer = NoulAnswer | ChoiceAnswer | ScoreAnswer module-attribute

Union type for all possible answers.

PROBABILITY_SUM_TOLERANCE = 1e-06 module-attribute

Tolerance for probability sum validation.

Recorded sums in this repo deviate by 0.0. Float64 accumulation bound is k·ε with ε = 2.22e-16. A 1000-key distribution accumulates at most ≈2.2e-13, so 1e-6 sits four orders of magnitude above the arithmetic worst case.

Open question: if the live service rounds probabilities to 2-3 decimals, a normalized distribution can sum off by up to ~0.0005·k and would be rejected. Change this tolerance only with observed evidence and record any rounding behavior in docs/reference/api.md. Existing calls do not establish a general rounding guarantee.

ChoiceAnswer dataclass

A selected choice with probabilities and confidence.

See: https://docs.typesafe.ai/primitives/choice

This frozen dataclass validates values in __post_init__. Confidence and probabilities must be finite, numeric and within [0.0, 1.0], excluding booleans. Probabilities must sum to 1.0 and contain the selected choice.

Attributes:

Name Type Description
choice str

The name of the choice with highest probability.

confidence float

Confidence in the selected choice, from 0 to 1.

probabilities dict[str, float]

Probability of each choice, keyed by choice name.

Examples:

answer = ChoiceAnswer(
    choice="yes",
    confidence=0.8,
    probabilities={"yes": 0.8, "no": 0.2},
)
assert answer.choice in answer.probabilities
See Also

__post_init__()

Validate choice, confidence, and probabilities.

Ensures confidence is finite in [0.0, 1.0], all probability values are finite in [0.0, 1.0], probabilities sum to 1.0, and choice is a key.

Raises:

Type Description
TypeError

If confidence or any probability is nonnumeric or a boolean.

ValueError

If a numeric value is nonfinite or outside [0.0, 1.0]. Also raised if probabilities do not sum to 1.0 or choice is missing from probabilities.

NoulAnswer dataclass

A yes/no answer with probability of true.

See: https://docs.typesafe.ai/primitives/noul

This is a frozen dataclass with validation in __post_init__ to ensure noul is finite and numeric (not bool) and in [0.0, 1.0].

Attributes:

Name Type Description
noul float

Probability of a yes answer or true statement, from 0 to 1.

Examples:

answer = NoulAnswer(noul=0.75)
assert 0.0 <= answer.noul <= 1.0
See Also

__post_init__()

Validate noul is finite, numeric and in [0.0, 1.0], excluding bool.

Raises:

Type Description
TypeError

If noul is not a numeric type or is a bool.

ValueError

If noul is nonfinite or outside [0.0, 1.0].

ScoreAnswer dataclass

A scored response with rubric and probabilities.

See: https://docs.typesafe.ai/primitives/score

This frozen dataclass validates values in __post_init__. Score must lie in legend range and be finite and numeric, excluding booleans. Confidence and probabilities must also be finite and numeric, excluding booleans, and within [0.0, 1.0]. Probabilities must sum to 1.0, and legend/probability keys must match.

Attributes:

Name Type Description
score float

Expected score (probability-weighted average of rubric levels).

confidence float

Confidence in the score, from 0 to 1.

legend dict[int, str]

Rubric descriptions keyed by integer score.

probabilities dict[int, float]

Probability of each score level, keyed by integer score.

Examples:

answer = ScoreAnswer(
    score=2.5,
    confidence=0.9,
    legend={1: "poor", 2: "fair", 3: "good"},
    probabilities={1: 0.1, 2: 0.2, 3: 0.7},
)
assert 1 <= len(answer.legend) == len(answer.probabilities)
See Also

__post_init__()

Validate score, confidence, legend, and probabilities.

Checks finite score against legend range and finite confidence against [0.0, 1.0]. Checks finite numeric probabilities against [0.0, 1.0] and their sum against 1.0. Checks that legend/probability keys match.

Raises:

Type Description
TypeError

If any numeric key or value is not the expected type or is a boolean.

ValueError

If any numeric value is nonfinite, score is outside legend range, or confidence or any probability is outside [0.0, 1.0]. Also raised if probabilities do not sum to 1.0 or legend/probability keys do not match.