Ballot Tally Algorithms
We publish our counting logic so anyone can reproduce tallies offline. For Ranked Choice Voting (Instant Runoff), each round counts current first preferences; the lowest candidate is eliminated and their ballots transfer to the next ranked continuing candidate until a winner emerges or a tie persists.
Ranked Choice (IRV) Example
[
{
"round": 1,
"counts": {
"A": 2,
"B": 2,
"C": 1
},
"eliminated": "C",
"exhausted": 0
},
{
"round": 2,
"counts": {
"A": 2,
"B": 3
},
"exhausted": 0
}
]Winner: B
Tie-break strategy (if needed): lexicographically compare candidate IDs among lowest group; eliminate last.
Simple & Approval
Simple: highest vote count wins. Approval: each option accrues one count per approving voter; highest total wins. Hash of tally uses canonical JSON: sha256(JSON.stringify({ ballotId, type, results })).
Verification Tools
Use the offline CLI (packages/shared/dist/verify/cli.js) to recompute tally hashes and verify the ledger chain. Download a ballot export bundle and run:
node packages/shared/dist/verify/cli.js --ballot export.json --ledger ledger.json
