4 — System Architecture
This section describes the technical system — how the pieces of the Actual Vote ecosystem fit together. The conceptual case for why the system exists is in Section 2. The operational case for how to use it is in Section 7 and Section 10. The methodology for analyzing what it produces is in Section 8. This section is the technical model: what the parts are, how data flows between them, and what each component contributes to the quality of the evidence.
There are eight subsections. Section 4.1 provides the system overview and data flow. Section 4.2 describes the recording layer (the Actual Vote app). Section 4.3 describes the vetting layer (human review of submissions). Section 4.4 describes the analysis layer (the comparison pipeline) as the labor it has historically been. Section 4.5 defines the formal data model — the object types, relationships, and taxonomies that structure the system’s data. Section 4.6 documents the Actual Vote Video Archive in detail, since users interact with it directly and it is the canonical record of every submission. Section 4.7 addresses accessibility and inclusion. Section 4.8, new to this edition, documents Actual Vote Assist (AVA) — the engineered pipeline that now automates most of the analysis layer under human guidance.
A reader who wants the big picture can read Section 4.1 alone. A reader who will be using the app should also read Section 4.2 and Section 4.6. A reader who wants to understand how evidence gets from recording to finding should read Section 4.1 through Section 4.5 in sequence. A reader who wants the engineering detail of how the comparison is actually computed today should read Section 4.8.
4.1 — System Overview
Three-layer architecture
The Actual Vote system has three functional layers, each serving a distinct role in the evidence production process.
The recording layer is where evidence enters the system. It consists of the Actual Vote app and the people who use it. Users go to polling places after polls close, video-record the publicly posted poll tapes, and submit the recordings through the app. The app captures the video, timestamps, GPS coordinates, and user-entered metadata (precinct identifier), and uploads everything to the Actual Vote Video Archive. The recording layer’s job is to produce raw evidence with correct metadata attached.
The vetting layer is where raw submissions are reviewed for quality, completeness, and privacy compliance before they become part of the public record. This layer is staffed by America Counts team members who examine each submission, check it against a set of criteria, and either approve it (making it publicly visible in the archive), reject it (keeping it private), or flag it for re-recording. The vetting layer’s job is to ensure that only evidence meeting AC’s quality standards enters the comparison pipeline.
The analysis layer is where vetted submissions are turned into findings. This layer consists of the comparison pipeline — the nine-step process described in full in Section 8 — which takes transcribed poll tape values, matches them against officially reported results, investigates any discrepancies, and produces findings about the accuracy of vote reporting. The analysis layer’s job is to transform raw evidence into defensible conclusions.
Data flow
The data flow through the system follows a linear sequence with quality gates at each transition:
Recording → Submission → Vetting → Transcription → Comparison → Investigation → Publication
At the recording stage, a user creates a video with metadata. At submission, the video is uploaded to the archive and assigned a unique integer ID. At vetting, an AC team member reviews the submission and classifies it (approved, rejected, practice, context, or other categories). At transcription, the numeric values visible on approved poll tapes are manually extracted and entered into a structured spreadsheet. At comparison, the transcribed values are matched against the corresponding officially reported values using jurisdiction-specific comparison logic. At investigation, any initial non-matches are subjected to the seven-check investigation process (Section 8.9). At publication, the findings are compiled into a report — either the static analysis report format or the rolling operational log format — and published on the America Counts website.
Each stage serves as a quality gate for the next. A submission that fails vetting never enters transcription. A transcription that cannot be matched against official results because the comparison logic is unclear is held until the logic is resolved. A discrepancy that is not thoroughly investigated is not reported as confirmed. The linear flow with quality gates is what produces the methodological rigor that distinguishes AC’s work from less careful approaches.
The role of each component in maintaining evidence quality
Every component of the system contributes to the quality of the evidence in a specific way.
The app contributes metadata integrity. By automatically capturing GPS coordinates and timestamps at the moment of recording, the app provides provenance data that does not depend on the user’s memory or notes. The metadata is part of the chain of custody — it establishes when and where the recording was made.
The vetting process contributes quality control and privacy protection. Vetters check that recordings are legible, that they depict the correct type of poll tape (a results tape, not a zero tape or test tape), that no personally identifying information is visible (faces, names, addresses, license plates), and that the metadata is consistent with what the video shows. Vetting prevents bad data from entering the pipeline and prevents privacy violations from reaching the public archive.
The transcription process contributes data extraction accuracy. Transcription can be done by hand — a human watches the video and enters the numbers into a spreadsheet — and for years that was the only reliable option, because off-the-shelf optical character recognition could not read the thermal-printed fonts on most poll tapes. The hand process is described in Section 4.4 and Section 8.6. It is now, in most cases, performed automatically: Actual Vote Assist (Section 4.8) reads the tapes with AI vision OCR under human guidance and routes only its uncertain reads to a person. Whether by hand or by AVA, the governing discipline is the same — uncertainties are flagged for review rather than silently resolved.
The comparison logic contributes analytical precision. Building the comparison logic for each jurisdiction requires understanding how that jurisdiction’s official results are structured — at what level of granularity results are reported, how voting methods are categorized, how write-ins and provisional ballots are handled, and what aggregation rules apply. Getting this right is one of the hardest parts of the pipeline and one where AC has accumulated significant institutional knowledge across multiple election cycles.
The investigation process contributes intellectual honesty. Before any discrepancy is reported externally, every non-match is subjected to a thorough internal review that systematically considers whether the difference is an artifact of AC’s own process or a discrepancy. The review checks for transcription errors, matching errors, missing poll tapes, duplicate poll tapes, aggregation logic errors, undocumented vote reporting logic, and operational context that might explain the difference. As documented in Section 8.9, “we did the comparison wrong” is one of the most common outcomes of reviewing an initial non-match.
Technical backend overview
The current technical infrastructure has three layers. The user-facing layer consists of the iOS and Android apps, built natively for each platform. The cloud services layer consists of the Actual Vote Video Archive web application hosted on Microsoft Azure, the API endpoints used by the apps for upload and authentication, the database storing submission metadata and user accounts, and the file storage for video recordings. The analysis pipeline layer currently uses Google Drive folders that store working materials for each analysis: submission inventories, transcription spreadsheets, comparison logic files, intermediate processing outputs, and final reports.
The split between the professional cloud services (Layer 2) and the informal Google Drive pipeline (Layer 3) reflects the system’s evolutionary development. The user-facing components were built professionally from the start; the analysis pipeline grew organically around AC’s working processes using the most accessible tools available. AC acknowledges this split as suboptimal and has identified a modernization workstream that would migrate the analysis pipeline to database-backed storage with formal schema, artifact versioning, workflow automation, better tooling for human review, and API access for derived applications. The modernization workstream has been scoped but not yet resourced.
The technical data standards — including the unique ID format, folder structure, CSV field names, and comparison output schema — are documented in B.10.
4.2 — The Recording Layer: The Actual Vote App
What the app does
The Actual Vote app is the user-facing front end of the system. It runs on iOS (iPhone, iPad) and Android (phone, tablet). It is published by America Counts and is free.
The app’s job is to make it easy and reliable for a user to video-record a poll tape and have that recording end up in the Actual Vote Video Archive with the right metadata attached. Concretely, the app does the following:
Authenticates the user. A user must have an account to submit recordings. Authentication is currently via Google sign-in, with email-and-password as the alternative. The account exists primarily so that submissions can be associated with a submitter for chain-of-custody purposes. The Privacy Policy (B.4) details what data is and is not retained.
Records video and audio. The user holds the phone in front of the poll tape and presses record. The app uses the device’s standard camera and microphone hardware. There is no special-purpose video processing on-device — the recording is a normal video file.
Captures metadata. Alongside the video, the app captures the recording timestamp (from the device clock) and the GPS coordinates (from the device’s location services, if permission is granted). It also prompts the user to enter a precinct identifier (a free-text field) so that the recording can be associated with a specific polling place when GPS coordinates are ambiguous or when the polling place serves multiple precincts.
Uploads the recording. When the device has a network connection, the app uploads the recording and its metadata to the Actual Vote Video Archive backend. Uploads are queued if the network is unavailable and retried later. The upload is automatic once connectivity is established.
Confirms success. Once a recording has been successfully uploaded, the app shows the user a confirmation. The user can then see the recording in the My Actual Vote Videos tab of the archive.
What the app deliberately does not do
The app deliberately does not transcribe, analyze, score, display recommendations, communicate directly with election officials, or engage in any kind of polling or voter outreach. The single-purpose design is intentional: the more the app does, the harder it is to argue that it is a neutral data-collection tool, and the harder it is to maintain the regulatory and trust posture that makes Actual Vote work.
iOS and Android availability
The app is available in both major app stores, but availability is not always guaranteed. In November 2024, the Google Play Store classified Actual Vote as “government information” and rejected several builds in the days leading up to the general election, delaying the launch of the latest Android version until November 8 — after election day. This reflects an ongoing tension between America Counts and app store gatekeepers who face their own pressures regarding politically-charged apps. America Counts maintains the app’s compliance with all relevant store policies, but the rejection process is opaque and unpredictable.
Users who cannot install or update the app have a fallback: they can record with their device’s native camera app and email the recordings to America Counts, upload them via Google Drive, or use other file-sharing methods. The recordings produced this way are functionally identical — a video file with GPS and timestamp metadata embedded by the device — but they lack the in-app metadata fields (precinct identifier) and must be manually processed by AC during intake. Section 10.11 documents the troubleshooting protocol for app failures.
Offline recording capability
The app supports offline recording. If the device does not have network connectivity at the time of recording (common at rural polling places or in basements where cell signal is weak), the recording is saved locally on the device and queued for upload. When connectivity is restored, the upload proceeds automatically. This design means that users do not need to worry about connectivity during the critical recording window — the evidence is captured regardless.
The practice poll tape training feature
America Counts publishes a sample practice poll tape as a printable PDF. New users are encouraged to download it, print it, and practice the recording technique against it using the app’s practice mode. A practice recording produced this way is a valid submission — it enters the system and is preserved in the user’s My Actual Vote Videos tab — but it is classified as a practice submission and is not transcribed for analysis purposes. The practice tape’s values do not correspond to any real election.
The practice feature serves two purposes. It gives users experience with the physical mechanics of recording a poll tape (holding the phone steady, panning slowly enough for legibility, capturing the full tape from header to footer) before they are in the time-pressured environment of a polling place on election night. It also gives AC a way to identify users who are engaged and ready to deploy, since a user who has completed a practice recording has demonstrated both intent and capability.
4.3 — The Vetting Layer
What vetting means
Vetting is the human review of each submission for quality, privacy, and completeness. Every submission that enters the Actual Vote system — whether from the app, from emailed videos, or from any other intake method — passes through vetting before it can be classified as approved and made publicly visible in the archive.
Vetting is not a rubber stamp. It is a substantive review that checks whether the recording meets the standards necessary for it to serve as evidence. Recordings that fail vetting are not destroyed — they remain in the system and are visible to the submitter via the My Actual Vote Videos tab — but they are not published and do not enter the comparison pipeline.
Vetting criteria
The vetter evaluates each submission against several criteria:
Legibility. Is the poll tape readable in the video? Can the contest names, candidate names, and vote totals be discerned? A recording that is too blurry, too dark, too shaky, or too far away to read may be classified as not-practical-to-transcribe even if it is otherwise legitimate.
Correct poll tape type. Is this a results tape (printed at the close of polls, showing vote totals) rather than a zero tape (printed before polls open, showing all zeroes to confirm the machine starts empty) or a test tape? The distinction matters because only results tapes produce values that can be compared against official results.
No personally identifying information visible. The vetter checks for faces, names, addresses, license plates, health information, or any other PII that may have been captured incidentally. Poll tapes themselves do not contain voter PII, but the recording environment — a polling place at closing time, with poll workers and possibly voters still present — can. If PII is visible, the submission may be rejected or the submitter may be asked to re-record with the PII cropped out.
Metadata consistency. Do the GPS coordinates match a known polling place location? Is the timestamp consistent with the date and time of the election? Metadata inconsistencies do not automatically disqualify a submission (a user might have recorded with location services disabled, producing no GPS data), but they are flagged for the record.
Approval, rejection, and re-recording workflows
Submissions that pass vetting are classified as approved and become visible in the public archive. Submissions that fail vetting are classified as rejected with a reason noted in the comment field. In some cases, the vetter contacts the submitter to request a re-recording — for instance, if the original recording captured the right tape but was too blurry to read, the user may be able to return and record again (timing permitting).
The vetting workflow includes several classification outcomes beyond simple approve/reject. A submission may be classified as a context submission — depicting something important other than poll tape values, such as tapes posted behind a window where they cannot be read, tapes that were not posted when they should have been, or other observations about conditions at the polling place. Context submissions may not produce transcribable values but they document the operational environment and may be relevant to compliance findings.
The vetter’s role in privacy protection
Privacy protection during vetting is not merely a quality-control measure — it is part of AC’s commitment to the safety and dignity of people captured incidentally in recordings. Poll workers, voters, and bystanders who appear in recordings did not consent to being part of AC’s archive. AC’s responsibility is to ensure that no one is identifiable in the public archive unless their identity is an inherent part of the evidence (as when a poll worker’s signature appears on a poll tape as part of the closing procedure).
The vetting privacy check covers faces, names, addresses, license plates, visible health information, and any other information that could identify an individual. When such information is detected, the vetter determines whether it can be removed (by cropping or re-recording) or whether the submission must be rejected for the public archive while retained privately for analysis purposes only.
4.4 — The Analysis Layer: The Comparison Pipeline
Overview
The analysis layer is where vetted submissions are transformed into findings about the accuracy of vote reporting. The full pipeline — the nine-step Comparison Analysis — is documented in detail in Section 8 (Methodology). This subsection provides the architectural overview: what the pipeline does, what its components are, and how it fits into the broader system.
Transcription
The first step of the analysis pipeline after vetting is transcription: extracting the numeric values visible on each approved poll tape and entering them into a structured spreadsheet. Each transcribed value is associated with a submission ID, a contest name, a choice name, a voting method, and the numeric value itself. A typical transcribable submission produces between a few dozen and a few hundred transcribed values, depending on how many contests are on the ballot.
Transcription can be done manually, and this subsection describes that baseline because it is the clearest way to understand what the step accomplishes. A trained transcriber watches the video, identifies each contest-choice-value triple, and enters the data into a spreadsheet. This is slow but accurate — and critically, it allows the transcriber to flag uncertainties (an ambiguous digit, a partially obscured value, a tape that appears to have been printed with low ink) rather than silently resolving them the way a naïve automated system might. The transcribed dataset is the foundation on which all comparison findings rest; its accuracy is non-negotiable.
The same step is now, in most cases, performed by Actual Vote Assist (AVA) — an engineered pipeline that reads the tapes with AI vision OCR, reconciles each value across multiple video frames, compares the reads against official results automatically, and surfaces only its uncertain reads and discrepancies to a human. AVA does not replace human judgment so much as relocate it: a person still excludes unusable recordings up front, supplies the list of valid contest-choice combinations that tells the OCR what the tape should contain, and adjudicates everything the system flags. Section 4.8 documents AVA in full, including why fully unattended automation is infeasible and how the human-in-the-loop design makes the automated path acceptably reliable. The rest of this subsection describes the analysis layer in terms that hold whether the reading is done by hand or by AVA.
Comparison logic development
Before transcribed values can be compared against official results, AC must build the comparison logic for the specific jurisdiction and election. This requires understanding how the jurisdiction structures its official results: at what level of granularity results are reported, how voting methods are categorized, how contest and choice names are formatted, how write-ins and provisional ballots are handled, and what aggregation rules apply.
The comparison logic varies by jurisdiction. Some jurisdictions report results at the precinct level for each voting method (making direct comparison straightforward). Others report at the county level only for certain voting methods (requiring AC to aggregate transcribed values before comparing). Some jurisdictions use contest names on their official results that differ from the contest names printed on poll tapes, requiring a mapping table. The comparison logic is jurisdiction-specific, election-specific, and must be figured out anew (or verified against prior experience) for each Actual Vote analysis.
This step is documented in detail in Section 8.6. The key architectural point is that the comparison logic is not a fixed algorithm — it is a set of rules inferred from the structure of each jurisdiction’s official results and verified through the comparison process itself.
Comparison execution
With transcribed values on one side and official results on the other, and comparison logic connecting them, the comparison step is the automated matching process. The Python scripts that perform the comparison take the transcribed dataset, apply the comparison logic (including any necessary aggregation of values from multiple poll tapes), and match each aggregated transcribed value against the corresponding official value.
The output is a set of comparisons, each of which is, on first pass, either an exact match or an initial non-match (the values differ) that review then triages into a match or a discrepancy.
Investigation
Initial non-matches are the starting point for investigation, not the conclusion. The seven-check investigation process documented in Section 8.9 systematically triages each initial non-match to determine whether it is an artifact of AC’s own process or a discrepancy. The checks cover transcription errors, matching errors, missing poll tapes, duplicate poll tapes, aggregation logic errors, undocumented vote reporting logic, and operational context.
Investigation is where the most rigorous methodological work happens. Many initial non-matches resolve as cases where AC’s comparison logic had an error that the non-match itself revealed. The error gets fixed, the comparison is re-run, and the non-match either resolves to a match or sharpens into a discrepancy. This iterative process is central to the methodology’s credibility.
Publication
The findings from the investigation phase are compiled into a report. Two report formats are currently in use: the static analysis report (a comprehensive document published once the analysis is complete, modeled on the NC 2024 primary report) and the rolling operational log (a live-updated page during an active analysis, modeled on the 2024 General Election News Page). Both formats are described in Section 12 (Findings and Reports).
Publication is the point at which AC’s work enters the public domain. Every published finding is backed by the full chain of evidence from recording through investigation, and the underlying data is preserved in the archive for independent verification.
4.5 — The Data Model
Purpose and scope
This subsection defines the formal object types in the Actual Vote system and the relationships between them. The preceding subsections (Section 4.2 through Section 4.4) describe the three layers functionally — what they do and how they work. This subsection provides the conceptual data model: the things that have names, the rules for how they are created, and how they relate to each other. These definitions are canonical throughout the manual and throughout AC’s published work.
The model has six core object types: submissions, transcribed values, comparisons, official-results versions, analyses, and findings — with the comparison-outcome classification (a comparison’s status and lineage) layered on comparisons. Each is defined below.
Submissions
A submission is the atomic unit of input to the Actual Vote system. A submission is what a user creates when they video-record one specific thing and that recording (or set of recordings) ends up in the archive.
The “one specific thing” rule determines the submission boundary. The boundary is set by what is being depicted, not by the number of video files or the duration of the recording. If a user records one poll tape from start to finish in a single video file, that is one submission with one transcribable content. If a user records one poll tape across two video files because they had to restart the recording partway through — the phone died, the user got interrupted, the video got too long — that is still one submission with one transcribable content; the transcriber stitches the two files together when extracting values. If a user records one video file that shows two distinct poll tapes back-to-back, that is one submission with two transcribable contents, and the transcriber extracts values from each tape shown in the file. If a user records two separate video files, each showing a different poll tape, those are two submissions.
Each submission has a unique integer ID assigned by the archive system. The ID is persistent and serves as the canonical reference for the submission throughout the AC pipeline — in transcription spreadsheets, comparison code, investigation notes, published reports, and all written communication.
Submissions are categorized by type. The full taxonomy is:
| Submission type | Definition | Counted in totals? |
|---|---|---|
| Submission (general) | Any video uploaded via the Actual Vote app or sent directly to America Counts. The base category. | Yes (all submissions are counted in raw totals) |
| Practice Submission | A submission intentionally recording a practice poll tape, used for user training and onboarding. Visible only to the submitter via the My Actual Vote Videos tab. | Yes for volunteer-effort metrics, no for analysis metrics |
| Approved Submission | A submission that has passed vetting. Has usable content, no disqualifying privacy issues, not a practice recording. Appears on the public Actual Vote Video Archive. | Yes |
| Rejected Submission | A submission that failed vetting. Common reasons: contains personally identifying information, no usable content, inappropriate material. Not published. Visible to the submitter via My Actual Vote Videos. | Yes as a count of vetting workload, no for analysis |
| Transcribable Submission | An approved submission depicting one specific poll tape, with state, county, election date, voting method, and precinct clearly readable in the header, and containing at least one legible contest/choice/vote total triple. This is the category that feeds the comparison pipeline. | Yes — this is the key denominator for analysis reporting |
| Not-practical-to-transcribe Submission | An approved submission with poll tape content that is legitimate but not reasonably transcribable. May be too blurry, partial, or in a format that does not allow direct comparison. | Yes as a count, no for comparisons |
| Context Submission | An approved submission that depicts something important other than poll tape values — poll tapes posted behind a window where they cannot be read, poll tapes not posted when they should be, the entrance to a polling place, or other observations about conditions on the ground. | Yes (as evidence of conditions and volunteer effort) |
| Analyzed Submission | A transcribable submission whose values have been entered into the comparison pipeline and matched against official results. | Yes |
The distinction between “total submissions” and “transcribable submissions” matters for reporting. Total submissions measure volunteer effort and system throughput; transcribable submissions measure what can actually feed the analysis pipeline. The NC 2024 primary report’s headline number “Total Transcribable Submissions: 52” is the latter, not the former.
Context submissions deserve particular attention. Most context submissions do not generate any follow-up — they are documented for completeness and that is the end of it. But some context submissions warrant follow-up. If a county is far out of compliance with poll tape posting law and a context submission documents this, that finding may warrant escalation. Context submissions are reviewed individually as part of the Comparison Analysis (Section 8.9).
Transcribed values
A transcribed value is a single number read from one poll tape and entered into the transcription spreadsheet. Each transcribed value is associated with the submission it came from (by submission ID), the poll tape on the submission (most submissions have one tape, some have multiple), the contest the value is for (such as “President of the United States”), the choice within that contest (such as “Joe Biden” or “Donald Trump”), the voting method (such as “Election Day” or “Early Voting”), and the number itself (such as 247).
A typical transcribable submission produces somewhere between a few dozen and a few hundred transcribed values, depending on how many contests are on the ballot and how many voting methods the tape covers. To give a concrete sense of scale: the NC 2024 primary report covered 52 transcribable submissions and produced 4,625 transcribed values — an average of about 89 values per submission.
Transcribed values are the atomic unit of data in the comparison pipeline. They are the things that get compared against official results.
Comparisons and aggregation
A comparison is the matching of one or more transcribed values against one corresponding officially reported value, evaluated against a specific official-results version. On its first pass it is either an exact match or an initial non-match.
The “one or more” is important. In the simplest case, one transcribed value maps to one official value: the poll tape says 247 for Biden in Election Day at Precinct 03A, the official results say 247 for Biden in Election Day at Precinct 03A, and the comparison succeeds. But this simple case is not universal. Many comparisons require aggregating multiple transcribed values before matching against one official value. The most common reason is that a single precinct may have multiple voting machines on Election Day, each producing its own poll tape with its own values. The official Election Day total for that precinct is the sum of the values from all machines. The corresponding comparison must sum the transcribed values from each tape before matching against the single official total.
The aggregation logic is specific to each jurisdiction and election. Figuring it out is one of the harder parts of building the comparison logic for an Actual Vote analysis. Section 8.6 describes this in detail.
A comparison’s first pass yields one of two results. An exact match occurs when the aggregated transcribed values equal the official value; this is the typical case. An initial non-match occurs when they differ — a first-pass mismatch, for any reason, which review then triages. An initial non-match is not yet a discrepancy: most are AC’s own errors (transcription, matching, aggregation) and are corrected to a match, while the rest are discrepancies. The full set of states a comparison can reach — match, likely attributable discrepancy, apparent discrepancy, escalatable, escalated, true discrepancy — is the comparison-outcome classification described below.
Two attributes ride on every comparison. Its status is its current state in that classification, evaluated against the current official-results version and updated in real time. Its lineage is the story of how it reached that status — orthogonal to the status, and the place a noteworthy history (an apparent discrepancy an office acknowledged and restated, say) is recorded even when the current status is simply “match.”
Because official results evolve — an unofficial election-night tally, later amendments, the certified result, and rarely a post-court restatement — a comparison is evaluated against a specific official-results version, and its status (and any true discrepancy) is relative to that version. A reporting error confirmed against the election-night numbers and restated before certification was a true discrepancy in that earlier version and a match against the certified one.
The relationship between submissions, transcribed values, and comparisons is a one-to-many cascade with aggregation at each step. The NC 2024 primary report had 52 transcribable submissions, which produced 4,625 transcribed values, which (after aggregation) fed into comparisons covering a total of 321,502 audited votes. The 2024 General Election News Page reports per-state comparison counts: 4,045 for North Carolina, 399 for Florida (Broward County only), 326 for Georgia.
The County/Precinct/Voting Method triple
The County/Precinct/Voting Method triple is the 3-tuple that identifies the specific jurisdiction × ballot-type combination that a poll tape represents. In most US jurisdictions, one triple corresponds to one logical poll tape: the Election Day tape for Wake County’s Precinct 03A is one triple, the Early Voting tape for the same precinct is a separate triple, and a different precinct in the same county is a third triple.
The triple is conceptual, not necessarily physical. Some triples are produced by multiple physical poll tapes (multiple tabulators in one precinct each producing their own tape, all of which together represent the Election Day votes for that precinct). Some triples may have multiple submissions of various types (duplicate recordings from different users, context submissions, rejected submissions). Some triples may be “synthetic” — constructed for reporting purposes that combine values from multiple physical sources.
The triple is the unit at which discrepancies are typically reported. The NC 2024 primary report’s headline finding was “Number of County/Precinct/Voting Method Triples With Apparent Discrepancies: 0” — meaning that across all triples that had transcribed values comparable against official values, none had a discrepancy that survived investigation.
The comparison grain
The comparison grain is the set of dimensions at which a specific Actual Vote analysis performs comparisons. It is determined per analysis by inspecting the structure of the official results that the relevant jurisdiction publishes for the election in question.
The typical comparison grain is County × Precinct × Voting Method × Contest × Choice. This is what most analyses use and what the NC 2024 primary report used. This phrasing should be used when describing the general case.
The typical grain is not universal, however. It is specific to each analysis and reflects the structure of that jurisdiction’s official results. Georgia provides the clearest example: Early Voting in Georgia is reported at the vote-center level rather than the precinct level, so poll tapes from a single Early Voting vote center cannot be matched against precinct-level Early Voting totals — there are no such totals to match against. The comparison grain for Early Voting in Georgia therefore includes the vote center rather than the precinct. Similarly, in some North Carolina counties, certain voting methods are reported only at the county level; the comparison grain for those methods omits the precinct dimension entirely. In jurisdictions with combined or consolidated precincts, the precinct dimension may be more or less granular than expected.
The comparison grain is one of several things scoped per analysis. Others include the list of in-scope voting methods, the state-specific terminology mapping, and the inferred comparison logic. Each of these is figured out as part of the comparison logic step (Section 8.6) and recorded as part of the analysis’s permanent artifacts.
The Actual Vote Analysis
An Actual Vote analysis is one complete unit of work: one specific election in one specific state, encompassing all submissions, transcriptions, comparisons, investigations, and findings needed to produce one final report.
The scope rule: America Counts defines the scope of an Actual Vote analysis as any vote reporting in one specific election for one specific state. An Actual Vote analysis typically covers multiple counties in that state. A different election in the same state, or a different state in the same election, is a separate Actual Vote analysis.
Each Actual Vote analysis has a unique identifier of the form [date]_[country]_[state]_[county], where the date is the election date in YYYYMMDD format, the country is usa, the state is the two-letter postal code, and the county is either the specific county name (lowercased) or the literal multi for multi-county analyses. The county component is preserved even for multi-county analyses (using _multi) because it emphasizes that each analysis corresponds to one unit of reporting logic with its own processing methodology — different counties in the same state can require very different comparison logic. Examples: 20240305_usa_nc_multi is the North Carolina March 5, 2024 primary election analysis, covering seven counties; 20210803_usa_oh_summit is the Summit County, Ohio, August 3, 2021 election analysis (single county).
The formal term is “Actual Vote analysis” — the brand capitalized, the noun lowercase (in titles and headings it takes title case, “Actual Vote Analysis”). The variants “Actual Vote audit” and “vote reporting audit” mean the same thing and are acceptable in less formal contexts. “Audit” is the proper technical term for the activity, but “analysis” is sometimes preferred in public-facing contexts to avoid the connotations that “audit” carries in election integrity discourse.
An Actual Vote analysis goes through a lifecycle. Initiation occurs when America Counts decides to run the analysis, typically based on volunteer activity in the relevant jurisdiction or in response to a specific request. Submission collection is the period during which volunteers (or AC directly) collect submissions from polling places, through poll observers, via FOIA requests, or through other access methods. The Comparison Analysis pipeline is the nine-step process described in Section 8 — the concrete labor of vetting, classifying, transcribing, processing, building comparison logic, running comparisons, investigating, handling discrepancies, and reporting. Report writing compiles the findings into a report in either the static or rolling-log format. Publication makes the report public on americacounts.us. Follow-up asks the relevant elections office about any unresolved discrepancies and, for anything that survives even that, pursues escalation to a court-capable party; the analysis may be reopened if new information arrives.
Distinction between Actual Vote Analysis and Comparison Analysis
The term Comparison Analysis names the concrete pipeline work that happens inside an Actual Vote analysis. The distinction is one of scope. An Actual Vote analysis names the whole effort and its formal scope (one election × one state). A Comparison Analysis names the specific pipeline work — the vetting, classifying, transcribing, processing, building, running, investigating, handling, and reporting steps that constitute the technical pipeline. The two are not the same: an Actual Vote analysis includes things outside the Comparison Analysis (the initial decision to run it, the submission collection effort, the publication and follow-up), while a Comparison Analysis is the pipeline part specifically.
Comparison outcomes
How AC classifies the outcome of a comparison is central to its credibility and to the precision of its reporting. The full lifecycle — every path a comparison can take — is mapped in Section 12.3; the essentials follow.
A first-pass mismatch is an initial non-match, not yet a discrepancy. Review triages it: AC’s own errors are corrected to a match (and not reported), and what remains as a real difference in the reporting record is a discrepancy. A discrepancy for which AC holds a benign, probably-correct hypothesis is likely attributable; one for which review found no benign hypothesis is apparent — and apparent is the only path to a confirmed error.
An apparent discrepancy that neither AC nor the elections office can resolve becomes escalatable: it must be handed to a party able to bring a court case. “Escalation” names only this court stage — contacting the elections office is a cooperative ask, never an escalation. Once a court-capable party takes it up, it is escalated.
A true discrepancy is a discrepancy the responsible authority has confirmed to be a genuine vote-reporting error — the elections office acknowledging it, or a court ruling on it. AC never self-declares one. It is relative to an official-results version, so the headline measure is the number of true discrepancies that ever existed in an analysis. To date, that number is zero.
Discrepancy codes
Alongside the status classification, each non-match and discrepancy receives a discrepancy code that categorizes why it arose or how it resolved, for reporting and trend analysis. The codes align with the comparison-outcome model, in three groups.
Resolved to a match. AC transcription error; AC comparison/matching/aggregation error; missing poll tape (the official total exceeds the tapes AC holds); duplicate poll tape; plausibly equivalent write-in situation (PEWS); ballot-jam re-scan; undocumented vote-reporting logic; operational event (relocation, weather closure, emergency); precinct redacted in official results for anonymity.
Coverage / access (not a vote-reporting discrepancy). No poll tape posted at the voting location; no poll tapes received from the elections office; coverage gap (an officially reported unit for which AC has no submission).
Open or confirmed discrepancy. Apparent (no benign hypothesis; heavier ask pending); escalatable (unresolved by AC and by the office; ready for a court-capable party); true discrepancy (authority-confirmed, version-relative).
This list supersedes the earlier six-code list in the Actual Vote Data Standards document, which predated the comparison-outcome model; the Data Standards documentation (and Appendix B.10) will be brought into line with it.
4.6 — The Actual Vote Video Archive
Canonical name and URL
The canonical name of the archive is Actual Vote Video Archive. The canonical URL is https://av.democracycounts.org/. The “av” subdomain stands for “Actual Vote.” The domain is democracycounts.org because Democracy Counts, Inc. is the parent legal entity.
Permanent URLs for each submission
Every submission in the archive has a permanent URL of the form:
https://av.democracycounts.org/PollTape/{id}
For example, https://av.democracycounts.org/PollTape/1524 is the page for submission 1524. The CamelCase /PollTape/ is the canonical form. The ID is a persistent integer assigned by the archive system at the time of submission. This ID is the canonical reference for the submission throughout the AC pipeline — in transcription spreadsheets, comparison code, investigation notes, published reports, and all written communication.
Site structure
The archive has three tabs in its primary navigation. The Overview tab is a public landing page explaining what the archive is, with links to the app and to the Get Started section of americacounts.us. The Actual Vote Video Archive tab is a public listing of all approved submissions — a sortable, searchable table where each row shows summary information about one submission (ID, thumbnail, status, precinct, county, state, date, and other metadata). Clicking a row takes the user to that submission’s detail page. The My Actual Vote Videos tab is private to each logged-in user and shows all videos that user has submitted, including practice recordings and rejected submissions that are not visible to the public.
The submission data model
Every submission stored in the archive carries the following data:
The video file(s). The actual recording, stored as binary blobs. This is the primary evidence.
The submission ID. A persistent integer assigned at upload time. The canonical reference for this submission throughout the pipeline.
User account reference. The user who submitted the recording, linked by account ID.
Timestamp. When the recording was made, from the device clock at recording time. Establishes the temporal provenance of the evidence.
GPS coordinates. From the device’s location services at recording time, if the user granted permission. Establishes geographic provenance. Auto-populated with city, county, state, ZIP code, and country derived from the coordinates.
User-entered precinct identifier. A free-text field the user fills in at submission time. Useful but unreliable — users frequently leave it blank or enter incorrect values. The vetter and transcriber typically confirm the precinct from the tape header itself.
Status. The vetting outcome: Approved, Rejected, Practice, or other categories.
Comment. Free-text notes added by AC vetters during the vetting process — observations about quality, flags for the transcriber, notes about PII, or other relevant information.
Analysis Result and Report fields. Currently usually blank; intended for future use to link each submission to the Actual Vote analysis it participated in and the resulting report.
What the submission data model does not store is equally important. It does not store the user’s voting history, party affiliation, demographic information, or political views. It does not store any information about the voters whose ballots were counted by the machine that produced the poll tape. The Privacy Policy (B.5) details AC’s data handling commitments.
The submission detail page
The detail page for each submission displays the video player (showing the actual recording), the full set of metadata fields listed above, and navigation links to browse adjacent submissions. The detail page is the primary surface through which a researcher, journalist, or auditor would inspect a specific piece of evidence.
Search and browse functionality
The public listing supports column sorting and free-text search. A search for a county name returns all submissions from that county. A search for a date returns submissions from that date. The combination of search and sort allows users to find specific submissions or to browse submissions from a particular jurisdiction, election, or time period.
Canonical citation format
When referencing a specific submission in any context — published reports, correspondence with elections offices, internal documentation — the canonical citation includes the submission ID and the permanent URL. For example: “submission 1524 (av.democracycounts.org/PollTape/1524).” This format is unambiguous and allows any reader to inspect the underlying evidence directly.
Role as public evidence repository
The archive is not merely a database — it is a public evidence repository. Every approved submission is publicly accessible, permanently preserved, and independently verifiable. The archive’s role in the broader system is to ensure that the evidence on which AC’s findings rest is available for inspection by anyone: elections officials, journalists, researchers, courts, or members of the public. This openness is a core expression of the Transparency Principle (Section 13.1).
The archive also serves as a deterrent. When elections officials know that independent recordings of their posted poll tapes exist in a permanent public archive, the incentive to maintain proper procedures is strengthened. Errors that might have been dismissed as “nobody noticed” become documented and potentially discoverable.
4.7 — Accessibility and Inclusion
Design philosophy
Actual Vote is intended for anyone with a mobile phone. Participation is not limited to eligible voters, US citizens, or English speakers. The design philosophy is that election transparency is a public good that anyone can contribute to, and that the system should impose as few barriers to participation as possible.
This philosophy is reflected in several design choices. The app is free. No credential beyond a basic account is required to submit recordings. No special training is necessary beyond familiarity with using a smartphone camera and a basic understanding of what a poll tape is (provided by the practice feature and by AC’s public-facing educational materials). The recording process itself — pointing a phone at a piece of paper and pressing record — is a low-skill activity that does not require expertise in election administration, computer science, law, or statistics.
Current accessibility features
The current version of the AV system has several features that support broad accessibility. The app’s interface is simple, with minimal navigation and a clear primary action (record). The practice mode allows users to build confidence before attempting a real recording. The offline capability means that users in areas with poor connectivity can still participate. The upload-when-connected behavior means that users do not need to manage file transfers manually.
The evidence collection process itself is designed to require minimal special access. Method 1 (recording publicly posted poll tapes after polls close, Section 7.2) requires no appointment, no credential, and no permission beyond the right to be in a public place. This is the lowest-barrier access method and the one most users will employ.
Known accessibility gaps
AC is honest about the current system’s limitations in this area. There is no formal accessibility statement — the app has not been audited against WCAG or other accessibility standards. Non-English language support is limited; the app interface, educational materials, and reports are currently available only in English, which excludes potential volunteers in communities where English is not the primary language. There are no specific accommodations for users with visual impairments (the recording process depends on being able to see the poll tape through the phone screen) or mobility impairments (the recording process requires physical presence at a polling place, which may involve standing, walking, and holding a phone steady).
Planned improvements
AC recognizes these gaps and has identified several improvements for future development. An accessibility statement, developed in consultation with accessibility experts, would establish a baseline and identify specific remediation targets. Language support — at minimum for Spanish, given the size of the Spanish-speaking population in key AV states — would expand the volunteer base significantly. Interface improvements informed by usability testing with diverse populations would identify and remove barriers that the current team may not have recognized.
Inclusion considerations
AV’s design choices serve inclusion in ways that go beyond technical accessibility. The open participation model — anyone can contribute, not just registered voters or party-appointed observers — means that immigrants, non-citizens, young people below voting age, and others who cannot vote can still participate in election transparency. This is a meaningful form of civic engagement for populations that are often excluded from election-related activities.
The free app with no credential requirements means that economic barriers are minimized. The low training barrier means that educational barriers are minimized. The public evidence model means that contributions from any participant are equally valued — a recording from a first-time volunteer has the same evidentiary value as a recording from an experienced election observer, provided it meets the quality standards enforced by vetting.
AC’s operational planning should consider the specific safety concerns that participants from marginalized communities may face when recording at polling places. Section 10.5 (safety while recording) addresses general safety considerations, but AC should be particularly attentive to the risks faced by people of color, immigrants, and other groups who may encounter hostility or suspicion when exercising their right to observe and record public activities at polling places. The Broward 2018 experience, where volunteers encountered confrontations with police, illustrates that these risks are real and must be addressed in training and operational planning.
4.8 — Actual Vote Assist: The Automated Comparison Pipeline
Why AVA exists, and what kind of automation it is
Section 4.4 describes the analysis layer as the hand labor it has historically been: a transcriber reads each tape into a spreadsheet, an analyst builds the comparison logic, and the comparison is run and investigated. That description remains accurate as a model of what the step accomplishes. Actual Vote Assist (AVA) is the engineering that now performs most of it.
AVA is a Python pipeline that transcribes poll-tape videos using AI vision OCR, reconciles the transcribed vote counts against official per-tabulator or per-precinct results, and surfaces only discrepancies for human adjudication. Its objective is the same as the manual pipeline’s — to make certified results independently verifiable from the physical tapes — but at a throughput that hand transcription cannot reach.
It is worth being precise about the claim, because earlier editions of this manual stated that automated OCR was not reliable enough to use, and that remains true of unattended automation. Fully hands-off transcription is infeasible for two stubborn reasons: many recordings are too bad — blurry, bowed, glare-struck, partially filmed — to read mechanically, and a poll tape’s structure (which contests it contains, how their names are spelled, how they map to the official record) cannot be inferred procedurally with enough confidence to trust. AVA solves both with human guidance at the edges of an otherwise automated core. A person excludes the obviously unreadable recordings before they enter the pipeline, and supplies the list of valid contest-and-choice combinations — the source of truth — that tells the OCR what the tape should contain and how to join it to the official results. Given that guidance, the OCR and the automated comparison run reliably. When they finish, every read the system was unsure about is written into a review page for a human to confirm or correct, and the pipeline includes tooling for a human to spot-check even the reads it was confident about. The result is not “no human in the loop” — it is far less human labor per tape, concentrated where human judgment actually adds value, which is what makes the automated path acceptably reliable.
The system is data-folder driven: one analysis is one self-contained directory, and the code is analysis-agnostic, resolving every path from an environment variable. This is the same one-analysis-one-unit-of-work model that Section 4.5 defines conceptually (the Actual Vote analysis) and Appendix B.10 documents at the field level.
Repository and package layout
AVA separates an analysis-agnostic package (ava/) from the per-analysis data folders. The package is the reusable machine; each data folder is one election’s inputs and outputs.
actual-vote-assist/├─ ava/ # the analysis-agnostic package│ ├─ core/ cache · ids · log · checks · dag · config│ ├─ kernels/ transcribe · flatten · layout · crosswalk ·│ │ official_pdf · compare · sequences · align · tape_schema · fetch│ ├─ stages/ comparison.py (the single cached artifact) · pipeline.py (the DAG)│ ├─ web/ review_html · render_cache · server · verify_metadata · sample_exhibit · _ui│ └─ cli.py command surface├─ <YYYYMMDD>_<cc>_<state>_<county>/ # one analysis = one data folder│ ├─ inputs/ videos, manifest, official source(s), source_of_truth, analysis.json,│ │ tape_overrides.csv, verified_metadata.csv, manual_values.csv│ └─ outputs/ ocr/<tape>/ · comparison.parquet · review/ · exhibits/└─ RUNBOOK.md · README.md · CLAUDE.mdThe four package layers map to four responsibilities. core/ is the runtime spine: a content-fingerprint freshness cache, stable contest and choice IDs, unbuffered progress logging, the invariant gates (checks), the incremental DAG runner, and config (which resolves the active analysis from the AVA_ANALYSIS environment variable). kernels/ holds the validated compute units, each independently testable. stages/ is orchestration: comparison.py produces the one cached artifact every consumer reads, and pipeline.py registers the DAG. web/ is all human-facing HTML output and the local review server. The folder naming — <YYYYMMDD>_<cc>_<state>_<county> — is the same unique-identifier convention given for an Actual Vote analysis in Section 4.5.
The central design idea: one cached artifact and a content-addressed DAG
AVA’s architecture turns on a single decision: the comparison is computed once into outputs/comparison.parquet — one row per (tape, contest, choice), carrying the OCR vote, the official vote, the signed difference, the join status, and provenance. Every downstream consumer — the review UI, the public exhibits, the export package, the summary tables — reads that one artifact rather than recomputing it. The comparison row is the AVA-level realization of the comparison object defined in Section 4.5.
Freshness is governed by a content fingerprint, not by file timestamps. Each stage’s inputs are hashed, so a run rebuilds only what actually changed. In practice a fresh comparison is a roughly one-second cache hit rather than a multi-minute recompute, which is what makes iteration cheap: after a fix or a data update, re-checking a whole county is a near-instant refresh. On every build, core/checks.py gates a set of invariants — contest IDs are 1:1, verdicts resolve to live cards, the comparison forms a valid partition, and per-tape vote totals checksum — so a regression fails loudly and immediately instead of shipping a silently wrong number.
The pipeline is expressed as a directed acyclic graph. ava run [stage] [--force] [-jN] and ava status drive it, and the graph registers compare → {review, spotcheck, dedup, exhibits, package} — every product hangs off the one comparison artifact.
The pipeline, stage by stage
Fetch (kernels/fetch.py) pulls tape videos from the Actual Vote archive’s public media endpoint using the staging spreadsheet’s Id and MediaLocation columns — no database credentials required. Submission status A means results (kept by default), P means practice (no votes), and R means rejected, mirroring the vetting outcomes of Section 4.3. Submission provenance is tracked because tapes arrive three ways — video from the Actual Vote app, still photos, and video from a phone’s native camera app — and the ingestion records which, since it affects expected framing and quality.
Transcribe / OCR (kernels/transcribe.py) is the heart of the system. For each video it runs five steps. First, rotation detection auto-corrects sideways or upside-down tapes, with the rotation convention unified between detection and application. Second, screenshot extraction selects candidate still frames by three complementary strategies, merged and de-duplicated by proximity: interval frames every N seconds, skipping any frame below a blur threshold (measured by Laplacian variance); still-moment frames, taking the sharpest frame from each cluster where camera motion drops, which captures the deliberate pauses recorders make; and a header guarantee, which force-keeps the sharpest frame from the opening window (the first few seconds, where the tape’s header with Voting Location and Tabulator Name is filmed) regardless of the blur floor, so the header is never lost to a still-settling camera. A uniformly blurry video falls back to interval sampling rather than hard-failing. Third, preprocessing grayscales each selected frame, upscales it 2× (cubic), and adaptively thresholds it to binary for maximum legibility. Fourth, vision OCR transcribes each frame with Claude vision (claude-sonnet-4-6), returning structured contest/choice/value rows plus header metadata; the engine is verified at runtime — the log must read Using Claude (Anthropic), and an API-key load failure that would silently fall back to a weak local model raises a loud warning. Fifth, cross-frame reconciliation exploits the fact that the same contest-choice is read on multiple frames: flatten reconciles by plurality vote across frames and preserves every disagreeing reading, so the confidence behind each value stays auditable. Per tape, the stage emits raw_ocr.csv, metadata.csv, results.csv, a layout.json (Tesseract boxes aligned to the AI rows, used to bracket a contest in the review UI), and the screenshots/.
Flatten (kernels/flatten.py) collapses the raw per-frame OCR into one reconciled row per (tape, contest, choice) and one per (tape, header field), preserving tape order via the minimum frame ordinal.
Crosswalk (kernels/crosswalk.py) maps the OCR’d contest and choice names onto the official source-of-truth names by fuzzy match (token_set_ratio), collapsing OCR variants such as Flemins → Fleming or Abilah Parkes → Nabilah Parkes. This is the stage that consumes the human-supplied list of valid contest-choice combinations described above. A frozen crosswalk (inputs/crosswalk_frozen.csv, keyed per tabulator) lets a person bless specific joins before fuzzy matching runs; it is part of the comparison fingerprint, so editing it invalidates the cache. The guiding rule: with a source of truth present, every OCR’d contest and choice should reconcile to something in it, or be explicitly dropped.
Compare (stages/comparison.py, kernels/compare.py, kernels/official_pdf.py) is source-aware, switching on inputs/analysis.json → compare_source (or the AVA_COMPARE_SOURCE override). In the pdf mode (ES&S equipment, as in California / Santa Clara), official truth comes from the ES&S ElectionSummaryReport PDFs — the digital twins of the tapes — and the tape-to-official join key is the Tabulator ID in each tape’s header, using the system-specific identity tabulator = ICP − 1971; per-tape manual fixes live in inputs/tape_overrides.csv. In the ga_precinct mode (Dominion ImageCast, as in New York and Georgia), official truth comes from the EnhancedVoting per-precinct export JSON, flattened into precinct × contest × choice × voting-method rows, and election-day tapes join by precinct. Null-group handling is critical here: where a state withholds a per-method cell for voter privacy (shown as ”–”), the loader keeps it as None meaning “no official, held out” — never 0 — so it produces neither a false discrepancy nor a false 0 = 0 match. The comparison also auto-reconciles known benign patterns, such as write-in attribution, and leaves genuine judgment calls (an undervote that may map to a Yes, for example) for the human — exactly the initial-non-match triage that Section 4.5 and Section 8.9 define.
Review, exhibits, and package (web/) turn the artifact into human- and public-facing products. The review UI (review_html.py plus static review.css/review.js) reads the artifact and renders each discrepancy card’s images once to outputs/review/images/<sha>.png via render_cache.py, emitting a slim page; this render-once design took the resolved-diffs HTML from about 93 MB to roughly 0.1 MB, and cold card rendering is parallelized across a process pool because the PDF layer is not thread-safe. ava serve runs a local server that writes verdicts straight to the store, keyed on the stable contest ID. The exhibits layer (sample_exhibit.py and related) produces a public-facing sample_comparisons.html of random exact matches — each with a citation into the official source — along with the per-analysis running <id>_ava_notes.html, the privacy_screen.md, and stakeholder letters. The package step (export_package.py) is the standardized hand-off to the report writer, deriving the analysis ID from the folder name and the source from compare_source().
Metadata verification
A tape’s header metadata — Tabulator ID, poll times, serials, model — is raw OCR with no source of truth to check it against, so AVA treats it as provisional until a human verifies it against the video in a generated HTML tool (ava verify-metadata → correct → ava apply-metadata → inputs/verified_metadata.csv). One field is self-verifying: the precinct or location is fuzzy-checked against the official precinct list, where a high score means verified and a low score is consistent with an advance-voting site rather than a home precinct.
For recognized tape types, a canonical header schema (tape_schema.py) fixes the field names and order the tape always prints, replacing noisy per-frame OCR labels. The Georgia Dominion ImageCast (PCOS-320C) schema is defined — County, Date, Election Name, Expanded Date, Tabulator Name, Tabulator ID, Voting Location, Poll Opened/Closed, Report Printed, Unit Model, Unit Serial, Protective Counter, Software Version, Total Scanned, Total Voters — and the tool renders fields in that order, prefills already-verified values, and offers a Quick mode for the two fields actually used downstream (Tabulator Name and Voting Location).
Quality and integrity subsystems
AVA’s credibility rests on a set of guards that run alongside the main pipeline, each designed to fail loudly rather than bluff. The invariant gates (core/checks.py) run on every build, enforcing partition validity, 1:1 contest IDs, verdict resolution, and the per-tape vote-total checksum. Duplicate-recording detection (dedup.py) finds two videos of the same tape (matching votes and metadata) and keeps only the canonical copy in the review queue. The tabulator-match audit (tabulator_match.py) scores each tape’s votes against candidate tabulators and flags any whose resolved join is not its best data match, catching Tabulator-ID misreads and split-recording mis-citations. The ballot-secrecy screen (privacy-screen) flags unanimous cells — where one choice received every vote within a reporting unit × contest × method — per the America Counts standard, requiring at least two captured choices so that incomplete OCR cannot false-flag; because a recording cannot be partly redacted, any tape with an at-risk cell is withdrawn or replaced in full. Finally, manual entry (manual-entry / apply-manual) handles the bowed or blurry tapes the OCR cannot fully read: a human fills the remaining values from the embedded video, the form folds orphan OCR variants back to the source of truth so only real candidates appear, and the filled values join the comparison marked on_tape="manual". This last subsystem is the formal home of the “exclude the unreadable, let a human supply what the machine can’t” principle described at the top of this section.
Voting-system specifics
AVA already spans two major vendor ecosystems. The differences are confined to the official source and the join key; the rest of the pipeline is shared.
| ES&S (e.g. CA / Santa Clara) | Dominion ImageCast (e.g. NY, GA) | |
|---|---|---|
| Official source | ElectionSummaryReport PDFs + Clarity bulk export | EnhancedVoting per-precinct JSON |
compare_source | pdf | ga_precinct |
| Join key | Tabulator ID (tabulator = ICP − 1971) | precinct / vote-center |
| Tape layout | full county ballot per vote-center tape | compact tabular contest blocks |
| Privacy redaction | — | per-method cells withheld for small counts (kept as None) |
One structural limit deserves explicit statement because it shapes what AVA can and cannot confirm in Georgia. The public results there report advance (early) votes by each voter’s home precinct, not by the scanner that counted them. A single advance-voting scanner blends many precincts, so no published figure equals any one advance-voting tape’s total. AVA detects this case (no precinct in tape_overrides), skips those tapes from the comparison rather than fabricating false differences, and the analysis notes quantify exactly what could not be checked and why — the same honesty-over-coverage discipline that governs the hand pipeline.
Operating the pipeline
The command surface mirrors the stages above. A typical run proceeds:
export AVA_ANALYSIS="$(pwd)/<YYYYMMDD>_<cc>_<state>_<county>"python -m ava.cli fetch <staging.xlsx> --county "X" --date YYYY-MM-DD # download tapespython -m ava.cli ocr <video> # transcribe (must log "Using Claude (Anthropic)")python -m ava.cli run [stage] [-jN] # incremental DAG; rebuilds only stale stagespython -m ava.cli status # what is fresh / stalepython -m ava.cli serve # local review server (verdicts save to the store)python -m ava.cli verify-metadata # human-verify header fieldspython -m ava.cli privacy-screen # ballot-secrecy screen before posting recordingspython -m ava.cli package # standardized report hand-offThe full end-to-end procedure — from the staging spreadsheet to the final report hand-off — is maintained in the codebase’s RUNBOOK.md, with orientation in its CLAUDE.md.
Extending to a new jurisdiction
Onboarding a new county is a configuration-and-mapping task, not a rewrite. The steps are: (1) create the analysis folder and inputs/analysis.json with compare_source, county, state, and voting_system; (2) fetch and OCR the tapes, adding a canonical tape_schema entry if the tape format is new; (3) ingest the official source (a new loader only if the vendor or export format is new) along with the contest/choice source of truth; (4) map tapes to their join unit in tape_overrides.csv and freeze any blessed crosswalk joins; and (5) run compare → review, adjudicate the flagged differences, verify metadata, run the privacy screen, package, and write the <id>_ava_notes.html and report hand-off. Because the package is analysis-agnostic and the join logic is the only vendor-specific piece, the same pipeline already runs across ES&S and Dominion ImageCast equipment in California, New York, and Georgia.
Where AVA leaves human judgment
AVA changes the economics of the analysis layer without changing its standards. The conceptual model of Section 4.5 — submissions, transcribed values, comparisons, the comparison grain, the comparison-outcome classification — is unchanged; AVA simply computes those objects faster and at greater scale. The methodology of Section 8 still governs which comparisons are valid and how a discrepancy is investigated; the seven-check investigation of Section 8.9 still runs on whatever AVA surfaces. What AVA removes is the manual transcription bottleneck and the manual re-computation cost. What it deliberately keeps is the human at the two points where human judgment is irreplaceable: deciding which recordings are usable and what the tape is supposed to say, and adjudicating every read or comparison the system was not sure about. That division of labor — machine reads and compares, human guides and judges — is the whole design.