diff --git a/CIP-0136/README.md b/CIP-0136/README.md new file mode 100644 index 000000000..9f3de4b33 --- /dev/null +++ b/CIP-0136/README.md @@ -0,0 +1,210 @@ +--- +CIP: 136 +Title: Governance metadata - Constitutional Committee votes +Category: Metadata +Status: Proposed +Authors: + - Ryan Williams + - Eystein Magnus Hansen +Implementors: [] +Discussions: + - https://github.com/cardano-foundation/CIPs/pull/878 +Created: 2024-07-17 +License: CC-BY-4.0 +--- + +## Abstract + +The Conway ledger era ushers in on-chain governance for Cardano via [CIP-1694 | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md), with the addition of many new on-chain governance artifacts. +Some of these artifacts support the linking of off-chain metadata, as a way to provide context to on-chain actions. + +The [CIP-100 | Governance Metadata](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0100) standard provides a base framework for how all off-chain governance metadata can be formed and handled. +This standard was intentionally limited in scope, so that it can be expanded upon by more specific subsequent CIPs. + +This proposal aims to provide a specification for the off-chain metadata vocabulary that can be used to give context to Constitutional Committee (CC) votes. + +## Motivation: why is this CIP necessary? + +The high-level motivation for this proposal is to provide a standard which improves legitimacy of Cardano's governance system. + +### Clarity for governance action authors + +Governance action authors are likely to have dedicated a significant amount of time to making their action meaningful and effective (as well as locking a significant deposit). +If this action is not able to be ratified by the CC, it is fair for the author to expect a reasonable explanation from the CC. + +Without reasonable context being provided by the CC votes, authors may struggle to iterate upon their actions, until they are deemed constitutional. +This situation could decrease perceived legitimacy in Cardano's governance. + +### Context for other voting bodies + +By producing a standard we hope to encourage all CC members to attach rich contextual metadata to their votes. +This context should show CC member's decision making is fair and reasonable. + +This context allows the other voting bodies to adequately check the power of the CC. + +### CC votes are different to other types of vote + +The CC and their votes are fundamentally very different from the other voting bodies. +This makes reusing standards from these voting bodies problematic. + +### Inclusion within interim constitution + +Cardano's [Interim Constitution Article VI Section 4](https://github.com/IntersectMBO/interim-constitution/blob/75155526ce850118898bd5eacf460f5d68ceb083/cardano-constitution-0.txt#L330) states: + +```txt +Constitutional Committee processes shall be transparent. +The Constitutional Committee shall publish each decision. +When voting no on a proposal, the Committee shall set forth the basis +for its decision with reference to specific Articles of this Constitution +that are in conflict with a given proposal. +``` + +This mandates that the CC must provide rationale for at least `no` votes. +Specifying a structure and common vocabulary for this improves the efforts to be transparent. + +### Tooling + +By creating and implementing these metadata standards we facilitate the creation of tooling that can read and write this data. +Such tooling greatly expands the reach and effectiveness of rationales as it allows for rich user interfaces to be created. +i.e. translation tools, rationale comparison tools, + +## Specification + +We define a specification for fields which can be added to CC votes. + +### Extended Body Vocabulary + +The following properties extend the potential vocabulary of [CIP-100](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0100)'s `body` property. + +#### `summary` + +- A short text field. Limited to `200` characters. +- Authors SHOULD use this field to clearly state their stance on the issue. +- Authors SHOULD use this field to succinctly describe their rationale. +- Authors SHOULD give a brief overview of the main arguments will support your position. +- This SHOULD NOT support markdown text styling. +- Compulsory. + +#### `rationaleStatement` + +- A long text field. +- Authors SHOULD use this field to fully describe their rationale. +- Authors SHOULD discuss their arguments in full detail. +- This field SHOULD support markdown text styling. +- Compulsory. + +#### `precedentDiscussion` + +- A long text field. +- The author SHOULD use this field to discuss what they feel is relevant precedent. +- This field SHOULD support markdown text styling. +- Optional. + +#### `counterargumentDiscussion` + +- A long text field. +- The author SHOULD use this field to discuss significant counter arguments to the position taken. +- This field SHOULD support markdown text styling. +- Optional. + +#### `conclusion` + +- A long text field. +- The author SHOULD use this field to conclude their rationale. +- This SHOULD NOT support markdown text styling. +- Optional. + +#### `internalVote` + +- A custom object field. +- This field SHOULD be used to reflect any internal voting decisions within CC member. +- This field SHOULD be used by members who are constructed from organizations or consortiums. +- Optional. + +##### `constitutional` + +- A positive integer. +- The author SHOULD use this field to represent a number of internal votes for the constitutionality of the action. + +##### `unconstitutional` + +- A positive integer. +- The author SHOULD use this field to represent a number of internal votes against the constitutionality of the action. + +##### `abstain` + +- A positive integer. +- The author SHOULD use this field to represent a number of internal abstain votes for the action. + +##### `didNotVote` + +- A positive integer. +- The author SHOULD use this field to represent a number of unused internal votes. + +### Extended `references` Vocabulary + +Here we extend CIP-100's `references` field. + +#### `RelevantArticles` + +- We add to CIP-100's `@type`s, with a type of `RelevantArticles`. +- Authors SHOULD use this field to list the relevant constitution articles to their argument. + +### Application + +CC must include all compulsory fields to be considered CIP-XXX compliant. +As this is an extension to CIP-100, all CIP-100 fields can be included within CIP-XXX compliant metadata. + +### Test Vector + +// todo + +See [test-vector.md](./test-vector.md) for examples. + +### Versioning + +This proposal should not be versioned, to update this standard a new CIP should be proposed. +Although through the JSON-LD mechanism further CIPs can add to the common governance metadata vocabulary. + +## Rationale: how does this CIP achieve its goals? + +// todo - fill in details + +### `summary` + +- useful for users to quickly see a preview of the whole rationale +- gives tooling the option to show a high level intro + +### `rationaleStatement` + +### `precedentDiscussion` + +### `counterargumentDiscussion` + +### `conclusion` + +### `internalVote` + +### `relevantArticles` + +## Path to Active + +### Acceptance Criteria + +- [ ] This standard is supported by two different tooling providers used to submit governance actions to chain. +- [ ] This standard is supported by two different chain indexing tools, used to read and render metadata. + +### Implementation Plan + +#### Solicitation of feedback + +- [ ] Run two online workshops to gather insights from stakeholders. +- [ ] Seek community answers on all [Open Questions](#open-questions). + +#### Implementation + +- [ ] Author to provide example metadata and schema files. + +## Copyright + +This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). diff --git a/CIP-0136/cip-136.common.jsonld b/CIP-0136/cip-136.common.jsonld new file mode 100644 index 000000000..e3ab95906 --- /dev/null +++ b/CIP-0136/cip-136.common.jsonld @@ -0,0 +1,54 @@ +{ + "@context": { + "@language": "en-us", + "CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + "CIP136": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0136/README.md#", + "hashAlgorithm": "CIP100:hashAlgorithm", + "body": { + "@id": "CIP136:body", + "@context": { + "references": { + "@id": "CIP100:references", + "@container": "@set", + "@context": { + "GovernanceMetadata": "CIP100:GovernanceMetadataReference", + "Other": "CIP100:OtherReference", + "label": "CIP100:reference-label", + "uri": "CIP100:reference-uri", + "RelevantArticles": "CIP136:RelevantArticles" + } + }, + "summary": "CIP136:summary", + "rationaleStatement": "CIP136:rationaleStatement", + "precedentDiscussion": "CIP136:precedentDiscussion", + "counterargumentDiscussion": "CIP136:counterargumentDiscussion", + "conclusion": "CIP136:conclusion", + "internalVote": { + "@id": "CIP136:internalVote", + "@context": { + "constitutional": "CIP136:constitutional", + "unconstitutional": "CIP136:unconstitutional", + "abstain": "CIP136:abstain", + "didNotVote": "CIP136:didNotVote" + } + } + } + }, + "authors": { + "@id": "CIP100:authors", + "@container": "@set", + "@context": { + "did": "@id", + "name": "http://xmlns.com/foaf/0.1/name", + "witness": { + "@id": "CIP100:witness", + "@context": { + "witnessAlgorithm": "CIP100:witnessAlgorithm", + "publicKey": "CIP100:publicKey", + "signature": "CIP100:signature" + } + } + } + } + } +} \ No newline at end of file diff --git a/CIP-0136/cip-136.common.schema.json b/CIP-0136/cip-136.common.schema.json new file mode 100644 index 000000000..742bfc7ce --- /dev/null +++ b/CIP-0136/cip-136.common.schema.json @@ -0,0 +1,155 @@ +{ + "title": "CIP-136 Common", + "description": "Metadata document for Cardano Constitutional Committee vote rationales, extending CIP-100", + "type": "object", + "required": ["hashAlgorithm", "authors", "body"], + "properties": { + "hashAlgorithm": { + "$ref": "#/definitions/hashAlgorithm" + }, + "authors": { + "$ref": "#/definitions/authors" + }, + "body": { + "$ref": "#/definitions/body" + } + }, + "definitions": { + "hashAlgorithm": { + "type": "string", + "enum": ["blake2b-256"], + "title": "Hash Algorithm", + "description": "The algorithm used to authenticate this document externally (CIP-100)" + }, + "authors": { + "title": "Authors", + "description": "The authors of this governance metadata (CIP-100)", + "type": "array", + "items": { + "$ref": "#/definitions/author" + } + }, + "author": { + "title": "Author", + "description": "An author endorsing the content of a metadata document (CIP-100)", + "type": "object", + "required": ["name", "witness"], + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "witness": { + "$ref": "#/definitions/witness" + } + } + }, + "Witness": { + "title": "Witness", + "description": "A witness proving that the author endorses the content of the metadata", + "type": "object", + "properties": { + "witnessAlgorithm": { + "title": "WitnessAlgorithm", + "type": "string", + "enum": [ + "ed25519" + ] + }, + "publicKey": { + "title": "PublicKey", + "type": "string" + }, + "signature": { + "title": "Signature", + "type": "string" + } + } + }, + "body": { + "title": "Body", + "description": "The body of the metadata document that is hashed to produce a signature (CIP-100)", + "type": "object", + "required": ["summary", "rationaleStatement"], + "properties": { + "references": { + "title": "References", + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "summary": { + "type": "string", + "title": "Summary", + "description": "" + }, + "rationaleStatement": { + "type": "string", + "title": "Rationale Statement", + "description": "" + }, + "precedentDiscussion": { + "type": "string", + "title": "Precedent Discussion", + "description": "" + }, + "counterargumentDiscussion": { + "type": "string", + "title": "Counterargument Discussion", + "description": "" + }, + "conclusion": { + "type": "string", + "title": "conclusion", + "description": "" + } + } + }, + "reference": { + "title": "Reference", + "description": "A reference to a document", + "type": "object", + "required": ["type", "label", "uri"], + "properties": { + "type": { + "type": "string", + "enum": ["GovernanceMetadata", "Other", "RelevantArticles"], + "title": "Type" + }, + "label": { + "type": "string", + "title": "Label" + }, + "uri": { + "type": "string", + "title": "URI" + } + } + }, + "internalVote": { + "title": "Internal Vote", + "description": "", + "type": "object", + "required": ["constitutional", "unconstitutional", "abstain", "didNotVote"], + "properties": { + "constitutional": { + "type": "integer", + "title": "" + }, + "unconstitutional": { + "type": "integer", + "title": "" + }, + "abstain": { + "type": "integer", + "title": "" + }, + "didNotVote": { + "type": "integer", + "title": "" + } + } + } + } +} \ No newline at end of file diff --git a/CIP-0136/examples/treasury-withdrawal-unconstitutional.jsonld b/CIP-0136/examples/treasury-withdrawal-unconstitutional.jsonld new file mode 100644 index 000000000..41e8aa6e8 --- /dev/null +++ b/CIP-0136/examples/treasury-withdrawal-unconstitutional.jsonld @@ -0,0 +1,91 @@ +{ + "@context": { + "@language": "en-us", + "CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + "CIP136": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0136/README.md#", + "hashAlgorithm": "CIP100:hashAlgorithm", + "body": { + "@id": "CIP136:body", + "@context": { + "references": { + "@id": "CIP100:references", + "@container": "@set", + "@context": { + "GovernanceMetadata": "CIP100:GovernanceMetadataReference", + "Other": "CIP100:OtherReference", + "label": "CIP100:reference-label", + "uri": "CIP100:reference-uri", + "RelevantArticles": "CIP136:RelevantArticles" + } + }, + "summary": "CIP136:summary", + "rationaleStatement": "CIP136:rationaleStatement", + "precedentDiscussion": "CIP136:precedentDiscussion", + "counterargumentDiscussion": "CIP136:counterargumentDiscussion", + "conclusion": "CIP136:conclusion", + "internalVote": { + "@id": "CIP136:internalVote", + "@container": "@set", + "@context": { + "constitutional": "CIP136:constitutional", + "unconstitutional": "CIP136:unconstitutional", + "abstain": "CIP136:abstain", + "didNotVote": "CIP136:didNotVote" + } + } + } + }, + "authors": { + "@id": "CIP100:authors", + "@container": "@set", + "@context": { + "did": "@id", + "name": "http://xmlns.com/foaf/0.1/name", + "witness": { + "@id": "CIP100:witness", + "@context": { + "witnessAlgorithm": "CIP100:witnessAlgorithm", + "publicKey": "CIP100:publicKey", + "signature": "CIP100:signature" + } + } + } + } + }, + "hashAlgorithm": "blake2b-256", + "body": { + "summary": "Ryan using treasury funds to buy an island is unconstitutional.", + "rationaleStatement": "The Cardano treasury is not meant to be used for personal gain, it should be for the benefit of the community.", + "precedentDiscussion": "No precedent", + "counterargumentDiscussion": "It would be pretty cool.", + "conclusion": "In conclusion spending the treasury to benefit a single dude, bad.", + "internalVote": { + "constitutional": 1, + "unconstitutional": 0, + "abstain": 0, + "didNotVote": 0 + }, + "references": [ + { + "@type": "relevantArticles", + "label": "Article III section 8.", + "uri": "https://github.com/IntersectMBO/interim-constitution/blob/main/cardano-constitution-0.txt#L231" + }, + { + "@type": "Other", + "label": "A cool island for Ryan", + "uri": "https://www.google.com/maps/place/World's+only+5th+order+recursive+island/@62.6511465,-97.7946829,15.75z/data=!4m14!1m7!3m6!1s0x5216a167810cee39:0x11431abdfe4c7421!2sWorld's+only+5th+order+recursive+island!8m2!3d62.651114!4d-97.7872244!16s%2Fg%2F11spwk2b6n!3m5!1s0x5216a167810cee39:0x11431abdfe4c7421!8m2!3d62.651114!4d-97.7872244!16s%2Fg%2F11spwk2b6n?authuser=0&entry=ttu" + } + ] + }, + "authors": [ + { + "name": "Ryan Williams", + "witness": { + "witnessAlgorithm": "ed25519", + "publicKey": "7ea09a34aebb13c9841c71397b1cabfec5ddf950405293dee496cac2f437480a", + "signature": "a476985b4cc0d457f247797611799a6f6a80fc8cb7ec9dcb5a8223888d0618e30de165f3d869c4a0d9107d8a5b612ad7c5e42441907f5b91796f0d7187d64a01" + } + } + ] +} diff --git a/CIP-0136/test-vector.md b/CIP-0136/test-vector.md new file mode 100644 index 000000000..d71054799 --- /dev/null +++ b/CIP-0136/test-vector.md @@ -0,0 +1,50 @@ +# Test Vector for CIP-136 + +Here we create some useful definitions and some examples. + +## Common Context + +### Common Fields + +The context fields which could be added to CIP-136 compliant jsonld files. +See [cip-0136.common.jsonld](./cip-0136.common.jsonld). + +### Common Fields Schema + +A json schema for the common context fields. +See [cip-0136.common.schema.json](./cip-0136.common.schema.json). + +## Examples + +### Treasury Withdrawal is Unconstitutional + +Example metadata document file: [treasury-withdrawal-unconstitutional.jsonld](./examples/treasury-withdrawal-unconstitutional.jsonld). +Blake2b-256 of the file content (to go onchain): `` + +#### Intermediate files + +Files produced to articulate process, these are not necessary in implementations. + +Body files, used to correctly generate author's witness: +- [treasury-withdrawal-unconstitutional.body.jsonld](./examples/treasury-withdrawal-unconstitutional.body.jsonld) +- [treasury-withdrawal-unconstitutional.body.nq](./examples/treasury-withdrawal-unconstitutional.body.nq) + +Blake2b-256 hash digest of canonicalized body: `` + +## How-to Recreate Examples + +This tutorial creates additional intermediate files, these are not required in implementations but are shown here to articulate the process. + +### Author + +Keys used for author property, provided here for convenience. + +Private extended signing key (hex): `105d2ef2192150655a926bca9cccf5e2f6e496efa9580508192e1f4a790e6f53de06529129511d1cacb0664bcf04853fdc0055a47cc6d2c6d205127020760652` + +Public verification key (hex): +`7ea09a34aebb13c9841c71397b1cabfec5ddf950405293dee496cac2f437480a` + +Public verification key hash (hex): `0fdc780023d8be7c9ff3a6bdc0d8d3b263bd0cc12448c40948efbf42` + +Mainnet public enterprize address (hex): `610fdc780023d8be7c9ff3a6bdc0d8d3b263bd0cc12448c40948efbf42` +