voidly
Sentinel · causal attribution

What caused this shutdown?

Synthetic difference-in-differences attribution. For any country + date, we build a counterfactual block-rate from a weighted combination of stable-democracy donors that fit the treated country's pre-period trend, then measure the post-period gap. The gap is the causal-effect estimate. Permutation p-value gauges significance.

Method: Arkhangelsky et al. arXiv:1812.09970 · Internet Society NetLoss (ACM JCSS 2024) · Raw JSON

Try: IR 2026-05-13 · VE 2026-05-10 · RU 2026-05-15

Enter a 2-letter country code (e.g. IR, VE, RU) and a date (YYYY-MM-DD) above to run the attribution. The synthetic-control method needs at least 5 evidence observations in each of the pre-period (T−14..T−1) and post-period (T..T+6) to be meaningful.

Method — how this works

  1. Pull daily block_rate for the treated country from T−14 through T+6 using the OONI + IODA + CensoredPlanet aggregates in evidence.
  2. Pull the same window for 15 candidate donors (stable democracies). Filter to those with ≥5 observations per period.
  3. Fit synthetic-control weights via scipy SLSQP with constraints: w ≥ 0, Σw = 1. Minimize sum-of-squares between treated's and weighted-donors' pre-period series.
  4. Compute post-period treated mean and synthetic mean. The gap is the causal effect.
  5. Run an in-space placebo: pretend each donor was the treated, refit, compute their effect. Permutation p-value = fraction of placebos with |effect| ≥ observed.
  6. Cross-reference events.db for political events within ±7 days. Prefer hard events (election/protest/coup) over auto-mined signals.

Honest caveats: if pre_rmse > 0.10 the pre-period donor match is poor — don't cite the effect. If the treated country is already at a ceiling block_rate before T (like Iran usually is at ~95%), SDiD will produce a small or negative effect because there's no “room above” the trigger to lift things. The script reports low_confidence: true + a reason in those cases.

References