layout | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
A cast vote record is a record of voter selections based on the system's interpretation of a scanned ballot. Each cast vote record corresponds to a single scanned ballot sheet. Multi-sheet ballots produce multiple cast vote records.
Cast vote records are exported from VxScan and VxCentralScan onto USB drives and then imported into VxAdmin. Each cast vote record export is created with a digital signature. VxAdmin verifies this signature when importing cast vote records to ensure that the export has not been tampered with.
In order to export cast vote records efficiently and without compromising voter privacy, every cast vote record is generated individually. The structure of a cast vote record directory is as follows:
- root
- metadata.json
- 0cfaa953-11fa-4483-af03-04eed1d8cc6f
- cast-vote-record-report.json
- 0cfaa953-11fa-4483-af03-04eed1d8cc6f-front.jpg
- 0cfaa953-11fa-4483-af03-04eed1d8cc6f-front.layout.json
- 0cfaa953-11fa-4483-af03-04eed1d8cc6f-back.jpg
- 0cfaa953-11fa-4483-af03-04eed1d8cc6f-back.layout.json
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c
- cast-vote-record-report.json
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-front.jpg
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-front.layout.json
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-back.jpg
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-back.layout.json
- ...
- ...
- ...
The cast vote record export contains a directory for each cast vote record, labelled with its UUID. Each specific cast vote record directory contains:
- Cast Vote Record Report - Contains information about the election and the ballot interpretation in the Common Data Format. The information in the report is used as the basis for tabulation by VxAdmin.
- Images - Ballot images to be used in write-in adjudication or auditing
- Interpreted Ballot Layouts - Metadata for the position of ballot features such as contests, contest options, and bubbles in the ballot image. The interpreted layout data is used to properly crop and highlight ballot images for write-in adjudication.
In addition, there is a metadata file that applies to the entire export at the root of the directory, metadata.json.
The v4 UUID (universally unique identifier) for each cast vote record is generated when the ballot information is first stored in the database in VxScan or VxCentralScan. It is generated with the node package uuid
which uses the system's underlying FIPS-complaint OpenSSL implementation to generated random bytes.
In VxScan, ballot images and layouts are always included. In VxCentralScan, ballot images and layouts are only included in the cast vote record export if the ballot has write-ins that may require adjudication. When exporting a backup from VxCentralScan, however, ballot images and layouts are included for all ballots.
Layouts are not included for machine marked ballots.
In VxScan, images of rejected ballots are always included. In VxCentralScan, images of rejected ballots are not included in the cast vote record export but are included in the backup. There are no layout files or cast vote record report for rejected ballots because they are often uninterpretable. When rejected ballots are included, they will appear in the directory with the prefix rejected-
, as in the following example:
- root
- ...
- rejected-0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-front.jpg
- 0cfbf789-d8a0-4d3f-a221-b7fe8e0bb47c-back.jpg
- ...
VxSuite does not use any data extensions beyond the NIST specification, but some fields are made required that are not required in the original NIST specification. The two specifications can be compared by comparing the NIST JSON schema with the VxSuite JSON schema. The additionally required fields are listed in a table below.
Because VxAdmin requires a VxSuite digital signature on all imported cast vote records, it's not possible to import a cast vote record from outside of VxSuite. The goal of using CDF is to help external systems consume VxSuite cast vote records for audit or analysis.
CDF Class | Additionally Required Attributes |
---|---|
CVR | BallotStyleId, BallotStyleUnitId, BatchId, CreatingDeviceId, UniqueId |
CVRContest | CVRContestSelection |
CVRContestSelection |
|
CVRSnapshot | CVRContest |
The CDF specification includes many metadata fields that might help a consumer make sense of the cast vote record data. For example, you may define the candidates that are referenced as contest selections. VxSuite cast vote records all include this metadata to conform to the CDF, but nearly none of it is actually utilized when imported into VxAdmin. VxAdmin already has that information from the election package. The only data that is utilized by VxAdmin is the GeneratedDate
and the indication of whether or not the report is a test report in ReportType
and OtherReportType
.
CDF Attribute | Usage |
---|---|
Version | Fixed to "1.0.0" |
ReportType | Always includes "originating-device-export". If a test report, also includes "other" |
OtherReportType | If a test report, "test", otherwise undefined |
GeneratedDate | The generated date in Date Time String Format |
ReportGeneratingDeviceIds | The scanner serial number |
Only one ReportingDevice
is ever listed:
CDF Attribute | Usage |
---|---|
@id | The scanner serial number |
SerialNumber | The scanner serial number |
Manufacturer | Fixed to "VotingWorks" |
The list of parties in the cast vote record report is mapped directly from the Party list in the election definition:
CDF Attribute | Usage |
---|---|
@id | The party identifier from the election definition |
Name | The full name of the party, e.g. "Democratic Party" |
Abbreviation | The abbreviation of the party, e.g. "R" |
GpUnit
s are created for each Precinct in the election, for the County, and for the state:
CDF Attribute | Usage |
---|---|
@id |
|
Type |
|
Name | The precinct, county, or state name |
The Election
class has values mapped to it directly from the election definition:
CDF Attribute | Usage |
---|---|
@id | The election's ballot hash |
Name | The title of the election |
ElectionScopeId | Fixed to "election-state" |
Candidate.@id | The candidate identifier from the election definition |
Candidate.Name | The candidate name |
Contest.@id | The contest identifier from the election definition |
Contest.Name | The contest title |
CandidateContest.VotesAllowed | The contest's number of seats |
CandidateContest.PrimaryPartyId | The party identifier of the associated party, if a primary contest |
CandidateSelection.@id | The candidate identifier from the election definition |
CandidateSelection.CandidateIds | The candidate identifier from the election definition |
CandidateSelection.IsWriteIn | Whether the selection represents a write-in bubble |
BallotMeasureSelection.@id | The option identifier from the election definition |
BallotMeasureSelection.Selection | The option label that appeared on the ballot |
Each cast vote record includes a set of ballot metadata attributes:
CDF Attribute | Usage |
---|---|
BallotSheetId | The index of the sheet within the ballot. For the second sheet of a multi-sheet ballot, it would be 2 |
BallotStyleId | The ballot style identifier from the election definition |
BallotStyleUnitId | The precinct identifier from the election definition |
Batch | The batch identifier |
CreatingDeviceId | The scanner serial number |
ElectionId | The election's ballot hash |
PartyIds | The party identifier from the election definition, if for a primary ballot |
UniqueId | The UUID for the ballot generated by the scanner |
BatchSequenceId | When using VxCentralScan, contains the index of the sheet within the batch. 1-indexed. |
BallotAuditId | When using an imprinter on VxCentralScan, contains the UUID imprinted on the ballot |
The CVR.BallotImage
attribute exists when there are images accompanying the cast vote record. If it exists, it always contains images for both sides of the ballot. Its attributes are as follows:
CDF Attribute | Usage |
---|---|
Location | Location of the image file relative to the report, such as:
|
Hash.Type | Fixed to "sha-256" |
Hash.Value |
|
Hashes of the ballot image and ballot layout files are included in the cast vote record report so that the hash (and digital signature) of the cast vote record export will reflect any change to the image or layout files.
The CDF specification allows detailing multiple versions of the same cast vote record as "snapshots."
For hand marked paper ballots, there are both "original" and "modified" snapshots. The "original" snapshot contains mark thresholds for every single bubble on the ballot and is included purely for auditability. The "modified" snapshot contains only the marks that were detected as definite marks and counted as valid or invalid votes.
For machine marked ballots, there is only an "original" snapshot.
The snapshot is referenced in the CVR.CurrentSnapshotId
field by it's identifier, which will be the unique identifier of the cast vote record along with its type, such as
864a2854-ee26-4223-8097-9633b7bed096-modified
The CDF specification does not have any allowance for a ballot type such as "absentee" or "precinct" at the metadata level, so it is added as information to each snapshot:
CDF Attribute | Usage |
---|---|
CVRSnapshot.Status | Fixed to ["other"] |
CVRSnapshot.OtherStatus | JSON blob representing the ballot type. The possible values are "absentee", "precinct", or "provisional".
|
The CVRContest
class within each snapshot contains a list of vote records by contest. The fields are used as follows:
CDF Attribute | Usage |
---|---|
CVRContest.ContestId | The contest identifier from the election definition |
CVRContest.Overvotes | The number of overvotes for a contest. The number can only be 0 or the maximum number of votes in the contest |
CVRContest.Undervotes | The number of undervotes for a contest |
CVRContest.WriteIns | The number of write-ins for a contest |
CVRContest.Status | The list of applicable contest statuses:
|
CVRContestSelection.ContestSelectionId | The option identifier from the election definition |
CVRContestSelection.OptionPosition | The index of the contest position within the contest |
CVRContestSelection.Status | The list of applicable contest selection statuses:
|
SelectionPosition.HasIndication | "yes" or "no" depending on whether a mark in the bubble passed the mark threshold. In the original hand marked paper ballot snapshots, this may be either value. In the modified snapshot, it is always "yes" except for unmarked write-ins. |
SelectionPosition.NumberVotes | Fixed to 1 |
SelectionPosition.IsAllocable | "yes" except:
|
SelectionPosition.MarkMetricValue | The mark score, a decimal between 0 and 1.00 such as 0.23. Only included in the original snapshots. |
SelectionPosition.Status |
|
SelectionPosition.OtherStatus | "unmarked-write-in" if an unmarked write-in |
CVRWriteIn.WriteInImage | The BallotImage data for the side of the sheet on which the write-in occurs |
Ballot images are .jpg
files. They are included in the cast vote record in order to be used for write-in adjudication or auditing. Ballot images are generated by the scanning hardware and then normalized to reduce skew and enforce a consistent orientation. Images from VxCentralScan are in grayscale while images for VxScan are in black and white.
Ballot layouts are JSON files which describe the discovered position of ballot content within interpreted ballots, including where each contest and contest option appears. Although the layout of ballot content within the ballot grid is specified by the election definition, the ballot content may be positioned in a slightly differently location in each scanned ballot image due to offset or skew of the ballot during scanning. As a result, the layouts are included in order to have accurate image highlights and crops for write-in adjudication.
The metadata file includes data that applies to all cast vote records in the export. There is only one per export. The relevant attributes are:
Attribute | Usage |
---|---|
arePollsClosed | For VxScan exports, the flag indicates whether polls where closed at the time of export. If polls were not closed, that may indicate an incomplete export |
castVoteRecordReportMetadata | The cast vote record report without any specific cast vote record data. In other words, only data about the election and its contests |
castVoteRecordRootHash | A hash of all cast vote record files in the export. Including the hash here, which rolls up into the digital signature, ensures that cast vote records cannot be added or removed from the export |
batchManifest | The list of batches on the originating scanner, see below |
Each cast vote record is associated with a batch via its BatchId
metadata field. The CDF doesn't have a place within the cast vote record report to include batch metadata, so it is included here.
Attribute | Usage |
---|---|
id | The UUID of the batch generated by the scanner |
label | The label for the batch |
batchNumber | The sequential number of the batch, e.g. 2 for the second batch |
startTime | The time a batch was started in ISO 8601 format |
endTime | The time a batch ended in ISO 8601 format |
sheetCount | The number of sheets (i.e. cast vote records) in a batch |
scannerId | The serial number of the scanner |