The Atlas already ships a per-country shutdown forecast (XGBoost + isotonic, AUC 0.954) and a per-platform variant covering 12 platforms. The most journalist-relevant question still hadn't shipped though — not "will Iran tighten?", but "will Iran block twitter.com in the next 7 days?" This finding closes that gap.

The build

Results

Honest caveats

The headline AUC is misleading without context. Once a domain is blocked in a country, it tends to stay blocked for the 7-day horizon — the persistence is ~85%. So the model is mostly answering "will the current block state persist?", which it does extremely well. The minority of state transitions (~15% of pair-days) are where the model has to actually generalize. Per-platform forecasts showed the same pattern (and the same honest caveat — see the per-platform sidecar).

Other limitations: (a) the cross-country contagion feature n_countries_blocked_30d is identical across all countries on a given (domain, date), so it behaves as a global "this domain is hot right now" prior — it can't discriminate WITHIN a single day. (b) Countries with zero historical evidence on a domain score the feature-vector floor (≈base rate) — treat thin-coverage pairs as low-information. (c) Only 42 of the targeted 100 domains have any evidence in the table — the missing 58 are upstream-coverage gaps, not model gaps.

Sample predictions (2026-05-21)

What ships

Four endpoints under /v1/forecast/domain/*: /{'{'}domain{'}'}/{'{'}cc{'}'} (single pair), /{'{'}domain{'}'} (one domain across all countries), /info (sidecar), /list (universe). Every response includes the top-3 features by gain with their current values, the pair-specific n_obs_90d, the domain's LOCO AUC, and the full honest_caveats array. No frontend pages — API + sidecar + this finding only.

Leakage audit (2026-05-21). A label-leakage audit flagged this model as LEAKED — not via a circular feature, but via target triviality. The target (any anomaly in the next 7 days on a domain/country pair) is near-constant per pair: ~75% of rows are positive and the MIN_PAIR_OBSERVATIONS>=5 filter keeps only persistently measured pairs. For a domain blocked every day (twitter in Iran), the trailing anomaly_rate_7d is ~1.0 and the future label is always 1, so the LOCO AUC of 0.999 measures "is this pair currently blocked," not forecast skill. On status-transition days the honest AUC is expected to be ~0.55-0.65. Recommended fix: re-define the target as a newly-blocked status transition (0-to-1), or report AUC restricted to transition days / non-persistent pairs.