Page MenuHomePhabricator

Voting in drop-down STV elections doesn't work
Closed, ResolvedPublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

  • $wgSecurePollSingleTransferableVoteEnabled = true;
  • Vote in a STV Droop quota election using the drop-down vote feature
  • Submit vote

What happens?:

  • Voting fails with error, Options cannot be selected multiple times in the ranking. Please change the option for: Preference n, Preference n + 1... (where n = the number of candidates selected) This isn't actually the case, the numbers appear to kind of correspond to the candidates.

What should have happened instead?:

  • Vote should have submitted.

I think the issue might be that it thinks that unselected options are all ranked at 0. I hope so since that might be an easy fix.

Event Timeline

jrbs triaged this task as High priority.Aug 21 2024, 8:46 PM

High priority since this will impact the Board election starting in a few days

I happened to be screen recording at the time which actually proves it's even weirder than I thought.

I will test if randomising the options is the culprit...

Alas that was not the problem.

I troubleshooted a bit with a test election (apologies that the "D" candidate is missing, that's an oversight on my part obviously)

  1. Selecting option A, B, C, and submitting vote: Options cannot be selected multiple times in the ranking. Please change the option for: Preference 5, Preference 6, Preference 7, Preference 8, Preference 9, Preference 10, Preference 11
  2. Selecting option H, I, J, and submitting vote: Options cannot be selected multiple times in the ranking. Please change the option for: Preference 2, Preference 3, Preference 4, Preference 5, Preference 6, Preference 10, Preference 11
  3. Selecting option J, K, L, and submitting vote: Options cannot be selected multiple times in the ranking. Please change the option for: Preference 2, Preference 3, Preference 4, Preference 5, Preference 6, Preference 7, Preference 8

So it looks like it has to do with the candidate themselves indeed. In all scenarios, in the next screen all candidates are re-added:

Screenshot 2024-08-21 at 10.25.43 PM.png (1×1 px, 161 KB)

In scenario 1, removing one option from this list submits correctly. However removing only the first two results in the error ... Please change the option for: Preference 2:

Screenshot 2024-08-21 at 10.27.31 PM.png (1×1 px, 147 KB)

And removing the first five results in ... Please change the option for: Preference 2, Preference 3, Preference 4, Preference 5.

I think the drag and drop input is sending malformed data. Testing it against the non-js form, I expect an array like [1135, 1136, 1137, 1138] where those numbers are the id of the candidates being voted for. The drag and drop input is sending data like [1, 'A', 'A', 'A'] (where A is the name of the candidate) back which the ballot doesn't know how to process. It's keeping the A values and since there are more than 1, it's being flagged as a duplicate, hence the user error. For that reason if you vote for n-1 unique candidates, it'll successfully go through.

Can you confirm/deny if you're able to get an election using the drop down to tally correctly? My tallies from testing are very malformed as well.

Can you confirm what the expected user input should be? Do voters have to vote for every candidate? I checked on no-js and it looks like all inputs are forced to have some value and because they all have to be unique, all candidates must be ranked. This validation behavior isn't replicated in the drag and drop input as I can vote for as few candidates as I'd like (well, n-1 candidates). However, the video suggests that voters should be able to vote for a subset of candidates?

Thanks for looking into this, I do appreciate it. :)

I think the drag and drop input is sending malformed data. Testing it against the non-js form, I expect an array like [1135, 1136, 1137, 1138] where those numbers are the id of the candidates being voted for. The drag and drop input is sending data like [1, 'A', 'A', 'A'] (where A is the name of the candidate) back which the ballot doesn't know how to process. It's keeping the A values and since there are more than 1, it's being flagged as a duplicate, hence the user error. For that reason if you vote for n-1 unique candidates, it'll successfully go through.

Can you confirm/deny if you're able to get an election using the drop down to tally correctly? My tallies from testing are very malformed as well.

I tallied the test election I ran on production (it has only one vote, so not exactly representative) and it looks totally broken. Note especially that it doesn't seem that any votes at all were counted.

screencapture-vote-wikimedia-org-wiki-Special-SecurePoll-tally-1652-2024-08-23-13_46_13.png (6×3 px, 1 MB)

I'll try this on my own wiki shortly which has additional votes but probably needs SecurePoll updated locally.

Can you confirm what the expected user input should be? Do voters have to vote for every candidate? I checked on no-js and it looks like all inputs are forced to have some value and because they all have to be unique, all candidates must be ranked. This validation behavior isn't replicated in the drag and drop input as I can vote for as few candidates as I'd like (well, n-1 candidates). However, the video suggests that voters should be able to vote for a subset of candidates?

