Voidly

Do the sources agree?

Cross-source agreement

Compare independent sources on the same country-day. Agreement measures overlap, not ground truth.

Generated 2026-10-03T05:15:02 · window 365d · 13,388 country-days · Raw JSON

Pairwise Cohen's kappa

OONIIODACensoredPlanetVoidly probesOONIIODACensoredPlanetVoidly probes1.00self-0.53κ0.16κ-0.09κ-0.53κ1.00self-0.27κ-0.09κ0.16κ-0.27κ1.00self-0.10κ-0.09κ-0.09κ-0.10κ1.00selfκ scale:< 0~ 00.1-0.4> 0.4

Low or negative kappa here is the honest finding — the four sources observe different layers of the internet (active probing vs BGP route changes vs DNS scans vs reachability checks). They rarely fire on the exact same country-day, which is why the multi-source corroboration rate above (≥2 sources, 17.6%) is a more journalistically actionable signal than pairwise kappa.

For each pair of sources, kappa measures agreement on the binary “did this source fire today?” indicator, adjusted for chance agreement. κ = 1.0 is perfect agreement, κ = 0 is chance-level, κ < 0 is systematic disagreement.

Headline
52.5% of confirmed censorship-days are corroborated by ≥2 independent sources.
Across all anomalous country-days, 24.9% had ≥2 sources firing together (3,329 of 13,388 days). When restricted to days with a confirmed censorship incident in the voidly_data.db incidents table, the rate rises to 52.5% (2034 of 3873 confirmed days) — a tangible measure of how often censorship leaves multiple independent fingerprints.
Reading this view

How often do OONI, IODA, CensoredPlanet, and the Voidly probe network independently flag the same country-day as anomalous? Two metrics: pairwise Cohen's kappa (chance-adjusted agreement) and the share of country-days where 2+ sources fire together. Designed for journalists who want to know whether a finding is corroborated across multiple independent sensors.

Per-source marginal fire rate

OONI
43.2%
5,780 country-days
IODA
54.9%
7,355 country-days
CensoredPlanet
22.8%
3,052 country-days
Voidly probes
8.1%
1,079 country-days

Share of all anomalous country-days (n= 13,388) on which each source emitted at least one elevated/warning/critical-level row. Cohen's kappa above is computed against this baseline.

Multi-source corroboration rate, last 12 months

Per-month fraction of anomalous country-days where ≥2 sources fired. Bar height = n country-days that month; teal overlay = share with ≥2 sources.

5551110166522202025-100%2025-110%2025-120%2026-011%2026-0218%2026-0323%2026-0419%2026-0526%2026-0629%2026-0728%2026-0832%2026-0930%2026-1025%total country-days≥ 2 sources corroborating
Per-month table
MonthTotal≥2 sourcesRate
2025-106400.0%
2025-116100.0%
2025-126300.0%
2026-0158271.2%
2026-021,21621817.9%
2026-031,51734222.5%
2026-041,45828119.3%
2026-051,17030726.2%
2026-061,16233328.7%
2026-071,61945227.9%
2026-082,11668032.1%
2026-092,22067430.4%
2026-101403525.0%

Scroll to see every column.

Methodology

Methodology

The four sources

  • OONI — active web-connectivity, Signal, WhatsApp, Telegram, Tor, and middlebox-detection probes run by volunteers worldwide.
  • IODA — BGP route observations + Trinocular active probing aggregated by Georgia Tech, surfacing AS-level outages.
  • CensoredPlanet — University of Michigan's Satellite (DNS) and Hyperquack (HTTP/HTTPS) global scans from outside the target country.
  • Voidly probes — our 40-node active probe network (Vultr + Fly.io + community probes) running 62-domain reachability checks every 5 minutes.

The unit: country-day

For each (country, date), we ask: did source s emit at least one row with signal_level in (elevated, warning, critical)? If yes, source s “fired.” This gives a 4-bit indicator per country-day: (ooni, ioda, censoredplanet, voidly_probes).

Cohen's kappa

For each pair of sources (a, b), kappa measures chance-adjusted agreement on the binary fire indicator:

Po = observed agreement   = (n_11 + n_00) / N
Pe = chance agreement     = P(a=1)*P(b=1) + P(a=0)*P(b=0)
κ  = (Po - Pe) / (1 - Pe)

Kappa is computed over country-days where at least one source fired — days where no source observed anything anomalous are excluded so that trivial “both quiet” agreement across 130 countries doesn't artificially inflate the metric.

The ≥2-sources rate

For the journalist-facing “is this corroborated?” answer, we compute the simpler metric: of all anomalous country-days, what fraction had ≥2 sources firing? When restricted to country-days with a confirmed censorship incident (type in ('censorship', 'mixed'); IODA-only disruptions excluded), this rises to 52.5%.

Honest caveats

  • Source-presence is binary at the country-day level (one row -> present), so a single elevated OONI test counts the same as a dozen IODA outage rows. This avoids letting one noisy source dominate the agreement rate.
  • Voidly and Voidly-Community are merged into a single voidly_probes bucket -- their coverage overlaps geographically.
  • Cohen's kappa is computed over country-days WHERE AT LEAST ONE SOURCE FIRED. Days where no source fired are excluded so kappa isn't inflated by trivial 'both quiet' agreement across 200+ countries.
  • Most pairwise kappas are LOW (0.05-0.20). This is the honest finding -- the four sources observe DIFFERENT layers of the internet (active probing vs BGP vs DNS scans vs reachability checks) and rarely happen to fire on the same country-day. Low kappa here doesn't mean the sources are wrong; it means they're complementary, which is exactly why multi-source corroboration is informative when it DOES happen.
  • IODA fires heavily on connectivity disruptions that are not censorship (fiber cuts, BGP misconfigs). This is why the forecast pipeline excludes IODA from confirmed-censorship labels -- but we still report IODA presence here, because the journalist's question 'did multiple sources see this?' is answered by what they observed, not by our label rules.
GET /v1/atlas/source-agreement
Full sidecar — pairwise κ + monthly time series
GET /v1/atlas/source-agreement/{cc}
Per-country timeline (Iran example)
Bayesian corroboration
Posterior P(censorship | sources observed)

Sidecar generated: 2026-10-03T05:15:02.733754Z