last changed 9/23/2026
See Corla2020notes for description of the cvr files.
This is called “row redaction”: the entire row is redacted, the aggregations are given, in this case aggregated by style.
This is called “column redaction”: the ids are retained and the votes are redacted.
A form of “row redaction”: the entire row is redacted, no aggregation. Derive the missing card ids and count from the manifest. Derive the vote aggregation from the “voteDifference”.
Arapahoe has 100 missing cards, but vote difference (reported - cvrs) needs 115. The reported population agrees with the manifest, but the reported votes are inconsistent in 3 contests. One thing to do is to increase the population and the redacted pool by 115. This leaves the reported vote intact. In a real election, we could resolve the discrepency. In our simulation, it means that the simulated ballots will be short of the reported votes.
Does anonymize_cvr.py think that redactions are needed? Standard paremenets are minBallots = 10, contest_balancing = true.
needs redaction
totalManifest = 4104185
totalNcvrs = 4100064
totalMissing = 4121
redactedCvrs = 3171
totalNgroups = 42
ncounties with missing > 0 = 18
In summary:
Using this algorithm on the 2020 General election, the following table shows which counties had redactions.
The column “missing” is the number of cards in each county’s redacted pool:
| county | phantoms | population | manifestCount | cvrUnredacted | cvrRedacted | missing | manifestNoCvr | minCardsForVote | cvrInManifest | cvrNoManifest | nredacted |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Adams | 0 | 239425 | 239425 | 239409 | 0 | 16 | 16 | 16 | 239409 | 0 | 0 |
| Alamosa | 0 | 7923 | 7923 | 7923 | 0 | 0 | 0 | 0 | 7923 | 0 | 0 |
| Arapahoe | 0 | 354347 | 354347 | 354247 | 0 | 100 | 100 | 115 | 354247 | 0 | 84 |
| Archuleta | 0 | 9404 | 9404 | 9404 | 0 | 0 | 0 | 0 | 9404 | 0 | 0 |
| Bent | 0 | 2295 | 2295 | 2295 | 0 | 0 | 0 | 0 | 2295 | 0 | 0 |
| Boulder | 0 | 208445 | 208445 | 205796 | 0 | 2649 | 2649 | 2628 | 205796 | 0 | 0 |
| Broomfield | 0 | 47103 | 47103 | 47103 | 0 | 0 | 0 | 0 | 47103 | 0 | 0 |
| Chaffee | 0 | 13862 | 13862 | 13862 | 0 | 0 | 0 | 0 | 13862 | 0 | 0 |
| Cheyenne | 0 | 1146 | 1146 | 1146 | 0 | 0 | 0 | 0 | 1146 | 0 | 0 |
| Clear Creek | 0 | 6608 | 6608 | 6608 | 0 | 0 | 0 | 0 | 6608 | 0 | 0 |
| Conejos | 0 | 4404 | 4404 | 4404 | 0 | 0 | 0 | 0 | 4404 | 0 | 0 |
| Costilla | 0 | 2139 | 2139 | 2139 | 0 | 0 | 0 | 0 | 2139 | 0 | 0 |
| Crowley | 0 | 1769 | 1769 | 1769 | 0 | 0 | 0 | 0 | 1769 | 0 | 0 |
| Custer | 0 | 3670 | 3670 | 3670 | 0 | 0 | 0 | 0 | 3670 | 0 | 0 |
| Delta | 0 | 19553 | 19553 | 19553 | 0 | 0 | 0 | 0 | 19553 | 0 | 0 |
| Denver | 0 | 1181464 | 1181464 | 1181464 | 0 | 0 | 0 | 0 | 1181464 | 0 | 34 |
| Dolores | 0 | 1500 | 1500 | 1500 | 0 | 0 | 0 | 0 | 1500 | 0 | 0 |
| Douglas | 0 | 234272 | 234272 | 234216 | 56 | 0 | 56 | 56 | 234216 | 0 | 0 |
| Eagle | 0 | 58589 | 58589 | 58571 | 20 | -2 | 20 | 9 | 58569 | 2 | 0 |
| El Paso | 0 | 382583 | 382583 | 383160 | 44 | -621 | 159 | 8 | 382424 | 736 | 0 |
| Elbert | 0 | 19150 | 19150 | 19150 | 0 | 0 | 0 | 0 | 19150 | 0 | 0 |
| Fremont | 0 | 26289 | 26289 | 26289 | 0 | 0 | 0 | 0 | 26289 | 0 | 0 |
| Garfield | 0 | 31245 | 31245 | 30544 | 0 | 701 | 701 | 690 | 30544 | 0 | 0 |
| Gilpin | 0 | 4239 | 4239 | 4240 | 0 | -1 | 0 | 0 | 4239 | 1 | 0 |
| Grand | 0 | 10483 | 10483 | 10483 | 0 | 0 | 0 | 0 | 10483 | 0 | 0 |
| Hinsdale | 0 | 640 | 640 | 640 | 0 | 0 | 0 | 0 | 640 | 0 | 0 |
| Huerfano | 0 | 4459 | 4459 | 4459 | 0 | 0 | 0 | 0 | 4459 | 0 | 0 |
| Jackson | 0 | 889 | 889 | 886 | 0 | 3 | 3 | 3 | 886 | 0 | 0 |
| Jefferson | 0 | 381834 | 381834 | 381793 | 47 | -6 | 47 | 32 | 381787 | 6 | 0 |
| Kiowa | 0 | 909 | 909 | 909 | 0 | 0 | 0 | 0 | 909 | 0 | 0 |
| Kit Carson | 0 | 3892 | 3892 | 3893 | 0 | -1 | 0 | 0 | 3892 | 1 | 0 |
| La Plata | 0 | 35995 | 35995 | 35995 | 0 | 0 | 0 | 0 | 35995 | 0 | 20 |
| Lake | 0 | 4010 | 4010 | 4010 | 0 | 0 | 0 | 0 | 4010 | 0 | 0 |
| Larimer | 0 | 226896 | 226896 | 226844 | 57 | -5 | 57 | 52 | 226839 | 5 | 40 |
| Lincoln | 0 | 2665 | 2665 | 2665 | 0 | 0 | 0 | 0 | 2665 | 0 | 0 |
| Logan | 0 | 10685 | 10685 | 10664 | 21 | 0 | 21 | 21 | 10664 | 0 | 0 |
| Mesa | 0 | 91506 | 91506 | 91506 | 0 | 0 | 0 | 0 | 91506 | 0 | 56 |
| Mineral | 0 | 767 | 767 | 767 | 0 | 0 | 0 | 0 | 767 | 0 | 0 |
| Moffat | 0 | 7074 | 7074 | 7074 | 0 | 0 | 0 | 0 | 7074 | 0 | 0 |
| Montezuma | 0 | 15631 | 15631 | 15631 | 0 | 0 | 0 | 0 | 15631 | 0 | 0 |
| Montrose | 0 | 25159 | 25159 | 25159 | 0 | 0 | 0 | 0 | 25159 | 0 | 0 |
| Morgan | 0 | 13860 | 13860 | 13855 | 5 | 0 | 5 | 5 | 13855 | 0 | 0 |
| Otero | 0 | 9704 | 9704 | 9704 | 0 | 0 | 0 | 0 | 9704 | 0 | 0 |
| Ouray | 0 | 4050 | 4050 | 4050 | 0 | 0 | 0 | 0 | 4050 | 0 | 0 |
| Park | 0 | 12406 | 12406 | 12406 | 0 | 0 | 0 | 0 | 12406 | 0 | 0 |
| Phillips | 0 | 2561 | 2561 | 2561 | 0 | 0 | 0 | 0 | 2561 | 0 | 0 |
| Pitkin | 0 | 12089 | 12089 | 12063 | 26 | 0 | 26 | 23 | 12063 | 0 | 0 |
| Prowers | 0 | 5601 | 5601 | 5601 | 0 | 0 | 0 | 0 | 5601 | 0 | 0 |
| Pueblo | 0 | 89155 | 89155 | 89108 | 47 | 0 | 47 | 46 | 89108 | 0 | 0 |
| Rio Blanco | 0 | 3709 | 3709 | 3705 | 4 | 0 | 4 | 4 | 3705 | 0 | 0 |
| Rio Grande | 0 | 6451 | 6451 | 6451 | 0 | 0 | 0 | 0 | 6451 | 0 | 0 |
| Routt | 0 | 33008 | 33008 | 33008 | 0 | 0 | 0 | 0 | 33008 | 0 | 18 |
| Saguache | 0 | 6821 | 6821 | 6821 | 0 | 0 | 0 | 0 | 6821 | 0 | 31 |
| San Miguel | 0 | 5189 | 5189 | 5190 | 0 | -1 | 0 | 0 | 5189 | 1 | 0 |
| Sedgwick | 0 | 1496 | 1496 | 1496 | 0 | 0 | 0 | 0 | 1496 | 0 | 17 |
| Summit | 0 | 18943 | 18943 | 18788 | 169 | -14 | 169 | 154 | 18774 | 14 | 0 |
| Teller | 91 | 17178 | 17087 | 17087 | 0 | 91 | 0 | 91 | 17087 | 0 | 0 |
| Washington | 0 | 3028 | 3028 | 3028 | 0 | 0 | 0 | 0 | 3028 | 0 | 0 |
| Weld | 0 | 169080 | 169080 | 169061 | 41 | -22 | 41 | 27 | 169039 | 22 | 0 |
| Yuma | 0 | 5029 | 5029 | 5029 | 0 | 0 | 0 | 0 | 5029 | 0 | 0 |
where
| field | example | description |
|---|---|---|
| county | Larimer | county name |
| phantoms | 0 | population - manifestCount |
| population | 226896 | county population from round.ballotCardCount |
| manifestCount | 226896 | number of entries in the manifest |
| cvrUnredacted | 226844 | count of unredacted Cvrs |
| cvrRedacted | 57 | count of redacted Cvrs |
| missing | -5 | manifestCount - (cvrUnredacted + cvrRedacted) |
| manifestNoCvr | 57 | count of Manifest entries that dont match cvrs |
| minCardsForVote | 52 | minimum cards needed for missing votes |
| cvrInManifest | 226839 | count of Cvrs that match entries in the Manifest |
| cvrNoManifest | 5 | count of Cvrs that dont match entries in the Manifest |
| nredacted | 40 | number of redacted rows added by Anonymizer |
(Skipping “styles” variant for now, as none of the existing cvr files can support it).
| ncontests | nredactions | ncards | npools | phantoms | onePool | unredacted | |
|---|---|---|---|---|---|---|---|
| Corla2020 | 562 | 4121 | 4104185 | 18 | 19721 (561) | 17182 | 16789 |
TODO test that extra cards in phantoms dont affect the diluted margin, ie the population size remains constant: read the cardManifest and tabulate npops. Alos, could add that to CorlaStateElection.
10/05/2026
Boulder has no precinct portion. It also has 1600 redacted ballots. I suspect they used precincts in their redaction, and then removed that column.
Ok heres what I know: none of La Plata, Weld or Morgan had the problem with CVRs (where the same ballotType had different contests, aka card styles), in either the 2026 primary or the 2020 general election. Douglas also did not have that problem in its 2020 CVRs.
In the 2026 Primary, La Plata and Morgan clearly ran our anonymizer which redacted 9 and 25 ballots, respectively. Weld did not run our anonymizer, but they redacted 20 rows by blanking out the votes. Our anonymizer did not find further ballots for Weld it thought should be redacted, but of course it did not have the unredacted CVR file.
In 2020 General, Douglas had 56 redacted ballots and our anonomizer did not find further ballots it thought should be redacted.
In summary, those 4 counties don’t appear to have any of the problems that might mess up our Excel macro. And it seems to me that the current macro will work fine on all of these counties without change. The macro can replace what they are doing now. (Lori, am I missing something about that?)
The macro only does rare styles, not “contest balancing”, so if those counties were willing to again run our python anonomizer, that would be more accurate. And we also think that with the exception of Boulder, no county is currently doing contest balancing, so the macro isn’t making things worse.
I think I will send a pull request to Neal’s repo (or should i use Lori’s?) to change it to put * only where redacted votes exist. So if that is an option for some counties, they can use the python anonomizer and the file format will look the same as with the macro.
If we only have 4 counties, if needed maybe each of us can be at one of the counties when they do the redaction, in case there is a problem.
PS: there is one factoid not particularly relevant to redaction, but in 2026 Primary, La Plata had 50 cvrs in the CVR file that were not present in their manifest that we have in auditcenter. I mention it only because maybe we can alert them so they can double-check it next time.