Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
Result announcement, verification docs and ballots
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Nov 5, 2024
1 parent b970f47 commit 48d6094
Show file tree
Hide file tree
Showing 7 changed files with 1,126 additions and 12 deletions.
451 changes: 451 additions & 0 deletions civs_ballots.csv

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@ rec {
# Verifies the voters.json and returns a derivation with the emails/github ids
voters = import ./nix/voters.nix { inherit pkgs; };

verifyBallotMatch = import ./nix/verify-ballot-match.nix { inherit pkgs; };

inherit pkgs;
}
111 changes: 105 additions & 6 deletions doc/verify.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,109 @@
# How to verify the election result

TODO
The resulting Nix Steering Committee for this election is (sorted alphabetically):
- @Ericson2314 (2 year term)
- @fpletz (1 year term)
- @Gabriella439 (2 year term)
- @jtojnar (2 year term)
- @roberth (2 year term)
- @tomberek (1 year term)
- @winterqt (1 year term)

Because it's anonymous, there's no way to know that exactly those people got a link.
Could ask random people whether they got to vote and whether their ballot is in the final list.
You can verify this as follows:
1. Check that the result matches <https://civs1.civs.us/cgi-bin/results.pl?id=E_8589ef69d0e60845> (see the winning set of choices).
The terms are assigned according to the individual preference order.
2. Clone this repository. Subsequent commands assume it's available under `SC-election-2024`.
2. Download the CIVS ballots from <https://civs1.civs.us/cgi-bin/download_ballots.pl?id=E_8589ef69d0e60845> and verify that they match the [ones in the repository](../civs_ballots.csv):
```bash
curl 'https://civs1.civs.us/cgi-bin/download_ballots.pl?id=E_8589ef69d0e60845' > civs_ballots.csv
diff <(sort civs_ballots.csv) <(sort SC-election-2024/civs_ballots.csv)
```
3. Download the OpaVote ballots from <https://opavote.com/results/6251213851459584> ([direct link](https://opavote.com/ballots/6251213851459584/0?d=1)) and verify that it matches the [ones in the repository](../opavote_ballots.blt):
```
diff ballots1.txt SC-election-2024/opavote_ballots.blt
```

