Skip to content

Commit

Permalink
refactor: rename Registrar to Electorate
Browse files Browse the repository at this point in the history
committeeRegistrar became committee
  • Loading branch information
Chris-Hibbert committed Sep 30, 2021
1 parent 17c6aa9 commit 8554897
Show file tree
Hide file tree
Showing 21 changed files with 244 additions and 240 deletions.
105 changes: 54 additions & 51 deletions packages/governance/README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@
# Governance

This package provides Registrars and VoteCounters to create a general
This package provides Electorates and VoteCounters to create a general
framework for governance. It has implementations for particular kinds of
electorates and different ways of tallying votes.

The registrars and VoteCounters are self-describing and reveal what they are
The electorates and VoteCounters are self-describing and reveal what they are
connected to so that voters can verify that their votes mean what they say and
will be tabulated as expected.

Any occasion of governance starts with the creation of a Registrar. Two kinds
Any occasion of governance starts with the creation of an Electorate. Two kinds
exist currently that represent committees and stakeholders (Stakeholder support
is in review). The electorate may deal with many questions governing many
things, so the electorate has to exist before any questions can be posed.

The next piece to be created is an ElectionManager. (A Contract Governor, is a
particular example, discussed below). An ElectionManager is tied to a particular
Registrar. It supports creation of questions, can manage what happens with the
Electorate. It supports creation of questions, can manage what happens with the
results, and may limit the kinds of questions it can handle. The ElectionManager
is also responsible for specifying which VoteCounter will be used with any
particular question. Different VoteCounters will handle elections with two
positions or more, with plurality voting, single-transferable-vote, or
instant-runoff-voting.

When a question is posed, it is only with respect to a particular Registrar,
When a question is posed, it is only with respect to a particular Electorate,
(which identifies a collection of eligible voters) and a particular vote
counting contract. The QuestionSpec consists of `{ choiceMethod, issue,
positions, electionType, maxChoices }`. The issue and positions can be
strings or structured objects. ChoiceMethod is one of UNRANKED and ORDER, which
is sufficient to describe all the most common kinds of votes. A vote between two
candidates or positions uses UNRANKED with a limit of one vote. ORDER will be
useful for Single Transferable Vote or Instant Runoff Voting. ElectionType
distinguishes PARAM_CHANGE, which has structured questions, from others where
the issue is a string.
counting contract. The QuestionSpec consists of `{ method, issue, positions,
electionType, maxChoices }`. The issue and positions can be strings or
structured objects. Method is one of UNRANKED and ORDER, which is sufficient to
describe all the most common kinds of votes. A vote between two candidates or
positions uses UNRANKED with a limit of one vote. ORDER will be useful for
Single Transferable Vote or Instant Runoff Voting. ElectionType distinguishes
PARAM_CHANGE, which has structured questions, from others where the issue is a
string.

When posing a particular question to be voted on, the closingRule also has to be
specified. When voters are presented with a question to vote on, they have access
to QuestionDetails, which includes information from the QuestionSpec, the
closingRule, and the VoteCounter instance. The VoteCounter has the Registrar
specified. When voters are presented with a question to vote on, they have
access to QuestionDetails, which includes information from the QuestionSpec, the
closingRule, and the VoteCounter instance. The VoteCounter has the Electorate
in its terms, so voters can verify it.

Voters get a voting facet via an invitation, so they're sure they're connected
to the Registrar that's responsible for this vote. They can subscribe with the
registrar to get a list of new questions. They can use the questionHandle from the
notifier to get the questionDetails. Voters cast their vote by sending their
selected list of positions to their registrar, which they know and trust.
to the Electorate that's responsible for this vote. They can subscribe with the
electorate to get a list of new questions. They can use the questionHandle from
the notifier to get the questionDetails. Voters cast their vote by sending their
selected list of positions to their electorate, which they know and trust.

This structure of Registrars and VoteCounters allows voters and observers to
This structure of Electorates and VoteCounters allows voters and observers to
verify how votes will be counted, and who can vote on them, but doesn't
constrain the process of creating questions. ElectionManagers make that process
visible. ContractGovernor is a particular example of that that makes it possible
for a contract to publish details of how its parameters will be subject to
governance.

## Registrar
## Electorate

