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

Russia on 2026-05-15

Causal effect
+0.0pp
treated − synthetic
P-value (placebo)
0.88
not significant
Pre-period fit (RMSE)
0.040
good fit
Donors used
6
of 8 eligible
low_confidence: reason unspecified. Don't cite the causal_effect; treat as exploratory.
Treated post-mean
71.9%
block_rate, T..T+6
Synthetic post-mean
71.9%
what we'd expect without trigger

Candidate trigger event

Social signal: OONI anomaly rate 33% (62776/190964 measurements)
2026-05-10 · signal · importance: high · source: social_signals
Evidence class: upstream_anomaly_signalNo political event found in window; attribution rests on OONI anomaly signal preceding T.

Synthetic-control donor weights

The synthetic counterfactual is a weighted combination of these donor countries. Weights are non-negative and sum to 1, fit on the 10 pre-period observations by constrained least-squares.

DonorWeightShare
NL 0.717
AU 0.103
DE 0.079
JP 0.047
FR 0.035
CA 0.019

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