In case of CoI disqualifications:
For every disqualification round of a CoI candidate:
- Get the ballots from the new election and make sure it matches the previous one with only the CoI conflicted persons being removed
Note that the ballots will only be available from OpaVote until 2024-12-27, after that you cannot verify this part.
4. The two ballot lists are in very different formats, but should have the same data.
To verify that, inspect the code in this repository and run:
```
nix-build SC-election-2024 -A verifyBallotMatch
```
5. Recreate the CIVS result (optional, only works if CIVS doesn't change the implementation)
1. [Create a new poll](https://civs1.civs.us/civs_create.html) with these options:
- <details>
<summary>Candidates:</summary>
```
asymmetric
cafkafk
djacu
doronbehar
Ericson2314
fpletz
Gabriella439
getchoo
Infinidoge
jtojnar
kloenk
linsui
lovesegfault
mschwaig
numinit
nyabinary
phaer
proofconstruction
roberth
Scrumplex
tomberek
winterqt
yu-re-ka
```
</details>
- How many choices will win: 7
- [x] Make this a test poll: read all votes from a file.
- [x] Enforce proportional representation (rank of their favorite choice)
2. Once on the poll control page, load the ballot data from `result/civs_ballots.txt`, which was generated from the previous step.
3. Close the poll and verify that the results match.
## Verifying the voters
To verify that only people eligible [according to the constitution](https://github.com/NixOS/nix-constitutional-assembly/blob/00b53920442a5077fa8c295a9955042e45080323/constitution.md#vote-eligibility) are in the [`voters.json`](../voters.json) file:
1. Generate the initial list of automatically eligible people as was done by the EC in [this commit](https://github.com/NixOS/SC-election-2024/commit/fd157a8ad1b19733788325ad59d036fa6b434d20), inspect the code of this repository and run
```
# If you don't have 4TB of space or can't wait 10 CPU days for processing:
nix-shell -p cachix --run "cachix use nca"
nix-build -A generateVoters
./result
```
2. See the approved exception requests, email changes and voters waiving their voting rights by inspecting the [Git history of `voters.json`](https://github.com/NixOS/SC-election-2024/commits/main/voters.json).
Because OpaVote does not give public access to the list of emails that were invited to vote, you need to trust the EC on it matching [`voters.json`](../voters.json).
Members of the EC can verify it as follows:
1. Download the voter list at <https://opavote.com/manage/6251213851459584/final?d=1>.
This requires logging into the OpaVote account and is likely only available until 2024-12-27.
The SHA256 hash of the file is
```
8f10d15ca2c06a4812cf4ab5ebbdfc774bb831487507266acc0f67a9d6b51d42 voter_list.csv
```
2. In `nix-shell -p csvkit jq diffutils`, run
``` bash
diff \
<(jq -r 'keys[] | select(startswith("@") | not) | ascii_downcase' voters.json | sort) \
<(csvjson voter_list.csv | jq -r '.[] | select((.Voted == true or .Bounce != true) and .Disabled != true) | .Voter' | sort)
```
Note that:
- Voters who didn't have an email address in `voters.json` couldn't be invited to vote.
They were informed of needing to set an email address ([1](https://github.com/NixOS/SC-election-2024/issues/1#issuecomment-2354208422) [2](https://github.com/NixOS/SC-election-2024/issues/130)), which some did with subsequent PRs.
- Some voters were invited, but their email bounced, in which case those voters were [given another chance](https://github.com/NixOS/SC-election-2024/commit/42efa5e76267e28c6bb053f0c3f26637d25213b1) to add a different email.

There is also one special case of somebody being able to vote, but an email being bounced,
most likely due to a later reminder email that bounced.
That person was not given the chance to add another email.
No other bounced emails cast a vote.
- Some voters voluntarily waived their voter rights and were thus manually disabled by the EC to stop sending email reminders.
53 changes: 53 additions & 0 deletions ec/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -615,4 +615,57 @@ in
We cannot change the voter emails where the voting link has been delivered, but for missing and bouncing addresses, users can still [update their email address](https://github.com/nix-constitutional-assembly-2024/SC-election-2024/blob/main/doc/email.md). Everybody without an email address in `voters.json` will be notified once more.
'';
};

result = buildAnnouncement {
title = "Results for the Nix Steering Committee Election 2024";
announcement =
platform: loginExists: discourseLink:
''
After successfully tallying the 450 ballots cast (56% turnout) using CIVS,
We are hereby concluding this election!
We congratulate the first members of the Nix Steering Committee (SC) (ordered alphabetically):
- [@Ericson2314] (2 year term)
- [@fpletz] (1 year term)
- [@Gabriella439] (2 year term)
- [@jtojnar] (2 year term)
- [@roberth] (2 year term)
- [@tomberek] (1 year term)
- [@winterqt] (1 year term)
[@Ericson2314]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/Ericson2314.md
[@fpletz]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/fpletz.md
[@Gabriella439]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/Gabriella439.md
[@jtojnar]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/jtojnar.md
[@roberth]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/roberth.md
[@tomberek]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/tomberek.md
[@winterqt]: https://github.com/NixOS/SC-election-2024/blob/main/candidates/winterqt.md
This result is certified by all [Election Committee][ec] members.
[ec]: https://github.com/nixos/SC-election-2024?tab=readme-ov-file#election-committee-ec
For verification purposes,
all OpaVote ballots will soon be available [here][opavote]
(the result there should be ignored; voters will also get an email),
while the CIVS tally to determine the result using the same ballots
is already available [here][civs].
See [the new docs][verify] for more info on result verification.
[opavote]: https://opavote.com/results/6251213851459584
[civs]: https://civs1.civs.us/cgi-bin/results.pl?id=E_8589ef69d0e60845
[verify]: ${p ../doc/verify.md}
We are now establishing communications with the first SC members
and will soon make a final handover announcement on behalf of the EC / NCA.
We, the members of the EC / NCA, and @ron from the NixOS Foundation board,
are thankful for everybody's participation in this first election,
and are looking forward to see the first SC getting started.
'' + lib.optionalString (platform != "discourse") ''
Note that you can also read and publicly discuss this announcement [on Discourse][discourse].
[discourse]: ${discourseLink}
'';
};
}
25 changes: 19 additions & 6 deletions nix/process.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

set -euo pipefail

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit

read -r candidateCount _seatCount;
echo "Candidate count: $candidateCount" >&2
while read -ra ballot; do
Expand Down Expand Up @@ -40,23 +43,33 @@ while read -ra ballot; do
candidateRanks[candidate]=$(( rank-- ))
done

echo "${ballot[@]}" "->" "${candidateRanks[@]}" >&2
echo "${candidateRanks[@]}"
echo "${ballot[@]}" "->" "${candidateRanks[@]}" >&2
(
IFS=,
echo "${candidateRanks[*]}"
)
fi
done
done | sort -n > "$tmp/sorted"

candidates=()
echo "Candidates (fill this into the candidate field):" >&2
for candidate in $(seq "${candidateCount}"); do
read -r name
name=${name%\"}
name=${name#\"}
if [[ "$name" == "0" ]]; then
# For some reason CIVS doesn't store candidates named "0"
echo "0.0" >&2
else
echo "$name" >&2
name="0.0"
fi
echo "$name" >&2
candidates+=("$name")
done

(
IFS=,
echo "#" "${candidates[*]}"
)
cat "$tmp/sorted"

read -r title
echo "Title: $title" >&2
20 changes: 20 additions & 0 deletions nix/verify-ballot-match.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ pkgs }:
pkgs.runCommand "verify-ballot-match" {
src = pkgs.lib.fileset.toSource {
root = ../.;
fileset = pkgs.lib.fileset.unions [
./process.sh
../civs_ballots.csv
../opavote_ballots.blt
];
};
} ''
unpackPhase
cd "$sourceRoot"
patchShebangs .
export PATH=${pkgs.lib.makeBinPath [ pkgs.bc pkgs.coreutils pkgs.diffutils ]}
mkdir $out
nix/process.sh < ./opavote_ballots.blt > $out/civs_ballots.txt
diff <(tail -n+2 civs_ballots.csv | sort -n) <(tail -n+2 $out/civs_ballots.txt)
''
Loading

0 comments on commit 48d6094

Please sign in to comment.