Why hourly

Until today, the only shutdown forecast Voidly published was daily — a single risk number per country-day. That works for the common case (e.g. Iran has 35% risk this week) but throws away an obvious axis of structure: shutdowns happen on specific hours. Election-morning DNS blocks, midnight protest-suppression cuts, a 06:00 UTC fiber-restoration window — the daily forecast collapses 24 hours of inside-day variance into a single bucket.

We trained three within-day XGBoost classifiers, one per horizon: K = 6, 12, 24 hours. Each predicts P(at least one censorship-class incident starts in the next K hours) at hourly granularity. Live at GET /v1/forecast/{cc}/hourly?horizon=6|12|24.

Features

Fifteen-dimensional, all observable on the country panel without leakage:

Training panel

90-day evidence × 45 countries × 24 hours = 97,245 cells. Drop cells with no recent evidence (MIN_EVIDENCE_24H ≥ 1) → 75,570 training rows. Country set is the union of every country with a confirmed censorship/mixed incident in the window (36) plus the top-30 by evidence volume.

Positive rates: y_6h 1.3%, y_12h 2.6%, y_24h 5.1%. Imbalanced as expected — most hours, in most countries, are uneventful.

Honest caveats — read these before citing

Evaluation

Temporal holdout: the most recent 30 days (April 21 → May 21 2026) is held out; everything earlier is training. The model has never seen any country's hourly observations after the cutoff. Per-country AUC is graded only on countries whose holdout has both classes AND where the model produced a non-degenerate ranking (AUC ≠ 0.5 exactly — those ties come from flat predictions on country windows where the model can't separate hours, which is real but not informative for ranking quality).

Horizon Global AUC Median per-country n countries
K=6h (best) 0.741 0.721 11
K=12h 0.724 0.690 12
K=24h 0.801 0.667 12

All three horizons clear the 0.60 per-country AUC floor. The promote rule is intentionally lower than for daily (0.70) because hourly granularity is noisier and the labels themselves are coarser.

Per-country, K=6h

Where the model has strong inside-day signal:

Where the model is at or below chance:

The pattern is clear: countries whose shutdowns concentrate at specific hours (likely tied to election windows, prayer time, or protest hours) are predictable. Countries whose shutdowns are spread evenly across the day are not — and the model honestly admits it.

Endpoints

Response includes probability, p_low, p_high, the top-5 features ranked by gain × live value, and the full honest_caveats array on every call. Countries with no recent evidence (MIN_EVIDENCE_24H == 0) get a 404 + an explicit refusal message — the model does NOT score no-data countries.

What we are NOT claiming