Mechanisms
A mechanism is the pure aggregation function that converts submitted choice inputs plus configured parameters into a binding outcome. Mechanisms are deterministic — same inputs, same parameters, same seed always produce the same outcome.
Why determinism matters
Determinism is what makes receipts standalone-verifiable. Anyone with the receipt + the room’s public key can re-run the mechanism on the recorded inputs and confirm the outcome was computed correctly. The outcome is a pure function of the recorded inputs — anyone can recompute it, and a host that computed anything else would be contradicted by its own receipt.
Built-in mechanisms
| Mechanism | Ballot shape | Use case |
|---|---|---|
simple_majority | single option | Binary or narrow decisions where a strict majority should be required |
supermajority | single option | High-stakes ratification and safety gates |
plurality | single option | Baseline multi-option selection; top option wins |
approval | option array | Find the broadest viable intersection, especially scheduling |
ranked_choice | ranked option array | IRV compatibility and familiar public ranked-choice semantics |
ranked_pairwise | ranked option array | Pairwise preference aggregation for serious mechanism comparisons |
score_vote | option-to-score map | Confidence/intensity-aware selection |
quadratic_vote | option-to-credit map | Costly conviction under a fixed credit budget |
budget_allocation and quadratic_funding are reserved identifiers for post-v0.1 allocation mechanisms — not part of the v0.1 set of eight. conviction_vote, liquid delegation, and custom third-party mechanisms remain deferred.
simple_majority parameters
The default v0.1 mechanism takes:
{
"kind": "simple_majority",
"options": ["yes", "no", "maybe"],
"ballot_mode": "single_choice",
"quorum": 0.5, // fraction (v0.1 engine accepts both fraction or count)
"pass_threshold": 0.5, // fraction of cast votes needed to pass
"tie_break": "no_pass" // no_pass | first_listed | random_seeded
}Resolution algorithm:
-
Quorum check. If
votes.length / eligible_voters < quorum, return{ status: "failed", failure_reason: "quorum_unmet" }. -
Per-option tally. Sum votes per option.
-
Winner selection. The option with the most votes wins, IF its share of cast votes meets
pass_threshold. Otherwise:tie_break: "no_pass"→ no winner; outcome isno_passtie_break: "first_listed"→ the first option inoptionsorder winstie_break: "random_seeded"→ deterministic seeded RNG picks among tied options
-
Output.
{ status: "completed", outcome: "pass" | "no_pass", winner, per_option_score, trace }.
Why “pure” matters operationally
The mechanism implementations ship in the open-source @grp-protocol/engine package. It takes a typed input and returns a typed output. No side effects, no I/O, no time-of-day dependencies. This means:
- The mechanism can be re-run by any verifier holding the recorded choice inputs and parameters.
- The mechanism can be tested with property-based tests (no fixtures or mocks).
- The mechanism can run in a sim suite of synthetic agents to stress-test against adversarial scenarios.
- Different rooms can run different mechanisms; the receipt records which.
Cross-references
- Receipts — what the mechanism’s output becomes
- Specification: Mechanisms — normative spec
- Examples — different mechanisms across scenarios