|
| 1 | +# AXONE Governance Contract (`axone-gov`) |
| 2 | + |
| 3 | +The AXONE Governance contract attaches **governance capabilities** to a resource represented by an **Abstract Account (AA)**. |
| 4 | + |
| 5 | +In the AXONE protocol, resources are first-class citizens. Instantiating this contract on a resource AA equips that resource with an explicit, programmable governance layer. |
| 6 | + |
| 7 | +## Core Concepts |
| 8 | + |
| 9 | +### Resource & Abstract Account |
| 10 | + |
| 11 | +In AXONE, every resource is represented by an **Abstract Account (AA)**. The AA acts as the canonical on-chain identity and execution context for the resource. |
| 12 | + |
| 13 | +The `axone-gov` contract is deployed **on top of** an AA. Doing so does not create governance in isolation: it **binds governance to the resource itself**. |
| 14 | + |
| 15 | +### Constitution |
| 16 | + |
| 17 | +A **constitution** is a Prolog program stored by the contract. It defines the governance rules of the resource. |
| 18 | + |
| 19 | +Concretely, the constitution: |
| 20 | + |
| 21 | +- Encodes governance rules as Prolog predicates |
| 22 | +- May query on-chain facts via the AXONE logic module |
| 23 | +- Is the single source of truth for all governance decisions |
| 24 | + |
| 25 | +The constitution exposes the following entrypoints: |
| 26 | + |
| 27 | +- `governance:decide/2` |
| 28 | +- `governance:decide/3` |
| 29 | + |
| 30 | +These predicates are validated at contract instantiation. |
| 31 | + |
| 32 | +### Case |
| 33 | + |
| 34 | +A **Case** represents the context submitted for a governance decision. |
| 35 | + |
| 36 | +It is expressed as a Prolog dictionary, conventionally written as `ctx{...}`. A case may include any contextual elements required by the constitution, such as: |
| 37 | + |
| 38 | +- intents |
| 39 | +- actors |
| 40 | +- subjects |
| 41 | +- external facts or signals |
| 42 | + |
| 43 | +On-chain facts (e.g. verifiable credentials, resource state) are **not** passed through the case. They are queried directly by the constitution itself. |
| 44 | + |
| 45 | +## Governance Decisions |
| 46 | + |
| 47 | +The core governance operation is the evaluation of a case through the constitution. |
| 48 | + |
| 49 | +Depending on the query mode, the constitution returns: |
| 50 | + |
| 51 | +- a **verdict** (`decide/2`) |
| 52 | +- or a **verdict with motivation** (`decide/3`) |
| 53 | + |
| 54 | +Both the verdict and the motivation are arbitrary Prolog terms. The contract does not constrain their structure. |
| 55 | + |
| 56 | +## Constitutional Revision |
| 57 | + |
| 58 | +The constitution is not static. It can be revised through a governance-controlled process. |
| 59 | + |
| 60 | +A constitutional revision is performed by submitting an execution message that: |
| 61 | + |
| 62 | +1. Proposes a new constitution |
| 63 | +2. Evaluates the **current** constitution on a case containing the intent `gov:revise_constitution` |
| 64 | + |
| 65 | +The revision is applied **only if** the verdict returned by the constitution is exactly: |
| 66 | + |
| 67 | +```prolog |
| 68 | +gov:permitted |
| 69 | +``` |
| 70 | + |
| 71 | +Any other verdict (atom or compound term) results in a refusal. |
| 72 | + |
| 73 | +## InstantiateMsg |
| 74 | + |
| 75 | +Instantiate message. |
| 76 | + |
| 77 | +In Axone, a resource is represented by an Abstract Account (AA). Instantiating this `gov` app on the resource AA attaches a **governance capability** to that resource. |
| 78 | + |
| 79 | +A **constitution** (or governance constitution) is the Prolog program stored by this contract. It expresses the resource governance as rules that decide cases and may query on-chain facts via the Axone logic module. |
| 80 | + |
| 81 | +The `constitution` payload MUST be a UTF-8 encoded Prolog program. |
| 82 | + |
| 83 | +On instantiation, the contract validates that the program can be evaluated and that it defines the required entrypoints: |
| 84 | + |
| 85 | +- `decide/2` as `governance:decide(+Case, -Verdict)` |
| 86 | + |
| 87 | +- `decide/3` as `governance:decide(+Case, -Verdict, -Motivation)` |
| 88 | + |
| 89 | +Where: |
| 90 | + |
| 91 | +- `Case` is a Prolog dict term (typically `ctx{...}`) representing the decision context. It can include any key-value facts required by the constitution (e.g. intent, actor, subject). |
| 92 | + |
| 93 | +- `Verdict` is an arbitrary Prolog term (atom or compound) representing the decision outcome. |
| 94 | + |
| 95 | +- `Motivation` is an arbitrary Prolog term intended to justify the verdict (e.g. applicable articles, findings, interpretation rules). |
| 96 | + |
| 97 | +| variant | description | |
| 98 | +| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 99 | +| InstantiateMsg | **object**. Instantiate message.<br /><br />In Axone, a resource is represented by an Abstract Account (AA). Instantiating this `gov` app on the resource AA attaches a **governance capability** to that resource.<br /><br />A **constitution** (or governance constitution) is the Prolog program stored by this contract. It expresses the resource governance as rules that decide cases and may query on-chain facts via the Axone logic module.<br /><br />The `constitution` payload MUST be a UTF-8 encoded Prolog program.<br /><br />On instantiation, the contract validates that the program can be evaluated and that it defines the required entrypoints:<br /><br />- `decide/2` as `governance:decide(+Case, -Verdict)`<br /><br />- `decide/3` as `governance:decide(+Case, -Verdict, -Motivation)`<br /><br />Where:<br /><br />- `Case` is a Prolog dict term (typically `ctx{...}`) representing the decision context. It can include any key-value facts required by the constitution (e.g. intent, actor, subject).<br /><br />- `Verdict` is an arbitrary Prolog term (atom or compound) representing the decision outcome.<br /><br />- `Motivation` is an arbitrary Prolog term intended to justify the verdict (e.g. applicable articles, findings, interpretation rules). | |
| 100 | + |
| 101 | +## ExecuteMsg |
| 102 | + |
| 103 | +Execute messages. |
| 104 | + |
| 105 | +### ExecuteMsg::revise_constitution |
| 106 | + |
| 107 | +Propose a constitutional revision (constitutional amendment). |
| 108 | + |
| 109 | +The contract asks the **current** constitution to decide whether the revision is allowed by evaluating a case that includes the intent `gov:revise_constitution`. |
| 110 | + |
| 111 | +The contract builds the decision case by merging the caller-provided `case` (if any) with contract-enriched context. The complete case structure is: |
| 112 | + |
| 113 | +`prolog ctx{ intent: 'gov:revise_constitution', 'gov:proposed_constitution_hash': <hex_string>, % SHA256 of constitution bytes (authoritative) 'gov:module': module{ id: <atom>, % Contract module ID (e.g., 'axone:axone-gov') version: <atom> % Contract version (e.g., '1.2.3') }, 'gov:cosmwasm': cosmwasm{ message: message{ sender: <atom>, % Bech32 address of message sender funds: [coin(Amount, Denom), ...] % List of coins sent with message }, block: block{ height: <integer>, % Block height time: <integer>, % Block timestamp (seconds since epoch) tx_index: <integer> % Transaction index } }, <caller_provided_keys>: <caller_provided_values> % Any additional keys from caller's case } ` |
| 114 | + |
| 115 | +The revision is applied only if the decision verdict is exactly the atom `gov:permitted`. Any other verdict (atom or compound term) refuses the revision. |
| 116 | + |
| 117 | +| parameter | description | |
| 118 | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
| 119 | +| `revise_constitution` | _(Required.) _ **object**. | |
| 120 | +| `revise_constitution.case` | **string\|null**. Optional additional decision context provided by the caller.<br /><br />This is a Prolog dict term string (typically `ctx{...}`) merged into the case used to evaluate the `gov:revise_constitution` intent. | |
| 121 | +| `revise_constitution.constitution` | _(Required.) _ **[Binary](#binary)**. The proposed new constitution (UTF-8 Prolog program bytes). | |
| 122 | + |
| 123 | +## QueryMsg |
| 124 | + |
| 125 | +Query messages. |
| 126 | + |
| 127 | +### QueryMsg::constitution |
| 128 | + |
| 129 | +Return the currently stored constitution (raw Prolog program bytes). |
| 130 | + |
| 131 | +| parameter | description | |
| 132 | +| -------------- | -------------------------- | |
| 133 | +| `constitution` | _(Required.) _ **object**. | |
| 134 | + |
| 135 | +### QueryMsg::constitution_status |
| 136 | + |
| 137 | +Return the current constitution metadata (revision and hash). |
| 138 | + |
| 139 | +| parameter | description | |
| 140 | +| --------------------- | -------------------------- | |
| 141 | +| `constitution_status` | _(Required.) _ **object**. | |
| 142 | + |
| 143 | +### QueryMsg::decide |
| 144 | + |
| 145 | +Decide a case using the stored constitution. |
| 146 | + |
| 147 | +The `case` parameter is a Prolog dict term string (typically `ctx{...}`) representing the decision context. This is passed as the `Case` argument to `governance:decide/2` or `governance:decide/3`. |
| 148 | + |
| 149 | +Example: |
| 150 | + |
| 151 | +`ctx{intent:read, user:"did:example:123", object:"obj:42"}` |
| 152 | + |
| 153 | +- If `motivated` is `false`, the contract calls `decide/2` and returns only the verdict. - If `motivated` is `true`, the contract calls `decide/3` and returns both verdict and motivation. |
| 154 | + |
| 155 | +The returned `verdict` is an arbitrary Prolog term (atom or compound), for example: |
| 156 | + |
| 157 | +- `gov:permitted` - `gov:forbidden` - `pay("did:...", 1000)` |
| 158 | + |
| 159 | +The optional `motivation` is an arbitrary Prolog term returned by the constitution and intended to justify the verdict (e.g. grounds/articles, findings, interpretation rules). |
| 160 | + |
| 161 | +| parameter | description | |
| 162 | +| ------------------ | --------------------------- | |
| 163 | +| `decide` | _(Required.) _ **object**. | |
| 164 | +| `decide.case` | _(Required.) _ **string**. | |
| 165 | +| `decide.motivated` | _(Required.) _ **boolean**. | |
| 166 | + |
| 167 | +## MigrateMsg |
| 168 | + |
| 169 | +Migrate message. |
| 170 | + |
| 171 | +Reserved for future migrations. |
| 172 | + |
| 173 | +### MigrateMsg::MigrateMsg |
| 174 | + |
| 175 | +Migrate message. |
| 176 | + |
| 177 | +Reserved for future migrations. |
| 178 | + |
| 179 | +| parameter | description | |
| 180 | +| --------- | ----------- | |
| 181 | + |
| 182 | +## Responses |
| 183 | + |
| 184 | +### constitution |
| 185 | + |
| 186 | +Response returned by `QueryMsg::Constitution`. |
| 187 | + |
| 188 | +| property | description | |
| 189 | +| ------------ | ----------------------------------------------------------------------------------------- | |
| 190 | +| `governance` | _(Required.) _ **[Binary](#binary)**. The stored constitution (raw Prolog program bytes). | |
| 191 | + |
| 192 | +### constitution_status |
| 193 | + |
| 194 | +Response returned by `QueryMsg::ConstitutionStatus`. |
| 195 | + |
| 196 | +| property | description | |
| 197 | +| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 198 | +| `constitution_hash` | _(Required.) _ **[Binary](#binary)**. The stored constitution hash (32 bytes, sha256). | |
| 199 | +| `constitution_revision` | _(Required.) _ **integer**. The constitution revision number.<br /><br />The initially instantiated constitution has revision `0`. Each successful revision increments it by `1`. | |
| 200 | + |
| 201 | +### decide |
| 202 | + |
| 203 | +Response returned by `QueryMsg::Decide`. |
| 204 | + |
| 205 | +| property | description | |
| 206 | +| ------------ | -------------------------------------------------------------------------------------------- | |
| 207 | +| `motivation` | **string\|null**. Optional motivation term returned as the third argument of `decide/3`. | |
| 208 | +| `verdict` | _(Required.) _ **string**. The verdict returned by the constitution as a Prolog term string. | |
| 209 | + |
| 210 | +## Definitions |
| 211 | + |
| 212 | +### Binary |
| 213 | + |
| 214 | +A string containing Base64-encoded data. |
| 215 | + |
| 216 | +| type | |
| 217 | +| ----------- | |
| 218 | +| **string**. | |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +_Rendered by [Fadroma](https://fadroma.tech) ([@fadroma/schema 1.1.0](https://www.npmjs.com/package/@fadroma/schema)) from `axone-gov.json` (`9c380ee3f4499a8b`)_ |
0 commit comments