Colombia · Content & data
Colombia · Sala de Crisis describes what the suite is. This page writes down what until now lived only in the head of whoever operated it: the content operating model — which file powers which surface, at what rhythm each source refreshes, which data comes next and under which editorial rules. The 14 routes of the module map consume two data lanes that never mix: the real lane (public/data/colombia/real/, 24 citable files plus the freshness thermometer) and the demo lane (public/data/colombia/fixtures/, synthetic by design). The source-by-source detail — caveats, licences, unresolved discrepancies — lives in public/data/colombia/real/MANIFEST.md; this page is the operating map on top of that inventory.
Inventory: which dataset powers which surface
Real lane
| File | Source | Surface that mounts it | What it contributes |
|---|---|---|---|
seismic-catalog.json | USGS FDSN | Sala de Crisis (seismic layer) | Aftershock catalogue M2.5+ with hours since the event |
shakemap-intensity.json | USGS ShakeMap | Sala de Crisis (seismic layer) | MMI intensity contours |
shakemap-departments.json | USGS ShakeMap + DANE | Sala de Crisis (seismic layer) | Maximum MMI per departmental seat |
pager-estimates.json | USGS PAGER | Sala de Crisis (seismic layer) | Probabilistic fatality and loss distributions (model, never a count) |
dyfi.json | USGS Did You Feel It | Sala de Crisis (seismic layer) | Citizen reports and maximum CDI |
feeds.json | IFRC GO + GDACS | Briefing ("Fuentes en vivo") | Unified situational feed, deduplicated by URL |
ifrc-appeal.json | IFRC GO | Briefing ("Fuentes en vivo") | Appeal MDRCO036: requested vs. funded (CHF) |
gdacs.json | GDACS | Briefing ("Fuentes en vivo") | Red alert and exposed population (model) |
external-trackers.json | colombiatebusca.com | Briefing ("Fuentes en vivo") | Counters of the citizen tracker, labelled "not official" |
pledges.json | Consolidated press dossier 2026-08-13 | Fondo Milagro ("Respuesta internacional") | Pledges by donor with explicit status |
cat-ddo-terms.json | Consolidated press dossier 2026-08-13 | Fondo Milagro ("Respuesta internacional") | Full terms of the CAT DDO line |
trm.json | Superfinanciera (datos.gov.co) | Fondo Milagro ("Respuesta internacional") | The only rate admissible for COP→USD conversions |
sitreps.json | IFRC GO | Fondo Milagro ("Respuesta internacional") | Appeal records and situation reports |
services-status.json | Aerocivil + MinTIC + address + press | Servicios | Restoration by sector, each row with its own citation and as_of |
donation-channels.json | Officialised press | Donation verifier | Authorised channels + negative registry |
promesas-tecnologicas.json | Addresses and the published tech plan | Promise clock | Commitments on the 100-day clock, statuses as facts |
satellite-damage.json | Copernicus EMS (EMSR916) | Reconstruction (satellite panel) | Damage evidence independent of the government |
citations-real.json | — (registry) | Every real-lane surface | The 42+ citations backing every displayed figure |
data-health-colombia.json | — (locally derived) | Surface pending | fresh|aging|stale freshness of every file in the lane |
Seven more files are baked, typed and have an exported loader (src/lib/colombia-real-data.ts) but no dedicated surface yet — denominators and context available to any stream:
| File | Expected role |
|---|---|
seismic-events.json | The seismic truth of the event (hypocentre, mww magnitude); any surface showing depth must read it, not the fixtures constant |
demographics.json | Per-DIVIPOLA denominator (school-age 5–16 cohort, not total population) |
health-facilities.json | Denominator for reconciling the "179 health centres" (3,051 IPS sites) |
schools.json | Denominator for the 1,819 affected school sites (universe with 2019 reference year) |
procurement.json | Real published contracting: the urgencia manifiesta processes to watch |
fiscal.json | Fiscal frame (context, never impact) |
situation-reports.json | Target of the FIXTURE_TO_REAL swap of the fixture of the same name: 1 official balance instead of 3 snapshots |
Demo lane
Everything that reaches person or individual-operation level is synthetic, carries synthetic: true and mounts the DATOS DE DEMOSTRACIÓN banner:
| Fixture | Surface | Note |
|---|---|---|
situation-reports.json | Sala de Crisis, Briefing | Carries 2 reconstruido_demo snapshots that never cross into the real lane |
affected-zones.json | Sala de Crisis (map) | Demo municipal breakdown over real aggregates |
promises.json | Sala de Crisis ("Lo prometido") | The 17 commitments of the address |
fondo-ledger.json | Fondo Milagro | The hash-chained ledger — the fund has no real public ledger |
reconstruction-projects.json | Reconstruction + project sheet | 83 demo projects; real contracting is procurement.json |
relief-programs.json | Alivios | The 5 announced programmes as readable rules |
households.json | Registro, Alivios | Will never have a real counterpart: person-level data, the platform ingests no PII |
missing-persons.json | Person finder | Likewise: never a real counterpart |
shelters.json | Shelter network | No known public API |
aid-shipments.json, collection-points.json | Logistics | No public API for the "Colombia Un Solo Corazón" operation |
citations-colombia.json | (fixture registry) | Demo-lane citations |
Refresh cadence
Every source has its own rhythm, and the rhythm is declared — in the MANIFEST as prose and in bake-colombia-health.ts as numeric thresholds. Three mechanisms:
script(live API) —bun run scripts/colombia/ingest-*.tsqueries and re-bakes; idempotent, with a raw-response cache.manual, re-verified— figures transcribed from official sources, but the script probes the sources on every run (Aerocivil/MinTIC load-bearing phrases, dossier chains inpledges, the World Bank document index) and records what it observed.manual— curated against communiqués; updated when the source publishes.
| File | Mechanism | Fresh / aging threshold (days) | Cron candidate? |
|---|---|---|---|
seismic-events.json, seismic-catalog.json | script (ingest-seismic*.ts) | 2 / 7 | Yes — candidate #1 (aftershock auto-refresh) |
shakemap-*.json, pager-estimates.json, dyfi.json | script (ingest-seismic-deep.ts) | 3 / 14 | Yes (same run as the aftershocks) |
feeds.json, ifrc-appeal.json, gdacs.json, sitreps.json | script (ingest-feeds.ts, ingest-sitreps.ts) | 2 / 7 | Yes, daily while the operation stays open |
trm.json | script (ingest-pledges.ts) | 1 / 4 | Yes, daily (business day) |
procurement.json | script (ingest-procurement.ts) | 1 / 3 | Yes — frequent re-pull during urgencia manifiesta (see roadmap) |
external-trackers.json | script (ingest-feeds.ts) | 1 / 3 | Yes, daily |
satellite-damage.json | script (ingest-satellite.ts) | 2 / 7 | Yes while EMSR916 products remain pending |
demographics.json, schools.json, fiscal.json | script | 90 / 365 | No — annual sources; a quarterly verification run suffices |
health-facilities.json | script | 30 / 90 | No — periodic registry cut |
services-status.json | manual, re-verified (ingest-services.ts) | 2 / 7 | Partial: the probing yes; the consolidation is editorial judgement |
pledges.json, cat-ddo-terms.json | manual, re-verified (ingest-pledges.ts) | 3 / 14 · 7 / 30 | Partial: chain validation yes; new rows are curation |
situation-reports.json | manual (cited transcription) | 2 / 7 | No — replacing it with the UNGRD bulletin is the path, not a cron |
donation-channels.json | manual | 7 / 30 | No — changes only if the Presidency publishes channels |
promesas-tecnologicas.json | manual | 7 / 30 | No — updated per clock milestone (next: day 30) |
The cron pattern (reference, not adopted yet)
The repository already has the mechanism: vercel.json declares Vercel crons (today one, { "path": "/api/alerts-digest", "schedule": "0 13 * * 1" }). That is the pattern to follow when refresh gets automated — none is added in this wave, because the Colombia ingests are repository scripts that write baked, committed files: a Vercel cron only invokes a serverless route, so automating requires first deciding between (a) an /api/ route that re-ingests and serves from cache without touching the tree, or (b) a scheduled CI job that runs ingest-all.ts and commits the diff (which, thanks to idempotence, only exists when the source actually moved). That is an architecture decision, not a content one, and it is recorded here as pending.
The thermometer: data-health-colombia.json
bun run scripts/colombia/bake-colombia-health.ts reads the 24 lane files, joins each one's ingest.retrieved_at stamp with its declared cadence and bakes the per-file fresh | aging | stale classification (plus the per-row as_of range where it exists, as in services-status.json). Thresholds are per source: a TRM from three days ago is stale, an annual World Bank series from three months ago is fresh. The file declares citations: [] because it is locally derived — there is no upstream source to cite.
Registration in the gate is pending. data-health-colombia.json is not yet in the SPECS of scripts/colombia/check-real-data.ts. The original reason — another branch of the same wave was editing that file — went away when wave 4 was integrated; what remains is a gate-design decision: registering it forces an exemption to the generic "rows ⇒ at least one citation" rule for derived files with citations: [], and a gate exemption is opened deliberately, in its own PR, never in passing during an integration. Until then, the MANIFEST checker does not require it and the bake runs outside the prebuild.
Roadmap: next data
Prioritised by impact over effort. "Gate" names what has to happen outside the repository for the row to become possible.
| # | Candidate | What it unlocks | Effort | Impact | Gate |
|---|---|---|---|---|---|
| 1 | UNGRD bulletin / EDAN, machine-readable, when published | Replaces the transcribed address as the source of record for the official balance — the #1 declared replacement in the MANIFEST. With two or more cuts, the Sala de Crisis draws a real trend instead of one point | Low–medium (the SituationReport shape already exists) | High | UNGRD publishing; today the documentary chain ends in a speech |
| 2 | SECOP II re-pulls during urgencia manifiesta + OCDS red flags | The baseline is 2 urgencia manifiesta processes as of 2026-08-11; the peak will come with the 12 months of direct contracting under Decreto 1171. Frequent re-pull + OCDS-standard red flags (single bidder, ultra-fast award, contractor concentration, price deviating from the sector median) over real data — today the risk engine runs on fixtures | Medium (ingest-procurement.ts exists; cadence and rules are missing) | High — the central anticorruption surface | None: SECOP II is public |
| 3 | DANE total municipal population | Closes gap #1 of REAL_DATA_GAPS: real per-municipality denominators instead of the 5–16 school cohort | Medium (spreadsheet download, not an API: parser + vintage citation) | High | None, but it is versioned manual ingestion |
| 4 | Aftershock auto-refresh (USGS on a cron) | The catalogue stops aging between manual runs; the Sala's seismic layer maintains itself | Low (the idempotent script exists; the cron-pattern mechanism is missing) | Medium | The (a)/(b) architecture decision above |
| 5 | Medicina Legal communiqués | Forensic counters (bodies received / identified / delivered, comm. 06: 230/205/140) as manual_cited, so the person finder can reconcile the four parallel missing-person figures — official 287–496 vs. 4,211 on the citizen tracker | Medium (no API; cited transcription per communiqué) | Medium–high | Medicina Legal continuing to publish numbered communiqués |
| 6 | IDEAM alerts | Secondary-hazard layer (rain/landslides over the 5 departments) for Logistics and Shelters — the 24+ landslides that cut off the epicentre are the precedent | Medium | Medium | An IDEAM API/feed reachable from the ingest host |
| 7 | Granular DANE census layers (block/section) | Fine-grained shelter and registry planning: density and vulnerability under each satellite AOI | High (heavy geodata, spatial joins) | High in the medium term | None, but requires new geospatial tooling |
| 8 | Registraduría / SISBÉN cross-referencing for RUD dedup | The chokepoint the research flagged: the RUD is manual, offline, without dedup, run by 403 municipalities, and gates every household benefit | High | High | Hard gate: an MOU with the state. This is not public data and the platform does not ingest it — this row exists to say explicitly that it only proceeds inside an official pilot with regulated access. Until then, the Registro's demo dedup stays demo |
Two known gaps remain open outside this table because they do not depend on us: the SGC catalogue (endpoints unreachable from the ingest host — it would restore the M2–M4 seismicity USGS cannot see) and the ReliefWeb appname (a human OCHA process; once approved, coverage returns without touching code). Both are measured with their own citations.
Content principles
These are the editorial rules of the real lane. All of them are enforced by the gate (check-real-data.ts) where a machine can enforce them; where it cannot, they are written here and in the MANIFEST.
1 · Two lanes, zero mixing
Real and demo live in separate directories with the same envelope schema. synthetic is never inferred; the demo banner reads it from the envelope. A real-lane file with rows and no registered citation breaks the build. The operational consequence: migrating a surface means changing a path (FIXTURE_TO_REAL), never copying rows from one lane to the other — the reconstruido_demo snapshots of the balance fixture never cross, and the checker verifies it.
2 · sin_datos is a first-class state
An empty result is a finding. Chocó with 3 processes in SECOP is the datum (the epicentre department has the country's lowest installed contracting capacity), not a query error; 9 of the 33 service assets are baked without a figure because they circulated in the crisis room with no citable source, and the validator rejects a sin_datos row carrying a figure just as it rejects a figured row without a citation. Filling a hole with a plausible substitute would destroy the only thing the platform sells. A surface that needs data that does not exist shows the gap (REAL_DATA_GAPS).
3 · Offers are not receipts
Every financial commitment carries an explicit status: ofrecido, confirmado, desembolsado, denegado. The gate rejects any multilateral or bilateral row marked desembolsado because no disbursement to the state exists in the record — the USD 1.3 billion of the headlines are offers. The discipline extends to currency (every amount carries currency + unit; "mil millones" is never translated as "billones") and to press aggregates, which live as context and never as summable rows. The denied offer (El Salvador's 100 t) is baked with its citation: a refusal is also part of the balance.
4 · Quote provenance: the "cada peso" case
The case study that fixes the rule. The Infobae headline of 13 August — "cada peso girado quedará expuesto" (every peso transferred will be exposed) — circulated as if it were a government transparency commitment. It is not: the sentence belongs to Lorena Gutiérrez, dean at Universidad de San Buenaventura, describing how Article 215 works (automatic Court review, congressional control, oversight-body jurisdiction). The government has made no commitment to a dashboard, open data, citizen oversight or audit for the Fondo Milagro. The quote that does belong to the President predates the earthquake: on 23 July, about a transfer to the UNGRD, he demanded "garantizar la trazabilidad de cada peso" — guaranteeing the traceability of every peso (El Universal). Conflating the two would have put in the government's mouth a promise that does not exist — and would have given away the platform's argument, which is precisely that this promise is missing.
The rule that remains: every verbatim quote carries author, role, date, outlet and link; a headline is never attributed to the person quoted; and paraphrase is marked as such. In the data, this is the verbatim-quote field of promesas-tecnologicas.json and the per-row citations of services-status.json and pledges.json; in the prose, it is this discipline.
5 · Live citations
A citation is not a static ornament: it carries retrieved_at, URL and licence, and where the source is reachable it is re-verified on every run — the Aerocivil bulletins against their load-bearing phrase, the dossier rows chain by chain, the World Bank document index on every pledges bake. If a bulletin's text changes, the run flags it instead of silently upholding the transcription. Unreachable sources (INVIAS 403, ReliefWeb without an appname) keep their registered citation precisely so the gap stays measurable. data-health-colombia.json is the aggregation of this discipline: the age of every bake against the rhythm of its source.
The Day-30 plan — 2026-09-06
The government's technology plan runs on a 100-day clock; the days 1–30 cut ("Encender el motor") falls due around 6 September 2026, with four announced deliverables: the Decreto de Transparencia Digital, the Ecopetrol blockchain pilot, Ana IA activated and the national connectivity inventory. The August research called it the cleanest binary signal on whether this government builds transparency infrastructure or narrates it. That day the suite has to capture the outcome, whatever it is.
What the clock must capture (/colombia/reloj)
| Step | Detail |
|---|---|
| 1 · Verdict per promise | Every commitment due on day 30 moves to cumplido (with the instrument as its citation: decree number, pilot evidence, inventory URL) or to vencido (with the search for the instrument recorded and dated — absence is cited too) |
| 2 · No uncited intermediate states | en_curso on 6 September requires published evidence of progress; "it is said to be advancing" is not a state |
| 3 · Known cases | Ana IA already "exists" on a vendor domain with no gov.co presence and no privacy notice — if that is presented as fulfilment, the row records it with that note, not with a check mark |
| 4 · Bake the same day | promesas-tecnologicas.json is updated and baked on 6 September, not later; the update date is part of the record |
What the briefing must capture (/colombia/briefing)
- The Day-30 verdict as the lead block: what was promised for days 1–30, which instrument appeared, which did not.
- The Article 215 clock: if the economic-emergency decree was published (as of 13 August its number was still unpublished), its 30-day window has expired or is about to — and with it the CAT DDO precondition (promulgation of the decree), which touches
cat-ddo-terms.jsonandpledges.json. - The urgencia manifiesta trend: a SECOP II re-pull against the baseline (2 processes as of 11 August); one month after the quake, the count and its curve are the suite's most legible anticorruption indicator.
- The Chocó satellite products: the Quibdó and Istmina deliveries were expected on 14 August — by day 30 they are either in
satellite-damage.jsonor their absence is a finding the briefing states. - The balance-replacement status: does a machine-readable UNGRD bulletin exist yet, or is the source of record still a three-week-old speech?
- The MDRCO036 appeal funding (CHF 0 funded at the August cut) and the services-restoration trajectory.
- The full thermometer: that morning
ingest-all.ts+bake-colombia-health.tsrun; no figure in the Day-30 briefing may come from astalebake.
The run of the day
bun run scripts/colombia/ingest-all.ts --refresh # every live source
# curation: promesas-tecnologicas.json · services-status.json · pledges.json
bun run scripts/colombia/bake-colombia-health.ts # lane freshness
bun run scripts/colombia/check-real-data.ts # the gate, before publishing