Skip to main content
Scores are the primary output; pass/fail is a policy applied on top. Here’s the exact math, bottom to top.

Assertion scores

  • Deterministic assertions score 1.0 (passed) or 0.0 (failed).
  • Judge assertions score raw / 10, normalized to 0–1. Pairwise comparisons score win 1.0 / tie 0.5 / loss 0.0.
  • Skipped or errored assertions have no score (null) and are excluded from means.
  • Every assertion can carry a ->weight(float) (default 1.0).

Sample score

A sample is one invocation of the agent for one row.
  • If any gated assertion failed (or errored): the sample scores 0.0 and fails. Gates are binary preconditions — they’re excluded from the score mean, because “the response wasn’t empty” isn’t quality signal.
  • Otherwise: score = Σ(weightᵢ × scoreᵢ) / Σ(weightᵢ) over non-gate assertions with scores.
  • A sample whose only assertions were passing gates scores 1.0.
  • A sample whose agent invocation or evaluation threw is an error: no score, counted separately.
Weighting example

Row result

Each row (per model combo) aggregates its samples:
  • pass_rate = passed samples ÷ all samples (errors count in the denominator)
  • score_mean, score_stddev = over samples with scores (errors excluded from the mean)
The stddev matters: a row at 90% ± 2 and a row at 90% ± 25 are very different agents.

Run result

Rows aggregate with equal weight: run score_mean/score_stddev over row means, run pass_rate as the mean of row pass rates — plus totals (rows, samples, errors, cost, judge cost, duration). All of it is persisted on the run’s summary; nothing is recomputed later.

The gate

In Pest
  • minScore / minPassRate — thresholds on the run aggregates (0–1).
  • maxRegressions — enforced against the suite’s baseline when one exists.
Defaults come from config('evals.gate'); class-based evaluations can define gatePolicy(); the CLI accepts --min-score, --min-pass-rate, --max-regressions. In Pest a failed gate fails the test; in the CLI it sets exit code 1.
An eval where every sample errored always fails, regardless of gate configuration — a run that proves nothing must never pass.