S18 — Governance Protocol
Specifies how rule changes and constitutional amendments are proposed, voted on, and enforced in Colibri.
1. Proposal Lifecycle
1.1 Proposal Types
| Type code | Category | Threshold | Process |
|---|---|---|---|
AX |
Constitutional amendment | >80% supermajority | 3-stage time-lock (30-day intervals) |
PR |
Protected rule (reputation-domain parameter) | >80% supermajority | 3-stage time-lock |
GOV |
Protocol rule (non-constitutional) | >66% quorum | Single vote, expires in 10 epochs |
AX type is validated at submission: if the rule diff touches any of AX-01 through AX-07, the proposal is rejected with INVARIANT_VIOLATION. Constitutional axioms are not subject to governance votes.
1.2 Proposal Fields
| Field | Type | Description |
|---|---|---|
id |
UUID | Assigned on submission |
proposer_id |
string | Identity of proposer |
description |
string | Human-readable summary |
rule_diff |
string | Machine-parseable diff of the rule change |
category |
string | Economics, Social, Invariants, General |
voting_mode |
enum | SIMPLE or QUADRATIC |
created_at |
epoch | Epoch of submission |
expires_at |
epoch | created_at + 10 (10-epoch window) |
status |
enum | See §1.3 |
1.3 Status Transitions
PENDING → ACTIVE → PASSED
→ REJECTED
→ SUPERSEDED (replaced by a successor proposal)
PENDING: submitted, voting not yet open (used for 3-stage time-lock waiting periods)ACTIVE: voting is openPASSED: threshold reached —activation_epochis set, rule change takes effect at that epochREJECTED: threshold not reached, or explicitly voted down, or expired without quorumSUPERSEDED: a newer revision of the same rule replaces this proposal
2. Voting Mechanisms
2.1 Standard Quorum (>66%)
Used for GOV category proposals.
- One voter, one vote.
- Double-voting is blocked by a per-proposal voter registry (
voter_id → boolean). - Minimum participation: 3 unique voters before any outcome is declared.
- Early resolution: if one side reaches 66% of accumulated votes, the proposal resolves immediately.
Vote weights:
votes_yes += 1 (per yes voter)
votes_no += 1 (per no voter)
Outcome check:
const total = votes_yes + votes_no;
if (unique_voters >= 3 && total > 0) {
if (votes_yes / total >= 0.66) status = "passed";
if (votes_no / total >= 0.66) status = "rejected";
}
2.2 Supermajority (>80%)
Used for PR and AX-adjacent proposals where constitutional protection applies.
Same mechanics as §2.1 but the threshold is 80% of participating votes. Combined with the 3-stage time-lock (§4).
2.3 Quadratic Voting (reputation-weighted)
An alternative voting mode where credits are spent to express preference intensity.
Core formula (from governance.py):
voting_power = math.sqrt(max(0, credits_spent))
cost_for_N_votes = N * N # N² credits to get N votes
Credit-to-power table:
| Credits | Voting power | Marginal cost of last vote |
|---|---|---|
| 1 | 1.00 | 1 |
| 4 | 2.00 | 3 |
| 9 | 3.00 | 5 |
| 16 | 4.00 | 7 |
| 25 | 5.00 | 9 |
| 100 | 10.00 | 19 |
| 400 | 20.00 | 39 |
| 10,000 | 100.00 | 199 |
This sub-linear scaling means doubling credits gives only ~41% more votes (sqrt(2x) / sqrt(x) = sqrt(2) ≈ 1.41).
Vote record fields:
voter_id string voter identity
proposal_id string target proposal
direction "yes"|"no"
credits_spent integer credits consumed
voting_power float sqrt(credits_spent)
timestamp float unix epoch
Outcome check (quadratic mode):
yes_ratio = votes_yes / (votes_yes + votes_no)
no_ratio = votes_no / (votes_yes + votes_no)
if unique_voters >= 3:
if yes_ratio >= 0.66: → PASSED
if no_ratio >= 0.66: → REJECTED
Why quadratic?
Linear voting (1 credit = 1 vote) lets wealthy actors dominate by accumulating credits. Quadratic voting compresses the power differential: 100× more credits buys 10× more influence. Voters who feel very strongly about a proposal can still outweigh indifferent voters, but cannot steamroll everyone.
Error conditions:
credits <= 0: rejected (QuadraticVoteRequiresCredits)voter already voted: rejected (DuplicateVote)proposal not ACTIVE or PENDING: rejected (ProposalNotOpen)
2.4 Entropy Injection
Activated when any proposal’s numeric parameter delta exceeds 5%.
Mechanism:
- VRF selects 10% of the eligible voter pool at random (using
ECVRF.construct_seedfromvrf.py). - Selected voters’ ballots count as equal-weight: 1 vote each, regardless of credits spent or reputation.
- Non-selected voters vote normally (quadratic or simple, per the proposal’s
voting_mode). - The VRF proof is recorded with the proposal and is publicly verifiable.
VRF seed construction:
chain_entropy = SHA-256(checkpoint.state_root || fork_id || genesis_hash)
vrf_seed = SHA-256(proposal_id || epoch || chain_entropy)
Rationale: High-stakes changes are most likely to attract coordinated blocs of high-reputation actors. The entropy injection ensures that a random sample of ordinary participants always has a proportional voice in consequential decisions.
Threshold for activation: 5% numeric delta. Examples:
- Increasing the reputation cap by 6% → entropy injection active
- Changing a UI label → no numeric delta, no injection
- Changing stake requirement from 100 to 103 (3%) → no injection
- Changing stake requirement from 100 to 106 (6%) → injection active
3. Constitutional Protection
The seven constitutional axioms (S01) cannot be amended by any governance vote. They are enforced at the proposal submission layer:
| Axiom | Enforcement rule |
|---|---|
| AX-01 Append-only events | Proposals to add delete/update operations on event tables are rejected |
| AX-02 Derived reputation | Proposals to add admin-writable reputation fields are rejected |
| AX-03 No absolute authority | Proposals to add bypass roles or permission exceptions are rejected |
| AX-04 Consequence windows | Proposals to remove the sanction admission window are rejected |
| AX-05 Subjective finality | Proposals to make finality consensus-based are rejected |
| AX-06 Right to exit | Proposals to increase exit penalty above 10% are rejected |
| AX-07 Technical sovereignty | Proposals that require cross-node state sharing for validation are rejected |
Enforcement is static (rule diff is parsed and checked at submission) and runtime (axiom guards in src/governance/axiom-enforcement.js reject any rule engine execution that would violate an axiom).
4. Time-Lock Protocol
Constitutional (AX) and protected-rule (PR) proposals require three consecutive votes, each separated by 30 days (approximately 30 epochs at 1 epoch = 24 hours):
Day 0: Stage 1 — Initial vote (>80% required)
Day 30: Stage 2 — Confirmation vote (>80% required)
Day 60: Stage 3 — Ratification (>80% required)
→ activation_epoch assigned
→ rule takes effect at activation_epoch
If any stage fails:
- Proposal status →
REJECTED - Minimum 1-epoch cooldown before resubmission
- Proposer may revise the rule diff and resubmit
Why three stages?
Rule changes are hard to reverse once activated. The 30-day gaps allow:
- Implementation teams to prepare migration code
- Network participants to exit via fork if they disagree
- Early-stage fraud or coordination attacks to be detected between stages
5. Exhaustion Protection
Governance resources (voter attention, network bandwidth, state space) are finite. Three rate limits enforce responsible proposal cadence (S01, PR-02):
5.1 Delta Cap
Any numeric parameter may change by at most ±10% per 6-month window (measured from the value at the start of the window, not the last-changed value). Proposals that would exceed the cap are rejected at submission.
Constitutional peg: parameters anchored to genesis values. A parameter that has already drifted ±30% from genesis requires a 3-stage supermajority (§4) to change further, even for changes within the 10%/6-month window.
5.2 Parameter Cooldown
A minimum 1 full epoch must elapse between changes to the same parameter. Proposals that would violate the cooldown are held in PENDING status until the cooldown expires, then move to ACTIVE.
5.3 Stability Period
A maximum of 2 parameters per domain may be changed simultaneously. After each change within a domain, a 2-epoch stability period must elapse before another change in that domain is accepted. This prevents cascading parameter interactions.
5.4 Concurrent Proposal Limit
No more than 5 proposals may be in ACTIVE status simultaneously per domain. Excess proposals queue in PENDING and are admitted as active slots open.
6. Implementation Status
Verified against source: 2026-04-07
| Feature | Status | Notes |
|---|---|---|
Proposal data model (Proposal, ProposalStatus, VotingMode) |
Spec-only | Python reference: governance.py lines 8–68 |
Simple voting (_cast_simple_vote) |
Spec-only | Python reference: governance.py lines 135–158 |
Quadratic vote record (QuadraticVote, calculate_cost, calculate_power) |
Spec-only | Python reference: governance.py lines 22–47 |
Quadratic casting (_cast_quadratic_vote) |
Spec-only | Python reference: governance.py lines 161–208 |
Quadratic outcome check (_check_quadratic_outcome) |
Spec-only | Python reference: governance.py lines 210–229 |
Proposal stats (get_proposal_stats) |
Spec-only | Python reference: governance.py lines 239–258 |
| Entropy injection (VRF 10% equal-weight selection) | Spec-only | VRF reference: vrf.py, ECVRF. Not yet integrated in governance.py. Specified in MASTER-TASKS P6.2 |
| 3-stage time-lock | Spec-only | Specified in MASTER-TASKS P6.1; not in governance.py |
| Exhaustion limits (delta cap, cooldown, stability period) | Spec-only | Specified in MASTER-TASKS P6.2; not in governance.py |
| Constitutional axiom guards | Spec-only | Specified in MASTER-TASKS P6.3 |
Node.js src/domains/governance/ |
Not started | Phase 6, depends on Phase 5 (ι) |
See Also
- S01 — Constitution — the seven axioms this spec cannot override
- S11 — Rule Engine — governance changes rule versions
- S06 — Consensus — BFT quorum is a prerequisite for governance finalization
- π — Governance concept — reader-friendly introduction to this spec
- ADR-002 — VRF Implementation — library choice for entropy injection VRF