Every election here writes a permanent, verifiable record of itself as it runs. This page shows the machinery in plain terms: what gets recorded, why nothing can change quietly, and what still holds up when someone disputes the result. The claim is not that tampering is impossible. The claim is that tampering cannot succeed silently.
When anything happens in an election, the database itself writes an entry: the ballot goes live, a member votes, a deadline moves, the count freezes. Each entry gets a SHA-256 fingerprint, and each fingerprint includes the fingerprint of the entry before it. That is the whole trick. Change any entry, even one character, and its fingerprint no longer matches. Every entry after it points at a fingerprint that no longer exists.
The log is append-only. The database refuses edits and deletions of past entries for everyone, including us. We tested that refusal against our own administrator access.
This is a live model of six real entries. Click any entry to edit it and watch the verification respond. Click it again to restore it.
On a real election this check is not a demo. It is a button on the dashboard, a line on the results certificate, and a job that re-runs every night.
A chain of events proves what happened. It does not by itself prove that a stored ballot still says what the voter marked. So in the same instant a ballot is stored, the database computes a fingerprint of its content and commits that fingerprint into the chain. The fingerprint is salted with a secret value held on the ballot record, which means reading the log never reveals how anyone voted, not even for a simple yes or no question.
From then on, anyone with access can recompute: take the stored ballot, recompute its fingerprint, compare it with what the chain recorded at cast time. We ran this drill in production: edited a stored answer directly in the database, and the verification named the exact ballot that no longer matched. Then we restored it and the record verified clean again.
Disputes rarely start with "the ballots were forged." They start with "the deadline moved when our side was winning" or "her vote counted for five, mine for one." So the database watches the sensitive record itself. These entries are written by triggers inside the database. No application code path can skip them.
The deadline, quorum rule, eligibility, or secrecy setting of a live election changed. The entry records the old value and the new value.
A voter's weight or contact identity changed mid-election, with a flag for whether they had already voted. Identity changes are recorded as fingerprints, so the log itself never leaks a roster.
A member who had voted was marked as not having voted. No legitimate flow does this. If it ever appears, it is the first question to ask.
A member was removed from the roster of a running election, including whether they had already cast a ballot.
A ballot's content fingerprint, committed at cast time. The promise every later recount is checked against.
The final count froze, with its own fingerprint. The results row is then write-once: the database refuses any later change to it.
Some statutes, including California's and Florida's for association elections, require that a ballot can never be connected back to a member. For those elections we offer sealed ballots: the ballot is stored with no reference to the voter at all. The poll book records that a member voted. The ballot box holds ballots. Nothing joins the two, and the chain names who voted, never which ballot.
Because there is no per-ballot link, sealed ballots are protected as a box rather than one by one. When voting closes, the box is shuffled and rewritten in random order, and a checksum of the whole box is computed before and after. The two must match or the close refuses to happen. That checksum enters the chain, and every later check recomputes the box against it.
When an election closes, the results are computed once and frozen with their own SHA-256 fingerprint. The database refuses any later change to the frozen results, and the fingerprint itself enters the chain as results_frozen.
Where an inspector of elections is appointed, a named human being reviews and certifies. Their signed certification records the results fingerprint, the ballot count, and the head fingerprint of the entire chain at the moment of signing. A person put their name on a specific version of history. Rewriting that history later means contradicting a signature that already left the building.
Here is the honest limit, stated before you have to ask. A hash chain has no secret key. Someone with total control of the database could, in theory, rewrite the whole story and recompute every fingerprint so it self-verifies. What defeats that is not more math inside the same database. It is copies outside it.
Every results certificate prints the chain head fingerprint and entry count. Audit packages carry the full log to inspectors and auditors. Voters hold their own confirmations. Board packets get printed and emailed. A rewrite would have to be consistent with every copy already in other people's hands, and it cannot be. The database cannot un-print a PDF.
Tamper-evident records only matter if someone is looking. Every night, a sweep re-verifies every election's chain, recomputes every ballot fingerprint against its stored ballot, and checks every closed sealed box against the checksum recorded when it was sealed. Any anomaly raises an alert and emails the founder the same day. A sweep that fails to run is itself treated as an alert. Silence never reads as health.
| If this person tried… | What they can do | What they cannot do quietly |
|---|---|---|
| A voter | Cast their own ballot. Hold their own confirmation. Verify their ballot was recorded. | Vote twice, vote as someone else, or see anyone else's ballot. Eligibility, one-ballot rules, and verification are enforced before a ballot is accepted. |
| An organizer | Run the election: roster, schedule, reminders. Move a deadline. Fix a voter's record. | Change any of that invisibly. Every sensitive change lands in the chain with old and new values. Ballot content and frozen results are never editable, and on anonymous or sealed elections the organizer never sees how anyone voted. |
| vote.direct, operating the platform | Everything an organizer can, plus support access, which is itself chain-logged. | Edit or delete a past log entry. The database refuses the write, for us too. We tested the refusal with our own administrator access, and the nightly sweep would name any exception. |
| Someone with total database control | In theory: rewrite the whole record and recompute every fingerprint. | Make the rewrite agree with the certificates, audit packages, signed certifications, and confirmations that already left the building. Copies outside the database are the final control. |
The outcome, participation, verification methods, the chain head fingerprint, and the integrity status. Made for the board packet.
The full chained log, reconciliations, ballot fingerprint checks, and the sealed box comparison. Made for inspectors and auditors, sealed by its own fingerprint.
A named person's signed statement binding the results fingerprint and the chain head at the moment of signing.
Each voter's own proof their ballot was recorded, held by them, not by us.