What we shipped

A proactive next-24h contagion watchlist. The contagion-chain model shipped earlier this week is descriptive: it answers “given country A blocked today, P(B follows in 7d) = X.” This new endpoint flips the question around and runs it live: given the triggers that actually fired in the last 48h, which other countries are most at risk of blocking in the next 24-48h?

This is the difference between “here is a static contagion table” and a watchlist that updates every 6h.

How it works

  1. Pull active triggers — any country with a confirmed censorship or mixed incident in the last 48h. Dedup to one trigger per (country, day).
  2. Score every candidate follower at horizon = 3 days (the shortest supported horizon — closest proxy for “next 24-48h”). Each follower gets one probability per active trigger.
  3. Aggregate via noisy-OR: combined probability that the follower blocks given any active trigger fires is 1 - ∏(1 - p_i). This caps the combined probability at 1.0 and assumes triggers act ~independently.
  4. Base-rate-adjust: subtract base_rate_daily × 3 so countries that block every day anyway don’t dominate. Final score is max(0, noisy_or - base_prior_3d).
  5. Self-exclude: countries that were themselves triggers in the last 48h are excluded from the watchlist.

Endpoints

Example call

curl https://api.voidly.ai/v1/atlas/contagion-watchlist | jq .

Honest caveats (baked into every response)

Why this matters

Most censorship-forecasting work is either single-country (“Iran 7-day shutdown risk”) or static pairwise tables (“OM → JO is a high-confidence chain”). Neither tells a journalist or operator which 5 countries to watch right now. This watchlist is the connecting layer: it consumes the trigger stream that’s already in the incident pipeline, runs the existing pairwise classifier, and surfaces a small ranked set with per-trigger attribution — all with the same honest-caveats stack the underlying model carries.