Voidly's existing forecast model answers the question "will a shutdown happen?". But journalists also need to know "if it happens, how long will it last?" Russia's 2022 Twitter block has lasted years; Sri Lanka's 2022 social-media block lasted days. Same probability, very different consequences — and the duration is the dimension that lets you tell them apart.
We trained a Random Survival Forest (scikit-survival 0.25) on every confirmed censorship or mixed-type incident in the Voidly Atlas — n=343, with a 78% right-censoring rate (most incidents are still open or were only observed at a single point in time). The 13 input features are: country risk tier, continent one-hot, severity one-hot, incident-type one-hot, first-seen year + month, and a 24-month prior-shutdown count for the country. Training is stratified by event status so train and test both see the (few) confirmed- closed rows.
Test-set c-index = 0.728 (train 0.769).
That clears the 0.65 promote floor we agreed on for ML
ship decisions. Per-country test-set residuals are
available in the model sidecar at
/v1/forecast/duration/info.
POST /v1/forecast/duration
with body
{country, severity, incident_type}
returns median, P25, P75, IQR, the 5-point survival
curve, the c-index of the underlying model, and any
honest caveats triggered by the input (e.g.
"country not found in country_geography").
Example: for Iran in a critical/censorship scenario the
model returns median ≈ 5 days with a wide 2-day IQR,
driven by Iran's high prior-shutdown count and the
prevalence of long-running Iranian blocks in the
training cohort.
/opt/voidly-ai/models/shutdown_duration_rsf_v1.pkl
/opt/voidly-ai/models/shutdown_duration_rsf_v1.json
POST /v1/forecast/duration (proxied via api.voidly.ai)GET /v1/forecast/duration/infoscripts/build-survival-features.py,
scripts/train-shutdown-duration-rsf.py,
scripts/patch-duration-endpoint.py (idempotent, AST-validated).