# Governance

> On-chain governance in NeuroChain — who can propose and vote, stake-weighted voting, quorum and threshold, parameter changes with their allowed ranges, and the full list of governance parameters.

Source: https://docs.nro.world/learn/governance

Protocol parameters — minimum stake, rewards, gas budget, slashing, AI thresholds — are changed by **stake-weighted on-chain votes**, not by node operators editing config.

![Proposal lifecycle: a staker proposes, the proposal is active for its voting window while stakers vote weighted by self-stake; when the window ends it passes if votes reach 20% of total stake and yes is over 50% of votes, otherwise it is rejected; a passed PARAM_CHANGE updates the parameter if the value is within its allowed range](/diagrams/governance-lifecycle.svg)

## Proposing

| Rule | Value |
|------|-------|
| Who | A signed request from any address; a `.human` proposer must hold self-stake of at least `min_stake` |
| Kinds | `text` (signalling only) or `PARAM_CHANGE` (changes one parameter) |
| Voting window | 100 to `max_voting_duration_blocks` (default 1 000 000) blocks; 1 000 if not given |
| Limits | Title 200 characters, description 5 000, payload 10 KB |

A `PARAM_CHANGE` carries its change as a payload:

```json
{ "param_key": "max_block_gas", "param_value": "20000" }
```

The proposal is a [signed operation](./wallet#signed-operations) to `neuro:system.governance`; it is recorded in consensus, so every validator holds the identical proposal from the same height.

## Voting

- Only addresses with **self-stake** can vote. The vote weight is the voter's self-stake, read from chain state when the vote is applied. Delegations carry no vote.
- Stake added **after** a proposal was created cannot vote on it — this stops buying stake just to swing a vote.
- One vote per address per proposal: yes or no, final.
- Votes are signed operations recorded in consensus.

## Outcome

When the voting window ends:

| Check | Default | Proposal field |
|-------|---------|----------------|
| **Quorum** — yes + no weight ≥ this share of total self-stake | 20% | `quorum_bps` = 2 000 |
| **Threshold** — yes weight > this share of the votes cast | 50% | `threshold_bps` = 5 000 |

Both met → `passed`; otherwise → `rejected`. A passed `PARAM_CHANGE` updates the parameter — unless the new value is outside that parameter's allowed range, in which case it is refused and the old value stays.

::: warning Finalization status
<Badge type="warning" text="experimental" /> Creating proposals and voting run in consensus. Closing a proposal and applying a passed parameter change currently happens on each node when it serves the proposal list (`GET /api/v1/governance/proposals`), not in the block commit. Moving finalization into the commit path is planned; until then, check a parameter on every validator after a change passes.

**How it is tested:** `test_apply_tx_governance_propose_and_vote_in_consensus` in the node covers proposal and vote application; range checks are covered by the parameter tests (`test_deploy_risk_threshold_governance`, `test_deploy_security_governance_override`).
:::

## Parameters

Current values: `GET /api/v1/governance/params`. Some can also be set per node at start-up through an environment variable — intended for test networks.

### Staking and consensus

| Parameter | Default | Allowed range | Env override |
|-----------|---------|---------------|--------------|
| `min_stake` | 10 000 NRO (in uNRO) | 1 to 10¹⁵ uNRO | — |
| `unbonding_blocks` | 1 512 000 | 1 to 10⁹ | `NEUROCHAIN_UNBONDING_BLOCKS` |
| `base_apy_bps` | 1 200 (12%) | 0 to 100 000 | — |
| `genesis_apy_bps` | 2 400 (24%) | 0 to 100 000 | — |
| `reward_interval_blocks` | 216 000 | 1 to 10⁹ | `NEUROCHAIN_REWARD_INTERVAL_BLOCKS` |
| `blocks_per_year` | 78 840 000 | 1 to 10⁹ | — |
| `max_commission_bps` | 2 000 (20%) | — | — |
| `max_block_gas` | 10 000 | 1 to 10⁹ | — |
| `slash_fraction_double_sign_bps` | 500 (5% of `min_stake`) | 0 to 10 000 | `NEUROCHAIN_SLASH_FRACTION_DOUBLE_SIGN_BPS` |
| `slash_reward_fraction_bps` | 100 (1% to the reporter) | 0 to 10 000 | `NEUROCHAIN_SLASH_REWARD_FRACTION_BPS` |
| `slash_double_vote_bps` | 500 | 0 to 10 000 | — |
| `jail_blocks` | 10 000 | 1 to 10⁹ | `NEUROCHAIN_JAIL_BLOCKS` |
| `slash_evidence_window` | 10 000 | 1 to 10⁹ | `NEUROCHAIN_SLASH_EVIDENCE_WINDOW` |
| `quorum_bps` | 2 000 | 1 to 10 000 | — |
| `threshold_bps` | 5 000 | 1 to 10 000 | — |

### AI security

| Parameter | Default | Allowed range | Meaning |
|-----------|---------|---------------|---------|
| `deploy_security_enabled` | 1 | 0 or 1 | VMGuardian pre-deploy gate on/off (emergency switch) |
| `deploy_risk_threshold` | 80 | 0 to 100 | Deploy refused at risk score ≥ 0.80 |
| `sentinel_enabled` | 1 | 0 or 1 | Sentinel transaction scoring on/off |
| `sentinel_reject_threshold` | 85 | — | Transaction refused at score ≥ 0.85 |
| `sentinel_policy_enabled` | 0 | — | Graduated policy layer (hold / confirm) — off by default |
| `sentinel_hold_threshold` | 60 | — | Score from which a transfer is held |
| `sentinel_stepup_threshold` | 70 | — | Score from which the owner must confirm |
| `sentinel_hold_blocks` | 50 | — | Delay before a held transfer is released |
| `sentinel_confirm_expiry_blocks` | 1 000 | — | Wait for owner confirmation before refund |
| `sentinel_agent_confirm_threshold` | 60 | — | Score from which a session-key transfer needs the owner |
| `trust_activation_blocks` | 300 | — | Delay before a new trusted recipient counts |

The Sentinel policy parameters also have `NEUROCHAIN_SENTINEL_*` and `NEUROCHAIN_TRUST_ACTIVATION_BLOCKS` environment overrides; see [Sentinel](/ai/sentinel).

### Native assets and exchange

| Parameter | Default | Meaning |
|-----------|---------|---------|
| `asset_issue_fee` | 1 000 NRO | Fee for issuing a native asset |
| `asset_max_decimals` | 18 | Highest number of decimals an asset may have |
| `dex_shard` | 0 | Shard that holds asset and exchange records |

The exchange (AMM) also has parameters for the liquidity-provider fee, protocol fee, minimum liquidity, swaps per pool per block, and an emergency on/off switch; the [REST reference](/reference/rest) lists them with their current values.

A dash in *Allowed range* means the node does not yet check the range of that parameter when a change passes — propose values carefully.

## API

| Action | Endpoint |
|--------|----------|
| Propose | `POST /api/v1/governance/propose` |
| Vote | `POST /api/v1/governance/:id/vote` |
| List proposals | `GET /api/v1/governance/proposals?status=&limit=&offset=` |
| One proposal | `GET /api/v1/governance/:id` |
| Parameters | `GET /api/v1/governance/params` |