Yes, voters should be able to vote for as many candidates as they like. If that is not what the code is expecting I imagine it might be a challenge to tweak it?

Perhaps the best short-term solution here is to rollback this change and revise and re-implement after the BoT vote?

Note especially that it doesn't seem that any votes at all were counted.

Thanks for confirming. That matches with what I'm seeing locally.

Yes, voters should be able to vote for as many candidates as they like.

It looks like was changed alongside the drag and drop. On no-js it now forces a value. Checking against the commit right before the drag and drop, voters are able to vote for a subset of candidates so I suppose this is a bug as well.

Perhaps the best short-term solution here is to rollback this change and revise and re-implement after the BoT vote?

It depends on how critical you think drag and drop is I suppose. I could certainly try to fix this over the weekend but from what I can tell, it's fairly broken and there's not a lot of time between trying to get something up/QAing it and the election regardless.


Leaving some notes for myself (or whoever fixes this)

On known good submission, the inputs coming in are:

{
  "securepoll_q1133_opt0": "1135",
  "securepoll_q1133_opt1": "1134",
  "securepoll_q1133_opt2": "0",
  "securepoll_q1133_opt3": "0"
}

each select input corresponds to the ranking and passing along the value of the candidate chosen. 0s (no vote) are stripped out, leaving an ordered list of candidates.

On new input with js:

Options D, A, B, C

Voting A, B

{
  "securepoll_q1133_opt0": "D",
  "securepoll_q1133_opt1": "1",
  "securepoll_q1133_opt2": "2",
  "securepoll_q1133_opt3": "D",
}

Voting B, A

{
  "securepoll_q1133_opt0": "D",
  "securepoll_q1133_opt1": "2",
  "securepoll_q1133_opt2": "1",
  "securepoll_q1133_opt3": "D",
}

Each input looks like it's saving its position in the user's list and the order of options is based on its DOM order. This means votes aren't deterministic either since the order of options can be randomized.

On new input no-js I can't run a quick console log but I checked the tally and it looks like it's using the broken inputs as well, as the tally isn't right either.

It looks like was changed alongside the drag and drop. On no-js it now forces a value. Checking against the commit right before the drag and drop, voters are able to vote for a subset of candidates so I suppose this is a bug as well.

Dang. if it would be helpful I can file another bug about this tomorrow.

It depends on how critical you think drag and drop is I suppose. I could certainly try to fix this over the weekend but from what I can tell, it's fairly broken and there's not a lot of time between trying to get something up/QAing it and the election regardless.

In my opinion drag and drop is nice to have but if it's broken this badly I think we should just roll it back so we can stick to the election schedule. I think that would probably also be the opinion of others working on the process though I haven't directly asked them.

jrbs raised the priority of this task from High to Unbreak Now!.Aug 26 2024, 2:32 PM

UBN given the severity of the bug and its proximity to the elections

I went to go explore this bug more in a localhost environment, but I don't see anything at Special:SecurePoll/create -> "poll type" that sounds like "STV" or "droop quota". Are there some steps to reproduce missing?

image.png (412×580 px, 23 KB)

Anyway, my idea is to explore doing a git bisect to figure out what patch introduced the bug, then revert that patch, and backport the revert.

Change #1066791 had a related patch set uploaded (by STran; author: STran):

[mediawiki/extensions/SecurePoll@master] Hotfix drag and drop inputs in STV voting

https://gerrit.wikimedia.org/r/1066791

Dang. if it would be helpful I can file another bug about this tomorrow.

It was a part of the drag/drop implementation to avoid showing the null input as an option and could be fixed as part of any fixes to the drag/drop implementation.


In my opinion drag and drop is nice to have but if it's broken this badly I think we should just roll it back so we can stick to the election schedule.

I'm still in favor of reverting, as it's cutting it a bit close and ultimately if my hotfix can't clear review/QA in time it'll have to be reverted anyway. I created the revert patch here: https://gerrit.wikimedia.org/r/c/mediawiki/extensions/SecurePoll/+/1066792 (pending conflicts)

