The published dataset
Every number on this site can be recomputed from these three files using the published engine. If our arithmetic is wrong, this is how you show it.
The files
| File | What it holds |
|---|---|
| scores.json | The published score set: 250 countries, every dimension, computed 2026-10-15. |
| signals.json | Every signal the scores were computed from, each with its quote, source and date. |
| sources.json | The source registry. Needed because confidence counts independent sources by upstream origin. |
Three things worth knowing before you join on it
A country with no coverage has no score. Thirteen of them, mostly polar and island territories nobody writes advisories about, carryassessed: false with score and bandset to null. They are not zero. Published as zero they sorted below Norway, and a filter for score < 25 returned the places nobody has ever looked at as the safest on the list.
The headline is a mean, and it can hide a severe dimension.Most assessed countries have at least one dimension banding above their overall figure, so each record carries worstDimension with its own score and band. Read its directEvidenceCount before acting on it: where that is zero the dimension is inferred from related sources rather than established by one that says so directly.
Kosovo has no ISO 3166-1 code. We publish it asXKK, which is what our country table uses. Other datasets useXKX or XK, so both are listed in the record'saliases field and a join that consults it will not drop the country silently.
Checking a score
The engine is on GitHub under an MIT licence. It reads no files and makes no network call, so it runs against these three inputs and nothing else.
import { reproduceScoreSet, formatReproduction } from '@worldrisk/score';
const base = 'https://worldrisk.dansec.red/data';
const [scoreSet, signals, sources] = await Promise.all(
['scores', 'signals', 'sources'].map((f) => fetch(`${base}/${f}.json`).then((r) => r.json())),
);
console.log(formatReproduction(reproduceScoreSet({
scoreSet,
signals: signals.signals,
sources: new Map(sources.sources.map((s) => [s.id, s])),
})));Equality is exact rather than approximate, so a difference of one part in a thousand is reported as a mismatch. That is deliberate: a score that does not reproduce is a score somebody has to explain.
Terms
The engine is MIT. The data is not ours to relicense: each signal carries the terms of the source it was read from, and several are non-commercial or ShareAlike. Attribution travels with every signal in signals.json, and each country page credits the publishers behind its score. Check the terms of a specific source before redistributing what it contributed.
Rewritten by the pipeline on each run. The computedAt field in each file is the instant the run was anchored to, and passing it back to the scorer as asOf is what makes a past score reproducible.