From 5e62204c1d960d2913fd41139e3671c4e3209053 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Sun, 7 Dec 2025 14:21:56 +0300 Subject: [PATCH 01/10] feat(docs): Introduce `conditions` metadata field and Conditions document type: - Added a new `conditions` metadata field to parameter documents and user-submitted documents, specifying required terms and conditions. - Created a new Conditions document type to define terms users must accept before submitting documents, including validation rules and business logic for acceptance. - Updated the `signed_doc.json` specification to include the new Conditions document type and its associated metadata. - Enhanced documentation to clarify the role of conditions in the document submission process and validation requirements. --- .../08_concepts/signed_doc/docs/.pages | 1 + .../08_concepts/signed_doc/docs/conditions.md | 393 ++++++++++++++++++ .../08_concepts/signed_doc/metadata.md | 92 ++++ specs/signed_doc.json | 139 +++++++ 4 files changed, 625 insertions(+) create mode 100644 docs/src/architecture/08_concepts/signed_doc/docs/conditions.md diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/.pages b/docs/src/architecture/08_concepts/signed_doc/docs/.pages index 8669c9fee0..9bee0998a4 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/.pages +++ b/docs/src/architecture/08_concepts/signed_doc/docs/.pages @@ -7,6 +7,7 @@ nav: - Category Parameters: category_parameters.md - Category Parameters Form Template: category_parameters_form_template.md - Comment Moderation Action: comment_moderation_action.md + - Conditions: conditions.md - Contest Ballot: contest_ballot.md - Contest Ballot Checkpoint: contest_ballot_checkpoint.md - Contest Delegation: contest_delegation.md diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md new file mode 100644 index 0000000000..159798f382 --- /dev/null +++ b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md @@ -0,0 +1,393 @@ +# Conditions + +> **DRAFT STATUS** +> This document is currently in **DRAFT** status. Development should **NOT** begin until this specification is formally released. +> This specification is subject to change without notice. + +## Description + +Conditions documents are simple document types published by authoritative parties (such as Catalyst admins) to define terms and conditions that users must accept before submitting documents to the system. + +The Conditions document type supports multiple condition documents for different purposes, such as: + +* Terms of Use (TOU) +* License agreements +* Operational guidelines +* Regional restrictions +* Privacy policies +* Other legal or operational requirements + +The payload of a Conditions document contains the text of the terms and conditions, typically in Markdown or HTML format. This allows for rich formatting while maintaining human readability. + +Conditions documents are versioned and can be revoked, enabling administrators to update terms over time while maintaining an auditable history of what terms were in effect at any given time. + +Conditions documents are referenced by parameter documents (Brand, Campaign, Category, and Contest Parameters) to specify which conditions are required at each level of the system hierarchy. User-submitted documents (such as Proposals and Comments) must reference all required conditions from their parameter hierarchy, with the act of listing these references and signing the document serving as the user's digital signature and acceptance. + + + +```graphviz dot conditions.dot.svg + +{{ include_file('./../diagrams/conditions.dot', indent=4) }} +``` + + + +### Validation + +The Conditions document *MUST* be a valid signed document according to the Signed Document Standard. + +When a Conditions document is referenced in a parameter document's [`conditions`](../metadata.md#conditions) metadata field, the referenced document *MUST* exist and be of type "Conditions". + +When a Conditions document is referenced in a user-submitted document's [`conditions`](../metadata.md#conditions) metadata field, the referenced document *MUST* exist, be of type "Conditions", and not be revoked. + +### Business Logic + +#### Front End + +Front-end applications should: + +* Display Conditions documents to users when they are required to accept them +* Store user acceptance locally to minimize friction (users only need to explicitly accept conditions the first time they encounter them) +* Gray out submission buttons until all required conditions have been accepted +* Display a disclosure on submission listing all accepted conditions under which the document is being submitted +* Provide clear error messages if required conditions are missing or invalid + +#### Back End + +Back-end validation must: + +* Verify that all Conditions documents referenced in user-submitted documents exist and are valid +* Collect all required conditions from the parameter hierarchy (Brand → Campaign → Category → Contest) +* Ensure user-submitted documents include exactly the union of all required conditions from their parameter hierarchy +* Reject documents that reference revoked Conditions documents +* Reject documents that are missing required conditions or include conditions not in the parameter hierarchy + +The decentralized system (Hermes) will also reject documents without the required conditions, ensuring validation occurs at multiple layers. + +## [COSE Header Parameters][RFC9052-HeaderParameters] + +* [content type](../spec.md#content-type) = `text/markdown` or `text/html` +* [content-encoding](../spec.md#content-encoding) = `[br]` + +## Metadata + +### [`type`](../metadata.md#type) + + +| Parameter | Value | +| --- | --- | +| Required | yes | +| Format | [Document Type](../metadata.md#document-type) | +| Type | b664afc2-6472-4028-b90f-875bf6eefab8 | + +The document TYPE. + +#### [`type`](../metadata.md#type) Validation + +**MUST** be a known document type. + +### [`id`](../metadata.md#id) + + +| Parameter | Value | +| --- | --- | +| Required | yes | +| Format | [Document Id](../metadata.md#document-id) | + +Document ID, created the first time the document is created. +This must be a properly created [UUIDv7][RFC9562-V7] which contains the +timestamp of when the document was created. + +#### [`id`](../metadata.md#id) Validation + +The document ID validation is performed based on timestamp thresholds: + +* If `future_threshold` is configured, +the document [`id`](../metadata.md#id) cannot be too far in the future from the +current time. +* If `past_threshold` is configured, the document [`id`](../metadata.md#id) cannot be too far in the past from the +current time. + +### [`ver`](../metadata.md#ver) + + +| Parameter | Value | +| --- | --- | +| Required | yes | +| Format | [Document Ver](../metadata.md#document-ver) | + +The unique version of the document. +The first version of the document must set [`ver`](../metadata.md#ver) == [`id`](../metadata.md#id) + +[`ver`](../metadata.md#ver) represents new versions of the same document as it changes over time. + +#### [`ver`](../metadata.md#ver) Validation + +1. The document version must always be >= the document ID. +2. IF [`ver`](../metadata.md#ver) does not == [`id`](../metadata.md#id) + then a document with [`id`](../metadata.md#id) and [`ver`](../metadata.md#ver) being equal *MUST* exist. +3. When a document with the same [`id`](../metadata.md#id) already exists, + the new document's [`ver`](../metadata.md#ver) must be greater than + the latest known submitted version for that [`id`](../metadata.md#id). +4. When a document with the same [`id`](../metadata.md#id) already exists, + the new document's [`type`](../metadata.md#type) must be the same as + the latest known submitted document's [`type`](../metadata.md#type) for that [`id`](../metadata.md#id). + +### [`ref`](../metadata.md#ref) + + +| Parameter | Value | +| --- | --- | +| Required | optional | +| Format | [Document Reference](../metadata.md#document-reference) | + +Reference to a Linked Document or Documents. + +This field may be used to reference related documents, such as: +* Related Conditions documents (e.g., a privacy policy that references a terms of use) +* Legal documents or regulations that the conditions are based on +* Other relevant documentation + +#### [`ref`](../metadata.md#ref) Validation + +The following must be true for a valid reference: + +* The Referenced Document **MUST** Exist +* Every value in the `document_locator` must consistently reference the exact same document. +* The `document_id` and `document_ver` **MUST** match the values in the referenced document. +* In the event there are **MULTIPLE** [`ref`](../metadata.md#ref) listed, they **MUST** be sorted. + +Sorting for each element of [`ref`](../metadata.md#ref) follows the same sort order as specified for Map Keys, +as defined by [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] (4.3.2 Length-First Map Key Ordering). + +### [`revocations`](../metadata.md#revocations) + + +| Parameter | Value | +| --- | --- | +| Required | optional | +| Format | [Version Revocations](../metadata.md#version-revocations) | + +A document may include a list of any prior versions which are considered to be revoked. +Only the revocation list in the latest version of the document applies. +Revoked documents are flagged as no longer valid, and should not be displayed. +As a special case, if the revocations are set to `true` then all versions of the document +are revoked, including the latest document. + +In this case, when the latest document is revoked, the payload may be `nil`. +Any older document that has [`revocations`](../metadata.md#revocations) set to `true` is always to be filtered +and its payload is to be assumed to be invalid. + +This allows for an entire document and any/all published versions to be revoked. +A new version of the document that is published after this, may reinstate prior +document versions, by not listing them as revoked. +However, any document where revocations was set `true` can never be reinstated. + +#### [`revocations`](../metadata.md#revocations) Validation + +If the field is `true` the payload may be absent or invalid. +Such documents may never be submitted. + +**Important**: User-submitted documents that reference revoked Conditions documents *MUST* be rejected during validation. + +## Payload + +The Conditions document payload contains the text of the terms and conditions. + +The payload *MUST* be valid according to the content type specified in the COSE header: + +* If `content-type` is `text/markdown`, the payload must be valid Markdown +* If `content-type` is `text/html`, the payload must be valid HTML5 + +The payload is compressed using Brotli compression (`br` encoding) as specified in the `content-encoding` header. + +The payload content should be human-readable and clearly state: +* The purpose of the conditions +* What users are agreeing to +* Any obligations or restrictions +* Effective dates or version information +* Contact information for questions + +## Signers + +The following Admin roles may sign documents of this type: + +* Brand Admin +* Campaign Admin +* Category Admin +* Contest Admin + +The specific admin role required depends on the level at which the Conditions document is intended to be used. For example: +* Brand-level conditions should be signed by Brand Admin +* Campaign-level conditions should be signed by Campaign Admin or Brand Admin +* Category-level conditions should be signed by Category Admin or a parent-level admin +* Contest-level conditions should be signed by Contest Admin or a parent-level admin + +Updates are allowed by the original author and from the 'collaborators' metadata field +of the previous submitted document's version. + +## JSON Specification Requirements + +> **DRAFT STATUS** +> The following JSON specification changes are documented here but **MUST NOT** be implemented until this specification is formally released. +> The `signed_doc.json` file is the source of truth for code generation and must be marked as `draft: true` when these changes are added. + +### Required Changes to `signed_doc.json` + +The following changes must be made to `catalyst-libs/specs/signed_doc.json`: + +#### 1. Add "Conditions" Document Type + +Add a new entry to the `docs` section with the following structure: + +```json +"Conditions": { + "authors": { + "Nathan Bogale": "nathan.bogale@iohk.io", + "Steven Johnson": "steven.johnson@iohk.io" + }, + "description": "Conditions documents define terms and conditions that users must accept before submitting documents to the system. Supports multiple condition types (TOU, license agreements, operational guidelines, regional restrictions).", + "draft": true, + "type": "", + "headers": { + "content type": { + "coseLabel": 3, + "description": "Media Type/s allowed in the Payload", + "format": "Media Type", + "required": "yes", + "value": "text/markdown" + }, + "content-encoding": { + "coseLabel": "content-encoding", + "description": "Supported HTTP Encodings of the Payload", + "format": "HTTP Content Encoding", + "required": "optional", + "value": ["br"] + } + }, + "metadata": { + "type": { + "description": "The document TYPE.", + "format": "Document Type", + "required": "yes", + "validation": "**MUST** be a known document type." + }, + "id": { + "description": "Document ID, created the first time the document is created.", + "format": "Document Id", + "required": "yes" + }, + "ver": { + "description": "The unique version of the document.", + "format": "Document Ver", + "required": "yes" + }, + "ref": { + "description": "Reference to a Linked Document or Documents.", + "format": "Document Reference", + "required": "optional" + }, + "revocations": { + "description": "A document may include a list of any prior versions which are considered to be revoked.", + "format": "Version Revocations", + "required": "optional" + } + }, + "payload": { + "description": "The Conditions document payload contains the text of the terms and conditions in Markdown or HTML format.", + "nil": false + }, + "signers": { + "roles": { + "admin": ["Brand Admin", "Campaign Admin", "Category Admin", "Contest Admin"], + "user": [] + }, + "update": { + "description": "Updates are allowed by the original author and from the 'collaborators' metadata field of the previous submitted document's version.", + "type": "author" + } + }, + "validation": "The Conditions document *MUST* be a valid signed document according to the Signed Document Standard.", + "versions": [ + { + "version": "0.01", + "modified": "2025-01-XX", + "changes": "* First Published Version (DRAFT)" + } + ] +} +``` + +**Important Notes:** +- Generate a new UUIDv4 for the `type` field +- Set `draft: true` as required by Steven Johnson +- The `value` for `content type` may be `text/markdown` or `text/html` (consider supporting both) + +#### 2. Add "conditions" Metadata Field + +Add the `conditions` metadata field to the following document types in their `metadata` sections: + +**Parameter Documents** (Brand Parameters, Campaign Parameters, Category Parameters, Contest Parameters): +```json +"conditions": { + "description": "An array of references to Conditions documents that define terms and conditions required at this level.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": ["Conditions"], + "validation": "If present, must be an array of valid Conditions document references. All referenced documents must exist and be of type 'Conditions'. The array must be sorted according to CBOR Deterministic Encoding rules." +} +``` + +**User-Submitted Documents** (Proposal, Proposal Comment, etc.): +```json +"conditions": { + "description": "An array of references to all Conditions documents that the user has accepted. Must include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": ["Conditions"], + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy. All referenced documents must exist, be valid, and not be revoked. The array must be sorted according to CBOR Deterministic Encoding rules." +} +``` + +**Important Notes:** +- Set `multiple: true` to allow arrays of document references +- Set `required: "optional"` (but required when conditions are specified in parameter hierarchy for user documents) +- The validation logic for user documents requires transitive collection from parameter hierarchy + +#### 3. Update Document Types Table + +The `types.md` file will be automatically regenerated from the JSON specification once these changes are made. Ensure the Conditions document type appears in the generated table. + +### Code Generation Impact + +Once these changes are made to `signed_doc.json` and the specification is released (draft status removed), the following code will need to be updated: + +- **Rust**: Add `conditions` field to metadata structs and implement validation rules +- **Python**: Add `conditions` to `DocType` enum and metadata handling +- **Dart**: Add `conditions` to `DocumentType` enum +- **Backend Validation**: Implement transitive condition collection and matching logic +- **CLI Tools**: Add condition querying and acceptance prompts + +## Copyright + +| Copyright | :copyright: 2024-2025 IOG Singapore, All Rights Reserved | +| --- | --- | +| License | This document is licensed under [CC-BY-4.0] | +| Created | 2025-01-XX | +| Modified | 2025-01-XX | +| | Nathan Bogale | +| | Steven Johnson | + +### Changelog + +#### 0.01 (2025-01-XX) + +* First Published Version (DRAFT) + +[CBOR-LFD-ENCODING]: https://www.rfc-editor.org/rfc/rfc8949.html#section-4.2.3 +[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1 +[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode +[RFC9562-V7]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7 + diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index e72f34382d..4d492597e2 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -414,6 +414,98 @@ The profile template, or proposal templates could be defined at any of these levels, and as long as they all refer to the same chain of parameters in the hierarchy they are all valid. +### `conditions` + +> **DRAFT STATUS** +> This metadata field is currently in **DRAFT** status. Development should **NOT** begin until this specification is formally released. +> This specification is subject to change without notice. + + +| Parameter | Value | +| --- | --- | +| Required | optional | +| Format | [Document Reference](metadata.md#document-reference) | +| Multiple References | yes | +| Valid References | [Conditions](./docs/conditions.md) | + +An array of references to [Conditions](./docs/conditions.md) documents that define terms and conditions. + +The `conditions` metadata field serves two distinct purposes depending on the document type: + +1. **On Parameter Documents** (Brand Parameters, Campaign Parameters, Category Parameters, Contest Parameters): + * Lists the required condition documents for that level of the system hierarchy + * Specifies which terms users must accept when submitting documents at this level + * The field is optional - if not present, no conditions are required at that level + +2. **On User-Submitted Documents** (Proposals, Proposal Comments, etc.): + * References all condition documents that the user has accepted + * Must include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest) + * The act of listing these references and signing the document serves as the user's digital signature and acceptance + * The field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified + +#### `conditions` Validation + +**For Parameter Documents:** + +* The `conditions` field is optional +* If present, must be an array of valid [Conditions](./docs/conditions.md) document references +* All referenced documents must exist and be of type "Conditions" +* The array must be sorted according to [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] (4.3.2 Length-First Map Key Ordering) +* All array elements must be unique + +**For User-Submitted Documents:** + +The validation process for user-submitted documents involves transitive collection of required conditions: + +1. Extract the [`parameters`](metadata.md#parameters) reference from the user document +2. Follow the parameter chain: Contest → Category → Campaign → Brand +3. Collect all `conditions` arrays from each parameter level in the hierarchy +4. Union all condition references (removing duplicates based on document ID and version) +5. Sort the unioned list according to [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] +6. Compare the user document's `conditions` array with this unioned, sorted list +7. Validation succeeds only if they match exactly + +**Validation Rules:** + +* The user document's `conditions` array must exactly match the union of all required conditions from the parameter hierarchy +* All referenced Conditions documents must exist and be valid +* All referenced Conditions documents must not be revoked +* The array must be sorted (CBOR deterministic encoding order) +* All array elements must be unique + +**Validation Failures:** + +The document will be rejected if: +* Missing required conditions (conditions specified in parameter hierarchy but not in user document) +* Includes extra conditions (conditions in user document not in parameter hierarchy) +* Array is not sorted correctly +* Any referenced condition document doesn't exist or is invalid +* Any referenced condition document is revoked +* Array contains duplicate references + +**Edge Cases:** + +* **Parameter documents with no `conditions` field**: User documents don't need to include conditions at that level +* **Empty `conditions` arrays**: Valid if no conditions are required by any level in the parameter hierarchy +* **Revoked condition documents**: User documents referencing revoked conditions must be rejected +* **Multiple conditions at same level**: All conditions from a parameter level are required +* **Conditions at multiple levels**: User must accept all conditions from all levels (Brand, Campaign, Category, Contest) + +**Example:** + +A user submitting a Proposal to a Category must accept: +* All conditions from the Contest Parameters (if any) +* All conditions from the Category Parameters (if any) +* All conditions from the Campaign Parameters (if any) +* All conditions from the Brand Parameters (if any) + +The Proposal's `conditions` array must contain the union of all these conditions, sorted and deduplicated. + +In the event there are **MULTIPLE** [`conditions`](metadata.md#conditions) listed, they **MUST** be sorted. + +Sorting for each element of [`conditions`](metadata.md#conditions) follows the same sort order as specified for Map Keys, +as defined by [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] (4.3.2 Length-First Map Key Ordering). + ### `chain` diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 2d42af0377..3b20becc09 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -744,6 +744,16 @@ "required": "excluded", "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to Conditions documents that define terms and conditions required at this level.\n\nLists the required condition documents for this level of the system hierarchy.\nSpecifies which terms users must accept when submitting documents at this level.\nThe field is optional - if not present, no conditions are required at that level.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "If present, must be an array of valid Conditions document references.\nAll referenced documents must exist and be of type \"Conditions\".\nThe array must be sorted according to CBOR Deterministic Encoding rules.\nAll array elements must be unique." + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", @@ -1001,6 +1011,16 @@ "type": "Brand Parameters", "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to Conditions documents that define terms and conditions required at this level.\n\nLists the required condition documents for this level of the system hierarchy.\nSpecifies which terms users must accept when submitting documents at this level.\nThe field is optional - if not present, no conditions are required at that level.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "If present, must be an array of valid Conditions document references.\nAll referenced documents must exist and be of type \"Conditions\".\nThe array must be sorted according to CBOR Deterministic Encoding rules.\nAll array elements must be unique." + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", @@ -1592,6 +1612,105 @@ } ] }, + "Conditions": { + "authors": { + "Nathan Bogale": "nathan.bogale@iohk.io", + "Steven Johnson": "steven.johnson@iohk.io" + }, + "description": "Conditions documents define terms and conditions that users must accept before submitting documents to the system. Supports multiple condition types (TOU, license agreements, operational guidelines, regional restrictions).\n\nThe payload of a Conditions document contains the text of the terms and conditions, typically in Markdown or HTML format. This allows for rich formatting while maintaining human readability.\n\nConditions documents are versioned and can be revoked, enabling administrators to update terms over time while maintaining an auditable history of what terms were in effect at any given time.", + "draft": true, + "headers": { + "content type": { + "coseLabel": 3, + "description": "Media Type/s allowed in the Payload", + "format": "Media Type", + "required": "yes", + "value": "text/markdown" + }, + "content-encoding": { + "coseLabel": "content-encoding", + "description": "Supported HTTP Encodings of the Payload.\nIf no compression or encoding is used, then this field must not be present.", + "format": "HTTP Content Encoding", + "required": "optional", + "value": [ + "br" + ] + } + }, + "metadata": { + "chain": { + "description": "An immutable link to the previous document in a chained sequence of documents.\nBecause ID/Ver only defines values for the current document, and is not intended \nby itself to prevent insertion of documents in a sequence, the `chain`\nmetadata allows for the latest document to directly point to its previous iteration.\n\nIt also aids in discoverability, where the latest document may be pinned but prior\ndocuments can be discovered automatically by following the chain.", + "format": "Chain Link", + "required": "excluded", + "validation": "Chained Documents do not support collaborators.\nAny document which is attempted to be published in the sequence\nwhich is *NOT* published by the author of the first document in the\nsequence is fraudulent, and to be discarded.\n\nIn addition, the chained document *MUST*:\n\n* Not have `collaborators`;\n* Have the same `id` as the document being chained to;\n* Have a `ver` that is greater than the `ver` being chained to;\n* Have the same `type` as the chained document;\n* Have `parameters` match;\n* Have not be chaining to a document already chained to by another document;\n* Have its absolute `height` exactly one more than the `height` of the document being chained to.\n\nIF any of these validations fail, then the entire sequence of documents is INVALID.\nNot just the current document." + }, + "collaborators": { + "description": "A list of collaborators who may also publish updates to versions of this document.\nThis should include all parties who have not signed this document directly.\n\nEvery subsequent version can amend the collaborators list.\nHowever, the initial Author can never be removed from being able to\npublish a new version of the document.", + "format": "Collaborators Reference List", + "required": "optional", + "validation": "This list does not imply these collaborators have consented to collaborate, only that the author/s\nare permitting these potential collaborators to participate in the drafting and submission process.\nHow collaborators are counted on a final submission is determined by a parameter defined at the\nBrand/Campaign/Category level (parameter name TBD). \nDepending on that configuration:\n\n* All listed collaborators may be required to submit a `final` Submission Action in addition\n to the author; **OR**\n* Only collaborators who submit a `final` Submission Action for the referenced version are\n included as collaborators on that submission.\n\nIf the parameter is not present, default to the latter mode (only final-signing collaborators are\nincluded).\nIn all modes a document is only considered final when the original author has submitted `final`.\n\nIn the event there are **MULTIPLE** `collaborators` listed, they **MUST** be sorted.\n\nSorting for each element of `collaborators` follows the same sort order as specified for Map Keys, \nas defined by CBOR Deterministic Encoding (4.3.2 Length-First Map Key Ordering)." + }, + "id": { + "description": "Document ID, created the first time the document is created.\nThis must be a properly created UUIDv7 which contains the\ntimestamp of when the document was created.", + "format": "Document Id", + "required": "yes", + "validation": "The document ID validation is performed based on timestamp thresholds:\n\n* If `future_threshold` is configured,\nthe document `id` cannot be too far in the future from the\ncurrent time.\n* If `past_threshold` is configured, the document `id` cannot be too far in the past from the\ncurrent time." + }, + "ref": { + "description": "Reference to a Linked Document or Documents.\n\nThis field may be used to reference related documents, such as:\n* Related Conditions documents (e.g., a privacy policy that references a terms of use)\n* Legal documents or regulations that the conditions are based on\n* Other relevant documentation", + "format": "Document Reference", + "required": "optional", + "validation": "The following must be true for a valid reference:\n\n* The Referenced Document **MUST** Exist\n* Every value in the `document_locator` must consistently reference the exact same document.\n* The `document_id` and `document_ver` **MUST** match the values in the referenced document.\n* In the event there are **MULTIPLE** `ref` listed, they **MUST** be sorted.\n\nSorting for each element of `ref` follows the same sort order as specified for Map Keys, \nas defined by CBOR Deterministic Encoding (4.3.2 Length-First Map Key Ordering)." + }, + "revocations": { + "description": "A document may include a list of any prior versions which are considered to be revoked.\nOnly the revocation list in the latest version of the document applies.\nRevoked documents are flagged as no longer valid, and should not be displayed.\nAs a special case, if the revocations are set to `true` then all versions of the document\nare revoked, including the latest document.\n\nIn this case, when the latest document is revoked, the payload may be `nil`.\nAny older document that has `revocations` set to `true` is always to be filtered\nand its payload is to be assumed to be invalid.\n\nThis allows for an entire document and any/all published versions to be revoked.\nA new version of the document that is published after this, may reinstate prior\ndocument versions, by not listing them as revoked.\nHowever, any document where revocations was set `true` can never be reinstated.", + "format": "Version Revocations", + "required": "optional", + "validation": "If the field is `true` the payload may be absent or invalid.\nSuch documents may never be submitted.\n\n**Important**: User-submitted documents that reference revoked Conditions documents *MUST* be rejected during validation." + }, + "type": { + "description": "The document TYPE.", + "format": "Document Type", + "required": "yes", + "validation": "**MUST** be a known document type." + }, + "ver": { + "description": "The unique version of the document.\nThe first version of the document must set `ver` == `id`\n\n`ver` represents new versions of the same document as it changes over time.", + "format": "Document Ver", + "required": "yes", + "validation": "1. The document version must always be >= the document ID.\n2. IF `ver` does not == `id`\n then a document with `id` and `ver` being equal *MUST* exist.\n3. When a document with the same `id` already exists,\n the new document's `ver` must be greater than\n the latest known submitted version for that `id`.\n4. When a document with the same `id` already exists,\n the new document's `type` must be the same as\n the latest known submitted document's `type` for that `id`." + } + }, + "notes": [], + "payload": { + "description": "The Conditions document payload contains the text of the terms and conditions.\n\nThe payload *MUST* be valid according to the content type specified in the COSE header:\n\n* If `content-type` is `text/markdown`, the payload must be valid Markdown\n* If `content-type` is `text/html`, the payload must be valid HTML5\n\nThe payload is compressed using Brotli compression (`br` encoding) as specified in the `content-encoding` header.\n\nThe payload content should be human-readable and clearly state:\n* The purpose of the conditions\n* What users are agreeing to\n* Any obligations or restrictions\n* Effective dates or version information\n* Contact information for questions", + "nil": false + }, + "signers": { + "roles": { + "admin": [ + "Brand Admin", + "Campaign Admin", + "Category Admin", + "Contest Admin" + ], + "user": [] + }, + "update": { + "description": "Updates are allowed by the original author and from the 'collaborators' metadata field\nof the previous submitted document's version.", + "type": "author" + } + }, + "type": "b664afc2-6472-4028-b90f-875bf6eefab8", + "validation": "The Conditions document *MUST* be a valid signed document according to the Signed Document Standard.\n\nWhen a Conditions document is referenced in a parameter document's `conditions` metadata field, the referenced document *MUST* exist and be of type \"Conditions\".\n\nWhen a Conditions document is referenced in a user-submitted document's `conditions` metadata field, the referenced document *MUST* exist, be of type \"Conditions\", and not be revoked.", + "versions": [ + { + "changes": "* First Published Version (DRAFT)", + "modified": "2025-01-XX", + "version": "0.01" + } + ] + }, "Contest Ballot": { "authors": { "Steven Johnson": "steven.johnson@iohk.io" @@ -2611,6 +2730,16 @@ ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\nThe field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unioned list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unioned, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", @@ -2749,6 +2878,16 @@ ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\nThe field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unioned list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unioned, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", From 721f7ecd7bf3eda045da394ad50600b771463a0e Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Sun, 7 Dec 2025 14:31:28 +0300 Subject: [PATCH 02/10] feat(docs): Add `conditions` field to specifications and documentation - Updated the documentation to include the new Conditions document type, detailing its purpose and validation requirements. - Enhanced the types.md file to list the Conditions document type, ensuring clarity in the available document types. --- .../08_concepts/signed_doc/types.md | 1 + specs/generators/uv.lock | 6 +++--- specs/signed_doc.json | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/types.md b/docs/src/architecture/08_concepts/signed_doc/types.md index aeefad96f9..c3377fc22d 100644 --- a/docs/src/architecture/08_concepts/signed_doc/types.md +++ b/docs/src/architecture/08_concepts/signed_doc/types.md @@ -14,6 +14,7 @@ All Defined Document Types | [Category Parameters](docs/category_parameters.md) | 48c20109-362a-4d32-9bba-e0a9cf8b45be | `#6.37(h'48c20109362a4d329bbae0a9cf8b45be')` | | [Category Parameters Form Template](docs/category_parameters_form_template.md) | 65b1e8b0-51f1-46a5-9970-72cdf26884be | `#6.37(h'65b1e8b051f146a5997072cdf26884be')` | | [Comment Moderation Action](docs/comment_moderation_action.md) | 84a4b502-3b7e-47fd-84e4-6fee08794bd7 | `#6.37(h'84a4b5023b7e47fd84e46fee08794bd7')` | +| [Conditions](docs/conditions.md) | b664afc2-6472-4028-b90f-875bf6eefab8 | `#6.37(h'b664afc264724028b90f875bf6eefab8')` | | [Contest Ballot](docs/contest_ballot.md) | de1284b8-8533-4f7a-81cc-ff4bde5ef8d0 | `#6.37(h'de1284b885334f7a81ccff4bde5ef8d0')` | | [Contest Ballot Checkpoint](docs/contest_ballot_checkpoint.md) | 58608925-bda3-47df-b39a-ae0d0a1dd6ed | `#6.37(h'58608925bda347dfb39aae0d0a1dd6ed')` | | [Contest Delegation](docs/contest_delegation.md) | 764f17fb-cc50-4979-b14a-b213dbac5994 | `#6.37(h'764f17fbcc504979b14ab213dbac5994')` | diff --git a/specs/generators/uv.lock b/specs/generators/uv.lock index ffb314b9c9..c1d1f694dc 100644 --- a/specs/generators/uv.lock +++ b/specs/generators/uv.lock @@ -413,7 +413,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.12.4" +version = "2.12.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -421,9 +421,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, ] [[package]] diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 3b20becc09..5853c97a37 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -1283,6 +1283,16 @@ "type": "Campaign Parameters", "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to Conditions documents that define terms and conditions required at this level.\n\nLists the required condition documents for this level of the system hierarchy.\nSpecifies which terms users must accept when submitting documents at this level.\nThe field is optional - if not present, no conditions are required at that level.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "If present, must be an array of valid Conditions document references.\nAll referenced documents must exist and be of type \"Conditions\".\nThe array must be sorted according to CBOR Deterministic Encoding rules.\nAll array elements must be unique." + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", @@ -2245,6 +2255,16 @@ ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, + "conditions": { + "description": "An array of references to Conditions documents that define terms and conditions required at this level.\n\nLists the required condition documents for this level of the system hierarchy.\nSpecifies which terms users must accept when submitting documents at this level.\nThe field is optional - if not present, no conditions are required at that level.", + "format": "Document Reference", + "required": "optional", + "multiple": true, + "type": [ + "Conditions" + ], + "validation": "If present, must be an array of valid Conditions document references.\nAll referenced documents must exist and be of type \"Conditions\".\nThe array must be sorted according to CBOR Deterministic Encoding rules.\nAll array elements must be unique." + }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", "format": "Document Reference", From 0a36ee0bf33719f010150702787d42f6397af54f Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Sun, 7 Dec 2025 18:37:56 +0300 Subject: [PATCH 03/10] fix(docs): Improve formatting and clarity in Conditions documentation --- .../08_concepts/signed_doc/docs/conditions.md | 125 ++++++++++++------ .../08_concepts/signed_doc/metadata.md | 18 ++- specs/signed_doc.json | 4 +- 3 files changed, 102 insertions(+), 45 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md index 159798f382..839e4c5426 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md +++ b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md @@ -1,12 +1,15 @@ # Conditions > **DRAFT STATUS** -> This document is currently in **DRAFT** status. Development should **NOT** begin until this specification is formally released. +> This document is currently in **DRAFT** status. +> Development should **NOT** begin until this specification is formally released. > This specification is subject to change without notice. ## Description -Conditions documents are simple document types published by authoritative parties (such as Catalyst admins) to define terms and conditions that users must accept before submitting documents to the system. +Conditions documents are simple document types published by authoritative parties +(such as Catalyst admins) to define terms and conditions that users must accept +before submitting documents to the system. The Conditions document type supports multiple condition documents for different purposes, such as: @@ -17,11 +20,21 @@ The Conditions document type supports multiple condition documents for different * Privacy policies * Other legal or operational requirements -The payload of a Conditions document contains the text of the terms and conditions, typically in Markdown or HTML format. This allows for rich formatting while maintaining human readability. +The payload of a Conditions document contains the text of the terms and +conditions, typically in Markdown or HTML format. +This allows for rich formatting while maintaining human readability. -Conditions documents are versioned and can be revoked, enabling administrators to update terms over time while maintaining an auditable history of what terms were in effect at any given time. +Conditions documents are versioned and can be revoked, enabling administrators to +update terms over time while maintaining an auditable history of what terms were +in effect at any given time. -Conditions documents are referenced by parameter documents (Brand, Campaign, Category, and Contest Parameters) to specify which conditions are required at each level of the system hierarchy. User-submitted documents (such as Proposals and Comments) must reference all required conditions from their parameter hierarchy, with the act of listing these references and signing the document serving as the user's digital signature and acceptance. +Conditions documents are referenced by parameter documents (Brand, Campaign, +Category, and Contest Parameters) to specify which conditions are required at each +level of the system hierarchy. +User-submitted documents (such as Proposals and Comments) must reference all +required conditions from their parameter hierarchy, with the act of listing these +references and signing the document serving as the user's digital signature and +acceptance. @@ -34,11 +47,16 @@ Conditions documents are referenced by parameter documents (Brand, Campaign, Cat ### Validation -The Conditions document *MUST* be a valid signed document according to the Signed Document Standard. +The Conditions document *MUST* be a valid signed document according to the +Signed Document Standard. -When a Conditions document is referenced in a parameter document's [`conditions`](../metadata.md#conditions) metadata field, the referenced document *MUST* exist and be of type "Conditions". +When a Conditions document is referenced in a parameter document's +[`conditions`](../metadata.md#conditions) metadata field, the referenced document +*MUST* exist and be of type "Conditions". -When a Conditions document is referenced in a user-submitted document's [`conditions`](../metadata.md#conditions) metadata field, the referenced document *MUST* exist, be of type "Conditions", and not be revoked. +When a Conditions document is referenced in a user-submitted document's +[`conditions`](../metadata.md#conditions) metadata field, the referenced document +*MUST* exist, be of type "Conditions", and not be revoked. ### Business Logic @@ -56,13 +74,18 @@ Front-end applications should: Back-end validation must: -* Verify that all Conditions documents referenced in user-submitted documents exist and are valid -* Collect all required conditions from the parameter hierarchy (Brand → Campaign → Category → Contest) -* Ensure user-submitted documents include exactly the union of all required conditions from their parameter hierarchy +* Verify that all Conditions documents referenced in user-submitted documents + exist and are valid +* Collect all required conditions from the parameter hierarchy + (Brand → Campaign → Category → Contest) +* Ensure user-submitted documents include exactly the union of all required + conditions from their parameter hierarchy * Reject documents that reference revoked Conditions documents -* Reject documents that are missing required conditions or include conditions not in the parameter hierarchy +* Reject documents that are missing required conditions or include conditions not + in the parameter hierarchy -The decentralized system (Hermes) will also reject documents without the required conditions, ensuring validation occurs at multiple layers. +The decentralized system (Hermes) will also reject documents without the required +conditions, ensuring validation occurs at multiple layers. ## [COSE Header Parameters][RFC9052-HeaderParameters] @@ -144,7 +167,9 @@ The first version of the document must set [`ver`](../metadata.md#ver) == [`id`] Reference to a Linked Document or Documents. This field may be used to reference related documents, such as: -* Related Conditions documents (e.g., a privacy policy that references a terms of use) + +* Related Conditions documents (e.g., a privacy policy that references a terms of + use) * Legal documents or regulations that the conditions are based on * Other relevant documentation @@ -199,9 +224,11 @@ The payload *MUST* be valid according to the content type specified in the COSE * If `content-type` is `text/markdown`, the payload must be valid Markdown * If `content-type` is `text/html`, the payload must be valid HTML5 -The payload is compressed using Brotli compression (`br` encoding) as specified in the `content-encoding` header. +The payload is compressed using Brotli compression (`br` encoding) as specified +in the `content-encoding` header. The payload content should be human-readable and clearly state: + * The purpose of the conditions * What users are agreeing to * Any obligations or restrictions @@ -217,11 +244,16 @@ The following Admin roles may sign documents of this type: * Category Admin * Contest Admin -The specific admin role required depends on the level at which the Conditions document is intended to be used. For example: +The specific admin role required depends on the level at which the Conditions +document is intended to be used. +For example: + * Brand-level conditions should be signed by Brand Admin * Campaign-level conditions should be signed by Campaign Admin or Brand Admin -* Category-level conditions should be signed by Category Admin or a parent-level admin -* Contest-level conditions should be signed by Contest Admin or a parent-level admin +* Category-level conditions should be signed by Category Admin or a parent-level + admin +* Contest-level conditions should be signed by Contest Admin or a parent-level + admin Updates are allowed by the original author and from the 'collaborators' metadata field of the previous submitted document's version. @@ -229,8 +261,10 @@ of the previous submitted document's version. ## JSON Specification Requirements > **DRAFT STATUS** -> The following JSON specification changes are documented here but **MUST NOT** be implemented until this specification is formally released. -> The `signed_doc.json` file is the source of truth for code generation and must be marked as `draft: true` when these changes are added. +> The following JSON specification changes are documented here but **MUST NOT** be +> implemented until this specification is formally released. +> The `signed_doc.json` file is the source of truth for code generation and must +> be marked as `draft: true` when these changes are added. ### Required Changes to `signed_doc.json` @@ -319,15 +353,19 @@ Add a new entry to the `docs` section with the following structure: ``` **Important Notes:** -- Generate a new UUIDv4 for the `type` field -- Set `draft: true` as required by Steven Johnson -- The `value` for `content type` may be `text/markdown` or `text/html` (consider supporting both) + +* Generate a new UUIDv4 for the `type` field +* Set `draft: true` as required by Steven Johnson +* The `value` for `content type` may be `text/markdown` or `text/html` + (consider supporting both) #### 2. Add "conditions" Metadata Field Add the `conditions` metadata field to the following document types in their `metadata` sections: -**Parameter Documents** (Brand Parameters, Campaign Parameters, Category Parameters, Contest Parameters): +**Parameter Documents** (Brand Parameters, Campaign Parameters, Category +Parameters, Contest Parameters): + ```json "conditions": { "description": "An array of references to Conditions documents that define terms and conditions required at this level.", @@ -335,26 +373,37 @@ Add the `conditions` metadata field to the following document types in their `me "required": "optional", "multiple": true, "type": ["Conditions"], - "validation": "If present, must be an array of valid Conditions document references. All referenced documents must exist and be of type 'Conditions'. The array must be sorted according to CBOR Deterministic Encoding rules." + "validation": "If present, must be an array of valid Conditions document +references. All referenced documents must exist and be of type 'Conditions'. The +array must be sorted according to CBOR Deterministic Encoding rules." } ``` **User-Submitted Documents** (Proposal, Proposal Comment, etc.): + ```json "conditions": { - "description": "An array of references to all Conditions documents that the user has accepted. Must include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).", + "description": "An array of references to all Conditions documents that the +user has accepted. Must include ALL conditions required by the parameter +hierarchy (Brand → Campaign → Category → Contest).", "format": "Document Reference", "required": "optional", "multiple": true, "type": ["Conditions"], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy. All referenced documents must exist, be valid, and not be revoked. The array must be sorted according to CBOR Deterministic Encoding rules." + "validation": "Must exactly match the union of all required conditions from +the parameter hierarchy. All referenced documents must exist, be valid, and not +be revoked. The array must be sorted according to CBOR Deterministic Encoding +rules." } ``` **Important Notes:** -- Set `multiple: true` to allow arrays of document references -- Set `required: "optional"` (but required when conditions are specified in parameter hierarchy for user documents) -- The validation logic for user documents requires transitive collection from parameter hierarchy + +* Set `multiple: true` to allow arrays of document references +* Set `required: "optional"` (but required when conditions are specified in + parameter hierarchy for user documents) +* The validation logic for user documents requires transitive collection from + parameter hierarchy #### 3. Update Document Types Table @@ -362,13 +411,16 @@ The `types.md` file will be automatically regenerated from the JSON specificatio ### Code Generation Impact -Once these changes are made to `signed_doc.json` and the specification is released (draft status removed), the following code will need to be updated: +Once these changes are made to `signed_doc.json` and the specification is +released (draft status removed), the following code will need to be updated: -- **Rust**: Add `conditions` field to metadata structs and implement validation rules -- **Python**: Add `conditions` to `DocType` enum and metadata handling -- **Dart**: Add `conditions` to `DocumentType` enum -- **Backend Validation**: Implement transitive condition collection and matching logic -- **CLI Tools**: Add condition querying and acceptance prompts +* **Rust**: Add `conditions` field to metadata structs and implement validation + rules +* **Python**: Add `conditions` to `DocType` enum and metadata handling +* **Dart**: Add `conditions` to `DocumentType` enum +* **Backend Validation**: Implement transitive condition collection and matching + logic +* **CLI Tools**: Add condition querying and acceptance prompts ## Copyright @@ -390,4 +442,3 @@ Once these changes are made to `signed_doc.json` and the specification is releas [RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1 [CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode [RFC9562-V7]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7 - diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index 4d492597e2..0dcbc0ef53 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -417,7 +417,8 @@ hierarchy they are all valid. ### `conditions` > **DRAFT STATUS** -> This metadata field is currently in **DRAFT** status. Development should **NOT** begin until this specification is formally released. +> This metadata field is currently in **DRAFT** status. +> Development should **NOT** begin until this specification is formally released. > This specification is subject to change without notice. @@ -460,9 +461,10 @@ The validation process for user-submitted documents involves transitive collecti 1. Extract the [`parameters`](metadata.md#parameters) reference from the user document 2. Follow the parameter chain: Contest → Category → Campaign → Brand 3. Collect all `conditions` arrays from each parameter level in the hierarchy -4. Union all condition references (removing duplicates based on document ID and version) -5. Sort the unioned list according to [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] -6. Compare the user document's `conditions` array with this unioned, sorted list +4. Union all condition references (removing duplicates based on document ID and + version) +5. Sort the unified list according to [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] +6. Compare the user document's `conditions` array with this unified, sorted list 7. Validation succeeds only if they match exactly **Validation Rules:** @@ -476,8 +478,11 @@ The validation process for user-submitted documents involves transitive collecti **Validation Failures:** The document will be rejected if: -* Missing required conditions (conditions specified in parameter hierarchy but not in user document) -* Includes extra conditions (conditions in user document not in parameter hierarchy) + +* Missing required conditions (conditions specified in parameter hierarchy but not + in user document) +* Includes extra conditions (conditions in user document not in parameter + hierarchy) * Array is not sorted correctly * Any referenced condition document doesn't exist or is invalid * Any referenced condition document is revoked @@ -494,6 +499,7 @@ The document will be rejected if: **Example:** A user submitting a Proposal to a Category must accept: + * All conditions from the Contest Parameters (if any) * All conditions from the Category Parameters (if any) * All conditions from the Campaign Parameters (if any) diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 5853c97a37..5a8920674e 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -2758,7 +2758,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unioned list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unioned, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", @@ -2906,7 +2906,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unioned list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unioned, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", From 9f080c38d1f39635d2c6226a914ee44656b05880 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Mon, 8 Dec 2025 17:50:48 +0300 Subject: [PATCH 04/10] fix(docs): Restore Conditions system enhancements after rebase - Add conditions.cue definition file - Enhanced conditions metadata field documentation - Add Contest Parameters to System Parameters list - Support both Markdown and HTML content types with charset - Update validation process to clarify upward traversal - Add schema-level vs validation-level requirement distinction --- .../08_concepts/signed_doc/metadata.md | 25 +++- specs/definitions/signed_doc_types/types.cue | 1 + .../signed_docs/docs/conditions.cue | 140 ++++++++++++++++++ .../signed_docs/docs/generic_parameters.cue | 2 + specs/definitions/signed_docs/metadata.cue | 72 +++++++++ specs/signed_doc.json | 44 ++++-- 6 files changed, 264 insertions(+), 20 deletions(-) create mode 100644 specs/definitions/signed_docs/docs/conditions.cue diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index 0dcbc0ef53..6ef54e2503 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -442,7 +442,10 @@ The `conditions` metadata field serves two distinct purposes depending on the do * References all condition documents that the user has accepted * Must include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest) * The act of listing these references and signing the document serves as the user's digital signature and acceptance - * The field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified + * **Schema-level**: The field is marked as optional in the schema, allowing documents to be created without it + * **Validation-level**: During validation, this field becomes required when the parameter hierarchy specifies conditions. + If conditions are required by any level in the parameter hierarchy, the field must be present and must exactly + match all required conditions. If no conditions are specified in the parameter hierarchy, the field may be omitted #### `conditions` Validation @@ -456,17 +459,30 @@ The `conditions` metadata field serves two distinct purposes depending on the do **For User-Submitted Documents:** +**Important**: While the `conditions` field is optional at the schema level, validation enforces conditional requirements +based on the parameter hierarchy. This validation occurs at runtime, not during schema validation. + The validation process for user-submitted documents involves transitive collection of required conditions: 1. Extract the [`parameters`](metadata.md#parameters) reference from the user document -2. Follow the parameter chain: Contest → Category → Campaign → Brand -3. Collect all `conditions` arrays from each parameter level in the hierarchy +2. Starting from the referenced parameters document, follow the parent chain upward to Brand: + * If the document references **Contest Parameters**, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand + * If the document references **Category Parameters**, follow: Category → Campaign → Brand + * If the document references **Campaign Parameters**, follow: Campaign → Brand + * If the document references **Brand Parameters**, only Brand is included +3. Collect all `conditions` arrays from each parameter level encountered in the upward chain 4. Union all condition references (removing duplicates based on document ID and version) 5. Sort the unified list according to [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] 6. Compare the user document's `conditions` array with this unified, sorted list 7. Validation succeeds only if they match exactly +**Important**: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy. + +**If the unified list is non-empty** (conditions are required by the parameter hierarchy), the `conditions` field +becomes required and must be present in the user document. **If the unified list is empty** (no conditions are +required), the `conditions` field may be omitted. + **Validation Rules:** * The user document's `conditions` array must exactly match the union of all required conditions from the parameter hierarchy @@ -500,13 +516,14 @@ The document will be rejected if: A user submitting a Proposal to a Category must accept: -* All conditions from the Contest Parameters (if any) * All conditions from the Category Parameters (if any) * All conditions from the Campaign Parameters (if any) * All conditions from the Brand Parameters (if any) The Proposal's `conditions` array must contain the union of all these conditions, sorted and deduplicated. +Note: Contest Parameters are below Category in the hierarchy, so they do not apply to documents at the Category level. If a Proposal is submitted to a Contest, then Contest Parameters would be included in the chain (Contest → Category → Campaign → Brand). + In the event there are **MULTIPLE** [`conditions`](metadata.md#conditions) listed, they **MUST** be sorted. Sorting for each element of [`conditions`](metadata.md#conditions) follows the same sort order as specified for Map Keys, diff --git a/specs/definitions/signed_doc_types/types.cue b/specs/definitions/signed_doc_types/types.cue index e5fb859c96..f38e75d505 100644 --- a/specs/definitions/signed_doc_types/types.cue +++ b/specs/definitions/signed_doc_types/types.cue @@ -30,6 +30,7 @@ allDocTypes: { "Contest Delegation": "764f17fb-cc50-4979-b14a-b213dbac5994" "Contest Ballot": "de1284b8-8533-4f7a-81cc-ff4bde5ef8d0" "Contest Ballot Checkpoint": "58608925-bda3-47df-b39a-ae0d0a1dd6ed" + "Conditions": "b664afc2-6472-4028-b90f-875bf6eefab8" //"Rep Profile Moderation Action": "0e20010b-eeaf-4938-a7ee-ceb3df9e8af6" // speculative //"Rep Nomination Moderation Action": "d27ecb44-bd4d-42bb-9273-5e5433cdfdb6" // speculative } diff --git a/specs/definitions/signed_docs/docs/conditions.cue b/specs/definitions/signed_docs/docs/conditions.cue new file mode 100644 index 0000000000..f57b264701 --- /dev/null +++ b/specs/definitions/signed_docs/docs/conditions.cue @@ -0,0 +1,140 @@ +package signed_docs + +import ( + "github.com/input-output-hk/catalyst-libs/specs/signed_doc_types" +) + +// Conditions Document Definition + +docs: #DocumentDefinitions & { + Conditions: { + description: """ + Conditions documents define terms and conditions that users must accept + before submitting documents to the system. + + Supports multiple condition types (TOU, license agreements, operational + guidelines, regional restrictions). + + The payload of a Conditions document contains the text of the terms and + conditions, typically in Markdown or HTML format. + This allows for rich formatting while maintaining human readability. + + Conditions documents are versioned and can be revoked, enabling + administrators to update terms over time while maintaining an auditable + history of what terms were in effect at any given time. + """ + + validation: """ + The Conditions document *MUST* be a valid signed document according to + the Signed Document Standard. + + When a Conditions document is referenced in a parameter document's + `conditions` metadata field, the referenced document *MUST* exist and be + of type "Conditions". + + When a Conditions document is referenced in a user-submitted document's + `conditions` metadata field, the referenced document *MUST* exist, be of + type "Conditions", and not be revoked. + """ + + business_logic: { + front_end: """ + Front-end applications should: + + * Display Conditions documents to users when they are required to + accept them + * Store user acceptance locally to minimize friction (users only need + to explicitly accept conditions the first time they encounter them) + * Gray out submission buttons until all required conditions have been + accepted + * Display a disclosure on submission listing all accepted conditions + under which the document is being submitted + * Provide clear error messages if required conditions are missing or + invalid + """ + + back_end: """ + Back-end validation must: + + * Verify that all Conditions documents referenced in user-submitted + documents exist and are valid + * Collect all required conditions from the parameter hierarchy + (Brand → Campaign → Category → Contest) + * Ensure user-submitted documents include exactly the union of all + required conditions from their parameter hierarchy + * Reject documents that reference revoked Conditions documents + * Reject documents that are missing required conditions or include + conditions not in the parameter hierarchy + + The decentralized system (Hermes) will also reject documents without + the required conditions, ensuring validation occurs at multiple layers. + """ + } + + headers: "content type": value: [ + "text/markdown; charset=utf-8", + "text/html; charset=utf-8", + ] + + headers: "content-encoding": value: ["br"] + + metadata: { + ref: { + required: "optional" + type: signed_doc_types.allDocNames + } + + revocations: required: "optional" + } + + payload: description: """ + The Conditions document payload contains the text of the terms and + conditions. + + The payload *MUST* be valid according to the content type specified in + the COSE header: + + * If `content-type` is `text/markdown; charset=utf-8`, the payload must be + valid Markdown + * If `content-type` is `text/html; charset=utf-8`, the payload must be + valid HTML5 + + The payload is compressed using Brotli compression (`br` encoding) as + specified in the `content-encoding` header. + + The payload content should be human-readable and clearly state: + * The purpose of the conditions + * What users are agreeing to + * Any obligations or restrictions + * Effective dates or version information + * Contact information for questions + """ + + signers: { + roles: admin: [ + "Brand Admin", + "Campaign Admin", + "Category Admin", + "Contest Admin", + ] + + update: type: "author" + } + + authors: { + "Nathan Bogale": "nathan.bogale@iohk.io" + "Steven Johnson": "steven.johnson@iohk.io" + } + + versions: [ + { + version: "0.01" + modified: "2025-01-XX" + changes: """ + * First Published Version (DRAFT) + """ + }, + ] + } +} + diff --git a/specs/definitions/signed_docs/docs/generic_parameters.cue b/specs/definitions/signed_docs/docs/generic_parameters.cue index 9222a61c79..856aedea8b 100644 --- a/specs/definitions/signed_docs/docs/generic_parameters.cue +++ b/specs/definitions/signed_docs/docs/generic_parameters.cue @@ -47,6 +47,8 @@ _parameters_payload_description: """ revocations: required: "optional" parameters: required: _ | *"yes" + + conditions: required: "optional" } headers: "content type": value: "application/json" diff --git a/specs/definitions/signed_docs/metadata.cue b/specs/definitions/signed_docs/metadata.cue index 68ecd8cf89..23e6b515b7 100644 --- a/specs/definitions/signed_docs/metadata.cue +++ b/specs/definitions/signed_docs/metadata.cue @@ -87,6 +87,7 @@ _metadataNames: [ "collaborators", "revocations", "parameters", + "conditions", "chain", ] @@ -275,6 +276,71 @@ _allMetadataNames: or([ """ } + conditions: { + format: "Document Reference" + description: """ + An array of references to Conditions documents that define terms and conditions. + + The `conditions` metadata field serves two distinct purposes depending on the document type: + + 1. **On Parameter Documents** (Brand Parameters, Campaign Parameters, Category Parameters, Contest Parameters): + * Lists the required condition documents for that level of the system hierarchy + * Specifies which terms users must accept when submitting documents at this level + * The field is optional - if not present, no conditions are required at that level + + 2. **On User-Submitted Documents** (Proposals, Proposal Comments, etc.): + * References all condition documents that the user has accepted + * Must include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest) + * The act of listing these references and signing the document serves as the user's digital signature and acceptance + * The field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified + """ + validation: """ + **For Parameter Documents:** + + * The `conditions` field is optional + * If present, must be an array of valid Conditions document references + * All referenced documents must exist and be of type "Conditions" + * The array must be sorted according to CBOR Deterministic Encoding (4.3.2 Length-First Map Key Ordering) + * All array elements must be unique + + **For User-Submitted Documents:** + + The validation process for user-submitted documents involves transitive collection of required conditions: + + 1. Extract the `parameters` reference from the user document + 2. Starting from the referenced parameters document, follow the parent chain upward to Brand: + * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand + * If the document references Category Parameters, follow: Category → Campaign → Brand + * If the document references Campaign Parameters, follow: Campaign → Brand + * If the document references Brand Parameters, only Brand is included + 3. Collect all `conditions` arrays from each parameter level encountered in the upward chain + 4. Union all condition references (removing duplicates based on document ID and version) + 5. Sort the unified list according to CBOR Deterministic Encoding + 6. Compare the user document's `conditions` array with this unified, sorted list + 7. Validation succeeds only if they match exactly + + Important: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy. + + **Validation Rules:** + + * The user document's `conditions` array must exactly match the union of all required conditions from the parameter hierarchy + * All referenced Conditions documents must exist and be valid + * All referenced Conditions documents must not be revoked + * The array must be sorted (CBOR deterministic encoding order) + * All array elements must be unique + + **Validation Failures:** + + The document will be rejected if: + * Missing required conditions (conditions specified in parameter hierarchy but not in user document) + * Includes extra conditions (conditions in user document not in parameter hierarchy) + * Array is not sorted correctly + * Any referenced condition document doesn't exist or is invalid + * Any referenced condition document is revoked + * Array contains duplicate references + """ + } + } // Note: we make all normally excluded fields optional at the global level, because they are globally optional @@ -288,6 +354,12 @@ metadata: headers: { reply: type: signed_doc_types.commentDocNamesList section: required: "optional" collaborators: required: "optional" + conditions: { + required: "optional" + format: "Document Reference" + type: ["Conditions"] + multiple: true + } } // Preferred display order diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 5a8920674e..d64c3684e4 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -689,7 +689,8 @@ "docs": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ] } }, @@ -1635,7 +1636,10 @@ "description": "Media Type/s allowed in the Payload", "format": "Media Type", "required": "yes", - "value": "text/markdown" + "value": [ + "text/markdown; charset=utf-8", + "text/html; charset=utf-8" + ] }, "content-encoding": { "coseLabel": "content-encoding", @@ -1693,7 +1697,7 @@ }, "notes": [], "payload": { - "description": "The Conditions document payload contains the text of the terms and conditions.\n\nThe payload *MUST* be valid according to the content type specified in the COSE header:\n\n* If `content-type` is `text/markdown`, the payload must be valid Markdown\n* If `content-type` is `text/html`, the payload must be valid HTML5\n\nThe payload is compressed using Brotli compression (`br` encoding) as specified in the `content-encoding` header.\n\nThe payload content should be human-readable and clearly state:\n* The purpose of the conditions\n* What users are agreeing to\n* Any obligations or restrictions\n* Effective dates or version information\n* Contact information for questions", + "description": "The Conditions document payload contains the text of the terms and conditions.\n\nThe payload *MUST* be valid according to the content type specified in the COSE header:\n\n* If `content-type` is `text/markdown; charset=utf-8`, the payload must be valid Markdown\n* If `content-type` is `text/html; charset=utf-8`, the payload must be valid HTML5\n\nThe payload is compressed using Brotli compression (`br` encoding) as specified in the `content-encoding` header.\n\nThe payload content should be human-readable and clearly state:\n* The purpose of the conditions\n* What users are agreeing to\n* Any obligations or restrictions\n* Effective dates or version information\n* Contact information for questions", "nil": false }, "signers": { @@ -1707,7 +1711,7 @@ "user": [] }, "update": { - "description": "Updates are allowed by the original author and from the 'collaborators' metadata field\nof the previous submitted document's version.", + "description": "Only the original author can update and sign a new version of documents.", "type": "author" } }, @@ -2251,7 +2255,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, @@ -2393,7 +2398,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, @@ -2526,7 +2532,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, @@ -2746,19 +2753,20 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, "conditions": { - "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\nThe field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified.", + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.", "format": "Document Reference", "required": "optional", "multiple": true, "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", @@ -2894,19 +2902,20 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, "conditions": { - "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\nThe field is optional when no conditions are required by the parameter hierarchy, but required when conditions are specified.", + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.", "format": "Document Reference", "required": "optional", "multiple": true, "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Follow the parameter chain: Contest → Category → Campaign → Brand\n3. Collect all `conditions` arrays from each parameter level in the hierarchy\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", @@ -3041,7 +3050,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, @@ -3174,7 +3184,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, @@ -3431,7 +3442,8 @@ "type": [ "Brand Parameters", "Campaign Parameters", - "Category Parameters" + "Category Parameters", + "Contest Parameters" ], "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, From 35c14c2208a81a0201880415c8ddf4bf17e81b65 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Tue, 9 Dec 2025 11:16:30 +0300 Subject: [PATCH 05/10] fix(specs): Add Contest Parameters to System Parameters cluster in defs.cue - Add Contest Parameters to System Parameters docs array - Update comment to reflect that Contest Parameters are included - Aligns CUE definition with signed_doc.json specification - Fixes inconsistency where JSON included Contest Parameters but CUE excluded it --- specs/definitions/signed_doc_types/defs.cue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/definitions/signed_doc_types/defs.cue b/specs/definitions/signed_doc_types/defs.cue index 90ccc78dd7..869fabbc9f 100644 --- a/specs/definitions/signed_doc_types/defs.cue +++ b/specs/definitions/signed_doc_types/defs.cue @@ -38,12 +38,13 @@ allDocNames: [...#docName] & [ #DocClusters: [string]: #DocumentCluster doc_clusters: #DocClusters & { - // System parameters define the system, excludes Contests. + // System parameters define the system hierarchy. "System Parameters": { docs: [ "Brand Parameters", "Campaign Parameters", "Category Parameters", + "Contest Parameters", ] } } From 44942ae8bd796c352e6ef55b14b4b978c0712b5f Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Tue, 9 Dec 2025 11:22:01 +0300 Subject: [PATCH 06/10] fix(docs): Clarify Contest Parameters traversal paths in conditions validation - Replace ambiguous conditional description with explicit three-path specification - Clearly describe traversal for Contest parented by Brand, Campaign, or Category - Fixes potential implementation misinterpretation where conditional logic was embedded in linear description - Updates validation descriptions in metadata.md, metadata.cue, and signed_doc.json --- docs/src/architecture/08_concepts/signed_doc/metadata.md | 5 ++++- specs/definitions/signed_docs/metadata.cue | 5 ++++- specs/signed_doc.json | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index 6ef54e2503..731f5628a4 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -466,7 +466,10 @@ The validation process for user-submitted documents involves transitive collecti 1. Extract the [`parameters`](metadata.md#parameters) reference from the user document 2. Starting from the referenced parameters document, follow the parent chain upward to Brand: - * If the document references **Contest Parameters**, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand + * If the document references **Contest Parameters**, determine its parent and follow the appropriate path: + - If Contest's parent is **Brand**: Contest → Brand + - If Contest's parent is **Campaign**: Contest → Campaign → Brand + - If Contest's parent is **Category**: Contest → Category → Campaign → Brand * If the document references **Category Parameters**, follow: Category → Campaign → Brand * If the document references **Campaign Parameters**, follow: Campaign → Brand * If the document references **Brand Parameters**, only Brand is included diff --git a/specs/definitions/signed_docs/metadata.cue b/specs/definitions/signed_docs/metadata.cue index 23e6b515b7..fcfb0d9015 100644 --- a/specs/definitions/signed_docs/metadata.cue +++ b/specs/definitions/signed_docs/metadata.cue @@ -309,7 +309,10 @@ _allMetadataNames: or([ 1. Extract the `parameters` reference from the user document 2. Starting from the referenced parameters document, follow the parent chain upward to Brand: - * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand + * If the document references Contest Parameters, determine its parent and follow the appropriate path: + - If Contest's parent is Brand: Contest → Brand + - If Contest's parent is Campaign: Contest → Campaign → Brand + - If Contest's parent is Category: Contest → Category → Campaign → Brand * If the document references Category Parameters, follow: Category → Campaign → Brand * If the document references Campaign Parameters, follow: Campaign → Brand * If the document references Brand Parameters, only Brand is included diff --git a/specs/signed_doc.json b/specs/signed_doc.json index d64c3684e4..96718fe0c4 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -2766,7 +2766,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent and follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", @@ -2915,7 +2915,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, follow: Contest → (its parent: Brand/Campaign/Category) → Campaign (if parent was Category) → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent and follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", From f8b68a32ffacc8018d4fcc54cb91f0d9d3d24fdb Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Tue, 9 Dec 2025 11:36:26 +0300 Subject: [PATCH 07/10] fix(docs): Clarify Contest Parameters parent determination in validation - Add explicit instruction to examine Contest Parameters document's parameters field - Add note explaining Contest can anchor to Brand, Campaign, or Category - Clarify that validation must examine actual document, not assume fixed hierarchy - Updates metadata.md, metadata.cue, and signed_doc.json for consistency - Prevents implementation misinterpretation of flexible anchoring --- docs/src/architecture/08_concepts/signed_doc/metadata.md | 4 +++- specs/definitions/signed_docs/metadata.cue | 4 +++- specs/signed_doc.json | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index 731f5628a4..c72cc13599 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -466,13 +466,15 @@ The validation process for user-submitted documents involves transitive collecti 1. Extract the [`parameters`](metadata.md#parameters) reference from the user document 2. Starting from the referenced parameters document, follow the parent chain upward to Brand: - * If the document references **Contest Parameters**, determine its parent and follow the appropriate path: + * If the document references **Contest Parameters**, determine its parent by examining the Contest Parameters document's `parameters` metadata field, then follow the appropriate path: - If Contest's parent is **Brand**: Contest → Brand - If Contest's parent is **Campaign**: Contest → Campaign → Brand - If Contest's parent is **Category**: Contest → Category → Campaign → Brand * If the document references **Category Parameters**, follow: Category → Campaign → Brand * If the document references **Campaign Parameters**, follow: Campaign → Brand * If the document references **Brand Parameters**, only Brand is included + + **Note:** Contest Parameters can anchor to Brand, Campaign, or Category (as specified in the Contest Parameters document's `parameters` field). The validation must examine the actual Contest Parameters document to determine which parent chain applies. This is not a fixed hierarchy - the path depends on where the specific Contest is anchored. 3. Collect all `conditions` arrays from each parameter level encountered in the upward chain 4. Union all condition references (removing duplicates based on document ID and version) diff --git a/specs/definitions/signed_docs/metadata.cue b/specs/definitions/signed_docs/metadata.cue index fcfb0d9015..bd00851688 100644 --- a/specs/definitions/signed_docs/metadata.cue +++ b/specs/definitions/signed_docs/metadata.cue @@ -309,13 +309,15 @@ _allMetadataNames: or([ 1. Extract the `parameters` reference from the user document 2. Starting from the referenced parameters document, follow the parent chain upward to Brand: - * If the document references Contest Parameters, determine its parent and follow the appropriate path: + * If the document references Contest Parameters, determine its parent by examining the Contest Parameters document's `parameters` metadata field, then follow the appropriate path: - If Contest's parent is Brand: Contest → Brand - If Contest's parent is Campaign: Contest → Campaign → Brand - If Contest's parent is Category: Contest → Category → Campaign → Brand * If the document references Category Parameters, follow: Category → Campaign → Brand * If the document references Campaign Parameters, follow: Campaign → Brand * If the document references Brand Parameters, only Brand is included + + Note: Contest Parameters can anchor to Brand, Campaign, or Category (as specified in the Contest Parameters document's `parameters` field). The validation must examine the actual Contest Parameters document to determine which parent chain applies. This is not a fixed hierarchy - the path depends on where the specific Contest is anchored. 3. Collect all `conditions` arrays from each parameter level encountered in the upward chain 4. Union all condition references (removing duplicates based on document ID and version) 5. Sort the unified list according to CBOR Deterministic Encoding diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 96718fe0c4..aa2a1fcff0 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -2766,7 +2766,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent and follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent by examining the Contest Parameters document's `parameters` metadata field, then follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n\n Note: Contest Parameters can anchor to Brand, Campaign, or Category (as specified in the Contest Parameters document's `parameters` field). The validation must examine the actual Contest Parameters document to determine which parent chain applies. This is not a fixed hierarchy - the path depends on where the specific Contest is anchored.\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", @@ -2915,7 +2915,7 @@ "type": [ "Conditions" ], - "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent and follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" + "validation": "Must exactly match the union of all required conditions from the parameter hierarchy.\n\nValidation process:\n1. Extract the `parameters` reference from the user document\n2. Starting from the referenced parameters document, follow the parent chain upward to Brand:\n * If the document references Contest Parameters, determine its parent by examining the Contest Parameters document's `parameters` metadata field, then follow the appropriate path:\n - If Contest's parent is Brand: Contest → Brand\n - If Contest's parent is Campaign: Contest → Campaign → Brand\n - If Contest's parent is Category: Contest → Category → Campaign → Brand\n * If the document references Category Parameters, follow: Category → Campaign → Brand\n * If the document references Campaign Parameters, follow: Campaign → Brand\n * If the document references Brand Parameters, only Brand is included\n\n Note: Contest Parameters can anchor to Brand, Campaign, or Category (as specified in the Contest Parameters document's `parameters` field). The validation must examine the actual Contest Parameters document to determine which parent chain applies. This is not a fixed hierarchy - the path depends on where the specific Contest is anchored.\n3. Collect all `conditions` arrays from each parameter level encountered in the upward chain\n4. Union all condition references (removing duplicates based on document ID and version)\n5. Sort the unified list according to CBOR Deterministic Encoding\n6. Compare the user document's `conditions` array with this unified, sorted list\n7. Validation succeeds only if they match exactly\n\nImportant: The chain traversal always moves UPWARD from the document's referenced parameters document to Brand. Contest Parameters are only included if the document directly references them. The chain order depends on where the document is anchored in the hierarchy.\n\nAll referenced Conditions documents must exist, be valid, and not be revoked.\nThe array must be sorted (CBOR deterministic encoding order).\nAll array elements must be unique.\n\nValidation fails if:\n* Missing required conditions (conditions specified in parameter hierarchy but not in user document)\n* Includes extra conditions (conditions in user document not in parameter hierarchy)\n* Array is not sorted correctly\n* Any referenced condition document doesn't exist or is invalid\n* Any referenced condition document is revoked\n* Array contains duplicate references" }, "ref": { "description": "Reference to a Linked Document or Documents.\nThis is the primary hierarchical reference to a related document.\n\nIf a reference is defined as required, there must be at least 1 reference specified.\nSome documents allow multiple references, and they are documented as required.\n\nThe document reference serves two purposes:\n\n1. It ensures that the document referenced by an ID/Version is not substituted.\n\tIn other words, that the document intended to be referenced, is actually referenced.\n2. It Allows the document to be unambiguously located in decentralized storage systems.\n\nThere can be any number of Document Locations in any reference.\nThe currently defined locations are:\n\n* `cid` : A CBOR Encoded IPLD Content Identifier ( AKA an IPFS CID ).\n* Others may be added when further storage mechanisms are defined.\n\nThe document location does not guarantee that the document is actually stored.\nIt only defines that if it were stored, this is the identifier\nthat is required to retrieve it.\nTherefore it is required that Document References\nare unique and reproducible, given a documents contents.", From 3a98a31e488d13b56024fbd63f796c5a6f944ed6 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Tue, 9 Dec 2025 12:01:55 +0300 Subject: [PATCH 08/10] fix(specs): Resolve collaborators field contradiction in Conditions documents - Override collaborators description in Conditions to clarify they cannot update - Update Conditions document update rule documentation to state only author can update - Add drafts requirement: conditions must be included on every submission including drafts - Add collaborators exclusion: only document signer must accept conditions, not collaborators - Update JSON, CUE, and markdown documentation for consistency - Aligns with plan requirements for explicit acceptance, drafts, and individual signer responsibility --- .../08_concepts/signed_doc/docs/conditions.md | 6 ++--- .../08_concepts/signed_doc/metadata.md | 12 ++++++++++ .../signed_docs/docs/conditions.cue | 23 +++++++++++++++++++ specs/signed_doc.json | 8 +++---- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md index 839e4c5426..5b784f5d22 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md +++ b/docs/src/architecture/08_concepts/signed_doc/docs/conditions.md @@ -255,8 +255,8 @@ For example: * Contest-level conditions should be signed by Contest Admin or a parent-level admin -Updates are allowed by the original author and from the 'collaborators' metadata field -of the previous submitted document's version. +Updates are allowed only by the original author of the document. +Collaborators listed in the `collaborators` metadata field do not have permission to update Conditions documents. ## JSON Specification Requirements @@ -337,7 +337,7 @@ Add a new entry to the `docs` section with the following structure: "user": [] }, "update": { - "description": "Updates are allowed by the original author and from the 'collaborators' metadata field of the previous submitted document's version.", + "description": "Only the original author can update and sign a new version of documents.", "type": "author" } }, diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md index c72cc13599..1d178e1207 100644 --- a/docs/src/architecture/08_concepts/signed_doc/metadata.md +++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md @@ -488,6 +488,18 @@ The validation process for user-submitted documents involves transitive collecti becomes required and must be present in the user document. **If the unified list is empty** (no conditions are required), the `conditions` field may be omitted. +**Drafts Requirement**: Conditions must be included on **every submission**, including draft versions of proposals +or other documents. This ensures positive and current assent at every stage of document creation. Without this +requirement, a user could accept terms for the first draft, change their mind, and then submit a subsequent draft +without the terms, meaning their assent is no longer positively asserted. It also ensures that rules, such as those +against objectionable material, apply to the document at every stage of its creation. + +**Collaborators Exclusion**: The acceptance of terms is tied to the act of submission by an individual. The terms +and conditions apply only to the individual who signs and submits the document. Collaborators listed on the +document are **not required** to accept the conditions. This mirrors how contracts typically work, where each +party must sign individually. Only the document author (signer) must include the `conditions` field to indicate +their acceptance. + **Validation Rules:** * The user document's `conditions` array must exactly match the union of all required conditions from the parameter hierarchy diff --git a/specs/definitions/signed_docs/docs/conditions.cue b/specs/definitions/signed_docs/docs/conditions.cue index f57b264701..3094672477 100644 --- a/specs/definitions/signed_docs/docs/conditions.cue +++ b/specs/definitions/signed_docs/docs/conditions.cue @@ -84,6 +84,29 @@ docs: #DocumentDefinitions & { type: signed_doc_types.allDocNames } + collaborators: { + required: "optional" + description: """ + A list of collaborators who may be associated with this document. + + **Important**: For Conditions documents, only the original author can update + and sign new versions. Collaborators listed here do not have permission to + publish updates to this document. This field is optional and may be used for + documentation or organizational purposes only. + """ + validation: """ + For Conditions documents, collaborators do not have update permissions. + Only the original author can create new versions of Conditions documents. + + In the event there are **MULTIPLE** `collaborators` listed, they **MUST** be + sorted. + + Sorting for each element of `collaborators` follows the same sort order as + specified for Map Keys, as defined by CBOR Deterministic Encoding + (4.3.2 Length-First Map Key Ordering). + """ + } + revocations: required: "optional" } diff --git a/specs/signed_doc.json b/specs/signed_doc.json index aa2a1fcff0..693e627626 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -1659,10 +1659,10 @@ "validation": "Chained Documents do not support collaborators.\nAny document which is attempted to be published in the sequence\nwhich is *NOT* published by the author of the first document in the\nsequence is fraudulent, and to be discarded.\n\nIn addition, the chained document *MUST*:\n\n* Not have `collaborators`;\n* Have the same `id` as the document being chained to;\n* Have a `ver` that is greater than the `ver` being chained to;\n* Have the same `type` as the chained document;\n* Have `parameters` match;\n* Have not be chaining to a document already chained to by another document;\n* Have its absolute `height` exactly one more than the `height` of the document being chained to.\n\nIF any of these validations fail, then the entire sequence of documents is INVALID.\nNot just the current document." }, "collaborators": { - "description": "A list of collaborators who may also publish updates to versions of this document.\nThis should include all parties who have not signed this document directly.\n\nEvery subsequent version can amend the collaborators list.\nHowever, the initial Author can never be removed from being able to\npublish a new version of the document.", + "description": "A list of collaborators who may be associated with this document.\n\n**Important**: For Conditions documents, only the original author can update and sign new versions.\nCollaborators listed here do not have permission to publish updates to this document.\nThis field is optional and may be used for documentation or organizational purposes only.", "format": "Collaborators Reference List", "required": "optional", - "validation": "This list does not imply these collaborators have consented to collaborate, only that the author/s\nare permitting these potential collaborators to participate in the drafting and submission process.\nHow collaborators are counted on a final submission is determined by a parameter defined at the\nBrand/Campaign/Category level (parameter name TBD). \nDepending on that configuration:\n\n* All listed collaborators may be required to submit a `final` Submission Action in addition\n to the author; **OR**\n* Only collaborators who submit a `final` Submission Action for the referenced version are\n included as collaborators on that submission.\n\nIf the parameter is not present, default to the latter mode (only final-signing collaborators are\nincluded).\nIn all modes a document is only considered final when the original author has submitted `final`.\n\nIn the event there are **MULTIPLE** `collaborators` listed, they **MUST** be sorted.\n\nSorting for each element of `collaborators` follows the same sort order as specified for Map Keys, \nas defined by CBOR Deterministic Encoding (4.3.2 Length-First Map Key Ordering)." + "validation": "For Conditions documents, collaborators do not have update permissions.\nOnly the original author can create new versions of Conditions documents.\n\nIn the event there are **MULTIPLE** `collaborators` listed, they **MUST** be sorted.\n\nSorting for each element of `collaborators` follows the same sort order as specified for Map Keys, \nas defined by CBOR Deterministic Encoding (4.3.2 Length-First Map Key Ordering)." }, "id": { "description": "Document ID, created the first time the document is created.\nThis must be a properly created UUIDv7 which contains the\ntimestamp of when the document was created.", @@ -2759,7 +2759,7 @@ "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, "conditions": { - "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.", + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.\n\n**Drafts Requirement**: Conditions must be included on every submission, including draft versions of proposals or other documents.\nThis ensures positive and current assent at every stage of document creation. Without this requirement, a user could accept\nthe terms for the first draft, change their mind, and then submit a subsequent draft without the terms, meaning their\nassent is no longer positively asserted. It also ensures that rules, such as those against objectionable material, apply\nto the document at every stage of its creation.\n\n**Collaborators Exclusion**: The acceptance of terms is tied to the act of submission by an individual. The terms and conditions\napply only to the individual who signs and submits the document. Collaborators listed on the document are not required to\naccept the conditions. This mirrors how contracts typically work, where each party must sign individually. Only the document\nauthor (signer) must include the `conditions` field to indicate their acceptance.", "format": "Document Reference", "required": "optional", "multiple": true, @@ -2908,7 +2908,7 @@ "validation": "In addition to the validation performed for `Document Reference` type fields: \n\n* Any linked referenced document that includes a `parameters` metadata must match the \n`parameters` of the referencing document,\nor a parent of those `parameters`.\n\nFor example, a linked reference to `Contest Parameters` is transitively a reference to\nthe Parameters document it references, and each parameters document they reference \nuntil the `Brand` parameters document is reached.\n\nThe use case here is for Templates.\nThe profile template, or proposal templates could be defined at any of these\nlevels, and as long as they all refer to the same chain of parameters in the\nhierarchy they are all valid." }, "conditions": { - "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.", + "description": "An array of references to all Conditions documents that the user has accepted.\n\nMust include ALL conditions required by the parameter hierarchy (Brand → Campaign → Category → Contest).\nThe act of listing these references and signing the document serves as the user's digital signature and acceptance.\n\n**Schema-level requirement**: This field is marked as optional in the schema, allowing documents to be created without it.\n\n**Validation-level requirement**: During validation, this field becomes required when the parameter hierarchy specifies conditions.\nIf conditions are required by any level in the parameter hierarchy (Brand, Campaign, Category, or Contest),\nthe field must be present and must exactly match all required conditions. If no conditions are specified\nin the parameter hierarchy, the field may be omitted.\n\n**Drafts Requirement**: Conditions must be included on every submission, including draft versions of proposals or other documents.\nThis ensures positive and current assent at every stage of document creation. Without this requirement, a user could accept\nthe terms for the first draft, change their mind, and then submit a subsequent draft without the terms, meaning their\nassent is no longer positively asserted. It also ensures that rules, such as those against objectionable material, apply\nto the document at every stage of its creation.\n\n**Collaborators Exclusion**: The acceptance of terms is tied to the act of submission by an individual. The terms and conditions\napply only to the individual who signs and submits the document. Collaborators listed on the document are not required to\naccept the conditions. This mirrors how contracts typically work, where each party must sign individually. Only the document\nauthor (signer) must include the `conditions` field to indicate their acceptance.", "format": "Document Reference", "required": "optional", "multiple": true, From 9e89b6b8844f680d2f89f45159b484285626dd93 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Thu, 11 Dec 2025 15:45:17 +0300 Subject: [PATCH 09/10] Update contest delegation and representative nomination documentation - Clarified that the payload for contest delegation MAY be nil or must conform to the defined JSON schema. - Updated the requirement for representatives to delegate to their latest nomination for a Contest instead of a Category. - Specified that the signer of a representative nomination must be the same as the author of the referenced Rep Profile document. - Adjusted JSON schema to allow for null payloads and ensure proper validation rules are in place. --- .../signed_doc/docs/contest_delegation.md | 37 +++++++++++------- .../signed_doc/docs/rep_nomination.md | 2 +- .../signed_docs/docs/contest_delegation.cue | 4 +- .../contest_delegation.schema.json | 33 +++++++++------- .../signed_docs/docs/rep_nomintion.cue | 2 +- specs/signed_doc.json | 39 +++++++++++-------- 6 files changed, 69 insertions(+), 48 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/contest_delegation.md b/docs/src/architecture/08_concepts/signed_doc/docs/contest_delegation.md index d7d5f2223d..17b3eb7cb1 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/contest_delegation.md +++ b/docs/src/architecture/08_concepts/signed_doc/docs/contest_delegation.md @@ -76,9 +76,9 @@ with the highest priority. references are invalid. This is to prevent a Representative changing their nomination invalidating a delegation with multiple representatives. -* The payload MUST be nil. +* The payload MAY be nil, or if present, MUST conform to the JSON schema defined in the [Payload](#payload) section. -A Representative *MUST* Delegate to their latest Nomination for a Category, +A Representative *MUST* Delegate to their latest Nomination for a Contest, otherwise their Nomination is invalid. This is because Delegation points to a *SPECIFIC* Nomination, and it @@ -313,21 +313,28 @@ valid drep nominations. ], "title": "Contest Delegation Schema", "description": "Structure of the payload of a Contest Delegation.", - "type": "object", - "properties": { - "weights": { - "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", - "items": { - "exclusiveMinimum": 0, - "type": "integer" + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "weights": { + "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", + "items": { + "exclusiveMinimum": 0, + "type": "integer" + }, + "minItems": 0, + "type": "array" + } }, - "minItems": 0, - "type": "array" + "required": [ + "weights" + ] } - }, - "additionalProperties": false, - "required": [ - "weights" ], "x-changelog": { "2025-03-01": [ diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md b/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md index b3920042a9..0b3568ffed 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md +++ b/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md @@ -37,7 +37,7 @@ The payload of a profile is controlled by its template. ### Validation -* The signer MUST be a registered 'Representative'. +* The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document. * The 'ref' metadata field MUST point to a valid 'Representative Profile' document. * The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document. * The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document. diff --git a/specs/definitions/signed_docs/docs/contest_delegation.cue b/specs/definitions/signed_docs/docs/contest_delegation.cue index 9aa1b05498..0321caa519 100644 --- a/specs/definitions/signed_docs/docs/contest_delegation.cue +++ b/specs/definitions/signed_docs/docs/contest_delegation.cue @@ -68,9 +68,9 @@ docs: "Contest Delegation": { references are invalid. This is to prevent a Representative changing their nomination invalidating a delegation with multiple representatives. - * The payload MUST be nil. + * The payload MAY be nil, or if present, MUST conform to the JSON schema defined in the payload section. - A Representative *MUST* Delegate to their latest Nomination for a Category, + A Representative *MUST* Delegate to their latest Nomination for a Contest, otherwise their Nomination is invalid. \(docs."Rep Nomination"._latest_nomination_note) diff --git a/specs/definitions/signed_docs/docs/payload_schemas/contest_delegation.schema.json b/specs/definitions/signed_docs/docs/payload_schemas/contest_delegation.schema.json index 6e49605627..76b68a54b3 100644 --- a/specs/definitions/signed_docs/docs/payload_schemas/contest_delegation.schema.json +++ b/specs/definitions/signed_docs/docs/payload_schemas/contest_delegation.schema.json @@ -13,20 +13,27 @@ "First Version Created." ] }, - "type": "object", - "additionalProperties": false, - "properties": { - "weights": { - "type": "array", - "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", - "items": { - "type": "integer", - "exclusiveMinimum": 0 + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "weights": { + "type": "array", + "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", + "items": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "minItems": 0 + } }, - "minItems": 0 + "required": [ + "weights" + ] } - }, - "required": [ - "weights" ] } \ No newline at end of file diff --git a/specs/definitions/signed_docs/docs/rep_nomintion.cue b/specs/definitions/signed_docs/docs/rep_nomintion.cue index 8356ec2ea7..33c63a963b 100644 --- a/specs/definitions/signed_docs/docs/rep_nomintion.cue +++ b/specs/definitions/signed_docs/docs/rep_nomintion.cue @@ -44,7 +44,7 @@ docs: "Rep Nomination": { """ validation: """ - * The signer MUST be a registered 'Representative'. + * The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document. * The 'ref' metadata field MUST point to a valid 'Representative Profile' document. * The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document. * The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document. diff --git a/specs/signed_doc.json b/specs/signed_doc.json index 693e627626..fa0985e2ac 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -2142,10 +2142,9 @@ "title": "Three Delegation Weights" } ], - "nil": false, + "nil": true, "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, "description": "Structure of the payload of a Contest Delegation.", "maintainers": [ { @@ -2153,22 +2152,30 @@ "url": "https://projectcatalyst.io/" } ], - "properties": { - "weights": { - "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", - "items": { - "exclusiveMinimum": 0, - "type": "integer" + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "weights": { + "description": "List of weights to apply to each delegate.\nThis list is in the same order as the delegate references.\nIf there are fewer entries than delegates, then the missing weights are set to `1`.\nIf there are more weights, then the extra weights are ignored. If the payload is missing, OR the array is empty, then the weights assigned is `1`.", + "items": { + "exclusiveMinimum": 0, + "type": "integer" + }, + "minItems": 0, + "type": "array" + } }, - "minItems": 0, - "type": "array" + "required": [ + "weights" + ] } - }, - "required": [ - "weights" ], "title": "Contest Delegation Schema", - "type": "object", "x-changelog": { "2025-03-01": [ "First Version Created." @@ -2188,7 +2195,7 @@ } }, "type": "764f17fb-cc50-4979-b14a-b213dbac5994", - "validation": "* The `parameters` metadata *MUST* point to the same Contest as the \n\tNomination of the Representative.\n* The 'ref' metadata field MUST point to a valid 'Representative Nomination'.\n IF there are multiple representatives, then any which are not pointing\n to a valid `Representative Nomination` are excluded. \n The nomination is only invalid if ALL references `Representative Nomination` \n references are invalid.\n This is to prevent a Representative changing their nomination invalidating a\n delegation with multiple representatives.\n* The payload MUST be nil.\n\nA Representative *MUST* Delegate to their latest Nomination for a Category,\notherwise their Nomination is invalid.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.\n\nA Voter may withdraw their Delegation by revoking all delegation documents.\n`revocations` must be set to `true` to withdraw a delegation, OR\na later contest delegation may change the delegated representative without\nfirst revoking the prior delegation, as only the latest delegation is\nconsidered.", + "validation": "* The `parameters` metadata *MUST* point to the same Contest as the \n\tNomination of the Representative.\n* The 'ref' metadata field MUST point to a valid 'Representative Nomination'.\n IF there are multiple representatives, then any which are not pointing\n to a valid `Representative Nomination` are excluded. \n The nomination is only invalid if ALL references `Representative Nomination` \n references are invalid.\n This is to prevent a Representative changing their nomination invalidating a\n delegation with multiple representatives.\n* The payload MAY be nil, or if present, MUST conform to the JSON schema defined in the payload section.\n\nA Representative *MUST* Delegate to their latest Nomination for a Contest,\notherwise their Nomination is invalid.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.\n\nA Voter may withdraw their Delegation by revoking all delegation documents.\n`revocations` must be set to `true` to withdraw a delegation, OR\na later contest delegation may change the delegated representative without\nfirst revoking the prior delegation, as only the latest delegation is\nconsidered.", "versions": [ { "changes": "* First Published Version", @@ -3709,7 +3716,7 @@ } }, "type": "bf9abd97-5d1f-4429-8e80-740fea371a9c", - "validation": "* The signer MUST be a registered 'Representative'.\n* The 'ref' metadata field MUST point to a valid 'Representative Profile' document.\n* The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document.\n* The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document.\n* The payload MUST be valid against the JSON schema defined in the referenced template.\n* Other rules may apply as defined by the Contest or other parameters which can\n\tcontrol who may validly nominate as a representative in a Contest.\n\nNo Nomination is valid unless the latest Contest Delegation of the Delegate\nrefers to their own Nomination.\nThis requires that Nominating is a two step process:\n\n1. Post the Nomination Document.\n2. Post a Contest Delegation delegating to the new Nomination Document.\n\nUpdating the Nomination Document will invalidate all Nominations to the \nRepresentative.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.", + "validation": "* The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document.\n* The 'ref' metadata field MUST point to a valid 'Representative Profile' document.\n* The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document.\n* The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document.\n* The payload MUST be valid against the JSON schema defined in the referenced template.\n* Other rules may apply as defined by the Contest or other parameters which can\n\tcontrol who may validly nominate as a representative in a Contest.\n\nNo Nomination is valid unless the latest Contest Delegation of the Delegate\nrefers to their own Nomination.\nThis requires that Nominating is a two step process:\n\n1. Post the Nomination Document.\n2. Post a Contest Delegation delegating to the new Nomination Document.\n\nUpdating the Nomination Document will invalidate all Nominations to the \nRepresentative.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.", "versions": [ { "changes": "* First Published Version", From 34824b7c1683580d7d8718a84ccc3266544d9201 Mon Sep 17 00:00:00 2001 From: nathanbogale Date: Thu, 11 Dec 2025 18:20:19 +0300 Subject: [PATCH 10/10] Enhance validation requirements for representative nominations - Updated the validation rule to specify that the signer must use the Representative role from the Catalyst ID, rather than the normal Role0 signature. - Ensured consistency across documentation and JSON schema regarding the requirements for the signer of a representative nomination. --- .../architecture/08_concepts/signed_doc/docs/rep_nomination.md | 2 +- specs/definitions/signed_docs/docs/rep_nomintion.cue | 2 +- specs/signed_doc.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md b/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md index 0b3568ffed..74e893d2cf 100644 --- a/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md +++ b/docs/src/architecture/08_concepts/signed_doc/docs/rep_nomination.md @@ -37,7 +37,7 @@ The payload of a profile is controlled by its template. ### Validation -* The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document. +* The signer MUST be a registered 'Representative' (the signature MUST use the Representative role from the Catalyst ID, not the normal Role0 signature) and MUST be the same as the author of the referenced Rep Profile document. * The 'ref' metadata field MUST point to a valid 'Representative Profile' document. * The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document. * The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document. diff --git a/specs/definitions/signed_docs/docs/rep_nomintion.cue b/specs/definitions/signed_docs/docs/rep_nomintion.cue index 33c63a963b..2e6bc0ddb0 100644 --- a/specs/definitions/signed_docs/docs/rep_nomintion.cue +++ b/specs/definitions/signed_docs/docs/rep_nomintion.cue @@ -44,7 +44,7 @@ docs: "Rep Nomination": { """ validation: """ - * The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document. + * The signer MUST be a registered 'Representative' (the signature MUST use the Representative role from the Catalyst ID, not the normal Role0 signature) and MUST be the same as the author of the referenced Rep Profile document. * The 'ref' metadata field MUST point to a valid 'Representative Profile' document. * The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document. * The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document. diff --git a/specs/signed_doc.json b/specs/signed_doc.json index fa0985e2ac..3038e93fde 100644 --- a/specs/signed_doc.json +++ b/specs/signed_doc.json @@ -3716,7 +3716,7 @@ } }, "type": "bf9abd97-5d1f-4429-8e80-740fea371a9c", - "validation": "* The signer MUST be a registered 'Representative' and MUST be the same as the author of the referenced Rep Profile document.\n* The 'ref' metadata field MUST point to a valid 'Representative Profile' document.\n* The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document.\n* The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document.\n* The payload MUST be valid against the JSON schema defined in the referenced template.\n* Other rules may apply as defined by the Contest or other parameters which can\n\tcontrol who may validly nominate as a representative in a Contest.\n\nNo Nomination is valid unless the latest Contest Delegation of the Delegate\nrefers to their own Nomination.\nThis requires that Nominating is a two step process:\n\n1. Post the Nomination Document.\n2. Post a Contest Delegation delegating to the new Nomination Document.\n\nUpdating the Nomination Document will invalidate all Nominations to the \nRepresentative.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.", + "validation": "* The signer MUST be a registered 'Representative' (the signature MUST use the Representative role from the Catalyst ID, not the normal Role0 signature) and MUST be the same as the author of the referenced Rep Profile document.\n* The 'ref' metadata field MUST point to a valid 'Representative Profile' document.\n* The 'parameters' metadata field MUST point to a valid 'Contest Parameters' document.\n* The 'template' metadata field MUST point to a valid 'Representative Nomination Form Template' document.\n* The payload MUST be valid against the JSON schema defined in the referenced template.\n* Other rules may apply as defined by the Contest or other parameters which can\n\tcontrol who may validly nominate as a representative in a Contest.\n\nNo Nomination is valid unless the latest Contest Delegation of the Delegate\nrefers to their own Nomination.\nThis requires that Nominating is a two step process:\n\n1. Post the Nomination Document.\n2. Post a Contest Delegation delegating to the new Nomination Document.\n\nUpdating the Nomination Document will invalidate all Nominations to the \nRepresentative.\n\nThis is because Delegation points to a *SPECIFIC* Nomination, and it\n*MUST* be the latest for the Representative on the Contest.\nAs the Nomination contains information that the User relies on\nwhen choosing to delegate, changing that information could have a \nreal and detrimental result in the Delegation choice.\nTherefore, for a Delegation to be valid, it *MUST* point to the\nlatest Nomination for a Representative.\n\nPublishing a newer version of the Nomination Document to a specific contest will\ninvalidate all pre-existing delegations, and all voters will need\nto re-delegate to affirm the delegates latest nomination.", "versions": [ { "changes": "* First Published Version",