Baselines
- Automatic: in Pest, the first run that passes its gate becomes its suite’s baseline. Nothing to configure.
- Manual: promote any completed run from the dashboard, or:
Terminal
How runs are joined
Rows are matched across runs by content hash — a fingerprint of the row’s input, prior messages, and expected data, computed when the dataset is read. Reordering your JSONL file, adding rows, or renaming files changes nothing; the same logical row lines up across months of runs. (For single-model runs the reported provider/model id is deliberately ignored in the join — providers rotate dated model ids likegpt-5-mini-2025-08-07, and that must not sever your history.)
Classification
For each row present in both runs:
Rows only in the current run are new; rows only in the baseline are removed.
Why epsilon? You’re sampling a nondeterministic system — small score wobble is expected. A pass-rate drop is always a regression, but a
0.93 → 0.90 score drift shouldn’t page anyone. Tune evals.compare.epsilon to your tolerance.Failing the build on regressions
In Pest
What a regression failure looks like
Terminal
--compare also accepts a run id or latest. The dashboard’s compare view renders the same diff — regressed and improved tables with before → after scores. See Running in CI for the full pipeline recipe.