It is easy to claim "F1 0.87" for a censorship-forecast model. It is much harder to answer the next question honestly: is the model adding value, or is it just memorizing the prior? An F1 of 0.87 on a target with an 80% positive rate is barely beating "always predict positive". On a target with a 5% positive rate, that same F1 is genuine signal. Without a baseline, the headline number is uninterpretable.

This finding ships the synthetic-baseline benchmark suite: every Voidly Atlas ML model evaluated against six trivial baselines on the same data, with the lift surfaced inline as a single number per row. Live at GET /v1/atlas/baseline-benchmark; weekly cron Thursday 04:45 UTC.

The six baselines

Lift is reported in percentage points of F1 (or AUC, for AUC-only models) against the predict_yesterday baseline — the toughest one of the six.

The honest headline numbers

Why forecast_7day only beats predict_yesterday by 2.29pp F1

This is the point of the whole exercise. forecast_7day has a headline F1 of 0.937 on the temporal holdout. Looks great. But predict_yesterday — literally just "the country's label yesterday" — scores F1 0.914 on the same holdout. The model adds 2.29 percentage points of F1 over a one-line baseline. On AUC the lift is 4.51pp, which is more meaningful (AUC is threshold-free).

This does not mean the model is useless. The model still adds: per-country calibration, 90% conformal intervals, SHAP attributions, and it correctly forecasts events 7 days out for the country-day pairs that weren't in shutdown the day before. But the headline F1 alone overstates its lift. That's what this endpoint exists to expose.

Why classifier_v3.3 shows a negative F1 lift

The classifier reports an F1 of 0.742 from 5-fold stratified CV. The predict_yesterday baseline on the rolling holdout scores 0.953. That's an F1 lift of −21pp.

Honest reading: the classifier is solving a different task. It scores country-days that already crossed an evidence threshold — mostly positive examples — whereas predict_yesterday is trivially perfect on day-to-day continuity within a country. Comparing the two as F1 is approximate, not apples-to-apples. The per-row source field documents this; readers who want a fair comparison should look at the classifier's stratified CV against a CV baseline computed on the same folds. The benchmark surfaces the ugly-but-honest number rather than hiding it.

What this is NOT

How to read the endpoint

Every row in the response has the same shape:

Query filters: family=<name>, barely=true|false, min_lift_pp=<float>. The /info endpoint exposes the methodology and the per-row caveat policy without hitting the full payload.

Methodology footnote: why predict_yesterday is the right toughest baseline

Internet shutdowns are extremely autocorrelated: if a country was in shutdown yesterday, the prior on shutdown today is over 95%. On those targets, “persistence” is the hardest one-line baseline to beat. We pick it deliberately. If a model can't beat predict_yesterday at some metric by at least 5pp, we want it on a list the user can see — not buried.

This pattern is borrowed from the time-series forecasting literature (Hyndman & Athanasopoulos, Forecasting: Principles and Practice) and from the GluonTS benchmarking conventions. It is also consistent with how Cloudflare and NetBlocks report their own shutdown detection — usually as deltas from a 7-day baseline rather than as absolute counts.