pass_rate. Two metrics, computed from the --runs N data you already have, pull them apart — the framing follows Anthropic’s guidance on agent evals:
| Metric | Question it answers | What it measures |
|---|---|---|
| pass@k | ”Does at least one of k trials succeed?” | Capability — can the agent do it at all |
| pass^k | ”Do all k trials succeed?” | Reliability — what a user hitting this feature k times experiences |
The estimators
Both are computed per task from its n recorded trials (c of which passed), then averaged over tasks. pass@k uses the unbiased combinatorial estimator from the HumanEval paper:(c/n)^k is deliberately not implemented. It samples with replacement from a finite trial pool, which biases the estimate upward — a vanity metric. Concretely, with 3 passes in 5 trials at k=2:
From an eval report
No new run mode — the metrics come from the sameruns=N data:
pass_rate. A judge outage is not a capability signal.
Why the CI resamples cases, not trials
The confidence intervals are a cluster bootstrap: tasks are resampled with replacement, the mean of per-task estimators is recomputed, and a percentile interval is taken. Trials within a task are correlated — the same prompt, the same failure modes — so resampling raw trials would treat 20 tasks × 5 trials as 100 independent observations and fake precision the data doesn’t have. The unit of independence is the task; the CI respects that. Degenerate suites (every per-task estimate identical, including all-pass) fall back to a Wilson interval on the mean, so a perfect score still reportsci_low < 1.0 — the same honesty as pass_rate_ci().
The honest-UNKNOWN rule
You cannot estimate pass@10 from 5 trials without extrapolating, so multivon-eval doesn’t:value is None is the contract for UNKNOWN. There is no projected curve and no warning-then-guess. Rerun with runs >= k or lower k.
Lottery cases
The tasks driving the pass@k / pass^k gap — passing sometimes, never reliably — are ranked by per-task divergence:Gating on the CI lower bound
assert_pass_hat_k gates on the lower bound of the pass^k CI, not the point estimate — the same EvalGateFailure exit semantics as fail_threshold:
k > runs), the gate raises with the UNKNOWN reason rather than silently passing — an ungateable claim must fail loudly.
Serialization
Whenruns > 1, the JSON summary carries both metrics (pass_at_k / pass_hat_k, each with k, value, ci_95, estimator), and view --dir shows a pass^k column. Reports saved before 0.16.0 gain the metrics on load via EvalReport.from_dict — per-case trial counts were already stored, so no migration is needed.
