Voidly Atlas observes shutdowns from the network side: an IODA ASN flip, an OONI test-list anomaly, a 99% telemetry drop on a probe pair. That view is precise, but it’s also one-sided. Governments often publish — or fail to publish — a parallel narrative on their own ministry websites: “scheduled maintenance,” “regulatory action,” “security threat,” “spam attack.” This finding ships v1 of a curated government-statement scraper that turns that parallel narrative into structured, time-stamped, cross-referenceable evidence.
A statement near a confirmed shutdown is journalist-grade signal that a standalone statement (or a standalone shutdown) is not. If the Ministry of ICT tweets “routine maintenance” four hours before an IODA-confirmed outage, that’s a public warning the ministry doesn’t want to call a warning. If a regulator publishes a retroactive “spam attack” press release twenty-four hours after the network restores, that’s a cover story we should record alongside the network truth. Either way the pairing — not the standalone item — is what reporters cite.
We curate seven sources covering the highest-impact censorship regulators in the world. Each entry below documents the URL we poll plus an honest note on what we expect to retrieve:
https://rkn.gov.ru/news/rsoc/, language ru).
Frequently unreachable from our Vultr egress; documented as a
geo-restricted source we still keep configured.https://www.ict.gov.ir/fa/news, language fa). DNS
resolution and TLS handshakes often fail from outside Iran; coverage
expected sparse.https://www.pta.gov.pk/en/media-center/news,
language en). PTA’s media center is a JavaScript-rendered
single-page application; without a headless browser we retrieve the
shell only. Source kept so coverage lights up if they ever ship a
non-SPA listing.http://www.btrc.gov.bd/site/view/notices, language bn).
HTTP-only with a broken TLS chain; we drop verify deliberately.
Live coverage: 8 statements ingested on the first
fetch.https://mcit.gov.eg/en, language en). The
/Latest_News path is currently 500'ing; we fall
back to the home page, which lists news links but no items matched
keywords on the first run.https://www.btk.gov.tr/duyurular, language tr). Modern
Tailwind site; dates are embedded in anchor text as
DDMMMYYYY prefixes. Live coverage: 5 statements
ingested.https://www.miit.gov.cn/xwdt/gxdt/sjdt/index.html,
language zh). MIIT serves a ~5KB JavaScript shell on this page;
near-zero coverage is the truth and we say so up-front.requests.get per
source, 20s timeout, real Chrome User-Agent, TLS verify on by
default (off only when we’ve documented a broken chain).
We do not use a headless browser; we do not bypass logins,
paywalls, or robots.txt.21MAY2026-style date
prefix from the anchor text and store it as the canonical
published_at.schema.org, w3.org).INSERT OR IGNORE
into government_statements keyed on
sha1(country | ministry | url | title) so re-fetching
is safe. Statement text is stored in the original
language; we explicitly do not translate.
A second script,
correlate-statements-to-shutdowns.py, runs 30 min after
each scrape. For every statement it queries
incidents in the same country whose
first_seen is within ±72h of the statement’s
published_at (falling back to fetched_at
when the source did not expose a date). Each (statement, incident)
pair gets a transparent confidence score:
affected_domains, capped at 1.5.
Delta-hours is signed: “warning” for >+3h (statement
before incident), “retroactive” for <−3h
(statement after), “simultaneous” otherwise. Output is a
single JSON sidecar at
/opt/voidly-ai/ml-deploy/government_statement_correlations_v1.json
that the API serves verbatim.
disruption and get a 0.5x weight — that’s
the system working as designed, not a bug.Highest-confidence pair on first run: BTK Turkey, 30 NIS 2026 — a draft regulation about electronic device identity registration (“Elektronik Kimlik Bilgisini Haiz Cihazların Kayıt Altına Alınmasına Dair Yönetmelik”) was published ≈48h after a critical IODA-confirmed Internet connectivity disruption in Turkey on 2026-04-28. Confidence score 0.545, sign “retroactive,” type_weight 0.5 because the incident is classed disruption, not confirmed censorship. The pair is real, the timing is real, and the type-weight discount keeps the score out of the high-confidence tier — exactly what we want from a transparent, journalist-defensible index.
GET /v1/atlas/government-statements/info —
sources configured + per-country counts + last fetch time.GET /v1/atlas/government-statements?country=TR&limit=20
— list with filters (country, ministry, since, with_text).GET /v1/atlas/government-statements/{stmt_id}
— full record incl. statement_text.GET /v1/atlas/government-statements/correlations?min_conf=0.5
— (statement, nearby incident) pairs within ±72h.disruption, which our forecast labeling treats as
noise. The pair-weight 0.5x discount keeps disruption-only pairs
out of the high-confidence tier.