Cast Vote Records

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.

Directory Structure

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.

CVR UUIDs

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.

Including Ballot Images

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.

Including Rejected 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
    - ...

Cast Vote Record Report

CDF Implementation

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.

VxSuite Required Fields

CDF Class
Additionally Required Attributes

CVR

BallotStyleId, BallotStyleUnitId, BatchId, CreatingDeviceId, UniqueId

CVRContest

CVRContestSelection

CVRContestSelection

  • ContestSelectionId

  • SelectionPosition is limited to length 1

CVRSnapshot

CVRContest

Report Metadata

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.

CastVoteRecordReport

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

CastVoteRecordReport.ReportingDevices

Only one ReportingDevice is ever listed:

CDF Attribute
Usage

@id

The scanner serial number

SerialNumber

The scanner serial number

Manufacturer

Fixed to "VotingWorks"

CastVoteRecordReport.Party

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"

CastVoteRecordReport.GpUnit

GpUnits are created for each Precinct in the election, for the County, and for the state:

CDF Attribute
Usage

@id

  • Precinct: The precinct identifier from the election definition

  • County: Fixed to "election-county"

  • State: Fixed to "election-state"

Type

  • Precinct: "precinct"

  • County or State: "other"

Name

The precinct, county, or state name

CastVoteRecordReport.Election

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

Cast Vote Record Attributes

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

Ballot Images

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:

file:864a2854-ee26-4223-8097-9633b7bed096-front.jpg

Hash.Type

Fixed to "sha-256"

Hash.Value

  • No Images: Undefined

  • Images & Layouts: {SHA256 hash of image}-{SHA256 hash of layout}

  • Images Only: SHA256 hash of image

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.

Snapshots

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

Ballot Type

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".

{
  ballotType: "absentee"
}

Representing Votes

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:

  • "not-indicated" - no votes cast in contest

  • "undervoted" - fewer than allowed votes cast in contest

  • "overvoted" - more than allowed votes cast in contest

  • "invalidated-rules" - applies if overvoted

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:

  • "invalidated-rules" - mark is part of an overvote

  • "needs-adjudication" - mark corresponds to a write-in

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:

  • "no" if an overvote

  • "unknown" if an unmarked write-in

SelectionPosition.MarkMetricValue

The mark score, a decimal between 0 and 1.00 such as 0.23. Only included in the original snapshots.

SelectionPosition.Status

  • "invalidated-rules" if an overvote

  • "needs-adjudication" if an unmarked write-in

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

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

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.

Export Metadata

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

Batch Manifest

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

Last updated