- Cast Vote Record (CVR) Examples
These examples show how to use the NIST CVR Common Data Format (1500-103 CDF) to represent various voting scenarios.
- This document uses the ballot semantics model built by the NIST-EAC Election Modeling Working Group.
- Readers of this document are expected to have a working understanding of XML.
This section uses Example 2
The CVR specification permits a wide range of data to be stored in a CVR, ranging from minimal information about the selected contests and contest options to expanded information about all contests on the ballot as well as other items. This section explains the construction of a minimal 1500-103 instance, containing only the contests and candidates that were selected by the voter. It contains two CVRs, each indicating a selection for a candidate in a contest. Each CVR also references an image of the corresponding scanned ballot.
A 1500-103 instance (in XML or JSON) may contain one or more
CVRs
, which in turn must contain one or moreCVRSnapshots
, each representing a CVR at specific point in time.
The file is divided roughly into two parts: the CVR elements at the beginning followed by other elements for defining the election and its contests, candidates, and contest selections so that the CVR elements can link to them as necessary. Lines 205-244 describe an election containing the contest, candidate, and contest selection definitions.
The CVR elements link to these items by using identifiers defined in the contest, candidate, and contest selection's ObjectId
attributes. For example, the contest definition starting on line 228 contains:
<Contest ObjectId="_C1" xsi:type="CandidateContest">
so that CVR elements can link to this contest definition by using the ObjectId
_C1
.
Note that the object identifiers are not the same as the codes that a jurisdiction may use to identify contests or candidates. The object identifiers are entirely unique to a CVR report; the exporting application must add them as it builds the report file. These identifiers are used only as a means for linking contest, contest selections, etc., together within the report file.
Lines 3-204 contain the CVR elements. Each CVR
element includes at least one CVRSnapshot
.
Each
CVRSnapshot
represents a particularType
, such as theoriginal
captured from a scanner, or after it has beeninterpreted
(e.g. after business rules have been applied), or otherwisemodified
.
CVRSnapshot
element includes one or more CVRContest
, which links to the voted contest whose object identifier is _C1
, thereby identifying that contest within the report file. It then includes CVRContestSelection
, which links to a contest option that was selected by the voter.
This section uses Example 1
Consider the following contest:
For Treasurer of State
- Connie Pillich
- Josh Mandel
marked on a ballot marking device (BMD), can be represented with the following XML fragment:
<cdf:CVRContest>
<cdf:ContestId>_5TS</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1ECP</cdf:ContestSelectionId>
<cdf:OptionPosition>1</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
</cdf:CVRContestSelection>
</cdf:CVRContest>
The ContestSelectionId
value of _1ECP
represents the reference to the selected contest option:
<cdf:Candidate ObjectId="_1ECP">
...
<cdf:Name>Connie Pillich</cdf:Name>
...
</cdf:Candidate>
By dereferencing _5TS
, we can see this does indeed represent a contest selection of Connie Pillich for Treasurer of State.
<cdf:Contest xsi:type="cdf:CandidateContest" ObjectId="_5TS">
...
<cdf:Name>For Treasurer of State</cdf:Name>
<cdf:VoteVariation>n-of-m</cdf:VoteVariation>
<cdf:VotesAllowed>1</cdf:VotesAllowed>
</cdf:Contest>
Try it out yourself! Mark and generate your own CVR.
SelectionPosition
is used to state facts about an area on the ballot where a voter's selection in a particular contest can be indicated. This may include its position on the ballot, the number of votes represented by its selection, evidentiary information regarding the existence of a Mark
and determinations, among others.
SelectionPosition
, taken with CVRContestSelection
identifies the location on the ballot where a selection can be made.
Consider the following contest:
Member of County Council at Large
Contest Option | 1st | 2nd | 3rd |
---|---|---|---|
Ilene Shapiro | [x] |
[ ] |
[ ] |
Debbie Walsh | [ ] |
[ ] |
[x] |
Sandra Kurt | [ ] |
[X] |
[ ] |
The selection of Sandra Kurt's contest option corresponds to the following XML fragment:
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HSK</cdf:ContestSelectionId>
<cdf:OptionPosition>3</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Position>2</cdf:Position>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
Sandra Kurt (_1HSK
) position on the ballot is third (row), and the indicated contest position is second (column). This is represented by setting CVRContestSelection/OptionPosition
to 3
and SelectionPosition/Position
to 2
.
SelectionPosition
can be used to convey the selections that are potentially allocable to a contest option. Selections are identified via selection indications. Indications can come from the following sources:
- A
Mark
made by the voter on a paper ballot - A
Mark
made by a marking device onto a full face paper ballot - An indication made by the voter using a DRE
- An indication made by machine as a result applying business rules
- An indication made by an adjudicator
HasIndication
should be determined based on facts about the indication/Mark
alone. This means, for example, thatHasIndication
should be set toyes
, even if its underlying selection is invalided due to contest rules.
SelectionPosition
has an attribute, MarkMetricValue
, which should be used whenever a mark is placed upon a contest option position of a full face paper ballot.
A MarkMetricValue
provides evidence that an indication may exist, however, it does not confirm it. This is the purpose of HasIndication
. It can tell us if the mark met the threshold or logic of a MarkMetricType
to be considered a selection indication for the contest option (machine interpretation), or if adjudication resulted in the capture of a selection (human interpretation).
Mark type | HasIndication |
---|---|
machine-readable mark | yes |
marginally machine-readable mark | unknown |
machine unreadable mark | no |
Table: mapping of mark types to equivalent HasIndication
values
Marks should be treated as indelible. They can be added, but never removed from a CVR instance. Marks
are not shorthand for votes.
Barcodes placed onto a piece of paper (as to represent selections) are not considered marks.
A Mark
may be associated with one or more MarkMetricValue
, which is a implementation dependent measure of a mark.
For example:
...
<cdf:MarkMetricValue>98</cdf:MarkMetricValue>
...
MarkMetricValue
should be used to capture marks that are machine readable only. This usually means marks that fall within the contest selection position. Marks that convey voter intent but fall outside the target area should be handled without the use ofMarkMetricValue
.
When a metric is used, its type (MarkMetricType
) must be specified by the ReportingDevice
playing the role of the CVR
's CreatingDevice
.
<cdf:ReportingDevice ObjectId="rd">
<cdf:MarkMetricType>AJAX</cdf:MarkMetricType>
</cdf:ReportingDevice>
The MarkMetricType
used is expected to be the same for all marks originating from the same CreatingDevice
.
From the above examples, we can see that the mark has a quality measurement of type AJAX (a fictional quality measurement) and quality score of 98 (0 is the worst, 100 is the best).
This section only applies to adjudication done electronically.
If a mark is present, but was not captured in the initial CVR, then it should be indicated with HasIndication
set to yes
and a Status
element set to adjudicated
.
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Status>adjudicated</cdf:Status>
</cdf:SelectionPosition>
Conversely, if a mark is determined to not to exist for a given contest option, then set HasIndication
to no
.
IsAllocable
will always beno
(or omitted) whenHasIndication
isno
.
<cdf:SelectionPosition>
<cdf:HasIndication>no</cdf:HasIndication>
<cdf:IsAllocable>no</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Status>adjudicated</cdf:Status>
</cdf:SelectionPosition>
IsAllocable
tells us whether the selection (and the associated number of votes) should be allocated to the contest option's accumulator (counter).
Previous drafts of the spec used a complex set of statuses that the consumer was required to interpret. By using a single flag, we know if the mark counts, and the statuses can tell us why.
The value of
IsAllocable
should singularly determine ifNumberVotes
will be allocated to a contest option's accumulator.
If an indication was generated by machine, such as in the indirect selections of straight party voting, then use SelectionPosition
directly.
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:IsGenerated>yes</cdf:IsGenerated>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
This section only applies to paper ballots.
Consider the following contest:
For Treasurer of State
- Connie Pillich
- Josh Mandel
Can be represented with the XML below:
<cdf:CVRContest>
<cdf:ContestId>_5TS</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1ECP</cdf:ContestSelectionId>
<cdf:OptionPosition>1</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>no</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>0</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1EJM</cdf:ContestSelectionId>
<cdf:OptionPosition>2</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>no</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>0</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:Overvotes>1</cdf:Overvotes>
<cdf:Undervotes>0</cdf:Undervotes>
</cdf:CVRContest>
Note that the votes are still accounted for, even though the votes will not be allocated to the contest option accumulators for Connie Pillich nor John Mandel, but instead to the overvote accumulator.
If the CVR producer wants a downstream processor to adjudicate the selection indications, it should set
IsAllocable
tounknown
.
Consider the following contest:
Governor
- Edward FitzGerald
- John Kasich
- Anita Rios
- Write-In (John Smith)
can be represented with the following XML fragment:
<cdf:CVRContest>
<cdf:ContestId>_1GO</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:OptionPosition>4</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:CVRWriteIn>
<cdf:Text>John Smith</cdf:Text>
</cdf:CVRWriteIn>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>unknown</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
<cdf:Status>needs-adjudication</cdf:Status>
</cdf:CVRContestSelection>
</cdf:CVRContest>
Note that this fragment is the original
CVR from the CreatingDevice
, and thus we do not yet know the validity of the write-in. Still we can say some things about it.
The text of the write-in is John Smith
. This is represented using the Text
element.
SelectionPosition
represents both the selection of the write-in contest option and the write-in itself. Thus it is not possible to say that the selection of the write-in option is valid, but the write-in name provided is not.
If John Smith was determined to be a valid write-in, then the following may occur:
IsAllocable
is set toyes
CVRContestSelection
is linked to theContestSelection
associated with the candidate.
Some systems may not be capable of tabulating votes for the candidate underlying a write-in.
If desired, the CVRContest
may contain the number of WriteIns
, i.e the number of write-in contest options selected. This includes options that were selected, but no candidate was specified (e.g. a filled oval with an empty line).
Adjudication can do two things
-
Determine if the name represents a valid write-in option, i.e. does the write-in text represent a valid write-in option?
-
Determine if the contest selection should be allocated. This is different from (1), as even if it is determined that the write-in text represents a valid write-in option, it may be overwritten by interpretation of voter intent.
A CVR can be used throughout various points in the election lifecycle:
- Capture of contest selections
- Interpretation of contest selections
- Adjudication of contest selections
- Other operations
If a downstream system needs to modify the CVR, such as to add a CVRContestSelection
as the result of adjudication, a new CVRSnapshot should be created.
Consider the following XML fragment:
<cdf:CVRSnapshot ObjectId="css-02">
<cdf:CVRContest>
<cdf:ContestId>_6RC</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1FMZ</cdf:ContestSelectionId>
<cdf:OptionPosition>1</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>unknown</cdf:HasIndication>
<cdf:MarkMetricValue>76</cdf:MarkMetricValue>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
</cdf:CVRContestSelection>
</cdf:CVRContest>
<cdf:Status>needs-adjudication</cdf:Status>
<cdf:Type>original</cdf:Type>
</cdf:CVRSnapshot>
This represents a CVR having a single marked contest, in which the indication is unknown
(e.g. the mark is marginal). The Status
of the CVRSnapshot
is needs-adjudication
so as to flag a downstream system or process.
An adjudicator takes a look at the ballot, and determines that mark is a result of the voter resting their pen on the contest option position, and not voter intent to make a selection for Mark Zetzer
. Thus, HasIndication
is set to no
, and a new CVRSnapshot
is created recording this action:
...
<cdf:CVRSnapshot ObjectId="css-03">
<cdf:Annotation>
<cdf:AdjudicatorName>Mark Kennamond</cdf:AdjudicatorName>
<cdf:Message>Resting Mark, Mark Zetzer</cdf:Message>
<cdf:TimeStamp>2018-05-16T12:10:09</cdf:TimeStamp>
</cdf:Annotation>
<cdf:CVRContest>
<cdf:ContestId>_6RC</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1FMZ</cdf:ContestSelectionId>
<cdf:Position>1</cdf:Position>
<cdf:SelectionPosition>
<cdf:HasIndication>no</cdf:HasIndication>
<cdf:Mark>
<cdf:MarkMetricValue>76</cdf:MarkMetricValue>
</cdf:Mark>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
</cdf:CVRContestSelection>
</cdf:CVRContest>
<cdf:Type>interpreted</cdf:Type>
</cdf:CVRSnapshot>
Information about the adjudication is conveyed via the Annotation
element. We can see the name of the adjudicator and the a description of the changes to the CVR. There can be as many Annotation
elements as required to describe the changes made to the CVR.
Each
CVRSnapshot
should represent a set of changes to a CVR during a phase of processing. It is not necessary to create a separateCVRSnapshot
for every change.
If a system is looking to tabulate a set of CVRs, it must know for each CVR
, which CVRSnapshot
is the currently tabulatable record. This is achieved through a CurrentSnapshot
reference from CVR
to the CVRSnapshot
that should be used.
If a scanner is capable of capturing raster ballot images, then that data can be stored alongside the structured CVR.
Ballot images can either be referenced from the CVR as a URI, or stored within it, as base64
encoded binary.
<BallotImage>
<Location>http://192.168.1.1/imageserver/ballot1056.jpeg</Location>
</BallotImage>
<BallotImage>
<Image FileName="CVR1_Ballot.jpg" MimeType="image/jpeg">Q1ZSIEltYWdl</Image>
</BallotImage>
The NIST CVR CDF supports all major voting methods currently in use in the United States.
Consider the following contest:
Member of County Council at Large
Contest Option | 1st | 2nd | 3rd |
---|---|---|---|
Ilene Shapiro | [ ] |
[x] |
[ ] |
Debbie Walsh | [x] |
[ ] |
[ ] |
Sandra Kurt | [ ] |
[ ] |
[x] |
Table: Representation of a RCV contest
<cdf:CVRContest>
<cdf:ContestId>_9CC</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HIS</cdf:ContestSelectionId>
<cdf:OptionPosition>2</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Rank>2</cdf:Rank>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HDW</cdf:ContestSelectionId>
<cdf:OptionPosition>3</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Rank>1</cdf:Rank>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HSK</cdf:ContestSelectionId>
<cdf:OptionPosition>6</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Rank>3</cdf:Rank>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:Undervotes>0</cdf:Undervotes>
</cdf:CVRContest>
Each candidate may be ranked using the Rank
attribute. The rank may or may not be the same as the Position
.
Try it out yourself! Mark and generate your own RCV CVR.
Consider the following contest:
Member of County Council at Large
Contest Option | 1st | 2nd | 3rd |
---|---|---|---|
Ilene Shapiro | [ ] |
[x] |
[ ] |
Debbie Walsh | [x] |
[ ] |
[x] |
Sandra Kurt | [ ] |
[ ] |
[ ] |
Table: Representation of a cumulative voting contest
If the ballot was hand marked, then the following CVR could be constructed:
<cdf:CVRContest>
<cdf:ContestId>_9CC</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HIS</cdf:ContestSelectionId>
<cdf:OptionPosition>2</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Position>2</cdf:Position>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HDW</cdf:ContestSelectionId>
<cdf:OptionPosition>3</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Position>1</cdf:Position>
</cdf:SelectionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
<cdf:Position>3</cdf:Position>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>2</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:Undervotes>1</cdf:Undervotes>
</cdf:CVRContest>
Because Debbie Walsh received two votes, she has two SelectionIndications
.
If the same vote was cast on a ballot marking device, the CVR could be simplified somewhat:
<cdf:CVRContest>
<cdf:ContestId>_9CC</cdf:ContestId>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HIS</cdf:ContestSelectionId>
<cdf:OptionPosition>2</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>1</cdf:NumberVotes>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>1</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:CVRContestSelection>
<cdf:ContestSelectionId>_1HDW</cdf:ContestSelectionId>
<cdf:OptionPosition>3</cdf:OptionPosition>
<cdf:SelectionPosition>
<cdf:HasIndication>yes</cdf:HasIndication>
<cdf:IsAllocable>yes</cdf:IsAllocable>
<cdf:NumberVotes>2</cdf:NumberVotes>
</cdf:SelectionPosition>
<cdf:TotalNumberVotes>2</cdf:TotalNumberVotes>
</cdf:CVRContestSelection>
<cdf:Undervotes>0</cdf:Undervotes>
</cdf:CVRContest>
The representation of the indication for Ilene Shapiro is unchanged, but Debbie Walsh's votes have been consolidated into a single SelectionIndication
, with a NumberVotes
of 2
.