However, I did give it an extra day to see what I could do. There are a few problems with drag and drop as-is:

  • combobox (the main dropdown in the drag/drop UX) doesn't support value => label visuals. If you set both a value (eg. the id) and a label (eg. the candidate name), clicking on the candidate name will reveal the id in the textarea. That's suboptimal and the original patch chose to use the candidate name as the value instead. Unfortunately, the ballot processing logic didn't understand this.
  • the js input needs are completely different than the no-js input needs. This is actually a two for one: 1. the no-js inputs are ordered and use that ordering (via input id) to determine the ranking whereas the js inputs save the index of selected inputs but 2. don't consistently/correctly record which candidate is being voted for in the index but even if it did, it would require a different set of logic in the ballot processor.

I've made and attempt to fix some of them up but this is a bandaid and if my fix gets merged, I would prefer a more robust solution eventually replace what I've done here. My patch solves these problems by...toggling between two sets of inputs 🙃. Since the inputs used by the drag and drop ui don't generate valid data, it seemed easier to let it do that and then take what data it did provide and push it into a set of "clean" inputs. There's a bit of flash of unstyled content as a result but this was the best I could think of on short notice.

In theory, once the form inputs are in a format that the vote record expects, all STV calculations should work as expected as nothing in the original patch affected that.

oh @Novem_Linguae I'm sorry I was working on this today. You can feel free to take over. The commit that caused the issues is https://gerrit.wikimedia.org/r/c/mediawiki/extensions/SecurePoll/+/865096.

I went to go explore this bug more in a localhost environment, but I don't see anything at Special:SecurePoll/create -> "poll type" that sounds like "STV" or "droop quota". Are there some steps to reproduce missing?

You need to set $wgSecurePollSingleTransferableVoteEnabled = true;

oh @Novem_Linguae I'm sorry I was working on this today. You can feel free to take over. The commit that caused the issues is https://gerrit.wikimedia.org/r/c/mediawiki/extensions/SecurePoll/+/865096.

I was just poking around in the background. I think you should probably stay point on this if you're willing. You've got your head wrapped around this ticket really well it seems like.

Change #1066792 had a related patch set uploaded (by STran; author: STran):

[mediawiki/extensions/SecurePoll@master] Revert "Create a drag-drop solution for ranked choice voting"

https://gerrit.wikimedia.org/r/1066792

Change #1066792 merged by jenkins-bot:

[mediawiki/extensions/SecurePoll@master] Revert "Create a drag-drop solution for ranked choice voting"

https://gerrit.wikimedia.org/r/1066792

Change #1067317 had a related patch set uploaded (by STran; author: STran):

[mediawiki/extensions/SecurePoll@master] Revert "Revert "Create a drag-drop solution for ranked choice voting""

https://gerrit.wikimedia.org/r/1067317

Looks like the revert above did make the train and should be deployed everywhere by Thursday end of day.

https://www.mediawiki.org/wiki/MediaWiki_1.43/wmf.20#SecurePoll

Votewiki is group 1, so should receive the update Wednesday end of day.

What's the deadline for this to be fixed? Is this fast enough, or do we need a backport?

Looks like the revert above did make the train and should be deployed everywhere by Thursday end of day.

https://www.mediawiki.org/wiki/MediaWiki_1.43/wmf.20#SecurePoll

Votewiki is group 1, so should receive the update Wednesday end of day.

What's the deadline for this to be fixed? Is this fast enough, or do we need a backport?

Discussed internally, and it should be fine to be fixed via the train.

Dreamy_Jazz lowered the priority of this task from Unbreak Now! to Needs Triage.Aug 27 2024, 12:34 PM

Unmarking as UBN as the problem will not be present for the board election.

Change #1067317 abandoned by STran:

[mediawiki/extensions/SecurePoll@master] Revert "Revert "Create a drag-drop solution for ranked choice voting""

Reason:

no longer time sensitive/being actively worked on

https://gerrit.wikimedia.org/r/1067317

Change #1066791 abandoned by STran:

[mediawiki/extensions/SecurePoll@master] Hotfix drag and drop inputs in STV voting

Reason:

no longer time sensitive/being actively worked on

https://gerrit.wikimedia.org/r/1066791

What is the status of this ticket, so I can orientate myself for annual planning? :)

Change #1115145 had a related patch set uploaded (by Mimurawil; author: Mimurawil):

[mediawiki/extensions/SecurePoll@master] Re-implement the drag & drop solution for STV poll

https://gerrit.wikimedia.org/r/1115145

Mimurawil changed the task status from Open to In Progress.Jan 30 2025, 11:48 PM
Mimurawil claimed this task.

Change #1115145 merged by jenkins-bot:

[mediawiki/extensions/SecurePoll@master] Re-implement the drag & drop solution for STV poll

https://gerrit.wikimedia.org/r/1115145