A Registrar represents a set of voters. Each voter receives an invitation
An Electorate represents a set of voters. Each voter receives an invitation
for a voterFacet, which allows voting in all elections supported by
that registrar. The Registrar starts a new VoteCounter instance for each
that electorate. The Electorate starts a new VoteCounter instance for each
separate question, and gets the `creatorFacet`, which carries the `submitVote()`
method that registers votes with the voteCounter. The Registrar is responsible
method that registers votes with the voteCounter. The Electorate is responsible
for ensuring that `submitVote()` can only be called with the voter's unique
voterHandle.

Expand All @@ -72,7 +72,7 @@ accessing the param values and for setting them. The governed contract would use
the access facet internally, and make that visible to anyone who should be able
to see the values, while ensuring that the private facet, which can control the
values, is only accessible to a visible ContractGovernor. The ContractGovernor
makes the Registrar visible, while tightly controlling the process of
makes the Electorate visible, while tightly controlling the process of
creating new questions and presenting them to the electorate.

The governor starts up the Contract and can see what params are subject to
Expand All @@ -83,16 +83,16 @@ to governance, but that's too many meta-levels at this point.

The party that has the question-creating facet of the ContractGovernor can
create a question that asks about changing a particular parameter on the
contract instance. The registrar creates new questions, and makes a new instance
of a VoteCounter so everyone can see how questions will be counted.
contract instance. The electorate creates new questions, and makes a new
instance of a VoteCounter so everyone can see how questions will be counted.

Registrars have a public method to get from the questionHandle to a question.
Electorates have a public method to get from the questionHandle to a question.
Ballots include the questionSpec, the VoteCounter instance and closingRule. For
contract governance, the question specifies the governed contract instance, the
parameter to be changed, and the proposed new value.

This is sufficient for voters and others to verify that the contract is managed
by the governor, the registrar is the one the governor uses, and a particular
by the governor, the electorate is the one the governor uses, and a particular
voteCounter is in use.

The governed contract can be inspected to verify that some parameter values are
Expand Down Expand Up @@ -121,19 +121,20 @@ values are
`{ AMOUNT, BRAND, INSTANCE, INSTALLATION, NAT, RATIO, STRING, UNKNOWN }`.
The list can be extended as we find more types that contracts want to manage.

In order to make the management of parameters visible to clients of the
contract, it should
There's a contractHelper for the vast majority of expected clients that will
have a single set of parameters to manage. A contract only has to define the
parameters in a call to `handleParamGovernance()`, and add any needed methods
to the public and creator facets. This will
* validate that the declaration of the parameters is included in its terms,
* publish the accessor facet of the paramManager in its publicFacet, and
* include a paramManagerRetriever in its creatorFacet for the contractGovernor.
* add the parameter retriever appropriately to the publicFacet and creatorFacet

## Scenarios

### Examining a Contract before use

Governed contracts will make their governor and parameters visible, either
through the terms or the public facet. The governor, in turn, publicly shares
the registrar, which makes the list of questions visible. The questions show
the electorate, which makes the list of questions visible. The questions show
their voteCounters, which makes it possible to tell how the counting will be
done.

Expand All @@ -148,47 +149,49 @@ governor's public facet will also refer to the contract it governs. Once you
have the instance you can retrieve the installation from Zoe which allows you to
examine the source.

The governedContract will provide the registrar, which allows you to check the
The governedContract will provide the electorate, which allows you to check the
electorate, and retrieve a list of open questions. (We should add closed
questions and their resolution as well.) Each question refers to the
voteCounter it uses.

### Participating in Governance

Voters are managed by a Registrar. Prospective voters should only accept a
Voters are managed by an Electorate. Prospective voters should only accept a
voting API as the outcome of an invitation. The invitation allows you to verify
the particular registrar instance in use. The registrar's public facet has
`getQuestionSubscription()`, which allows you to find out about new questions for
the electorate and `getOpenQuestions()` which lists questions that haven't been
resolved.
the particular electorate instance in use. The electorate's public facet has
`getQuestionSubscription()`, which allows you to find out about new questions
for the electorate and `getOpenQuestions()` which lists questions that haven't
been resolved.

