PEP 8001: Python Governance Voting Process

PEP: 8001
Title: Python Governance Voting Process
Author: Brett Cannon brett@python.org,
Christian Heimes christian@python.org,
Eric Snow ericsnowcurrently@gmail.com,
Gregory P. Smith greg@krypto.org,
Łukasz Langa lukasz@python.org
Mariatta Wijaya mariatta@python.org,
Pablo Galindo Salgado pablogsal@gmail.com,
Raymond Hettinger python@rcn.com,
Zachary Ware zachary.ware@gmail.com
Status: Draft
Type: Process
Content-Type: text/x-rst
Created: 2018-08-24

Abstract

This PEP outlines the process for how the new model of Python governance is
selected, in the wake of Guido's retirement <https://mail.python.org/pipermail/python-committers/2018-July/005664.html>_.
Once the model is chosen by the procedures outlined here, it will be codified
in PEP 13.

Motivation and Rationale

Guido’s stepping down from the BDFL role left us with a meta-problem of
having to choose how we will choose how the Python project should be
governed from now on.

This document presents a concrete proposal how this choice can be made.
It summarizes discussion and conclusions of the proceedings of a working
group at the core sprint in Redmond in September 2018 (names of all
attendees are listed as authors). This PEP also summarizes a
subsequent thread <https://discuss.python.org/t/python-governance-electoral-system/290>_
that took place on discuss.python.org .

The governance situation should be resolved in a timely fashion.
Ideally that should happen by the end of the 2018 which unblocks
substantial improvements to be merged in time for Python 3.8. At the
latest, the governance situation needs to be resolved by PyCon US 2019 to
avoid a PR crisis.

Implementation

What are we voting for?

We are voting to choose which governance PEP should be implemented by
the Python project. The list of candidate PEPs is listed in PEP 8000
and consists of all PEPs numbered in the 801X range.

To ensure the vote is legitimate, the aforementioned PEPs must not be
modified during the voting period.

Who gets to vote?

Every CPython core developer is invited to vote. In the interest of
transparency and fairness, we are asking core developers to self-select
based on whether the governance situation will affect them directly.
In other words, we are recommending for inactive core developers who
intend to remain inactive
to abstain from voting.

When is the vote?

The vote will happen in a 2-week-long window from November 16 2018
to November 30 (Anywhere-on-Earth).

Where is the vote?

The vote will happen using a “private” poll on the
Condorcet Internet Voting Service <https://civs.cs.cornell.edu/>_. Every committer
will recieve an email with a link allowing them to rank the PEPs in their order of
preference.

The election wil be supervised by Ernest Durbin.

The results of the election, including anonymized ballots, will be made public on
December 1st, after the election has closed.

The following settings will be used for the vote in the CIVS system::

[x] Private
[ ] Make this a test poll: read all votes from a file.
[ ] Do not release results to all voters.
[x] Enable detailed ballot reporting.
    [ ] In detailed ballot report, also reveal the identity of the voter with each ballot.
[ ] Allow voters to write in new choices.
[ ] Present choices on voting page in exactly the given order.
[ ] Allow voters to select “no opinion” for some choices.
[ ] Enforce proportional representation

Which will have the effect of:

  • Making the election “private”, or in other words, invite only.
  • The results of the election will be released to all voters.
  • The contents of every ballot will be released to the public, along
    with a detailed report going over how the winner was elected.
  • The detailed ballots will not include any identifying information
    and the email addresses of the voters will be thrown away by the CIVS
    system as soon as the email with their voting link has been sent.
  • Voters will not be able to write in new choices, and will be limited
    only to the options specified in the election.
  • The default ordering for each ballot will be randomized to remove
    any influence that the order of the ballot may have on the election.
  • Voters will have to rank all choices somehow, but may rank multiple
    choices as equal.

Voting mechanics

The vote will be by ranked ballot. Every voter
orders all candidate PEPs from the most preferred to the least
preferred. The vote will be tallied and a winner chosen using the
Condorcet method <https://en.wikipedia.org/wiki/Condorcet_method>_.

