In one sentence. Changes to ComputeFlux must survive mandatory waiting periods, a staked deposit, and a threshold vote — and the founding admin key can be switched off permanently, with no way to switch it back on.
Picture it like this. A constitution with a demolition charge built into the throne. Every new country starts with somebody in charge, because at the beginning there's nobody to vote. What's unusual here is a lever the monarch can pull exactly once, which removes the throne and cannot be reversed — enforced not by a promise but by the absence of any code capable of undoing it.
Why it matters. "Progressive decentralization" is among the most abused phrases in crypto, because it's almost always a promise with no mechanism attached. This article is about what turning it into an actual mechanism looks like, including where the current defaults still fall short.
The interesting part is the one-way door.
Everything since Article 9 has been developer-facing infrastructure: retries, settlement, cross-chain sync, protocol translation, serialization, streaming, the API layer, and the login system from Article 16 that authenticates users into all of it. This article shifts altitude again, to protocol governance — who gets to change ComputeFlux, and how. The wallet addresses Article 16 derives from a user's email are the same addresses that submit proposals and cast votes below. Governance is where that identity does something other than authenticate.
ComputeFlux's Governance (Gov) contract runs a full lifecycle for protocol changes: proposal submission, deposit bonding, weighted voting, threshold-based approval, automatic execution. It's modeled on Polkadot's governance, adapted for a single chain, with a deliberate path from centralized control under Sudo to full decentralization once Sudo is disabled. Every decision here — Track time-lock periods, DecisionDeposit mechanics — takes a specific position on the trade between governance speed and governance security.
The Track Time-Lock Mechanism
A Track is a named governance pipeline with configurable time windows measured in blocks. Different proposal types route through different tracks: a routine parameter change might use a short track (hours), while a RuntimeUpgrade (replacing the entire WASM runtime) uses a long track (days or weeks). The Track system prevents majority attacks by forcing even popular proposals through mandatory deliberation periods.
PreparePeriod: after submission, a proposal sits in ProposalStatusPending for PreparePeriod blocks, during which the proposer must pay the DecisionDeposit. If unpaid within the window, the proposal expires — anyone can float an idea, but only those willing to stake capital advance to voting.
DecisionPeriod: once the deposit is paid and the prepare period elapses, the proposal moves to ProposalStatusOngoing and voting opens. The decision deadline is the proposal's deposit block plus DecisionPeriod — a block count that caps how long a proposal can sit in active voting before it must be settled one way or the other. (The name borrows from Polkadot OpenGov's decision_period field. OpenGov separately caps concurrent deciding referenda with max_deciding, an unrelated parameter; ComputeFlux is a hard deadline, where OpenGov re-queues expired referenda.)
ConfirmPeriod: when the vote tally meets both MinApproval (yes/(yes+no) ratio) and MinSupport (total votes/total supply) thresholds, the proposal doesn't pass immediately — it enters ProposalStatusConfirming and must maintain threshold support for ConfirmPeriod blocks. This is the cool-down: if a whale votes yes, pushes the proposal over threshold, then unlocks and withdraws their locked tokens (reducing total votes and thus the MinSupport numerator — total supply doesn't change), the confirm period catches the manipulation.
MinEnactmentPeriod: after confirmation, the proposal is ProposalStatusConfirmed but can't execute for MinEnactmentPeriod blocks — time for stakeholders to exit if they disagree, a form of market-based veto. If the change is controversial, token holders can sell before execution, depressing price and signaling dissent; the minimum period ensures even the fastest possible governance action can't be a surprise.
The Track parameters are themselves governable, creating a recursive check: a proposal to change a Track's periods must pass through that same Track's existing periods. Shortening MinEnactmentPeriod from 1,000 blocks to 10 would itself require waiting 1,000 blocks before taking effect.
DecisionDeposit Economics
The DecisionDeposit is the economic barrier between "I have an idea" and "the network must vote on this," serving three functions. Spam prevention: without a deposit, an attacker could submit thousands of proposals, exhausting voter attention; the deposit is configurable per-track, so minor-parameter tracks might require a 100-token deposit while a RuntimeUpgrade track requires 10,000. Commitment signaling: a high deposit signals the proposer's confidence — voters informally use deposit size as a heuristic for effort and seriousness. Slashing risk: a rejected proposal forfeits its deposit — a deliberate deviation from Polkadot OpenGov, which refunds the decision deposit whether the proposal passes or fails — creating a real cost for frivolous proposals and incentivizing consensus-building before formal submission. The deposit returns only if the proposal passes; a known limitation is that a proposal accepted but later found harmful still returns the deposit, so the proposer isn't held accountable for bad outcomes, only for wasting the network's time. DecisionDeposit also interacts with MaxBalance: a Track's proposals can only involve amounts up to MaxBalance in treasury spending, preventing a low-deposit track from authorizing a treasury transfer so large the deposit is trivial by comparison.
The Sudo Mechanism and the Path to Decentralization
Sudo is the administrator account — a single address that executes arbitrary contract calls without governance approval. It exists because a new blockchain can't bootstrap governance from day one: there are no token holders to vote, no established tracks, no precedent for what counts as a valid proposal. Sudo bridges the gap between genesis and mature governance.
The Sudo account is set once at genesis (or by system call) and can be transferred, but the critical design choice is that Sudo can be permanently disabled and never re-enabled:
func (d GovMutation) DisableSudo() error {
if err := d.ensureSudo(); err != nil { return err }
return d.sudoDisabled.Set(d.api.GetTxn(), true)
}
The sudoDisabled flag, once true, cannot be set back to false — there is no EnableSudo function. This is enforced by code, not convention: ensureSudo() reads sudoDisabled and returns ErrSudoDisabled if set, and no code path writes false to that storage slot.
The result is a one-way transition. The network launches with Sudo active and uses it to set up governance tracks, distribute initial tokens, and deploy core contracts. Once governance works and the community is ready, a Sudo-signed DisableSudo transaction hands all authority to the governance system permanently. From then on, every change — including changes to the Gov contract itself — goes through the Track-based proposal system.
Removing Sudo isn't the whole path to decentralization, though. What replaces it has to be robust enough for emergencies. Each Track's PreparePeriod and DecisionDeposit are independently configurable, so operators can in principle define a fast, low-deposit track for urgent fixes alongside slower tracks for routine and high-impact changes. The current default configuration doesn't appear to ship a dedicated emergency track out of the box.
RuntimeUpgrade: Self-Modifying Code Under Governance
RuntimeUpgrade replaces the blockchain's WASM runtime. It changes the constitution of what operations are even valid — the most powerful governance action available — and the safeguards are correspondingly strict.
- Dual authorization. It can be called by a system call from the DKG public key, representing the validator set, or by Sudo. Non-system callers are rejected unless they pass the Sudo check, and once Sudo is disabled, only system calls can trigger an upgrade. So even a passed
RuntimeUpgradeproposal still requires the validator set, acting collectively, to execute it. - Sequential versioning. The upgrade version must be exactly
currentVersion + 1. No skipping, no downgrading. That linear history is critical for deterministic state replay: the runtime version active at height H isinitialVersion + count(upgrades before H), computable from the upgrade log alone. - Activation height. The upgrade records a target block height — set at submission to a future height beyond the governance timeline — as
ActivationHeight, and the switch happens when that block executes. It's a clean cutover, and because the height is known in advance, validators get time to pre-load the new WASM blob before the critical block arrives.
The bytecode itself lives on-chain in the runtimeMetas mapping, keyed by version number. That preserves the chain's entire upgrade history for audit, and the CodeHash identifier lets validators verify received code against the on-chain record before executing any of it.
Proposal Lifecycle in Practice
Suppose a community member proposes cutting the Gateway's protocol fee from 1% to 0.5%. Here's the full path.
- Submission. The proposer calls
SubmitProposalwith aCallContenttargeting the Gateway contract'sSetProtocolFeemethod, on the "parameter changes" track. - Deposit. Within
PreparePeriod— say 100 blocks, roughly 10 minutes — the proposer puts up the required deposit, moving the proposal fromPendingtoOngoing. - Voting. During
DecisionPeriod, say 1,000 blocks or about 100 minutes, token holders vote withopinionYesandlockAmount. Those tokens are locked and unspendable for the vote's duration.VoteWeightderives from the lock amount; conviction-based weighting, where longer locks earn more weight, is in the schema but not yet implemented. - Confirmation. If the yes/no ratio clears
MinApproval(say 60%) and total votes clearMinSupport(say 10% of supply), the proposal entersConfirmPeriod. Miss either threshold by the end ofDecisionPeriodand the proposal is rejected and the deposit slashed. - Execution. Once
ConfirmPeriodandMinEnactmentPeriodelapse, anyone can callExecuteProposal. It runs the storedCallContentagainst the target contract and records the outcome inProposalResults— an auditable record of whether the proposal's effects actually landed.
Curves for Dynamic Thresholds
MinApproval and MinSupport are typed as Curve, not uint32 — functions mapping elapsed blocks since the decision period opened to a threshold value. The default is LinearDecreasingCurve, which starts high (100% approval required, say) and falls linearly to something low (0.5%) across the decision period.
That produces an interesting game-theoretic dynamic. Early in voting, a handful of highly convicted voters can pass a proposal: the threshold is high, but the voting pool is small. Late in the period, a large number of casual voters can pass or block one with much lower per-voter conviction, because the threshold has dropped while the pool has grown.
The curve's shape sets the balance between early-decision efficiency and late-stage inclusiveness. Three parameters control it: length, the blocks to decay over; perbill, the starting threshold in parts per billion; and floor, the minimum. The math runs in fixed-point, per-billion-precision arithmetic to avoid floating-point non-determinism: threshold = perbill - (perbill - floor) * elapsed / length, clamped to [floor, perbill].
Key Takeaways
- Deliberation is compulsory, even when a proposal is popular. Speed is treated here as an attack surface rather than a feature — the whole point is that a temporary majority can't act on the same day it forms.
- The waiting periods guard themselves. Shortening them requires waiting out the periods currently in force. A rushed change to the rules about rushing is impossible by construction, not by policy.
- A deposit separates "I have an idea" from "everyone must now vote on this." Rejected proposals forfeit it. The stated limitation: a proposal that passes and later turns out to be harmful still returns the deposit, so proposers are accountable for wasting attention, not for bad outcomes.
- The admin key can be permanently destroyed, and that's enforced by absence. There is no function to re-enable it. Not a commitment — a missing code path.
- The most dangerous action is the most constrained. Replacing the runtime requires dual authorization, strictly sequential version numbers, and a pre-announced activation block that lets validators prepare and verify beforehand.
- A gap worth naming: no emergency fast-track exists in the default configuration, even though the machinery to define one is there.
The Governance contract embodies progressive decentralization: a newborn blockchain needs centralized bootstrapping (Sudo), but the path away from it is irrevocable. The Track system forces mandatory deliberation even on popular changes, DecisionDeposit and Curve mechanics create economic incentives for honest participation, and the RuntimeUpgrade path — dual-authorized and sequentially versioned — makes the most dangerous governance action also the most carefully constrained.
Next — Article 18: Model Report Audit: governance decides what the rules are. It doesn't check whether the model you paid for is the model you got.