The archive holds 155 situation reports (through 2026-10-23). 145 are read at health-zone level — every report that prints a per-zone table — for 6,998 zone-day rows; the provincial summary covers 140 reports, and three early reports are read from their own prose. Every held report contributes case data at the finest level its pages print.
Data
2026 DRC Bundibugyo virus outbreak — sources, extraction, and what reconciles
Most of the text on this site, and most of the code behind it, was written by Anthropic’s Claude Code agents working under my direction. The outbreak produces a new situation report every day, and I wanted this data out fast and kept current, which I couldn’t have done by hand. The numbers are computed by the pipeline and checked against the reports (here’s how), but the writing was done in a hurry and will have mistakes. If you find one, please open an issue or get in touch. — Vince Buffalo
What’s here
The data on this page come from the situation reports (“sitreps”) that INSP, the DRC’s national public health institute, publishes on the outbreak. The reports count cases by health zone, the district-sized unit the country’s health system is organised into, and health zones roll up into provinces.
Every number and every figure on this page is read from a file the pipeline builds, at the moment the page renders. If a figure has no build rule behind it, or a file hasn’t been built yet, the render stops with an error, so nothing here can be typed in by hand or left over from an old build. To rebuild it all yourself, run make build, make streams, make figures and make compare.
'data/build/figures/latest/availability.png'
A few dates are worth keeping in your head as you read that figure. The suspected-case and contact-tracing series stop at the start of June, which is also when counts of confirmed deaths begin. On 13 July the reports start splitting each day’s deaths by how they were found: community deaths, confirmed by a post-mortem swab, and deaths in treatment centres. And sitreps 084 to 086 use a layout that prints no per-zone table at all, so for those three reports I only have province totals.
The reports annotate their own early numbers, and I treat those annotations as data. Nearly every report from 004 through 033 carries a footnote saying its headline cumulative count is still being harmonised, that is, reconciled across the levels of the health system. From sitrep 026 (9 June) the footnote also says which way the error runs. The count leaves out confirmed cases who are still in the community and patients who escaped from care, so it is too low. Sitreps 011 and 012 have a footnote saying the death count itself is underestimated. Later, from sitrep 060 to 083, the reports warn that the last few days’ changes should be read with caution, because notifications arrive late and the data are still being consolidated. Each of these statements is a row in provisional_caveat.csv, whose kind column says which sort of caveat it is: harmonisation_pending (still being harmonised), harmonisation_undercount (being harmonised, and stated to be too low), deaths_underestimated, or recent_data_provisional (the warning about recent days, flagged “caveat” in the index). The index below flags them report by report. This matters if you fit the first four weeks of the outbreak, because you’d be fitting numbers the source itself called provisional, and from 9 June called too low.
Index of situation reports
One row per report. Route is the table layout it was read through (— when no zone table exists); identity asks whether the page’s own arithmetic closes; flags mark the source’s own provisionality caveat, a hand-verified exception, or a rejected route.
| report | date | route | rows | identity | residual | flags |
|---|---|---|---|---|---|---|
| 001 | 2026-05-14 | — | 0 | — | ||
| 002 | 2026-05-17 | — | 0 | — | ||
| 004 | 2026-05-18 | zone_early | 8 | ok | 0 | harmonisation |
| 005 | 2026-05-19 | zone_early | 8 | ok | 0 | harmonisation |
| 006 | 2026-05-20 | zone_early | 10 | ok | 0 | harmonisation |
| 007 | 2026-05-21 | zone_early | 13 | ok | 0 | harmonisation |
| 008 | 2026-05-22 | zone_early | 13 | ok | 0 | harmonisation |
| 009 | 2026-05-23 | zone_early | 14 | ok | 0 | harmonisation |
| 010 | 2026-05-24 | zone_early | 18 | ok | 0 | harmonisation |
| 011 | 2026-05-25 | zone_early | 18 | ok | 0 | harmonisation, deaths understated |
| 012 | 2026-05-26 | — | 0 | — | deaths understated | |
| 013 | 2026-05-27 | zone_early | 21 | ok | 0 | harmonisation |
| 014 | 2026-05-28 | — | 0 | — | ||
| 015 | 2026-05-29 | zone_mixed | 31 | ok | 0 | |
| 016 | 2026-05-30 | — | 0 | — | harmonisation | |
| 017 | 2026-05-31 | — | 0 | — | harmonisation | |
| 018 | 2026-06-01 | zone_cumulative | 29 | ok | 0 | harmonisation |
| 019 | 2026-06-02 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 020 | 2026-06-03 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 021 | 2026-06-04 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 022 | 2026-06-05 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 023 | 2026-06-06 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 024 | 2026-06-07 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 025 | 2026-06-08 | zone_cumulative | 30 | ok | 0 | harmonisation |
| 026 | 2026-06-09 | zone_cumulative | 31 | ok | 0 | stated undercount |
| 027 | 2026-06-10 | zone_cumulative | 34 | ok | 0 | stated undercount |
| 028 | 2026-06-11 | zone_cumulative | 34 | ok | 0 | stated undercount |
| 030 | 2026-06-13 | zone_cumulative | 36 | ok | 0 | stated undercount |
| 031 | 2026-06-14 | zone_cumulative | 36 | ok | 0 | stated undercount |
| 032 | 2026-06-15 | zone_cumulative | 36 | ok | 0 | stated undercount |
| 033 | 2026-06-16 | — | 0 | — | stated undercount, route rejected | |
| 034 | 2026-06-17 | zone_cumulative | 39 | ok | 0 | exception |
| 035 | 2026-06-18 | zone_cumulative | 39 | ok | 0 | |
| 036 | 2026-06-19 | zone_cumulative | 39 | ok | 0 | |
| 037 | 2026-06-20 | zone_cumulative | 39 | ok | 0 | |
| 038 | 2026-06-21 | zone_cumulative | 39 | ok | 0 | |
| 039 | 2026-06-22 | zone_cumulative | 39 | ok | 0 | |
| 040 | 2026-06-23 | zone_cumulative | 39 | ok | 0 | |
| 041 | 2026-06-24 | zone_cumulative | 39 | ok | 0 | |
| 042 | 2026-06-25 | zone_cumulative | 39 | ok | 0 | |
| 044 | 2026-06-27 | zone_cumulative | 40 | ok | 0 | |
| 046 | 2026-06-29 | zone_cumulative | 40 | ok | 0 | |
| 047 | 2026-06-30 | zone_cumulative | 41 | ok | 0 | |
| 048 | 2026-07-01 | zone_cumulative | 41 | ok | 0 | |
| 049 | 2026-07-02 | zone_cumulative | 41 | ok | 0 | |
| 050 | 2026-07-03 | zone_cumulative | 41 | ok | 0 | |
| 051 | 2026-07-04 | zone_cumulative | 41 | ok | 0 | |
| 052 | 2026-07-05 | zone_cumulative | 41 | ok | 0 | |
| 053 | 2026-07-06 | zone_cumulative | 42 | fails | -5 | exception |
| 054 | 2026-07-07 | zone_cumulative | 42 | ok | 0 | |
| 055 | 2026-07-08 | zone_cumulative | 42 | ok | 0 | exception |
| 056 | 2026-07-09 | zone_cumulative | 42 | ok | 0 | |
| 057 | 2026-07-10 | zone_cumulative | 48 | fails | 5 | |
| 058 | 2026-07-11 | zone_cumulative | 49 | ok | 0 | |
| 059 | 2026-07-12 | zone_cumulative | 49 | ok | 0 | exception |
| 060 | 2026-07-13 | zone_cumulative | 52 | ok | 0 | caveat |
| 061 | 2026-07-14 | zone_cumulative | 52 | ok | 0 | caveat |
| 062 | 2026-07-15 | zone_cumulative | 53 | ok | 0 | caveat |
| 063 | 2026-07-16 | zone_cumulative | 53 | ok | 0 | caveat, exception |
| 064 | 2026-07-17 | zone_cumulative | 53 | ok | 0 | caveat |
| 065 | 2026-07-18 | zone_cumulative | 53 | ok | 0 | caveat |
| 066 | 2026-07-19 | zone_cumulative | 54 | ok | 0 | caveat |
| 067 | 2026-07-20 | zone_cumulative | 54 | ok | 0 | caveat |
| 068 | 2026-07-21 | zone_cumulative | 54 | ok | 0 | caveat |
| 069 | 2026-07-22 | zone_cumulative | 53 | ok | 0 | caveat |
| 070 | 2026-07-23 | zone_cumulative | 54 | ok | 0 | caveat |
| 071 | 2026-07-24 | zone_cumulative | 54 | ok | 0 | caveat |
| 072 | 2026-07-25 | zone_cumulative | 54 | ok | 0 | caveat |
| 073 | 2026-07-26 | zone_cumulative | 54 | ok | 0 | caveat |
| 074 | 2026-07-27 | zone_cumulative | 54 | ok | 0 | caveat |
| 077 | 2026-07-30 | zone_cumulative | 55 | ok | 0 | caveat |
| 078 | 2026-07-31 | zone_cumulative | 55 | ok | 0 | caveat |
| 079 | 2026-08-01 | zone_cumulative | 56 | ok | 0 | caveat |
| 080 | 2026-08-02 | zone_cumulative | 57 | ok | 0 | caveat, route rejected |
| 081 | 2026-08-03 | zone_cumulative | 57 | ok | 0 | caveat, exception |
| 082 | 2026-08-04 | zone_cumulative | 57 | ok | 0 | caveat |
| 083 | 2026-08-05 | zone_cumulative | 59 | ok | 0 | caveat, exception |
| 084 | 2026-08-06 | — | 0 | — | ||
| 085 | 2026-08-07 | — | 0 | — | ||
| 086 | 2026-08-08 | — | 0 | — | ||
| 087 | 2026-08-09 | zone_daily | 34 | ok | 0 | |
| 088 | 2026-08-10 | zone_cumulative | 60 | ok | 0 | |
| 089 | 2026-08-11 | zone_cumulative | 60 | fails | 1 | exception |
| 090 | 2026-08-12 | zone_cumulative | 62 | ok | 0 | |
| 091 | 2026-08-13 | zone_cumulative | 63 | ok | 0 | |
| 092 | 2026-08-14 | zone_cumulative | 63 | ok | 0 | |
| 093 | 2026-08-15 | zone_cumulative | 63 | ok | 0 | |
| 094 | 2026-08-16 | zone_cumulative | 63 | ok | 0 | |
| 095 | 2026-08-17 | zone_cumulative | 63 | ok | 0 | |
| 096 | 2026-08-18 | zone_cumulative | 64 | ok | 0 | |
| 097 | 2026-08-19 | zone_cumulative | 64 | ok | 0 | |
| 098 | 2026-08-20 | zone_cumulative | 64 | ok | 0 | |
| 099 | 2026-08-21 | zone_cumulative | 65 | ok | 0 | |
| 100 | 2026-08-22 | zone_cumulative | 65 | ok | 0 | |
| 101 | 2026-08-23 | zone_cumulative | 65 | ok | 0 | |
| 102 | 2026-08-24 | zone_cumulative | 66 | ok | 0 | |
| 103 | 2026-08-25 | zone_cumulative | 66 | ok | 0 | |
| 104 | 2026-08-26 | zone_cumulative | 68 | ok | 0 | |
| 105 | 2026-08-27 | zone_cumulative | 68 | ok | 0 | |
| 106 | 2026-08-28 | zone_cumulative | 68 | ok | 0 | |
| 107 | 2026-08-29 | zone_cumulative | 68 | ok | 0 | |
| 108 | 2026-08-30 | zone_cumulative | 68 | ok | 0 | |
| 109 | 2026-08-31 | zone_cumulative | 68 | ok | 0 | |
| 110 | 2026-09-01 | zone_cumulative | 68 | ok | 0 | |
| 111 | 2026-09-02 | zone_cumulative | 68 | ok | 0 | |
| 112 | 2026-09-03 | zone_cumulative | 68 | ok | 0 | |
| 113 | 2026-09-04 | zone_cumulative | 69 | ok | 0 | |
| 114 | 2026-09-05 | zone_cumulative | 69 | ok | 0 | |
| 115 | 2026-09-06 | zone_cumulative | 69 | ok | 0 | |
| 116 | 2026-09-07 | zone_cumulative | 69 | ok | 0 | |
| 117 | 2026-09-08 | zone_cumulative | 69 | ok | 0 | |
| 118 | 2026-09-09 | zone_cumulative | 69 | ok | 0 | |
| 119 | 2026-09-10 | zone_cumulative | 71 | ok | 0 | |
| 120 | 2026-09-11 | zone_cumulative | 71 | ok | 0 | |
| 121 | 2026-09-12 | zone_cumulative | 71 | ok | 0 | |
| 122 | 2026-09-13 | zone_cumulative | 71 | ok | 0 | |
| 123 | 2026-09-14 | zone_cumulative | 71 | ok | 0 | |
| 124 | 2026-09-15 | zone_cumulative | 71 | ok | 0 | |
| 125 | 2026-09-16 | zone_cumulative | 71 | ok | 0 | |
| 126 | 2026-09-17 | zone_cumulative | 71 | ok | 0 | |
| 127 | 2026-09-18 | zone_cumulative | 72 | ok | 0 | |
| 128 | 2026-09-19 | zone_cumulative | 72 | ok | 0 | |
| 129 | 2026-09-20 | zone_cumulative | 72 | ok | 0 | |
| 130 | 2026-09-21 | zone_cumulative | 72 | ok | 0 | |
| 131 | 2026-09-22 | zone_cumulative | 72 | ok | 0 | |
| 132 | 2026-09-23 | zone_cumulative | 72 | ok | 0 | |
| 133 | 2026-09-24 | zone_cumulative | 72 | ok | 0 | |
| 134 | 2026-09-25 | zone_cumulative | 72 | ok | 0 | |
| 135 | 2026-09-26 | zone_cumulative | 72 | ok | 0 | |
| 136 | 2026-09-27 | zone_cumulative | 72 | ok | 0 | |
| 137 | 2026-09-28 | zone_cumulative | 72 | ok | 0 | |
| 138 | 2026-09-29 | zone_cumulative | 72 | ok | 0 | |
| 139 | 2026-09-30 | zone_cumulative | 72 | ok | 0 | |
| 140 | 2026-10-01 | zone_cumulative | 72 | ok | 0 | |
| 141 | 2026-10-02 | zone_cumulative | 73 | ok | 0 | |
| 143 | 2026-10-04 | zone_cumulative | 73 | ok | 0 | |
| 144 | 2026-10-05 | zone_cumulative | 73 | ok | 0 | |
| 145 | 2026-10-06 | zone_cumulative | 73 | ok | 0 | |
| 146 | 2026-10-07 | zone_cumulative | 73 | ok | 0 | |
| 147 | 2026-10-08 | zone_cumulative | 74 | ok | 0 | |
| 148 | 2026-10-09 | zone_cumulative | 74 | ok | 0 | |
| 149 | 2026-10-10 | zone_cumulative | 74 | ok | 0 | |
| 150 | 2026-10-11 | zone_cumulative | 74 | ok | 0 | |
| 151 | 2026-10-12 | zone_cumulative | 74 | ok | 0 | |
| 152 | 2026-10-13 | zone_cumulative | 74 | ok | 0 | |
| 153 | 2026-10-14 | zone_cumulative | 74 | ok | 0 | |
| 154 | 2026-10-15 | zone_cumulative | 74 | ok | 0 | |
| 155 | 2026-10-16 | zone_cumulative | 76 | ok | 0 | |
| 156 | 2026-10-17 | zone_cumulative | 76 | ok | 0 | |
| 157 | 2026-10-18 | zone_cumulative | 76 | ok | 0 | |
| 158 | 2026-10-19 | zone_cumulative | 76 | ok | 0 | |
| 159 | 2026-10-20 | zone_cumulative | 76 | ok | 0 | |
| 160 | 2026-10-21 | zone_cumulative | 76 | ok | 0 | |
| 161 | 2026-10-22 | zone_cumulative | 76 | ok | 0 | |
| 163 | 2026-10-23 | zone_cumulative | 76 | ok | 0 |
One primary source, and two readings I only check against
The primary source is the set of situation-report PDFs that INSP (Institut National de Santé Publique) posts at insp.cd. I download them and pin each one with a committed index and a manifest of SHA-256 hashes, so I can tell if a file ever changes. Then I read the numbers from the table geometry drawn in the PDF itself.
Two other groups have read the same documents. INRB-UMIE, the national laboratory, keeps its own transcription, and epiforecasts has a scan. I use both only as checks; nothing on this page is built from them. Since all three of us read the same pages, agreement between us tells you the transcription is right. It tells you nothing about whether the counts themselves are right. A disagreement, on the other hand, always means something: either one of the readings has an error, or two versions of a revised report were read.
Against INRB-UMIE, per zone-day: 5,592 of 5,609 case values agree exactly and 5,490 of 5,499 death values; 23 rows disagree on either, each recorded with both values. The denominator is the inner join of the two lineages — 1,384 of our 6,998 zone-day rows have no INRB counterpart and sit outside every agreement figure, and they are not random: the INRB series currently ends 2026-10-18, ours 2026-10-23, so the most recent reports are uncompared by construction. Against the epiforecasts scan, the national cumulative agrees on 133 of 134 reports exactly. The largest disagreement is not ours: sitrep 032 prints Rwampara at 159 twice over — in its table and its narrative — where the INRB file carries 192.
'data/build/figures/latest/comparison_series.png'
Every table is checked against the page’s own arithmetic
Every table I extract has to add up the way the page says it does. A province’s health-zone rows, plus any rows the source counts but hasn’t assigned to a zone yet, must equal the province total printed on the page, and the provinces must add up to the printed national total. When they don’t, I assume the mistake is mine until reading the page shows otherwise.
Sometimes the page really doesn’t add up. When that happens the judgement goes into a register, a hand-kept file with one row per judgement. Each row is tied to the SHA-256 hash of that exact PDF, and it excuses that one gap on that one document and nothing else.
Province-reports: 719 reconcile exactly, 10 carry a hand-verified exception (the page disagrees with itself, read and recorded), 0 disagree and remain open, 30 print no total to check against.
This check has a blind spot. It only catches errors that break the arithmetic. If I read the neighbouring column of a table by mistake, say suspected cases instead of confirmed, that column adds up just as well, and the check passes. Mistakes like that get caught another way: by tests that pin the values of specific named reports, and by comparing the assembled series against the printed totals, further down.
The series
'data/build/figures/latest/province_series.png'
'data/build/figures/latest/streams_detail.png'
consolidating column that says which they are.'data/build/figures/latest/national_detail.png'
The streams that downstream models fit are weekly incidence per province. To build them I take the cumulative count, carry the last known value forward over days with no report, difference it, and bin the differences into weeks counted from day 0 (2026-05-19). Two checks have to pass. The total a stream emits has to equal exactly how far the cumulative count moved, and the assembled grid is compared against every province row the reports print.
| stream | obs | emitted | vs source Δ | grid = printed | final gap |
|---|---|---|---|---|---|
cases_bas_uele |
11 | 12 | 0 | 72/72 | +0 |
cases_daily_bas_uele |
71 | 12 | 0 | — | — |
cases_daily_haut_uele |
98 | 430 | 0 | — | — |
cases_daily_ituri |
142 | 7,105 | 0 | — | — |
cases_daily_national |
152 | 9,843 | 0 | — | — |
cases_daily_nord_kivu |
143 | 2,209 | 0 | — | — |
cases_daily_nord_ubangi |
7 | 1 | 0 | — | — |
cases_daily_sud_kivu |
140 | 2 | 0 | — | — |
cases_daily_sud_ubangi |
42 | 1 | 0 | — | — |
cases_daily_tshopo |
98 | 73 | 0 | — | — |
cases_haut_uele |
16 | 430 | 0 | 99/99 | +0 |
cases_ituri |
24 | 7,105 | 0 | 134/136 | +0 |
cases_national |
24 | 9,843 | 0 | — | — |
cases_nord_kivu |
24 | 2,209 | 0 | 133/136 | +0 |
cases_nord_ubangi |
2 | 1 | 0 | 8/8 | +0 |
cases_sud_kivu |
23 | 2 | 0 | 136/136 | +0 |
cases_sud_ubangi |
7 | 1 | 0 | 43/43 | +0 |
cases_tshopo |
16 | 73 | 0 | 99/99 | +0 |
community_deaths_bas_uele |
11 | 3 of 4 | — | 12/12 daily | — |
community_deaths_daily_bas_uele |
72 | 3 of 4 | — | 0 flagged | — |
community_deaths_daily_haut_uele |
87 | 75 of 165 | — | 13 flagged | — |
community_deaths_daily_ituri |
96 | 1,434 of 2,380 | — | 21 flagged | — |
community_deaths_daily_national |
96 | 2,313 of 3,636 | — | 21 flagged | — |
community_deaths_daily_nord_kivu |
96 | 789 of 1,063 | — | 21 flagged | — |
community_deaths_daily_nord_ubangi |
8 | 1 of 1 | — | 0 flagged | — |
community_deaths_daily_sud_kivu |
80 | 8 of 22 | — | 6 flagged | — |
community_deaths_daily_sud_ubangi |
43 | 1 of 1 | — | 0 flagged | — |
community_deaths_daily_tshopo |
79 | 10 of 22 | — | 5 flagged | — |
community_deaths_haut_uele |
16 | 75 of 165 | — | 72/84 daily | — |
community_deaths_ituri |
16 | 1,434 of 2,380 | — | 36/95 daily | — |
community_deaths_national |
16 | 2,313 of 3,636 | — | 93/96 daily | — |
community_deaths_nord_kivu |
16 | 789 of 1,063 | — | 81/96 daily | — |
community_deaths_nord_ubangi |
2 | 1 of 1 | — | 1/1 daily | — |
community_deaths_sud_kivu |
14 | 8 of 22 | — | 6/6 daily | — |
community_deaths_sud_ubangi |
7 | 1 of 1 | — | 2/2 daily | — |
community_deaths_tshopo |
13 | 10 of 22 | — | 38/41 daily | — |
cumul_recovered |
147 | 0 → 2,646 | — | stock, 2026-05-17 to 2026-10-23 | — |
deaths_bas_uele |
11 | 3 | 0 | 72/72 | +0 |
deaths_daily_bas_uele |
71 | 3 | 0 | — | — |
deaths_daily_haut_uele |
98 | 188 | 0 | — | — |
deaths_daily_ituri |
133 | 3,303 | 0 | — | — |
deaths_daily_national |
153 | 4,799 | 0 | — | — |
deaths_daily_nord_kivu |
133 | 1,236 | 0 | — | — |
deaths_daily_nord_ubangi |
7 | 0 | 0 | — | — |
deaths_daily_sud_kivu |
134 | 0 | 0 | — | — |
deaths_daily_sud_ubangi |
42 | 0 | 0 | — | — |
deaths_daily_tshopo |
98 | 25 | 0 | — | — |
deaths_haut_uele |
16 | 188 | 0 | 99/99 | +0 |
deaths_ituri |
22 | 3,303 | 0 | 132/135 | +0 |
deaths_national |
24 | 4,799 | 0 | — | — |
deaths_nord_kivu |
22 | 1,236 | 0 | 129/135 | +0 |
deaths_nord_ubangi |
2 | 0 | 0 | 8/8 | +0 |
deaths_sud_kivu |
22 | 0 | 0 | 135/135 | +0 |
deaths_sud_ubangi |
7 | 0 | 0 | 43/43 | +0 |
deaths_tshopo |
16 | 25 | 0 | 98/99 | +0 |
lab_daily_bas_uele |
33 | 7 of 270 tests | — | — | — |
lab_daily_haut_uele |
69 | 281 of 1,545 tests | — | — | — |
lab_daily_ituri |
125 | 5,675 of 25,619 tests | — | — | — |
lab_daily_national |
130 | 7,991 of 44,014 tests | — | 1–6 provinces/day | — |
lab_daily_nord_kivu |
111 | 1,915 of 15,648 tests | — | — | — |
lab_daily_nord_ubangi |
1 | 1 of 4 tests | — | — | — |
lab_daily_sud_kivu |
26 | 0 of 137 tests | — | — | — |
lab_daily_tshopo |
42 | 112 of 791 tests | — | — | — |
lab_national |
21 | 7,991 of 44,014 tests | — | 317/333 vs new cases | — |
patients_isolated |
139 | 173 → 1,018 | — | stock, 2026-06-01 to 2026-10-23 | — |
patients_isolated_confirmed |
49 | 47 → 335 | — | stock, 2026-06-02 to 2026-08-02 | — |
The registers hold the judgements I made by reading a page
Everything else in this repository is either downloaded or computed. The registers are different. Each row is a judgement I made after reading a page. Every row is keyed on the SHA-256 hash of the document it’s about, so if INSP revises a report, the hash stops matching and the row has to be judged again. And each row excuses exactly one value, so if the value we read changes, the excuse no longer covers it.
| register | rows | each row asserts |
|---|---|---|
reconciliation_exceptions.tsv |
15 | this page’s printed rows do not sum to its printed total, by exactly this much |
rejected_routes.tsv |
2 | this route, on this document, reads the wrong table – or reads the right one with named columns displaced |
zone_province_overrides.tsv |
13 | the page states in words which province this row belongs to |
zone_aliases_local.csv |
8 | this printed spelling is that canonical health zone |
sitrep_number_overrides.tsv |
29 | this upload’s filename misstates its report number or data date |
external_sitreps.tsv |
3 | INSP does not serve this report; it is held from a secondary archive and its PDF is committed, because nothing can fetch it again |
The care ledger
The reports also keep a ledger of the treatment centres, written out in words for each province in the section on patient care. It gives admissions; exits, and the four ways a patient can leave a centre; the census at the end of each day, split into confirmed and suspected patients; and the number of beds installed. extract_care_prose.py reads all of it into data/build/series/care_prose.csv, and the release publishes it as the care_* stream files, which the streams README lists. The confirmed census is worth a look if you’re fitting: it measures a state (how many confirmed patients are in care at one moment), while the case and death streams measure flows.
'data/build/figures/latest/care_ledger.png'
What isn’t here
I don’t extract the laboratory, alerts or contact-tracing tables yet. The reference pipeline reads them, and this one will. The care ledger comes from the report text only. The reports also print a patient-movement table with the same quantities per province, absconders included, and reading it would roughly triple the absconder coverage you see in panel D. I also don’t read the daily suspected inflow from the front-page dashboard after 12 July, so the national suspected series ends where the early layout stops printing it. The 23 disagreements with INRB are waiting to be settled: I’ll read each page, then decide case by case whether to report it upstream. Finally, no fit uses these streams yet. That work belongs to the modelling repository.