While the CIVS system does not provide an option for a “Pure”
Condorcet election, any Condorcet method will select the “Pure”
Condorcet winner if one exists and otherwise only vary if one
doesn’t exist. The CIVS system differentiates between a Condorcet
winner and a non Condorcet winner by stating if the winner was a
Condorcet winner, or if it merely wasn’t defeated versus any other
option. So a winner in the CIVS system will only be accepted if
it states it was a Condorcet winner.

In the unlikely case of a tie (or cycle as is possible under the
Condorcet method), a new election will be opened, limited to the
options involved in the tie or cycle, to select a new winner from
amongst the tied options. This new election will be open for a
week, and will be repeated until a single winner is determined.

Questions and Answers

Why the Condorcet method?

  1. It allows voters to express preference by ranking PEPs
  2. It is consensus decision-making <https://en.wikipedia.org/wiki/Consensus_decision-making#Condorcet_consensus>_
  3. In a poll <https://discuss.python.org/t/python-governance-electoral-system/290/26>_
    open to only core developers and run using Approval voting, it was
    the clear preference

Is omitting any candidate PEPs in the ranking allowed?

A vote which omits candidates in the ranking is invalid. This is
because such votes are incompatible with the desired properties listed
above, namely:

  • Making voters consider alternatives, as well as
  • Doing everything possible to reach a conclusion in a single election.

Why recommend for dormant core developers to not vote?

The choice of the governance model will have far reaching and long-term
consequences for Python and its community. We are inviting core
developers to assess their skin in the game.

Note: this is not an edict and will not be policed. We trust all
members of the core team to act in the best interest of Python.

Why should the vote be private?

When discussing the election system, a number of core developers expressed
concerns with the idea of having public ballots, with at least one core
developer stating that they were planning on abstaining from voting
altogether due to the use of a public ballot.

A secret ballot is considered by many to be a requirement for a free and
fair election, allowing members to vote their true preferences without
worry about social pressure or possible fallout for how they may have
voted.

Why the use of CIVS?

In the resulting discussion of this PEP, it was determined that core
developers wished to have a secret ballot. Unfortunately a secret ballot
requires either novel cryptography or a trusted party to anonymize the
ballots. Since there is not known to be any existing novel cryptographic
systems for Condorcet ballots, the CIVS system was chosen to act as a
trusted party.

More information about the security and privacy afforded by CIVS, including
how a malicous voter, election supervisor, or CIVS administrator can
influence the election can be be found
here <https://civs.cs.cornell.edu/sec_priv.html>_.

Are there any deficiencies in the Condorcet method?

There is no perfect voting method. It has been shown by the
Gibbard-Satterthwaite theorem <https://en.wikipedia.org/wiki/Gibbard%E2%80%93Satterthwaite_theorem>_
that any single-winner ranked voting method which is not dictatorial
must be susceptible to so-called “tactical voting”. This can lead to
people not voting as they truly believe in order to influence the
outcome.