Each question describes its subject. One field of the questionDetails is
`ElectionType`, which can be `PARAM_CHANGE`, `ELECTION`, or `SURVEY`. (I'm sure
we'll come up with more types.) When it is `PARAM_CHANGE`, the questionDetails
will also identify the contract instance, the particular parameter to be changed,
and the proposed new value. At present, all parameter change elections are by
majority vote, and if a majority doesn't vote in favor, then no change is made.
will also identify the contract instance, the particular parameter to be
changed, and the proposed new value. At present, all parameter change elections
are by majority vote, and if a majority doesn't vote in favor, then no change is
made.

## Future Extensions

The architecture is intended to support several scenarios that haven't been
filled in yet.

### Registrars
### Electorates

We currently have a committeeRegistrar, which has an opaque group of voters. The
The initial Electorate represents a Committee, with has an opaque group of
voters. The
contract makes no attempt to make the voters legible to others. This might be
useful for a private group making a decision, or a case where a dictator has the
ability to appoint a committee that will make decisions.

The ClaimsRegistrar (coming soon!) is a Registrar that gives the ability to vote
to anyone who has an Attestation payment from the Attestation contract.
The AttestedElectorate (coming soon!) is an Electorate that gives the ability to
vote to anyone who has an Attestation payment from the Attestation contract.
Observers can't tell who the voters are, but they can validate the
qualifications to vote.

Another plausible registrar would use the result of a public vote to give voting
facets to the election winners. There would have to be some kind of public
registration of the identities of the candidates to make them visible.
Another plausible electorate would use the result of a public vote to give
voting facets to the election winners. There would have to be some kind of
public registration of the identities of the candidates to make them visible.

### VoteCounters

Expand Down
26 changes: 13 additions & 13 deletions packages/governance/docs/AttackGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ stuff the ballot box.

I can't think of a way to evade the way BinaryVoteCounter ensures that each
vote is only counted once, but it's something to be aware of with new
VoteCounters, and particularly in combination with new Registrars.
VoteCounters, and particularly in combination with new Electorates.

## Break notification so voters don't hear about elections

Expand All @@ -41,7 +41,7 @@ provided for announcing new issues.
## Leak the ability to create new questions

Currently creating new questions is seen as tightly held. If that is loosened
in a new Registrar or ElectionManager, that provides a path for spamming
in a new Electorate or ElectionManager, that provides a path for spamming
voters.

## What shenanigans can be caused by creating multiple questions with the same or very similar text?
Expand All @@ -51,24 +51,24 @@ questionHandle for disambiguation. Voters ought to validate the particulars of
any question they intend to vote on. Can they be confused by corrections or
replacement? Is there a vulnerability here, or just a UI support need?

## Create a Question that refers to a different VoteCounter than the one the registrar will use
## Create a Question that refers to a different VoteCounter than the one the electorate will use

## Distribute questions that don't match the official one from the Registrar
## Distribute questions that don't match the official one from the Electorate

Questions themselves are not secure. The voter has to get a copy of the question
from the Registrar to have any assurance that it's valid. If someone else
from the Electorate to have any assurance that it's valid. If someone else
provides a question, they can replace various pieces to fool the voter as to
what is being voted on or how the votes will be tallied.

## Ordinary bugs in counting votes, reporting, etc.

If the code in VoteCounter, Registrar, ContractGovernor has subtle mistakes,
If the code in VoteCounter, Electorate, ContractGovernor has subtle mistakes,
wrong results will obtain.

## Produce a discrepancy between Terms and actions in VoteCounter or Registrar
## Produce a discrepancy between Terms and actions in VoteCounter or Electorate

The voter's assurance that a particular vote has the effect they expect
arises in part because the `terms` in the VoteCounter, Registrar,
arises in part because the `terms` in the VoteCounter, Electorate,
etc. dictate how those classes will act. If the code is changed to get info
from hidden parameters or to ignore some of the terms, voters will be misled.

Expand All @@ -79,17 +79,17 @@ timers, but timers aren't self-revealing. Participants should compare the
timers to known platform-provided timers before relying on them.
[A related bug has been filed](https://github.com/Agoric/agoric-sdk/issues/3748)

## Registrar allow unauthorized parties to cast votes
## Electorate allow unauthorized parties to cast votes

Every registrar will have some notion of who the authorized voters are. They
Every electorate will have some notion of who the authorized voters are. They
need to properly enforce that each voter can vote their weight once. The
initial implementation (committeeRegistrar) supports equal weight votes and
known voters. Future Registrars and VoteCounters will support other models.
initial implementation (Committee) supports equal weight votes and
known voters. Future Electorates and VoteCounters will support other models.
The combination of open-entry stake-holder votes with variable weight
voteCounters will require even more diligence to ensure there are no avenues
for multiply counting votes.

## Registrar accidentally re-use a voteCounter
## Electorate accidentally re-use a voteCounter

Each voteCounter is intended to be used once. If there's a path that allows
re-use, this would be a hazard.
Expand Down
12 changes: 6 additions & 6 deletions packages/governance/docs/contractGovernance.puml
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ package "GovernedContract Vat" <<Rectangle>> {
}

class "ContractGovernor\n(an ElectionManager)" as ContractGovernor {
<i>verifiable</i>: governedInstance, registrarInstance
<i>verifiable</i>: governedInstance, electorateInstance
--
+getRegistrar()
+getElectorate()
+getGovernedContract()
+validateVoteCounter()
+validateRegistrar()
+validateElectorate()
+validateTimer()
-startGovernedInstance(registrar, governed, ...)
-startGovernedInstance(electorate, governed, ...)
}
note left : ContractGovernor starts GovernedContract\nstartGovernedInstance() returns a tightly held facet\n with voteOnParamChange() for the creator.

class Registrar {
class Electorate {
Questions
===
-addQuestion()
Expand All @@ -41,7 +41,7 @@ class Registrar {
GovernedContract ..> ParamManager : creates >
GovernedContract --> ParamManager : access\nto params
ContractGovernor ..> GovernedContract : creates >
ContractGovernor --> Registrar
ContractGovernor --> Electorate
ContractGovernor ==> ParamManager : manages\nparams

@enduml
28 changes: 14 additions & 14 deletions packages/governance/docs/coreArchitecture.puml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ package Legend <<Rectangle>> #EEEEEE {
note "Contracts have a 'C' marker.\nInvitations have an 'I'.\nblue arrows show verifiable connections.\ncreator-created links are labelled" as NC
}

package "Registrar Vat" <<Rectangle>> {
class Registrar {
package "Electorate Vat" <<Rectangle>> {
class Electorate {
terms: committeeSize, committeeName
--
Questions[]
Expand All @@ -34,16 +34,16 @@ package "Registrar Vat" <<Rectangle>> {
}

note "produces VoterInvitations.\nPolymorphic over VoteCounters.\nquestions are enumerable." as N1
Registrar .. N1
Electorate .. N1

interface QuestionPoserInvitation {
Registrar
Electorate
--
addQuestion()
}

interface VoterInvitation {
Registrar
Electorate
--
getVoterFacet()
}
Expand All @@ -55,7 +55,7 @@ package "Registrar Vat" <<Rectangle>> {
note "instances held by\nindividual voters" as NVF
VoterFacet . NVF

Registrar --> VoterFacet : creates >
Electorate --> VoterFacet : creates >
}

object QuestionDetails {
Expand All @@ -69,7 +69,7 @@ object QuestionDetails {
counterInstance
}

note "QuestionDetails is a widely accessible record.\nverifiable copies are obtained from a Registrar" as N3
note "QuestionDetails is a widely accessible record.\nverifiable copies are obtained from an Electorate" as N3
QuestionDetails .. N3

package "VoteCounter Vat" <<Rectangle>> {
Expand All @@ -89,26 +89,26 @@ package "VoteCounter Vat" <<Rectangle>> {
---
submitVote(VoterHandle, ...positions)
}
note top: VoteCap is passed to and\ntightly held by Registrar.
note top: VoteCap is passed to and\ntightly held by Electorate.

note "unaware of voter registration.\n Only Registrar hands out voterFacets" as N2
note "unaware of voter registration.\n Only Electorate hands out voterFacets" as N2
VoteCounter .. N2

VoteCounter --> VoteCap : creates >
}

class ElectionManager {
Registrar
Electorate
addQuestion()
}
note top : ElectionManager is responsible\n for letting an appropriate\n party call addQuestion()

ElectionManager -.[#blue]-|> Registrar : verifiable
ElectionManager -.[#blue]-|> Electorate : verifiable

Registrar *. VoterInvitation
Registrar *. QuestionPoserInvitation
Electorate *. VoterInvitation
Electorate *. QuestionPoserInvitation
VoterInvitation -> VoterFacet
Registrar -> QuestionDetails : creates >
Electorate -> QuestionDetails : creates >
VoteCounter <|-.[#blue]-|> QuestionDetails : verifiable

VoterFacet --|> VoteCap : encapsulates
Expand Down
Loading

0 comments on commit 8554897

Please sign in to comment.