The Condorcet method also has the possibility of having cycles (known as
the Condorcet paradox <https://en.wikipedia.org/wiki/Condorcet_paradox>).
Due to the fact that the Condorcet method chooses a winner based on whether
they would win against the other options in a 1-on-1 race, there is a
possibility that PEP A > PEP B > PEP C > PEP A (or in terms of the game
rock-paper-scissors, imagine a three-player game where someone played rock,
another played paper, and the last person played scissors; no one wins that
game as everyone is defeated by someone). The chances of this occurring when
there are 21 or more voters, though, is
less than 1.5% <https://www.accuratedemocracy.com/l_cycles.htm>
.

Copyright

This document has been placed in the public domain.


Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End:

5 Likes

Overall +1 from me. Two questions:

What happens if some candidate PEPs are omitted from the ballot? Is that allowed, or is it an invalid ballot?

Can you explain what kind of “tactical voting” is alluded to here?

3 Likes

Antoine, thanks for your questions. These were rather critical omissions in the first draft.

I edited the PEP to state explicitly that a vote omitting any candidate PEPs in the ranking is invalid. This is important because an election with partial votes does not guarantee an outcome. If every voter specified just a single candidate, at six candidates this can easily lead to none of them gaining majority.

I added an explanation and some links to the PEP.

2 Likes

I also made this a Wiki for easier edits.

1 Like

One question: I assume everyone can see each other’s vote files in the repo. Would this not lead to tactical voting during the two weeks?

I’ve always said it should be resolved well before PyCon 2019 so we can make the announcement of who’s the new leadership and how it’s structured several months before PyCon. I don’t want this to be a big reveal at PyCon – I want it to be old news by then. The big reveal can be a press release or blog post by the PSF months before PyCon. At PyCon we can then just remind people that the core dev team has elected a constitution and leadership and business is going on as usual. Possibly a member of the new leadership team could give a talk, or there could be a panel with the new leadership for Q&A about how they plan to lead.

But the main thing for me is that this should be old news by PyCon.

6 Likes

I suppose you’re talking about US PyCon? Apparently it’s gonna be in May 2019.

Good question! We will probably see a little of this, yes. I’m not worried about that for a few reasons.

First and foremost, I genuinely trust the core team to take this seriously. Hopefully it will be obvious by the time of the vote which way the wind blows so the election result won’t be a surprise anyway. If our goal is a workable solution, one that receives support of the largest possible group within the core team, then some degree of tactical voting is not a problem, at least in its “casting a useful vote” form.

In the unlikely case of malicious antics, if people decide to dramatically change their votes mid-way or cast votes that are internally inconsistent, this will be recorded for perpetuity. That should be enough to deter people from such ideas. In particular, any organized attempts to steer the election one way or another will be visible.

What do you think?

1 Like

Yes, May 2019.

Why the use of a Github repository instead of using something like the voting software we use for board elections? Thst works well enough for the board, it seems strange to go out of our way to invent a different procedure.

I think it would be helpful to have a pre-commit hook that verified the format of the submissions. Also perhaps a template. I’m concerned about throwing out votes that are accidentally incomplete.

Using voting software would also help alleviate that concern.

Voting via file seems really poor to me. It encourages tactical voting by seeing what is currently “winning” and adjusting your votes on that and for people to wait to vote till the very end so they can see what other people are voting.

In general I think that the secret ballot is a key part of sane voting procedures, and we should strive to keep that property.

I’m not opposed to a secret ballot as long as we are able to:

  • ensure the voter population is 1:1 people on the “Python core” team on GitHub (remember that any veteran who isn’t at this point, can get inspired on Nov 29 to get their credentials);
  • keep track of participation during the vote (e.g. “Donald Stufft has not yet voted”);
  • publish ballots after they’re counted (e.g. “Donald Stufft voted 1,2,3,4,5,6”).

Is this possible with Helios?

Why is a 1:1 mapping with people on the GitHub team a mandatory trait? Why wouldn’t you just send it to the entire core team, and allow people to self select out of taking it if they feel like the outcome of the election doesn’t effect them. This seems like a specific solution to some problem, but not necessarily the only solution to said problem, but I don’t see a specific problem it solves other than trying to limit voters to those who bothered to request GitHub permissions. However it seems silly to me to try to do that, given we already trust someone with a commit bit, and thus we should probably trust them to exclude themselves if the outcome of the vote doesn’t really effect them.

However, I believe Helios does allow you to add voters to an ongoing election after it has been started.

With Helios, one of the “trustees” (e.g. election administrators) can see who has and hasn’t cast a ballot yet, as well as have the option to send emails out to everyone in the election, only people who haven’t yet voted in the election, or people who have voted in the election. It does not let the trustrees (or anyone) see how that particular voter voted.

Helios is fully verifiable, anyone can verify the results of an election. That being said, there is no way to link a particular vote to a particular individual. That’s sort of a core principal of a secret ballot that you can’t do that.

However, digging into things a bit more, it appears that Helios does not support IRV or ranked elections as such, and if we want to use IRV, likely wouldn’t be directly usable. There is a fork, Zeus, that does support that though. I’ve been digging a little bit since I made that suggestion a few hours ago, I’m not entirely sure that IRV is what we want here.

One of the traits that a IRV election has, is that saying if Option A is your first choice, than under no circumstances should putting Option B as your second choice should cause Option A to lose. However, I’m not entirely sure that this is a property we want in this case. The pathological case is that if a plurality of voters like Option A, but Option A is hated by some subset of the population, while Option B is everyone’s second choice, then an IRV election would likely end up selecting option A, even though Option B would be the “consensus” solution that has the most widespread support and leaves the fewest number of people feeling like they’ve gotten a choice that they hate (rather than maximizing the number of people who got their first or second choice). There is actually a real world example of this case, which is the Burlington Mayoral election of 2009.

The basic idea here is that IRV does not always elect the Condorcet winner, which means you still get the spoiler effect, it’s just somewhat reduced in cases where your first choice gets eliminated early.

One option that might be better than IRV, is to use a method called STAR voting, which unlike IRV which broadly falls under the category of ranked voting, it falls under the category of “scored” voting.

Basically how STAR voting works is that voters are allowed to express their preference for candidates by giving them a score, rather than by ranking them. This would be something like a 0-5 ranking where 0 means “I hate this” and 5 means “I love this”, then an average (or total, either way works) score is produced for each option and then a runoff is generated between the top two scoring choices, where if you scored A higher than B, that counts as having voted for A over B (and if you scored A and b equally, then your vote is effectively nullified for the runoff).

The effect of this is that not only do you get information about the ranked preferences of people (since you can infer that based on how they ranked each option) but also you get more information about the relative differences in how they view the different options, and using that you can determine which choice has the highest consensus amongst the largest share of voters.

Unfortunately, Helios neither supports STAR or IRV, although I believe it can be sort of made to support both by formulating the questions in a certain way, and using the API to iterate over the ballots and compute the tallies differently then how the helios system itself does it. However I am not 100% sure on that. If not, a simpler method of scored voting can be used I believe, where we just ask voters to score each proposal and we don’t use the run off and instead just select the highest scoring choice. Eliminating the run off reduces some level of tactical voting protection against bullet voting, but I think for our small organization the risk of doing so is pretty small anyways.

I agree that several months of working under the new governance structure / leadership prior to PyCon 2019 is important. It gives the greater community, as well as the core team, an opportunity to see that the new governance has been working effectively before PyCon. This helps build confidence in the ongoing leadership and the health of the core dev process.

1 Like

I would tend to agree with @ambv that, in the context of governance PEPs, we may want people’s votes to be public, at least after the election ends.

On other topics, especially politically-sensitive ones (diversity?), secret votes may be desirable to avoid witch hunts.

Thank you, Donald, for your thoughts on the matter. I think the fact that Helios doesn’t support neither the currently selected voting method, nor the one you’re proposing, disqualifies it at this point. We unfortunately don’t have time to implement and verify the implementation of a new voting method in the time we need to actually hold the vote. As you see, both @guido and @willingc stress the importance of the vote to happen well before PyCon 2019.

And remember that in the case of a BDFL and any council, we will need another vote to choose the actual representatives.

Unfortunately this goes against one of our explicit goals for this partical election, as @pitrou says. Think of our election more like a parliament vote where not only the totals but the votes of each representative are public. This is important for transparency.

Well, we currently have four distinct lists of “core developers” (the fourth is Discourse but I hope that will get rectified as soon as we enable GitHub login and a bit of scripting to automatically grant “committers” membership on Discourse via GitHub “Python core” team membership).

We want to avoid a fifth list of core developers. Anybody who wanted to vote but couldn’t, or shouldn’t vote but did, invalidates the vote.

Using GitHub without people being able to see the vote as it happens

There is a way to make this work with a Git repository. It would require everybody to encrypt their votes with a public key which private counterpart is only in @ewa.jodlowska’s possession (I’m not saying “Guido” since he qualifies as a voter, too). Ewa would then commit the private key to the repository once the vote period is over.

We could create a script that does the encryption and decryption that requires nothing but Python 3.5+ so that the process is as easy as possible (remember: we need to make sure nobody is excluded from voting). The script would also randomly pad the data to be encrypted so that the same vote by two different people doesn’t look the same in the repository.

In fact, with this idea we could use a single “voting” repository in the Python organization on GitHub and just have directories inside for different votes. This resolves a complaint by @dhellmann and @pitrou around littering GitHub with many dead repositories.

What do you think?

I would make that “Python 3.5 or later”, then :wink: Just like blurb.

1 Like

Fixed. What about the actual idea?

That sounds fine on the principle. There would be a new private key for each vote, then?