diff --git a/.gitignore b/.gitignore
index 9f75a0f579..4950c2b065 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,9 @@ $RECYCLE.BIN/
!/.vscode/settings.recommended.json
!/.vscode/tasks.recommended.json
+venv/
+# Python virtual environments
+
# Dart stuff
/pubspec.lock
/.dart_tool/**/*
diff --git a/.vscode/settings.recommended.json b/.vscode/settings.recommended.json
index c152c545fd..c63dff43ce 100644
--- a/.vscode/settings.recommended.json
+++ b/.vscode/settings.recommended.json
@@ -1,5 +1,5 @@
{
- // Recommended `settings.json` configuration
+ "$comment": "Recommended `settings.json` configuration",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true,
@@ -37,12 +37,20 @@
"rust",
"rust/c509-certificate",
"rust/cardano-chain-follower",
+ "rust/catalyst-types",
"rust/catalyst-voting",
+ "rust/immutable-ledger",
+ "rust/vote-tx-v1",
+ "rust/vote-tx-v2",
+ "rust/signed-doc",
"rust/cbork",
"rust/hermes-ipfs",
+ "rust/rbac-registration",
+ "rust/cardano-blockchain-types",
"dart",
"docs",
- "general"
+ "general",
+ "deps"
],
"conventionalCommits.gitmoji": false,
"markdown.extension.toc.unorderedList.marker": "*",
diff --git a/docs/src/architecture/08_concepts/signed_doc/diagrams/all.dot b/docs/src/architecture/08_concepts/signed_doc/diagrams/all.dot
index d22921c2f9..b810e40dbb 100644
--- a/docs/src/architecture/08_concepts/signed_doc/diagrams/all.dot
+++ b/docs/src/architecture/08_concepts/signed_doc/diagrams/all.dot
@@ -1,4 +1,4 @@
-digraph "None" {
+digraph "All" {
rankdir="LR"
graph [fontname="helvetica", fontsize="32", fontcolor="#29235c", bgcolor="white"];
node [penwidth="0", margin="0", fontname="helvetica", fontsize="32", fontcolor="#29235c"];
@@ -121,16 +121,6 @@ digraph "None" {
-
-
-
-
- parameters |
- Brand Parameters |
-
-
- |
-
>
@@ -186,16 +176,6 @@ digraph "None" {
-
-
-
-
- parameters |
- Campaign Parameters |
-
-
- |
-
>
@@ -437,7 +417,7 @@ digraph "None" {
parameters |
- Brand Parameters Campaign Parameters Category Parameters |
+ Decision Parameters |
@@ -963,10 +943,8 @@ digraph "None" {
];
- "Campaign Parameters":"parameters":e -> "Brand Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Category Parameters":"parameters":e -> "Campaign Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
"Comment Moderation Action":"ref":e -> "Proposal Comment":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Decision Parameters":"parameters":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
+ "Decision Parameters":"parameters":e -> "Decision Parameters":"title":n [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
"Proposal":"template":e -> "Proposal Template":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
"Proposal":"parameters":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment":"ref":e -> "Proposal":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
diff --git a/docs/src/architecture/08_concepts/signed_doc/diagrams/brand_parameters.dot b/docs/src/architecture/08_concepts/signed_doc/diagrams/brand_parameters.dot
index ec4702ddac..854ce68f55 100644
--- a/docs/src/architecture/08_concepts/signed_doc/diagrams/brand_parameters.dot
+++ b/docs/src/architecture/08_concepts/signed_doc/diagrams/brand_parameters.dot
@@ -72,38 +72,8 @@ Relationships"
>
];
-
- "Campaign Parameters" [
- id="Campaign Parameters";
- label=<
-
-
-
- Campaign Parameters
- |
-
-
-
- >
- ];
-
}
- "Decision Parameters" [
- id="Decision Parameters";
- label=<
-
-
-
- Decision Parameters
- |
-
-
-
- >
- ];
-
-
"Proposal" [
id="Proposal";
label=<
@@ -209,8 +179,6 @@ Relationships"
];
- "Campaign Parameters":"title":e -> "Brand Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Decision Parameters":"title":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal":"title":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment":"title":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment Meta Template":"title":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
diff --git a/docs/src/architecture/08_concepts/signed_doc/diagrams/campaign_parameters.dot b/docs/src/architecture/08_concepts/signed_doc/diagrams/campaign_parameters.dot
index f21afdeadf..c6746ece95 100644
--- a/docs/src/architecture/08_concepts/signed_doc/diagrams/campaign_parameters.dot
+++ b/docs/src/architecture/08_concepts/signed_doc/diagrams/campaign_parameters.dot
@@ -18,21 +18,6 @@ Relationships"
color=blue
penwidth=20
- "Brand Parameters" [
- id="Brand Parameters";
- label=<
-
-
-
- Brand Parameters
- |
-
-
-
- >
- ];
-
-
"Campaign Parameters" [
id="Campaign Parameters";
label=<
@@ -82,31 +67,6 @@ Relationships"
-
-
-
-
- parameters |
- Brand Parameters |
-
-
- |
-
-
-
- >
- ];
-
-
- "Category Parameters" [
- id="Category Parameters";
- label=<
-
-
-
- Category Parameters
- |
-
>
@@ -114,21 +74,6 @@ Relationships"
}
- "Decision Parameters" [
- id="Decision Parameters";
- label=<
-
-
-
- Decision Parameters
- |
-
-
-
- >
- ];
-
-
"Proposal" [
id="Proposal";
label=<
@@ -234,9 +179,6 @@ Relationships"
];
- "Campaign Parameters":"parameters":e -> "Brand Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Category Parameters":"title":e -> "Campaign Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Decision Parameters":"title":e -> "Campaign Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal":"title":e -> "Campaign Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment":"title":e -> "Campaign Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment Meta Template":"title":e -> "Campaign Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
diff --git a/docs/src/architecture/08_concepts/signed_doc/diagrams/category_parameters.dot b/docs/src/architecture/08_concepts/signed_doc/diagrams/category_parameters.dot
index b6a2aa470a..ff1f5e4b40 100644
--- a/docs/src/architecture/08_concepts/signed_doc/diagrams/category_parameters.dot
+++ b/docs/src/architecture/08_concepts/signed_doc/diagrams/category_parameters.dot
@@ -18,21 +18,6 @@ Relationships"
color=blue
penwidth=20
- "Campaign Parameters" [
- id="Campaign Parameters";
- label=<
-
-
-
- Campaign Parameters
- |
-
-
-
- >
- ];
-
-
"Category Parameters" [
id="Category Parameters";
label=<
@@ -82,16 +67,6 @@ Relationships"
-
-
-
-
- parameters |
- Campaign Parameters |
-
-
- |
-
>
@@ -99,21 +74,6 @@ Relationships"
}
- "Decision Parameters" [
- id="Decision Parameters";
- label=<
-
-
-
- Decision Parameters
- |
-
-
-
- >
- ];
-
-
"Proposal" [
id="Proposal";
label=<
@@ -219,8 +179,6 @@ Relationships"
];
- "Category Parameters":"parameters":e -> "Campaign Parameters":"title":w [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
- "Decision Parameters":"title":e -> "Category Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal":"title":e -> "Category Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment":"title":e -> "Category Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
"Proposal Comment Meta Template":"title":e -> "Category Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
diff --git a/docs/src/architecture/08_concepts/signed_doc/diagrams/decision_parameters.dot b/docs/src/architecture/08_concepts/signed_doc/diagrams/decision_parameters.dot
index ff41dcf0f6..eb5faa35e0 100644
--- a/docs/src/architecture/08_concepts/signed_doc/diagrams/decision_parameters.dot
+++ b/docs/src/architecture/08_concepts/signed_doc/diagrams/decision_parameters.dot
@@ -13,57 +13,6 @@ Relationships"
- subgraph cluster_system_parameters {
- label = "System Parameters";
- color=blue
- penwidth=20
-
- "Brand Parameters" [
- id="Brand Parameters";
- label=<
-
-
-
- Brand Parameters
- |
-
-
-
- >
- ];
-
-
- "Campaign Parameters" [
- id="Campaign Parameters";
- label=<
-
-
-
- Campaign Parameters
- |
-
-
-
- >
- ];
-
-
- "Category Parameters" [
- id="Category Parameters";
- label=<
-
-
-
- Category Parameters
- |
-
-
-
- >
- ];
-
- }
-
"Decision Parameters" [
id="Decision Parameters";
label=<
@@ -118,7 +67,7 @@ Relationships"
parameters |
- Brand Parameters Campaign Parameters Category Parameters |
+ Decision Parameters |
@@ -129,5 +78,5 @@ Relationships"
];
- "Decision Parameters":"parameters":e -> "Brand Parameters" [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*", lhead="cluster_system_parameters"]
+ "Decision Parameters":"parameters":e -> "Decision Parameters":"title":n [dir=forward, penwidth=6, color="#29235c", headlabel="1", taillabel="*"]
}
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/brand_parameters.md b/docs/src/architecture/08_concepts/signed_doc/docs/brand_parameters.md
index 6e74a9b972..95cc328f55 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/brand_parameters.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/brand_parameters.md
@@ -2,7 +2,10 @@
## Description
-Parameters which define this brand within the system.
+This specification outlines the required definitions for the current features.
+The document will be incrementally improved in future iterations as more functionality
+and features are added.
+This section will be included and updated in future iterations.
@@ -112,15 +115,19 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
### Changelog
-#### 0.01 (2025-04-04)
+#### v1 (2024-06-07)
+
+Initial version. Structure aligned with global metadata requirements.
+
+#### v2 (2025-04-04)
-* First Published Version
+Updated to include common definitions and examples.
[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1
[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/campaign_parameters.md b/docs/src/architecture/08_concepts/signed_doc/docs/campaign_parameters.md
index 40b40909c1..b86067891b 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/campaign_parameters.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/campaign_parameters.md
@@ -2,7 +2,10 @@
## Description
-Parameters which define a Campaign within a Brand in the system.
+This specification outlines the required definitions for the current features.
+The document will be incrementally improved in future iterations as more functionality
+and features are added.
+This section will be included and updated in future iterations.
@@ -89,24 +92,6 @@ The first version of the document must set [`ver`](../metadata.md#ver) == [`id`]
The document version must always be >= the document ID.
-### [`parameters`](../metadata.md#parameters)
-
-
-| Parameter | Value |
-| --- | --- |
-| Required | yes |
-| Format | [Document Reference](../metadata.md#document-reference) |
-| Valid References | [Brand Parameters](brand_parameters.md) |
-
-A reference to the Parameters Document this document lies under.
-
-#### [`parameters`](../metadata.md#parameters) Validation
-
-In addition to the validation performed for [Document Reference](../metadata.md#document-reference) type fields:
-
-* Any linked referenced document that includes a [`parameters`](../metadata.md#parameters) metadata must match the
-[`parameters`](../metadata.md#parameters) of the referencing document.
-
## Payload
This specification outlines the required definitions for the current features.
@@ -130,19 +115,15 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
### Changelog
-#### 0.01 (2025-04-04)
-
-* First Published Version
-
-#### 0.03 (2025-05-05)
+#### v1 (2024-06-07)
-* Use generalized parameters.
+Initial version. Structure aligned with global metadata requirements.
[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1
[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/category_parameters.md b/docs/src/architecture/08_concepts/signed_doc/docs/category_parameters.md
index 07f5156139..339da8e194 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/category_parameters.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/category_parameters.md
@@ -2,7 +2,10 @@
## Description
-Parameters which define a Category withing a Campaign under a Brand in the system.
+This specification outlines the required definitions for the current features.
+The document will be incrementally improved in future iterations as more functionality
+and features are added.
+This section will be included and updated in future iterations.
@@ -89,24 +92,6 @@ The first version of the document must set [`ver`](../metadata.md#ver) == [`id`]
The document version must always be >= the document ID.
-### [`parameters`](../metadata.md#parameters)
-
-
-| Parameter | Value |
-| --- | --- |
-| Required | yes |
-| Format | [Document Reference](../metadata.md#document-reference) |
-| Valid References | [Campaign Parameters](campaign_parameters.md) |
-
-A reference to the Parameters Document this document lies under.
-
-#### [`parameters`](../metadata.md#parameters) Validation
-
-In addition to the validation performed for [Document Reference](../metadata.md#document-reference) type fields:
-
-* Any linked referenced document that includes a [`parameters`](../metadata.md#parameters) metadata must match the
-[`parameters`](../metadata.md#parameters) of the referencing document.
-
## Payload
This specification outlines the required definitions for the current features.
@@ -130,19 +115,15 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
### Changelog
-#### 0.01 (2025-04-04)
-
-* First Published Version
-
-#### 0.03 (2025-05-05)
+#### v1 (2024-06-07)
-* Use generalized parameters.
+Initial version. Structure aligned with global metadata requirements.
[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1
[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/comment_moderation_action.md b/docs/src/architecture/08_concepts/signed_doc/docs/comment_moderation_action.md
index 5b9907ca1f..e8bd4caf85 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/comment_moderation_action.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/comment_moderation_action.md
@@ -153,7 +153,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/decision_parameters.md b/docs/src/architecture/08_concepts/signed_doc/docs/decision_parameters.md
index 95e049ecf2..5e50e1dc92 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/decision_parameters.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/decision_parameters.md
@@ -2,7 +2,7 @@
## Description
-Parameters which define an individual voting event.
+ Parameters which define an individual voting event.
@@ -96,9 +96,7 @@ The document version must always be >= the document ID.
| --- | --- |
| Required | yes |
| Format | [Document Reference](../metadata.md#document-reference) |
-| Valid References | [Brand Parameters](brand_parameters.md) |
-| | [Campaign Parameters](campaign_parameters.md) |
-| | [Category Parameters](category_parameters.md) |
+| Valid References | [Decision Parameters](decision_parameters.md) |
A reference to the Parameters Document this document lies under.
@@ -111,10 +109,32 @@ In addition to the validation performed for [Document Reference](../metadata.md#
## Payload
-This specification outlines the required definitions for the current features.
-The document will be incrementally improved in future iterations as more functionality
-and features are added.
-This section will be included and updated in future iterations.
+Payload for Decision Parameters document.
+
+### Schema
+
+
+??? abstract
+
+ Payload for Decision Parameters document.
+
+ ```json
+ {}
+ ```
+
+
+
+### Example
+
+??? example "Example: Final Proposal Submission"
+
+ This document indicates the linked proposal is final and requested to proceed for further consideration.
+
+ ```json
+ {}
+ ```
+
+
## Signers
@@ -132,7 +152,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-06-06 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
@@ -140,11 +160,15 @@ New versions of this document may be published by:
#### 0.01 (2025-04-04)
-* First Published Version
+ * First Published Version
#### 0.03 (2025-05-05)
-* Use generalized parameters.
+ * Use generalized parameters.
+
+#### 0.04 (2025-06-06)
+
+ * Added brand reference to decision parameters.
[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1
[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal.md
index c11ad6354e..70bffb1365 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal.md
@@ -226,7 +226,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment.md
index 212b50e7b4..984dd48cf3 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment.md
@@ -261,7 +261,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_meta_template.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_meta_template.md
index 305e9d497f..73280ae4f7 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_meta_template.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_meta_template.md
@@ -141,7 +141,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_template.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_template.md
index 91c7b241f9..ff64f26852 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_template.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_comment_template.md
@@ -154,7 +154,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_meta_template.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_meta_template.md
index 9ff14e8810..dd91bf8185 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_meta_template.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_meta_template.md
@@ -141,7 +141,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_moderation_action.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_moderation_action.md
index b8236d4597..8792ac4368 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_moderation_action.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_moderation_action.md
@@ -153,7 +153,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_submission_action.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_submission_action.md
index 68d7f89c2e..e15b76b4be 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_submission_action.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_submission_action.md
@@ -199,49 +199,106 @@ States:
`hide` is only actioned if sent by the author,
for a collaborator it identified that they do not wish to be listed as a `collaborator`.
-Schema :
-
-```json
-{
- "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/refs/heads/main/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json",
- "$schema": "http://json-schema.org/draft-07/schema#",
- "additionalProperties": false,
- "definitions": {
- "action": {
- "description": "The action being performed on the Proposal.",
- "enum": [
- "final",
- "draft",
- "hide"
+### Schema
+
+
+??? abstract
+
+ The kind of action is controlled by this payload.
+ The Payload is a [JSON][RFC8259] Document, and must conform to this schema.
+
+ States:
+
+ * `final` : All collaborators must publish a `final` status for the proposal to be `final`.
+ * `draft` : Reverses the previous `final` state for a signer and accepts collaborator status to a document.
+ * `hide` : Requests the proposal be hidden (not final, but a hidden draft).
+ `hide` is only actioned if sent by the author,
+ for a collaborator it identified that they do not wish to be listed as a `collaborator`.
+
+ ```json
+ {
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/refs/heads/main/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "additionalProperties": false,
+ "definitions": {
+ "action": {
+ "description": "The action being performed on the Proposal.",
+ "enum": [
+ "final",
+ "draft",
+ "hide"
+ ],
+ "type": "string"
+ }
+ },
+ "description": "Structure of the payload of a Proposal Submission Action.",
+ "maintainers": [
+ {
+ "name": "Catalyst Team",
+ "url": "https://projectcatalyst.io/"
+ }
],
- "type": "string"
+ "properties": {
+ "action": {
+ "$ref": "#/definitions/action"
+ }
+ },
+ "required": [
+ "action"
+ ],
+ "title": "Proposal Submission Action Payload Schema",
+ "type": "object",
+ "x-changelog": {
+ "2025-03-01": [
+ "First Version Created."
+ ]
+ }
+ }
+ ```
+
+
+
+### Examples
+
+??? example "Example: Final Proposal Submission"
+
+ This document indicates the linked proposal is final and requested to proceed for further consideration.
+
+ ```json
+ {
+ "action": "final"
}
- },
- "description": "Structure of the payload of a Proposal Submission Action.",
- "maintainers": [
+ ```
+
+
+
+??? example "Example: Draft Proposal Submission"
+
+ This document indicates the linked proposal is no longer final and should not proceed for further consideration.
+ It is also used by collaborators to accept that they are a collaborator on a document.
+
+ ```json
{
- "name": "Catalyst Team",
- "url": "https://projectcatalyst.io/"
+ "action": "draft"
}
- ],
- "properties": {
- "action": {
- "$ref": "#/definitions/action"
+ ```
+
+
+
+??? example "Example: Hidden Proposal Submission"
+
+ If submitted by the proposal author the document is hidden, it is still public but not shown as
+ a proposal being drafted.
+ If submitted by a collaborator, that collaborator is declaring they do not wish to be listed as
+ a collaborator on the proposal.
+
+ ```json
+ {
+ "action": "hide"
}
- },
- "required": [
- "action"
- ],
- "title": "Proposal Submission Action Payload Schema",
- "type": "object",
- "x-changelog": {
- "2025-03-01": [
- "First Version Created."
- ]
- }
-}
-```
-
+ ```
+
+
## Signers
@@ -260,7 +317,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_template.md b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_template.md
index b01b6eb41c..53ac87aff1 100644
--- a/docs/src/architecture/08_concepts/signed_doc/docs/proposal_template.md
+++ b/docs/src/architecture/08_concepts/signed_doc/docs/proposal_template.md
@@ -158,7 +158,7 @@ New versions of this document may be published by:
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/metadata.md b/docs/src/architecture/08_concepts/signed_doc/metadata.md
index 7b6fdc2e13..8daa80ac97 100644
--- a/docs/src/architecture/08_concepts/signed_doc/metadata.md
+++ b/docs/src/architecture/08_concepts/signed_doc/metadata.md
@@ -348,7 +348,7 @@ In addition to the validation performed for [Document Reference](metadata.md#doc
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/docs/src/architecture/08_concepts/signed_doc/spec.md b/docs/src/architecture/08_concepts/signed_doc/spec.md
index f2cc3a81bb..222eff96a0 100644
--- a/docs/src/architecture/08_concepts/signed_doc/spec.md
+++ b/docs/src/architecture/08_concepts/signed_doc/spec.md
@@ -25,6 +25,40 @@ Catalyst Signed Documents are based on [COSE][RFC9052].
Specifically, the [COSE Sign][RFC9052-CoseSign] format is used.
This allows one or more signatures to be attached to the same document.
+While every Catalyst Signed Document is a valid [COSE Sign][RFC9052-CoseSign] format document,
+not every [COSE Sign][RFC9052-CoseSign] format document is a valid Catalyst Signed Document.
+The following restrictions apply:
+
+### Unprotected Headers are not permitted
+
+It is a requirement that any document that contains exactly the same data, must produce the same
+catalyst signed document.
+This means that unprotected headers, which do not form part of the data protected by
+the signature are not permitted.
+Any document which contains any unprotected headers is not a valid Catalyst Signed Document,
+even though it may be a valid [COSE Sign][RFC9052-CoseSign] formatted document.
+
+### Only defined metadata and [COSE][RFC9052] Headers are allowed
+
+Each document type, defines a set of metadata and the [COSE][RFC9052] Headers which are allowed in that document type.
+Even if the Catalyst Signed document metadata exists in this specification, IF it is not defined as
+a valid metadata or [COSE][RFC9052] Header field for that particular document it may not be present.
+Unexpected but otherwise valid Metadata or [COSE][RFC9052] Header fields invalidate the Catalyst Signed Document.
+
+### No undefined metadata or unused [COSE][RFC9052] Headers may be present
+
+[COSE][RFC9052] Header Fields which are defined by the [COSE][RFC9052] Specification, but are NOT defined as part of a
+Catalyst Signed Document may not be present.
+Any such [COSE][RFC9052] Header Fields present in the document render it an invalid Catalyst Signed Document.
+
+Any metadata field that is not defined in this specification may not be present in any protected header.
+Unrecognized metadata fields in a document render it an invalid Catalyst Signed Document.
+
+### [CBOR Deterministic Encoding][CBOR-LFD-ENCODING] MUST be used
+
+The Catalyst Signed Document **MUST** be encoded using [CBOR Deterministic Encoding][CBOR-LFD-ENCODING].
+The "length-first core deterministic encoding requirements" variant of deterministic encoding *MUST* be used.
+
### Signed Document [CDDL][RFC8610] Definition
@@ -120,7 +154,7 @@ used to sign the protected portion of the document.
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
@@ -138,6 +172,15 @@ used to sign the protected portion of the document.
* Use generalized parameters.
+#### 0.04 (2025-05-30)
+
+* Improve and make document serialization more repeatable, and stricter.
+* TODO: Define Systems parameters
+* TODO: Define DReps documents.
+* TODO: Define Proposer Profiles.
+* TODO: Define Role 0 Profile.
+
+[CBOR-LFD-ENCODING]: https://www.rfc-editor.org/rfc/rfc8949.html#section-4.2.3
[application/schema+json]: https://datatracker.ietf.org/doc/draft-bhutton-json-schema/
[RFC9052-HeaderParameters]: https://www.rfc-editor.org/rfc/rfc8152#section-3.1
[application/cbor]: https://www.iana.org/assignments/media-types/application/cbor
diff --git a/docs/src/architecture/08_concepts/signed_doc/types.md b/docs/src/architecture/08_concepts/signed_doc/types.md
index c9b878b78e..35c823f1a5 100644
--- a/docs/src/architecture/08_concepts/signed_doc/types.md
+++ b/docs/src/architecture/08_concepts/signed_doc/types.md
@@ -55,7 +55,7 @@ All Defined Document Types
| --- | --- |
| License | This document is licensed under [CC-BY-4.0] |
| Created | 2024-12-27 |
-| Modified | 2025-05-05 |
+| Modified | 2025-05-30 |
| Authors | Alex Pozhylenkov |
| | Steven Johnson |
diff --git a/specs/gen_docs/gen/doc_generator.py b/specs/gen_docs/gen/doc_generator.py
index f392378355..aebfc401ba 100644
--- a/specs/gen_docs/gen/doc_generator.py
+++ b/specs/gen_docs/gen/doc_generator.py
@@ -170,7 +170,7 @@ def add_reference_links(self) -> None:
actual_link_names = self._spec.link_names()
- actual_links_used = {}
+ actual_links_used: dict[str, str] = {}
for link_name in actual_link_names:
esc_link_name = re.escape(link_name)
link_name_regex = f"(^|\\s)({esc_link_name})(\\.|\\s|$)"
@@ -190,7 +190,7 @@ def add_reference_links(self) -> None:
for link, actual in actual_links_used.items():
self._filedata += f"\n[{link}]: {actual}"
- def remove_tabs(self, tabstop: int = 4) -> str:
+ def remove_tabs(self, tabstop: int = 4) -> None:
"""Replace tabs in the input text with spaces so that the text aligns on tab stops.
Args:
@@ -343,7 +343,7 @@ def file_name(self) -> str:
"""Return the files name."""
return self._filename
- def file_path(self, relative_doc: typing.Self | None = None) -> Path:
+ def file_path(self, relative_doc: "DocGenerator | None" = None) -> Path:
"""Return a path to the file."""
if relative_doc is not None:
relative_path = relative_doc.file_path().parent
diff --git a/specs/gen_docs/gen/doc_relationship_diagrams.py b/specs/gen_docs/gen/doc_relationship_diagrams.py
index b7a0d68b2b..7f3c74fc3e 100644
--- a/specs/gen_docs/gen/doc_relationship_diagrams.py
+++ b/specs/gen_docs/gen/doc_relationship_diagrams.py
@@ -51,7 +51,7 @@ def generate(self) -> bool: # noqa: C901
file_title = textwrap.fill(f"{file_id} Document Relationships", width=30)
dot_file = DotFile(
- self._document_name, file_title, depth=self._depth, title_size=150 if self._document_name is None else 50
+ file_id, file_title, depth=self._depth, title_size=150 if self._document_name is None else 50
)
all_dst_refs: list[str] = []
@@ -66,7 +66,7 @@ def generate(self) -> bool: # noqa: C901
doc_data = self._spec.get_document(doc)
# Add content type explicitely to table.
- doc_table.add_row(TableRow(name="content type", value=doc_data.headers["content type"].value))
+ doc_table.add_row(TableRow(name="content type", value=doc_data.content_type))
# Add all used Metadata to table.
for meta in self._spec.all_headers(HeaderType.METADATA):
diff --git a/specs/gen_docs/gen/docs_page_md.py b/specs/gen_docs/gen/docs_page_md.py
index 970f2d4836..b07c17f440 100644
--- a/specs/gen_docs/gen/docs_page_md.py
+++ b/specs/gen_docs/gen/docs_page_md.py
@@ -1,11 +1,8 @@
"""Generate the individual pages docs/.md file."""
import argparse
-import json
import typing
-from pydantic import HttpUrl
-
from gen.doc_generator import DocGenerator
from gen.doc_relationship_diagrams import DocRelationshipFile
from spec.signed_doc import SignedDoc
@@ -62,24 +59,7 @@ def document_payload(self) -> str:
if self._doc.payload is None:
return self.TODO_MSG
- payload_docs = self._doc.payload.description + "\n"
-
- schema = self._doc.payload.doc_schema
- if schema is not None:
- if isinstance(schema, HttpUrl):
- if schema == "https://json-schema.org/draft-07/schema":
- payload_docs += "\n**Must be a valid JSON Schema Draft 7 document.**"
- else:
- payload_docs += f"\nMust be a valid according to <{schema}>."
- else:
- payload_docs += f"""\nSchema :
-
-```json
-{json.dumps(schema, indent=2, sort_keys=True)}
-```
-
-"""
- return payload_docs.strip()
+ return f"{self._doc.payload}"
def document_signers(self) -> str:
"""Generate documentation about who may sign this documents."""
diff --git a/specs/gen_docs/gen/graphviz_doc_diagram.py b/specs/gen_docs/gen/graphviz_doc_diagram.py
index 3c2ec65b70..2c1d78ce06 100644
--- a/specs/gen_docs/gen/graphviz_doc_diagram.py
+++ b/specs/gen_docs/gen/graphviz_doc_diagram.py
@@ -71,6 +71,11 @@ class TableRow(BaseModel):
model_config = ConfigDict(extra="forbid")
+ @classmethod
+ def default_list(cls) -> list["TableRow"]:
+ """Return a default list of this class."""
+ return []
+
def generate(self, bgcolor: str) -> str:
"""Generate a single row of the table."""
value = self.value
@@ -171,6 +176,7 @@ def from_doc_cluster(cls, cluster: DocCluster | None) -> "Cluster | None":
return None
return cls(name=cluster.name)
+ @property
def label(self) -> str:
"""Transform the name into a label."""
return "cluster_" + self.name.lower().replace(" ", "_").replace("-", "_")
@@ -178,7 +184,7 @@ def label(self) -> str:
def start(self) -> str:
"""Start a new cluster."""
return f"""
-subgraph {self.label()} {{
+subgraph {self.label} {{
label = "{self.name}";
color=blue
penwidth=20
@@ -188,7 +194,7 @@ def end(self) -> str:
"""End the cluster."""
return "}\n"
- def __eq__(self, other: "Cluster") -> bool:
+ def __eq__(self, other: object) -> bool:
"""Eq."""
if not isinstance(other, Cluster):
# don't attempt to compare against unrelated types
@@ -203,7 +209,7 @@ class DotSignedDoc(BaseModel):
title_port: str = Field(default="title")
title_href: str | None = Field(default=None)
theme: TableTheme = Field(default_factory=TableTheme)
- rows: list[TableRow] = Field(default_factory=list)
+ rows: list[TableRow] = Field(default_factory=TableRow.default_list)
cluster: Cluster | None = Field(default=None)
model_config = ConfigDict(extra="forbid")
@@ -296,6 +302,11 @@ def is_cluster(self) -> bool:
"""Is the link to a cluster."""
return isinstance(self.port, Cluster)
+ @property
+ def port_label(self) -> str | None:
+ """Get label of the port."""
+ return self.port.label if self.is_cluster else None # type: ignore # noqa: PGH003
+
def __str__(self) -> str:
"""Str."""
name = f'"{self.id}"'
@@ -305,7 +316,7 @@ def __str__(self) -> str:
name += f":{self.dir}"
return name
- def __eq__(self, other: "DotLinkEnd") -> bool:
+ def __eq__(self, other: object) -> bool:
"""Eq."""
if not isinstance(other, DotLinkEnd):
# don't attempt to compare against unrelated types
@@ -335,12 +346,10 @@ def model_post_init(self, context: typing.Any) -> None: # noqa: ANN401
super().model_post_init(context)
# Add cluster parameters to the theme.
- if self.src.is_cluster:
- self.theme.ltail = self.src.port.label()
- if self.dst.is_cluster:
- self.theme.lhead = self.dst.port.label()
+ self.theme.ltail = self.src.port_label
+ self.theme.lhead = self.dst.port_label
- def __eq__(self, other: "DotLink") -> bool:
+ def __eq__(self, other: object) -> bool:
"""Eq."""
if not isinstance(other, DotLink):
# don't attempt to compare against unrelated types
@@ -367,20 +376,20 @@ def __init__(self, file_id: str, title: str, depth: int = 0, title_size: int = 1
self.title = title
self.title_size = title_size
self.rankdir = "LR"
- self.graph = {
+ self.graph: dict[str, str | int] = {
"fontname": DEFAULT_FONT_NAME,
"fontsize": DEFAULT_FONT_SIZE,
"fontcolor": DEFAULT_FONT_COLOR,
"bgcolor": "white",
}
- self.node = {
+ self.node: dict[str, str | int] = {
"penwidth": 0,
"margin": 0,
"fontname": DEFAULT_FONT_NAME,
"fontsize": DEFAULT_FONT_SIZE,
"fontcolor": DEFAULT_FONT_COLOR,
}
- self.edge = {
+ self.edge: dict[str, str | int] = {
"fontname": DEFAULT_FONT_NAME,
"fontsize": DEFAULT_FONT_SIZE,
"fontcolor": "red",
@@ -401,7 +410,7 @@ def add_table(self, table: DotSignedDoc) -> None:
cluster_name = None
if table.cluster is not None:
cluster_name = table.cluster.name
- if cluster_name is not None and cluster_name not in self.clusters:
+ if cluster_name is not None and cluster_name not in self.clusters and table.cluster is not None:
self.clusters[cluster_name] = table.cluster
if cluster_name not in self.tables:
self.tables[cluster_name] = {}
@@ -438,9 +447,9 @@ def clustered_tables(self) -> str:
def __str__(self) -> str:
"""Generate the DOT file."""
- def defaults(name: str, settings: dict) -> str:
+ def defaults(name: str, settings: dict[str, str | int]) -> str:
"""Expand the defaults."""
- defaults = []
+ defaults: list[str] = []
for default, value in settings.items():
defaults.append(f'{default}="{value}"')
return f"{name} [{', '.join(defaults)}];"
diff --git a/specs/gen_docs/gen/spec_md.py b/specs/gen_docs/gen/spec_md.py
index bd8638c8db..f70b4345ac 100644
--- a/specs/gen_docs/gen/spec_md.py
+++ b/specs/gen_docs/gen/spec_md.py
@@ -23,7 +23,7 @@ def header_parameter_doc(self, header: str, header_type: HeaderType) -> str:
if not isinstance(label, str):
custom_header = ""
header_format = options["format"]
- header_value = options.get("value", None)
+ header_value: str | list[str] | None = options.get("value", None)
header_format_display = f"{header_format}"
if isinstance(header_value, list) and len(header_value) > 0:
header_format_display += "\n * Supported Values:"
@@ -93,6 +93,40 @@ def generate(self) -> bool:
Specifically, the COSE Sign format is used.
This allows one or more signatures to be attached to the same document.
+While every Catalyst Signed Document is a valid COSE Sign format document,
+not every COSE Sign format document is a valid Catalyst Signed Document.
+The following restrictions apply:
+
+### Unprotected Headers are not permitted
+
+It is a requirement that any document that contains exactly the same data, must produce the same
+catalyst signed document.
+This means that unprotected headers, which do not form part of the data protected by
+the signature are not permitted.
+Any document which contains any unprotected headers is not a valid Catalyst Signed Document,
+even though it may be a valid COSE Sign formatted document.
+
+### Only defined metadata and COSE Headers are allowed
+
+Each document type, defines a set of metadata and the COSE Headers which are allowed in that document type.
+Even if the Catalyst Signed document metadata exists in this specification, IF it is not defined as
+a valid metadata or COSE Header field for that particular document it may not be present.
+Unexpected but otherwise valid Metadata or COSE Header fields invalidate the Catalyst Signed Document.
+
+### No undefined metadata or unused COSE Headers may be present
+
+COSE Header Fields which are defined by the COSE Specification, but are NOT defined as part of a
+Catalyst Signed Document may not be present.
+Any such COSE Header Fields present in the document render it an invalid Catalyst Signed Document.
+
+Any metadata field that is not defined in this specification may not be present in any protected header.
+Unrecognized metadata fields in a document render it an invalid Catalyst Signed Document.
+
+### CBOR Deterministic Encoding MUST be used
+
+The Catalyst Signed Document **MUST** be encoded using CBOR Deterministic Encoding.
+The "length-first core deterministic encoding requirements" variant of deterministic encoding *MUST* be used.
+
### Signed Document CDDL Definition
{signed_doc_cddl.markdown_reference(relative_doc=self)}
diff --git a/specs/gen_docs/main.py b/specs/gen_docs/main.py
index 521f49338f..eb344ccbde 100755
--- a/specs/gen_docs/main.py
+++ b/specs/gen_docs/main.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env -S uv run
+#!/usr/bin/env python3
"""Autogenerate Documentation Pages from the specification."""
import argparse
@@ -77,6 +77,10 @@ def main(args: argparse.Namespace) -> None:
good &= MetadataMd(args, spec).save_or_validate()
good &= IndividualDocMd.save_or_validate_all(args, spec)
+ # Add generation for Brand, Campaign, Category, and Decision documents
+ for doc_name in ["Brand Parameters", "Campaign Parameters", "Category Parameters", "Decision Parameters"]:
+ good &= IndividualDocMd(args, spec, doc_name).save_or_validate()
+
if not good:
rich.print("File Comparisons Failed, Documentation is not current.")
sys.exit(1)
diff --git a/specs/gen_docs/pyproject.toml b/specs/gen_docs/pyproject.toml
index 6626530ffb..4046227b91 100644
--- a/specs/gen_docs/pyproject.toml
+++ b/specs/gen_docs/pyproject.toml
@@ -3,8 +3,9 @@ name = "gen-docs"
version = "0.1.0"
description = "Generate Signed Document documentation files."
readme = "README.md"
-requires-python = ">=3.13"
+requires-python = ">=3.10"
dependencies = [
+ "jsonschema[format]>=4.23.0",
"pydantic>=2.11.4",
"pydot>=3.0.4",
"rich>=14.0.0",
diff --git a/specs/gen_docs/spec/document.py b/specs/gen_docs/spec/document.py
index 1f9e8a9d39..c9c5414347 100644
--- a/specs/gen_docs/spec/document.py
+++ b/specs/gen_docs/spec/document.py
@@ -20,6 +20,11 @@ class DocumentBusinessLogic(BaseModel):
model_config = ConfigDict(extra="forbid")
+def empty_string_list() -> list[str]:
+ """Get an empty string list."""
+ return []
+
+
class Document(BaseModel):
"""Document Data Definition."""
@@ -38,8 +43,8 @@ class Document(BaseModel):
versions: list[ChangeLogEntry]
_name: str | None = PrivateAttr(default=None)
- _all_refs: list[str] = PrivateAttr(default_factory=list)
- _refed_by: list[str] = PrivateAttr(default_factory=list)
+ _all_refs: list[str] = PrivateAttr(default_factory=empty_string_list)
+ _refed_by: list[str] = PrivateAttr(default_factory=empty_string_list)
doc_name: str | None = Field(default=None) # Set when wwe get a document
@@ -74,11 +79,21 @@ def all_references(self) -> list[str]:
return self._all_refs
@property
- def name(self) -> list[str]:
+ def name(self) -> str:
"""Get name of this document."""
- return self._name
+ return self._name if self._name is not None else "Unknown"
@property
def all_docs_referencing(self) -> list[str]:
"""Get name of all documents which reference this document."""
return self._refed_by
+
+ @property
+ def content_type(self) -> str | list[str]:
+ """Get document content type."""
+ content_type = self.headers.get("content type")
+ if content_type is not None:
+ content_type = content_type.value
+ if content_type is None:
+ content_type = "Undefined"
+ return content_type
diff --git a/specs/gen_docs/spec/payload.py b/specs/gen_docs/spec/payload.py
index 732682508c..3caa4efdc0 100644
--- a/specs/gen_docs/spec/payload.py
+++ b/specs/gen_docs/spec/payload.py
@@ -1,14 +1,122 @@
"""Payload Specification."""
+import json
+import textwrap
+import urllib
+import urllib.request
from typing import Any
+import jsonschema
+import rich
from pydantic import BaseModel, ConfigDict, Field, HttpUrl
+class PayloadExample(BaseModel):
+ """An Example of the payload."""
+
+ title: str
+ description: str
+ example: dict[str, Any]
+
+ model_config = ConfigDict(extra="forbid")
+
+ @classmethod
+ def default(cls) -> list["PayloadExample"]:
+ """Return Default list."""
+ return []
+
+ def __str__(self) -> str:
+ """Get the example properly formatted as markdown."""
+ example = json.dumps(self.example, indent=2, sort_keys=True)
+ textwrap.indent(example, " ")
+
+ return f"""
+
+
+??? example "Example: {self.title}"
+
+{textwrap.indent(self.description, " ")}
+
+ ```json
+{textwrap.indent(example, " ")}
+ ```
+
+
+""".strip()
+
+
+class SchemaValidationError(Exception):
+ """Something is wrong with payload schema validation."""
+
+
class Payload(BaseModel):
"""Payload Deserialized Specification."""
description: str
doc_schema: HttpUrl | dict[str, Any] | None = Field(default=None, alias="schema")
+ examples: list[PayloadExample] = Field(default_factory=PayloadExample.default)
model_config = ConfigDict(extra="forbid")
+
+ def model_post_init(self, context: Any) -> None: # noqa: ANN401
+ """Validate the examples against the schema."""
+ schema = None
+ validator = None
+ if isinstance(self.doc_schema, HttpUrl):
+ if f"{self.doc_schema}" == "https://json-schema.org/draft-07/schema":
+ schema = jsonschema.Draft7Validator.META_SCHEMA
+ else:
+ rich.print(f"Downloading Schema from: {self.doc_schema}")
+ with urllib.request.urlopen(f"{self.doc_schema}") as response: # noqa: S310
+ schema = json.loads(response.read())
+ elif isinstance(self.doc_schema, dict):
+ schema = self.doc_schema
+
+ if schema is not None:
+ # Check that its valid jsonschema Draft 7.
+ jsonschema.Draft7Validator.check_schema(schema)
+ validator = jsonschema.Draft7Validator(schema, format_checker=jsonschema.draft7_format_checker)
+
+ for example in self.examples:
+ if validator is None:
+ msg = "No schema to validate payload examples."
+ raise SchemaValidationError(msg)
+ validator.validate(instance=example.example) # type: ignore # noqa: PGH003
+
+ return super().model_post_init(context)
+
+ def __str__(self) -> str:
+ """Get the examples properly formatted as markdown."""
+ docs = self.description + "\n"
+
+ schema = self.doc_schema
+ if schema is not None:
+ if isinstance(schema, HttpUrl):
+ if schema == "https://json-schema.org/draft-07/schema":
+ docs += "\n**Must be a valid JSON Schema Draft 7 document.**"
+ else:
+ docs += f"\nMust be a valid according to <{schema}>."
+ else:
+ docs += f"""\n### Schema
+
+
+??? abstract
+
+{textwrap.indent(self.description, " ")}
+
+ ```json
+{textwrap.indent(json.dumps(schema, indent=2, sort_keys=True), " ")}
+ ```
+
+
+"""
+
+ if len(self.examples) > 0:
+ docs += "\n### Example"
+ if len(self.examples) >= 2: # noqa: PLR2004
+ docs += "s"
+ docs += "\n"
+ for example in self.examples:
+ docs += f"{example}\n"
+
+ return docs.strip()
diff --git a/specs/gen_docs/spec/signed_doc.py b/specs/gen_docs/spec/signed_doc.py
index e9f832b361..ad1ae1d771 100644
--- a/specs/gen_docs/spec/signed_doc.py
+++ b/specs/gen_docs/spec/signed_doc.py
@@ -32,17 +32,17 @@ class HeaderType(Enum):
HEADERS: dict[str, dict[str, str]] = {
- HeaderType.DOCUMENT: {
+ HeaderType.DOCUMENT.name: {
"headers": "cose_headers",
"order": "cose_headers_order",
"format": "coseHeaderFormats",
},
- HeaderType.SIGNATURE: {
+ HeaderType.SIGNATURE.name: {
"headers": "cose_signature_headers",
"order": "cose_signature_headers_order",
"format": "coseHeaderFormats",
},
- HeaderType.METADATA: {
+ HeaderType.METADATA.name: {
"headers": "metadata",
"order": "metadata_order",
"format": "metadataFormats",
@@ -80,7 +80,7 @@ class SignedDoc(BaseModel):
def load(cls, spec_file: str) -> typing.Self:
"""Initialize the Signed Document Specification."""
with Path(spec_file).open("r") as f:
- data: dict = json.load(f)
+ data: dict[str, typing.Any] = json.load(f)
doc = cls(**data)
doc._data = data
doc._file = spec_file
@@ -121,19 +121,19 @@ def doc_in_cluster_name(self, doc_name: str) -> str | None:
return cluster.name
return None
- def data(self) -> dict:
+ def data(self) -> dict[str, typing.Any]:
"""Return the raw spec data."""
return self._data
def document_names(self) -> list[str]:
"""Get all documents."""
- return self.docs.keys()
+ return list(self.docs.keys())
def format_names(self, header_type: HeaderType) -> list[str]:
"""Get a list of all metadata format names defined."""
_, _, formats = self.headers_and_order(header_type=header_type)
- metadata_formats: dict = self._data[formats]
- return metadata_formats.keys()
+ metadata_formats: dict[str, typing.Any] = self._data[formats]
+ return list(metadata_formats.keys())
def link_name_aka(self, link_name: str) -> str | None:
"""Get a Link AKA for a link name, or None if it doesn't exist."""
@@ -151,9 +151,9 @@ def link_names(self) -> list[str]:
def link_for_link_name(self, link_name: str) -> str:
"""Get a link for a link name."""
- return self.documentation_links[link_name]
+ return f"{self.documentation_links[link_name]}"
- def header(self, header: str, header_type: HeaderType = HeaderType.DOCUMENT) -> dict:
+ def header(self, header: str, header_type: HeaderType = HeaderType.DOCUMENT) -> dict[str, typing.Any]:
"""Get Cose header definition."""
headers, _, _ = self.headers_and_order(header_type)
return headers[header]
@@ -166,14 +166,14 @@ def encoding_type_description(self, encoding_type: str) -> str:
"""Get a description for a known content type."""
return self.encoding_types[encoding_type].description
- def headers_and_order(self, header_type: HeaderType) -> tuple[dict, list[str], str]:
+ def headers_and_order(self, header_type: HeaderType) -> tuple[dict[str, typing.Any], list[str], str]:
"""Get headers and their ordering for a header_type."""
- headers = HEADERS[header_type]["headers"]
- header_order = HEADERS[header_type]["order"]
- formats = HEADERS[header_type]["format"]
+ headers_key = HEADERS[header_type.name]["headers"]
+ header_order_key = HEADERS[header_type.name]["order"]
+ formats = HEADERS[header_type.name]["format"]
- headers: dict = self._data[headers]
- header_order: list[str] = self._data.get(header_order, [])
+ headers: dict[str, typing.Any] = self._data[headers_key]
+ header_order: list[str] = self._data.get(header_order_key, [])
# Make sure unordered headers get included in the documentation.
for header in headers:
@@ -187,7 +187,7 @@ def all_headers(self, header_type: HeaderType = HeaderType.DOCUMENT) -> list[str
_, header_order, _ = self.headers_and_order(header_type)
return header_order
- def cddl_type_for_metadata(self, name: str | None, header_type: str) -> str:
+ def cddl_type_for_metadata(self, name: str, header_type: HeaderType) -> str:
"""Get the CDDL type for a given Metadata field."""
headers, _, formats = self.headers_and_order(header_type)
@@ -198,19 +198,23 @@ def cddl_type_for_metadata(self, name: str | None, header_type: str) -> str:
cddl_def = self._data[formats].get(cddl_def)
if cddl_def is not None:
cddl_def = cddl_def.get("cddl")
+ if cddl_def is None:
+ cddl_def = "Unknown"
return cddl_def
- def cddl_def(self, name: str) -> dict | None: # noqa: C901
+ def cddl_def(self, name: str) -> dict[str, typing.Any] | None: # noqa: C901
"""Get a cddl definition by name."""
- def synthetic_headers(defs: dict, header_type: HeaderType = HeaderType.METADATA) -> dict:
+ def synthetic_headers( # noqa: C901
+ defs: dict[str, typing.Any], header_type: HeaderType = HeaderType.METADATA
+ ) -> dict[str, str]:
"""Generate a synthetic cddl def for this type.
Needs to be generated from Metadata definitions.
"""
cddl_def = ""
defs["requires"] = []
- exclusives = []
+ exclusives: list[str] = []
headers, header_names, _ = self.headers_and_order(header_type)
@@ -222,19 +226,22 @@ def synthetic_headers(defs: dict, header_type: HeaderType = HeaderType.METADATA)
if exclusive is not None:
exclusive.append(header)
exclusive.sort()
- if exclusive not in exclusives:
- exclusives.append(exclusive)
+ for excl in exclusive:
+ if excl not in exclusives:
+ exclusives.append(excl)
else:
+ requires: list[str] = defs["requires"]
cddl_type = self.cddl_type_for_metadata(header, header_type)
field_name = header_data.get("coseLabel", header)
if isinstance(field_name, str):
field_name = f'"{field_name}"'
cddl_def += f"{optional}{field_name} => {cddl_type}\n"
- if cddl_type not in defs["requires"]:
- defs["requires"].append(cddl_type)
+ if cddl_type not in requires:
+ requires.append(cddl_type)
+ defs["requires"] = requires
for exclusive_set in exclusives:
# Exclusive sets are never required
- exclusive_fields = []
+ exclusive_fields: list[str] = []
for entry in exclusive_set:
cddl_type = self.cddl_type_for_metadata(entry, header_type)
field_name = headers[entry].get("coseLabel", entry)
diff --git a/specs/gen_docs/uv.lock b/specs/gen_docs/uv.lock
index 5a05c6644e..06aaec055a 100644
--- a/specs/gen_docs/uv.lock
+++ b/specs/gen_docs/uv.lock
@@ -6,9 +6,40 @@ requires-python = ">=3.13"
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload_time = "2024-05-20T21:33:25.928Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload_time = "2024-05-20T21:33:24.1Z" },
+ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
+]
+
+[[package]]
+name = "arrow"
+version = "1.3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-dateutil" },
+ { name = "types-python-dateutil" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" },
+]
+
+[[package]]
+name = "attrs"
+version = "25.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
+]
+
+[[package]]
+name = "fqdn"
+version = "1.5.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" },
]
[[package]]
@@ -16,6 +47,7 @@ name = "gen-docs"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
+ { name = "jsonschema", extra = ["format"] },
{ name = "pydantic" },
{ name = "pydot" },
{ name = "rich" },
@@ -24,12 +56,82 @@ dependencies = [
[package.metadata]
requires-dist = [
+ { name = "jsonschema", extras = ["format"], specifier = ">=4.23.0" },
{ name = "pydantic", specifier = ">=2.11.4" },
{ name = "pydot", specifier = ">=3.0.4" },
{ name = "rich", specifier = ">=14.0.0" },
{ name = "rich-argparse", specifier = ">=1.7.0" },
]
+[[package]]
+name = "idna"
+version = "3.10"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
+]
+
+[[package]]
+name = "isoduration"
+version = "20.11.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "arrow" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" },
+]
+
+[[package]]
+name = "jsonpointer"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" },
+]
+
+[[package]]
+name = "jsonschema"
+version = "4.23.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "jsonschema-specifications" },
+ { name = "referencing" },
+ { name = "rpds-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778, upload-time = "2024-07-08T18:40:05.546Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462, upload-time = "2024-07-08T18:40:00.165Z" },
+]
+
+[package.optional-dependencies]
+format = [
+ { name = "fqdn" },
+ { name = "idna" },
+ { name = "isoduration" },
+ { name = "jsonpointer" },
+ { name = "rfc3339-validator" },
+ { name = "rfc3987" },
+ { name = "uri-template" },
+ { name = "webcolors" },
+]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2025.4.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "referencing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" },
+]
+
[[package]]
name = "markdown-it-py"
version = "3.0.0"
@@ -37,18 +139,18 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mdurl" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload_time = "2023-06-03T06:41:14.443Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload_time = "2023-06-03T06:41:11.019Z" },
+ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
]
[[package]]
name = "mdurl"
version = "0.1.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload_time = "2022-08-14T12:40:10.846Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
]
[[package]]
@@ -61,9 +163,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload_time = "2025-04-29T20:38:55.02Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload_time = "2025-04-29T20:38:52.724Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" },
]
[[package]]
@@ -73,25 +175,25 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload_time = "2025-04-23T18:33:52.104Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload_time = "2025-04-23T18:31:53.175Z" },
- { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload_time = "2025-04-23T18:31:54.79Z" },
- { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload_time = "2025-04-23T18:31:57.393Z" },
- { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload_time = "2025-04-23T18:31:59.065Z" },
- { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload_time = "2025-04-23T18:32:00.78Z" },
- { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload_time = "2025-04-23T18:32:02.418Z" },
- { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload_time = "2025-04-23T18:32:04.152Z" },
- { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload_time = "2025-04-23T18:32:06.129Z" },
- { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload_time = "2025-04-23T18:32:08.178Z" },
- { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload_time = "2025-04-23T18:32:10.242Z" },
- { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload_time = "2025-04-23T18:32:12.382Z" },
- { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload_time = "2025-04-23T18:32:14.034Z" },
- { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload_time = "2025-04-23T18:32:15.783Z" },
- { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload_time = "2025-04-23T18:32:18.473Z" },
- { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload_time = "2025-04-23T18:32:20.188Z" },
- { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload_time = "2025-04-23T18:32:22.354Z" },
- { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload_time = "2025-04-23T18:32:25.088Z" },
+ { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" },
+ { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" },
+ { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" },
+ { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" },
+ { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" },
+ { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" },
]
[[package]]
@@ -101,27 +203,73 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyparsing" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167, upload_time = "2025-01-05T16:18:45.763Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167, upload-time = "2025-01-05T16:18:45.763Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776, upload_time = "2025-01-05T16:18:42.836Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776, upload-time = "2025-01-05T16:18:42.836Z" },
]
[[package]]
name = "pygments"
version = "2.19.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload_time = "2025-01-06T17:26:30.443Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload_time = "2025-01-06T17:26:25.553Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" },
]
[[package]]
name = "pyparsing"
version = "3.2.3"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload_time = "2025-03-25T05:01:28.114Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload_time = "2025-03-25T05:01:24.908Z" },
+ { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" },
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
+]
+
+[[package]]
+name = "referencing"
+version = "0.36.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "rpds-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
+]
+
+[[package]]
+name = "rfc3339-validator"
+version = "0.1.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" },
+]
+
+[[package]]
+name = "rfc3987"
+version = "1.3.8"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/14/bb/f1395c4b62f251a1cb503ff884500ebd248eed593f41b469f89caa3547bd/rfc3987-1.3.8.tar.gz", hash = "sha256:d3c4d257a560d544e9826b38bc81db676890c79ab9d7ac92b39c7a253d5ca733", size = 20700, upload-time = "2018-07-29T17:23:47.954Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/65/d4/f7407c3d15d5ac779c3dd34fbbc6ea2090f77bd7dd12f207ccf881551208/rfc3987-1.3.8-py2.py3-none-any.whl", hash = "sha256:10702b1e51e5658843460b189b185c0366d2cf4cff716f13111b0ea9fd2dce53", size = 13377, upload-time = "2018-07-29T17:23:45.313Z" },
]
[[package]]
@@ -132,9 +280,9 @@ dependencies = [
{ name = "markdown-it-py" },
{ name = "pygments" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload_time = "2025-03-30T14:15:14.23Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload_time = "2025-03-30T14:15:12.283Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" },
]
[[package]]
@@ -144,18 +292,70 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "rich" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/aa/b9/ff53663ee7fa6a4195fa96d91da499f2e00ca067541e016d345cce1c9ad2/rich_argparse-1.7.0.tar.gz", hash = "sha256:f31d809c465ee43f367d599ccaf88b73bc2c4d75d74ed43f2d538838c53544ba", size = 38009, upload_time = "2025-02-08T19:00:20.755Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/aa/b9/ff53663ee7fa6a4195fa96d91da499f2e00ca067541e016d345cce1c9ad2/rich_argparse-1.7.0.tar.gz", hash = "sha256:f31d809c465ee43f367d599ccaf88b73bc2c4d75d74ed43f2d538838c53544ba", size = 38009, upload-time = "2025-02-08T19:00:20.755Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/bb/9c/dc7cbeb99a7b7422392ed7f327efdbb958bc0faf424aef5f130309320bda/rich_argparse-1.7.0-py3-none-any.whl", hash = "sha256:b8ec8943588e9731967f4f97b735b03dc127c416f480a083060433a97baf2fd3", size = 25339, upload_time = "2025-02-08T19:00:17.911Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/9c/dc7cbeb99a7b7422392ed7f327efdbb958bc0faf424aef5f130309320bda/rich_argparse-1.7.0-py3-none-any.whl", hash = "sha256:b8ec8943588e9731967f4f97b735b03dc127c416f480a083060433a97baf2fd3", size = 25339, upload-time = "2025-02-08T19:00:17.911Z" },
+]
+
+[[package]]
+name = "rpds-py"
+version = "0.25.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/96/d2/7bed8453e53f6c9dea7ff4c19ee980fd87be607b2caf023d62c6579e6c30/rpds_py-0.25.0.tar.gz", hash = "sha256:4d97661bf5848dd9e5eb7ded480deccf9d32ce2cd500b88a26acbf7bd2864985", size = 26822, upload-time = "2025-05-15T13:42:03.815Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0d/d9/6534d5a9d00038261894551ee8043267f17c019e6c0df3c7d822fb5914f1/rpds_py-0.25.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4e5fe366fa53bd6777cf5440245366705338587b2cf8d61348ddaad744eb591a", size = 364375, upload-time = "2025-05-15T13:39:25.878Z" },
+ { url = "https://files.pythonhosted.org/packages/af/9d/f90c079635017cc50350cbbbf2c4fea7b2a75a24bea92211da1b0c52d55f/rpds_py-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:54f925ff8d4443b7cae23a5215954abbf4736a3404188bde53c4d744ac001d89", size = 350284, upload-time = "2025-05-15T13:39:27.336Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/04/b54c5b3abdccf03ca3ec3317bd68caaa7907a61fea063096ee08d128b6ed/rpds_py-0.25.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d58258a66255b2500ddaa4f33191ada5ec983a429c09eb151daf81efbb9aa115", size = 392107, upload-time = "2025-05-15T13:39:30.99Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/99/001bc3ab81c1798ee4c7bba7950134258d899e566d6839b6696b47248f71/rpds_py-0.25.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f3a57f08c558d0983a708bfe6d1265f47b5debff9b366b2f2091690fada055c", size = 398612, upload-time = "2025-05-15T13:39:32.505Z" },
+ { url = "https://files.pythonhosted.org/packages/00/e1/e22893e1043938811a50c857a5780e0a4e2da02dd10ac041ecca1044906a/rpds_py-0.25.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d60d42f1b9571341ad2322e748f7a60f9847546cd801a3a0eb72a1b54c6519", size = 452190, upload-time = "2025-05-15T13:39:34.024Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/6c/7071e6d27e784ac33ab4ca048eb550b5fc4f381b29e9ba33254bc6e7eaf6/rpds_py-0.25.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a54b94b0e4de95aa92618906fb631779d9fde29b4bf659f482c354a3a79fd025", size = 440634, upload-time = "2025-05-15T13:39:36.048Z" },
+ { url = "https://files.pythonhosted.org/packages/57/17/7343ea3ec906ee8c2b64a956d702de5067e0058b5d2869fbfb4b11625112/rpds_py-0.25.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af1c2241919304cc2f90e7dcb3eb1c1df6fb4172dd338e629dd6410e48b3d1a0", size = 391000, upload-time = "2025-05-15T13:39:37.802Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/ad/9b3c3e950108073448834f0548077e598588efa413ba8dcc91e7ad6ff59d/rpds_py-0.25.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7d34547810bfd61acf8a441e8a3651e7a919e8e8aed29850be14a1b05cfc6f41", size = 424621, upload-time = "2025-05-15T13:39:39.409Z" },
+ { url = "https://files.pythonhosted.org/packages/57/06/bd99ca30a6e539c18c6175501c1dd7f9ef0640f7b1dc0b14b094785b509a/rpds_py-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66568caacf18542f0cf213db7adf3de2da6ad58c7bf2c4fafec0d81ae557443b", size = 569529, upload-time = "2025-05-15T13:39:41.011Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/79/93381a25668466502adc082d3ce2a9ff35f8116e5e2711cedda0bfcfd699/rpds_py-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e49e4c3e899c32884d7828c91d6c3aff08d2f18857f50f86cc91187c31a4ca58", size = 594638, upload-time = "2025-05-15T13:39:43.15Z" },
+ { url = "https://files.pythonhosted.org/packages/91/ee/371ecc045d65af518e2210ad018892b1f7a7a21cd64661156b4d29dfd839/rpds_py-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:20af08b0b2d5b196a2bcb70becf0b97ec5af579cee0ae6750b08a2eea3b6c77d", size = 561413, upload-time = "2025-05-15T13:39:45.3Z" },
+ { url = "https://files.pythonhosted.org/packages/34/c4/85e9853312b7e5de3c98f100280fbfd903e63936f49f6f11e4cd4eb53299/rpds_py-0.25.0-cp313-cp313-win32.whl", hash = "sha256:d3dc8d6ce8f001c80919bdb49d8b0b815185933a0b8e9cdeaea42b0b6f27eeb0", size = 222326, upload-time = "2025-05-15T13:39:46.777Z" },
+ { url = "https://files.pythonhosted.org/packages/65/c6/ac744cc5752b6f291b2cf13e19cd7ea3cafe68922239a3b95f05f39287b7/rpds_py-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:113d134dc5a8d2503630ca2707b58a1bf5b1b3c69b35c7dab8690ee650c111b8", size = 234772, upload-time = "2025-05-15T13:39:48.804Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/aa/dabab50a2fb321a12ffe4668087e5d0f9b06286ccb260d345bf01c79b07c/rpds_py-0.25.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:6c72a4a8fab10bc96720ad40941bb471e3b1150fb8d62dab205d495511206cf1", size = 359693, upload-time = "2025-05-15T13:39:53.913Z" },
+ { url = "https://files.pythonhosted.org/packages/11/3d/acda0095fe54ee6c553d222fb3d275506f8db4198b6a72a69eef826d63c1/rpds_py-0.25.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bb979162323f3534dce84b59f86e689a0761a2a300e0212bfaedfa80d4eb8100", size = 345911, upload-time = "2025-05-15T13:39:55.623Z" },
+ { url = "https://files.pythonhosted.org/packages/db/f3/fba9b387077f9b305fce27fe22bdb731b75bfe208ae005fd09a127eced05/rpds_py-0.25.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35c8cb5dcf7d36d3adf2ae0730b60fb550a8feb6e432bee7ef84162a0d15714b", size = 387669, upload-time = "2025-05-15T13:39:57.103Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/a7/b8dbcdc9a8f1e96b5abc58bdfc22f2845178279694a9294fe4feb66ae330/rpds_py-0.25.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:673ba018df5ae5e7b6c9a021d51ffe39c0ae1daa0041611ed27a0bca634b2d2e", size = 392202, upload-time = "2025-05-15T13:39:59.456Z" },
+ { url = "https://files.pythonhosted.org/packages/60/60/2d46ad24207114cdb341490387d5a77c845827ac03f2a37182a19d072738/rpds_py-0.25.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16fb28d3a653f67c871a47c5ca0be17bce9fab8adb8bcf7bd09f3771b8c4d860", size = 450080, upload-time = "2025-05-15T13:40:01.131Z" },
+ { url = "https://files.pythonhosted.org/packages/85/ae/b1966ca161942f2edf0b2c4fb448b88c19bdb37e982d0907c4b484eb0bbc/rpds_py-0.25.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12a84c3851f9e68633d883c01347db3cb87e6160120a489f9c47162cd276b0a5", size = 438189, upload-time = "2025-05-15T13:40:02.816Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/b0/0a8bff40865e27fc8cd7bdf667958981794ccf5e7989890ae96c89112920/rpds_py-0.25.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b5f457afffb45d3804728a54083e31fbaf460e902e3f7d063e56d0d0814301e", size = 387925, upload-time = "2025-05-15T13:40:04.523Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/5d/62abbc77e18f9e67556ead54c84a7c662f39236b7a41cf1a39a24bf5e79f/rpds_py-0.25.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9442cbff21122e9a529b942811007d65eabe4182e7342d102caf119b229322c6", size = 417682, upload-time = "2025-05-15T13:40:06.879Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/eb/2f65e4332e3566d06c5ccad64441b1eaaf58a6c5999d533720f1f47d3118/rpds_py-0.25.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:383cf0d4288baf5a16812ed70d54ecb7f2064e255eb7fe42c38e926adeae4534", size = 565244, upload-time = "2025-05-15T13:40:08.598Z" },
+ { url = "https://files.pythonhosted.org/packages/02/3a/ae5f68ab4879d6fbe3abec3139eab1664c3372d8b42864ab940a4940a61c/rpds_py-0.25.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0dcdee07ebf76223092666c72a9552db276fbe46b98830ecd1bb836cc98adc81", size = 590459, upload-time = "2025-05-15T13:40:10.375Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/f6/ada6c3d9b803a9eb7bc9c8b3f3cebf7d779bbbb056cd7e3fc150e4c74c00/rpds_py-0.25.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5bbfbd9c74c4dd74815bd532bf29bedea6d27d38f35ef46f9754172a14e4c655", size = 558335, upload-time = "2025-05-15T13:40:13.695Z" },
+ { url = "https://files.pythonhosted.org/packages/68/9a/7d269e8f1bfe3143e699334ca0b578e16b37e6505bf10dca8c02aa8addc8/rpds_py-0.25.0-cp313-cp313t-win32.whl", hash = "sha256:90dbd2c42cb6463c07020695800ae8f347e7dbeff09da2975a988e467b624539", size = 218761, upload-time = "2025-05-15T13:40:16.043Z" },
+ { url = "https://files.pythonhosted.org/packages/16/16/f5843b19b7bfd16d63b960cf4c646953010886cc62dd41b00854d77b0eed/rpds_py-0.25.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8c2ad59c4342a176cb3e0d5753e1c911eabc95c210fc6d0e913c32bf560bf012", size = 232634, upload-time = "2025-05-15T13:40:17.633Z" },
+]
+
+[[package]]
+name = "six"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
+]
+
+[[package]]
+name = "types-python-dateutil"
+version = "2.9.0.20250516"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ef/88/d65ed807393285204ab6e2801e5d11fbbea811adcaa979a2ed3b67a5ef41/types_python_dateutil-2.9.0.20250516.tar.gz", hash = "sha256:13e80d6c9c47df23ad773d54b2826bd52dbbb41be87c3f339381c1700ad21ee5", size = 13943, upload-time = "2025-05-16T03:06:58.385Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c5/3f/b0e8db149896005adc938a1e7f371d6d7e9eca4053a29b108978ed15e0c2/types_python_dateutil-2.9.0.20250516-py3-none-any.whl", hash = "sha256:2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93", size = 14356, upload-time = "2025-05-16T03:06:57.249Z" },
]
[[package]]
name = "typing-extensions"
version = "4.13.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload_time = "2025-04-10T14:19:05.416Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload_time = "2025-04-10T14:19:03.967Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
]
[[package]]
@@ -165,7 +365,25 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload_time = "2025-02-25T17:27:59.638Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" },
+]
+
+[[package]]
+name = "uri-template"
+version = "1.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" },
+]
+
+[[package]]
+name = "webcolors"
+version = "24.11.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload_time = "2025-02-25T17:27:57.754Z" },
+ { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" },
]
diff --git a/specs/signed_doc.json b/specs/signed_doc.json
index 9706ba0d6b..786ce25514 100644
--- a/specs/signed_doc.json
+++ b/specs/signed_doc.json
@@ -253,6 +253,11 @@
"changes": "* Use generalized parameters.",
"modified": "2025-05-05",
"version": "0.03"
+ },
+ {
+ "changes": "* Improve and make document serialization more repeatable, and stricter.\n* TODO: Define Systems parameters\n* TODO: Define DReps documents.\n* TODO: Define Proposer Profiles.\n* TODO: Define Role 0 Profile.",
+ "modified": "2025-05-30",
+ "version": "0.04"
}
]
},
@@ -317,7 +322,6 @@
"docs": {
"Brand Parameters": {
"authors": {},
- "description": "Parameters which define this brand within the system.",
"headers": {
"content type": {
"coseLabel": 3,
@@ -424,15 +428,19 @@
],
"versions": [
{
- "changes": "* First Published Version",
+ "changes": "Initial version. Structure aligned with global metadata requirements.",
+ "modified": "2024-06-07",
+ "version": "v1"
+ },
+ {
+ "changes": "Updated to include common definitions and examples.",
"modified": "2025-04-04",
- "version": "0.01"
+ "version": "v2"
}
]
},
"Campaign Parameters": {
"authors": {},
- "description": "Parameters which define a Campaign within a Brand in the system.",
"headers": {
"content type": {
"coseLabel": 3,
@@ -470,10 +478,7 @@
"description": "A reference to the Parameters Document this document lies under.",
"exclusive": null,
"format": "Document Reference",
- "linked_refs": null,
- "multiple": false,
- "required": "yes",
- "type": "Brand Parameters",
+ "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."
},
"ref": {
@@ -542,20 +547,14 @@
],
"versions": [
{
- "changes": "* First Published Version",
- "modified": "2025-04-04",
- "version": "0.01"
- },
- {
- "changes": "* Use generalized parameters.",
- "modified": "2025-05-05",
- "version": "0.03"
+ "changes": "Initial version. Structure aligned with global metadata requirements.",
+ "modified": "2024-06-07",
+ "version": "v1"
}
]
},
"Category Parameters": {
"authors": {},
- "description": "Parameters which define a Category withing a Campaign under a Brand in the system.",
"headers": {
"content type": {
"coseLabel": 3,
@@ -593,10 +592,7 @@
"description": "A reference to the Parameters Document this document lies under.",
"exclusive": null,
"format": "Document Reference",
- "linked_refs": null,
- "multiple": false,
- "required": "yes",
- "type": "Campaign Parameters",
+ "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."
},
"ref": {
@@ -665,14 +661,9 @@
],
"versions": [
{
- "changes": "* First Published Version",
- "modified": "2025-04-04",
- "version": "0.01"
- },
- {
- "changes": "* Use generalized parameters.",
- "modified": "2025-05-05",
- "version": "0.03"
+ "changes": "Initial version. Structure aligned with global metadata requirements.",
+ "modified": "2024-06-07",
+ "version": "v1"
}
]
},
@@ -800,7 +791,7 @@
},
"Decision Parameters": {
"authors": {},
- "description": "Parameters which define an individual voting event.",
+ "description": "\tParameters which define an individual voting event.",
"headers": {
"content type": {
"coseLabel": 3,
@@ -841,11 +832,7 @@
"linked_refs": null,
"multiple": false,
"required": "yes",
- "type": [
- "Brand Parameters",
- "Campaign Parameters",
- "Category Parameters"
- ],
+ "type": "Decision 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."
},
"ref": {
@@ -899,6 +886,17 @@
}
},
"notes": [],
+ "payload": {
+ "description": "Payload for Decision Parameters document.",
+ "examples": [
+ {
+ "description": "This document indicates the linked proposal is final and requested to proceed for further consideration.",
+ "example": {},
+ "title": "Final Proposal Submission"
+ }
+ ],
+ "schema": {}
+ },
"signers": {
"roles": {
"user": [
@@ -914,14 +912,19 @@
],
"versions": [
{
- "changes": "* First Published Version",
+ "changes": "\t* First Published Version",
"modified": "2025-04-04",
"version": "0.01"
},
{
- "changes": "* Use generalized parameters.",
+ "changes": "\t* Use generalized parameters.",
"modified": "2025-05-05",
"version": "0.03"
+ },
+ {
+ "changes": "\t* Added brand reference to decision parameters.",
+ "modified": "2025-06-06",
+ "version": "0.04"
}
]
},
@@ -1856,6 +1859,29 @@
"notes": [],
"payload": {
"description": "The kind of action is controlled by this payload.\nThe Payload is a JSON Document, and must conform to this schema.\n\nStates:\n\n* `final` : All collaborators must publish a `final` status for the proposal to be `final`.\n* `draft` : Reverses the previous `final` state for a signer and accepts collaborator status to a document. \n* `hide` : Requests the proposal be hidden (not final, but a hidden draft). \n\t\t\t`hide` is only actioned if sent by the author, \n\t\t\tfor a collaborator it identified that they do not wish to be listed as a `collaborator`.",
+ "examples": [
+ {
+ "description": "This document indicates the linked proposal is final and requested to proceed for further consideration.",
+ "example": {
+ "action": "final"
+ },
+ "title": "Final Proposal Submission"
+ },
+ {
+ "description": "This document indicates the linked proposal is no longer final and should not proceed for further consideration.\nIt is also used by collaborators to accept that they are a collaborator on a document.",
+ "example": {
+ "action": "draft"
+ },
+ "title": "Draft Proposal Submission"
+ },
+ {
+ "description": "If submitted by the proposal author the document is hidden, it is still public but not shown as\na proposal being drafted.\nIf submitted by a collaborator, that collaborator is declaring they do not wish to be listed as\na collaborator on the proposal.",
+ "example": {
+ "action": "hide"
+ },
+ "title": "Hidden Proposal Submission"
+ }
+ ],
"schema": {
"$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/refs/heads/main/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
@@ -2066,6 +2092,7 @@
}
},
"documentationLinks": {
+ "CBOR-LFD-ENCODING": "https://www.rfc-editor.org/rfc/rfc8949.html#section-4.2.3",
"CBOR-TAG-37": "https://github.com/lucas-clemente/cbor-specs/blob/master/uuid.md",
"CBOR-TAG-42": "https://github.com/ipld/cid-cbor/",
"CC-BY-4.0": "https://creativecommons.org/licenses/by/4.0/legalcode",
@@ -2097,6 +2124,7 @@
"linkAKA": {
"BROTLI": "RFC7932",
"CBOR": "RFC8949",
+ "CBOR Deterministic Encoding": "CBOR-LFD-ENCODING",
"CBOR Encoded IPLD Content Identifier": "CBOR-TAG-42",
"CDDL": "RFC8610",
"COSE": "RFC9052",
diff --git a/specs/signed_docs/authors_copyright.cue b/specs/signed_docs/authors_copyright.cue
index c354a5b10e..2d9a8314d8 100644
--- a/specs/signed_docs/authors_copyright.cue
+++ b/specs/signed_docs/authors_copyright.cue
@@ -60,5 +60,16 @@ copyright: #copyrightNotice & {
* Use generalized parameters.
"""
},
+ {
+ version: "0.04"
+ modified: "2025-05-30"
+ changes: """
+ * Improve and make document serialization more repeatable, and stricter.
+ * TODO: Define Systems parameters
+ * TODO: Define DReps documents.
+ * TODO: Define Proposer Profiles.
+ * TODO: Define Role 0 Profile.
+ """
+ },
]
}
diff --git a/specs/signed_docs/docs/brand_parameters.cue b/specs/signed_docs/docs/brand_parameters.cue
index 75deb70f29..eff82abe57 100644
--- a/specs/signed_docs/docs/brand_parameters.cue
+++ b/specs/signed_docs/docs/brand_parameters.cue
@@ -1,21 +1,28 @@
package signed_docs
-// Proposal Document Definition
+_common_defs: {} @embed(file="./payload_schemas/common_definitions.schema.json")
+
+// Brand Parameters Document Definition
docs: #DocumentDefinitions & {
"Brand Parameters": {
-
- description: """
- Parameters which define this brand within the system.
- """
-
+ metadata: {
+ ref: metadata.ref // Reference to the next highest document
+ template: metadata.template // Reference to a brand/campaign/etc template document
+ }
versions: [
{
- version: "0.01"
+ version: "v1"
+ modified: "2024-06-07"
+ changes: "Initial version. Structure aligned with global metadata requirements."
+ },
+ {
+ version: "v2"
modified: "2025-04-04"
- changes: """
- * First Published Version
- """
+ changes: "Updated to include common definitions and examples."
},
- ]}
+ ]
+ // Payload is fully templated and not defined here
+ }
+
}
diff --git a/specs/signed_docs/docs/campaign_parameters.cue b/specs/signed_docs/docs/campaign_parameters.cue
index 9cafb80ba5..6376c36af7 100644
--- a/specs/signed_docs/docs/campaign_parameters.cue
+++ b/specs/signed_docs/docs/campaign_parameters.cue
@@ -1,34 +1,22 @@
package signed_docs
-// Proposal Document Definition
+// Import common definitions JSON schema for use in embedded schemas
+_common_defs: {} @embed(file="./payload_schemas/common_definitions.schema.json")
+// Campaign Parameters Document Definition
docs: #DocumentDefinitions & {
"Campaign Parameters": {
- description: """
- Parameters which define a Campaign within a Brand in the system.
- """
-
metadata: {
- parameters: {
- required: "yes"
- type: "Brand Parameters"
- }
+ ref: metadata.ref
+ template: metadata.template
}
-
versions: [
{
- version: "0.01"
- modified: "2025-04-04"
- changes: """
- * First Published Version
- """
- },
- {
- version: "0.03"
- modified: "2025-05-05"
- changes: """
- * Use generalized parameters.
- """
+ version: "v1"
+ modified: "2024-06-07"
+ changes: "Initial version. Structure aligned with global metadata requirements."
},
- ]}
+ ]
+ // Payload is fully templated and not defined here
+ }
}
diff --git a/specs/signed_docs/docs/category_parameters.cue b/specs/signed_docs/docs/category_parameters.cue
index 7d8904f7db..8fe82f891e 100644
--- a/specs/signed_docs/docs/category_parameters.cue
+++ b/specs/signed_docs/docs/category_parameters.cue
@@ -1,35 +1,22 @@
package signed_docs
-// Proposal Document Definition
+// Import common definitions JSON schema for use in embedded schemas
+_common_defs: {} @embed(file="./payload_schemas/common_definitions.schema.json")
+// Category Parameters Document Definition
docs: #DocumentDefinitions & {
"Category Parameters": {
-
- description: """
- Parameters which define a Category withing a Campaign under a Brand in the system.
- """
-
metadata: {
- parameters: {
- required: "yes"
- type: "Campaign Parameters"
- }
+ ref: metadata.ref
+ template: metadata.template
}
-
versions: [
{
- version: "0.01"
- modified: "2025-04-04"
- changes: """
- * First Published Version
- """
- },
- {
- version: "0.03"
- modified: "2025-05-05"
- changes: """
- * Use generalized parameters.
- """
+ version: "v1"
+ modified: "2024-06-07"
+ changes: "Initial version. Structure aligned with global metadata requirements."
},
- ]}
+ ]
+ // Payload is fully templated and not defined here
+ }
}
diff --git a/specs/signed_docs/docs/decision_parameters.cue b/specs/signed_docs/docs/decision_parameters.cue
index 133d908d5e..53e333f500 100644
--- a/specs/signed_docs/docs/decision_parameters.cue
+++ b/specs/signed_docs/docs/decision_parameters.cue
@@ -1,34 +1,54 @@
package signed_docs
-// Proposal Document Definition
+// Import common definitions JSON schema for use in embedded schemas
+_common_defs: {} @embed(file="./payload_schemas/common_definitions.schema.json")
+// Decision Parameters Document Definition
docs: #DocumentDefinitions & {
"Decision Parameters": {
description: """
- Parameters which define an individual voting event.
+ Parameters which define an individual voting event.
"""
-
metadata: {
parameters: {
required: "yes"
- type: doc_clusters."System Parameters".docs
+ type: "Decision Parameters"
}
}
-
+ payload: {
+ description: "Payload for Decision Parameters document."
+ schema: {} @embed(file="./payload_schemas/decision_parameters.schema.json")
+ examples: [
+ {
+ title: "Final Proposal Submission"
+ description: """
+ This document indicates the linked proposal is final and requested to proceed for further consideration.
+ """
+ example: {} @embed(file="./payload_schemas/decision_parameter.example.json")
+ },
+ ]}
versions: [
{
version: "0.01"
modified: "2025-04-04"
changes: """
- * First Published Version
+ * First Published Version
"""
},
{
version: "0.03"
modified: "2025-05-05"
changes: """
- * Use generalized parameters.
+ * Use generalized parameters.
+ """
+ },
+ {
+ version: "0.04"
+ modified: "2025-06-06"
+ changes: """
+ * Added brand reference to decision parameters.
"""
},
- ]}
+ ]
+ }
}
diff --git a/specs/signed_docs/docs/payload_schemas/brand_parameter.example.json b/specs/signed_docs/docs/payload_schemas/brand_parameter.example.json
new file mode 100644
index 0000000000..a161fefafc
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/brand_parameter.example.json
@@ -0,0 +1,11 @@
+{
+ "directVotingPrivacyState": true,
+ "brandName": "Catalyst Foundation",
+ "minimumBudgetRequestPerProposal": 15000,
+ "maximumBudgetRequestPerProposal": "200000 (variable per challenge)",
+ "maximumProposalsPerProposer": 6,
+ "communityReviewerRegistration": "Open to all ADA holders",
+ "votingPowerThreshold": 1000000,
+ "tallyingOptimization": "majority",
+ "proposalAcceptanceThreshold": 60
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/brand_parameters.schema.json b/specs/signed_docs/docs/payload_schemas/brand_parameters.schema.json
new file mode 100644
index 0000000000..186efb70a9
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/brand_parameters.schema.json
@@ -0,0 +1,85 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/main/specs/signed_docs/docs/payload_schemas/brand_parameters.schema.json",
+ "title": "Brand Parameters",
+ "description": "Schema for defining Catalyst brand-level parameters, with UI/UX metadata and logical grouping.",
+ "type": "object",
+ "properties": {
+ "directVotingPrivacyState": {
+ "$ref": "#/definitions/booleanParameter",
+ "title": "Direct Voting Privacy State",
+ "description": "Whether direct voting privacy is enabled.",
+ "x-guidance": "Set to true if direct voting privacy is required."
+ },
+ "brandName": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Brand Name",
+ "description": "The name of the brand.",
+ "x-guidance": "Enter the official brand name."
+ },
+ "minimumBudgetRequestPerProposal": {
+ "$ref": "#/definitions/adaAmount",
+ "title": "Minimum Budget Request Per Proposal",
+ "description": "The minimum ADA amount that can be requested per proposal.",
+ "x-guidance": "Specify the minimum allowed budget per proposal in ADA."
+ },
+ "maximumBudgetRequestPerProposal": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Maximum Budget Request Per Proposal",
+ "description": "The maximum ADA amount (variable per challenge/category) that can be requested per proposal.",
+ "x-guidance": "Specify the maximum allowed budget per proposal."
+ },
+ "maximumProposalsPerProposer": {
+ "$ref": "#/definitions/integerParameter",
+ "title": "Maximum Proposals per Proposer/co-proposer",
+ "description": "The maximum number of proposals a proposer or co-proposer can submit.",
+ "x-guidance": "Set the limit for proposals per proposer/co-proposer."
+ },
+ "communityReviewerRegistration": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Community Reviewer Registration",
+ "description": "Information or rules about community reviewer registration.",
+ "x-guidance": "Describe the process or requirements for community reviewer registration."
+ },
+ "votingPowerThreshold": {
+ "$ref": "#/definitions/lovelaceAmount",
+ "title": "Voting Power Threshold",
+ "description": "The minimum Lovelace required to participate in voting.",
+ "x-guidance": "Specify the minimum voting power threshold in Lovelace."
+ },
+ "tallyingOptimization": {
+ "$ref": "#/definitions/ratioFormula",
+ "title": "Tallying Optimization",
+ "description": "The ratio or formula used for tallying optimization.",
+ "x-guidance": "Provide the formula or ratio for tallying optimization."
+ },
+ "proposalAcceptanceThreshold": {
+ "$ref": "#/definitions/percentageParameter",
+ "title": "Proposal Acceptance Threshold",
+ "description": "The percentage threshold for proposal acceptance.",
+ "x-guidance": "Set the acceptance threshold as a percentage."
+ }
+ },
+ "required": [
+ "directVotingPrivacyState",
+ "brandName",
+ "minimumBudgetRequestPerProposal",
+ "maximumBudgetRequestPerProposal",
+ "maximumProposalsPerProposer",
+ "communityReviewerRegistration",
+ "votingPowerThreshold",
+ "tallyingOptimization",
+ "proposalAcceptanceThreshold"
+ ],
+ "x-order": [
+ "directVotingPrivacyState",
+ "brandName",
+ "minimumBudgetRequestPerProposal",
+ "maximumBudgetRequestPerProposal",
+ "maximumProposalsPerProposer",
+ "communityReviewerRegistration",
+ "votingPowerThreshold",
+ "tallyingOptimization",
+ "proposalAcceptanceThreshold"
+ ]
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/campaign_parameter.example.json b/specs/signed_docs/docs/payload_schemas/campaign_parameter.example.json
new file mode 100644
index 0000000000..4407a3c620
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/campaign_parameter.example.json
@@ -0,0 +1,27 @@
+{
+ "fundName": "Fund 14",
+ "fundSize": 5000000,
+ "campaignTitle": "Cardano Open Innovation",
+ "campaignBudget": 1000000,
+ "proposalSubmissionFee": 100,
+ "compensationsDistributionDate": "2025-07-01",
+ "proposalsRegistrationOnChain": "2025-06-15",
+ "drepDeadlineDate": "2025-06-10",
+ "registrationDeadlineDate": "2025-06-20T23:59:59Z",
+ "votingPeriodStart": "2025-07-05T00:00:00Z",
+ "votingPeriodEnd": "2025-07-12T23:59:59Z",
+ "startOfTallying": "2025-07-13",
+ "endOfTallying": "2025-07-15",
+ "proposalFundingLogic": "top N by votes",
+ "voterCompensations": 2.5,
+ "communityReviewCompensations": 1.5,
+ "communityModeratorCompensations": 1.0,
+ "onboardingCompensations": 0.5,
+ "projectAccountabilityManagementComp": 0.25,
+ "currentInsightSharingStart": "2025-05-01",
+ "currentProposalSubmissionStart": "2025-05-10",
+ "currentRefineProposalsStart": "2025-05-20",
+ "currentFinalizeProposalsStart": "2025-05-30",
+ "currentProposalAssessment": "2025-06-01",
+ "currentAssessmentQaStart": "2025-06-05"
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/campaign_parameters.schema.json b/specs/signed_docs/docs/payload_schemas/campaign_parameters.schema.json
new file mode 100644
index 0000000000..e800be43d0
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/campaign_parameters.schema.json
@@ -0,0 +1,208 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/main/specs/signed_docs/docs/payload_schemas/campaign_parameters.schema.json",
+ "title": "Campaign Parameters",
+ "description": "Schema for defining Catalyst campaign-level parameters, with UI/UX metadata and logical grouping.",
+ "type": "object",
+ "properties": {
+ "fundName": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Fund/Campaign Name"
+ },
+ "fundSize": {
+ "$ref": "#/definitions/adaAmount",
+ "title": "Fund/Campaign Size"
+ },
+ "campaignTitle": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Campaign (Challenge) Title"
+ },
+ "campaignBudget": {
+ "$ref": "#/definitions/adaAmount",
+ "title": "Campaign (Challenge) Budget"
+ },
+ "proposalSubmissionFee": {
+ "$ref": "#/definitions/currencyAmount",
+ "title": "Proposal Submission Fee"
+ },
+ "compensationsDistributionDate": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "Compensations and funds distribution target date"
+ },
+ "proposalsRegistrationOnChain": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "Proposals registration on the blockchain"
+ },
+ "drepDeadlineDate": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "Drep deadline date"
+ },
+ "registrationDeadlineDate": {
+ "$ref": "#/definitions/datetimeParameter",
+ "title": "Registration deadline date"
+ },
+ "votingPeriodStart": {
+ "$ref": "#/definitions/datetimeParameter",
+ "title": "Voting period start time"
+ },
+ "votingPeriodEnd": {
+ "$ref": "#/definitions/datetimeParameter",
+ "title": "Voting period end time"
+ },
+ "startOfTallying": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "Start of tallying"
+ },
+ "endOfTallying": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "End of tallying"
+ },
+ "proposalFundingLogic": {
+ "$ref": "#/definitions/stringRule",
+ "title": "Proposal Funding logic (winner selection)"
+ },
+ "voterCompensations": {
+ "$ref": "#/definitions/percentageOrAda",
+ "title": "Voter Compensations (Vrtotal)"
+ },
+ "communityReviewCompensations": {
+ "$ref": "#/definitions/percentageOrAda",
+ "title": "Community Review Compensations"
+ },
+ "communityModeratorCompensations": {
+ "$ref": "#/definitions/percentageOrAda",
+ "title": "Community Moderator Compensations (AArtotal)"
+ },
+ "onboardingCompensations": {
+ "$ref": "#/definitions/percentageOrAda",
+ "title": "Onboarding compensations (Cttotal)"
+ },
+ "projectAccountabilityManagementComp": {
+ "$ref": "#/definitions/percentageOrAda",
+ "title": "Project Accountability Management Comp."
+ },
+ "currentInsightSharingStart": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_insight_sharing_start"
+ },
+ "currentProposalSubmissionStart": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_proposal_submission_start"
+ },
+ "currentRefineProposalsStart": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_refine_proposals_start"
+ },
+ "currentFinalizeProposalsStart": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_finalize_proposals_start"
+ },
+ "currentProposalAssessment": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_proposal_assessment"
+ },
+ "currentAssessmentQaStart": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "current_assessment_qa_start"
+ }
+ },
+ "required": ["fundName", "fundSize", "campaignTitle", "campaignBudget"],
+ "x-order": [
+ "fundName",
+ "fundSize",
+ "campaignTitle",
+ "campaignBudget",
+ "proposalSubmissionFee",
+ "compensationsDistributionDate",
+ "proposalsRegistrationOnChain",
+ "drepDeadlineDate",
+ "registrationDeadlineDate",
+ "votingPeriodStart",
+ "votingPeriodEnd",
+ "startOfTallying",
+ "endOfTallying",
+ "proposalFundingLogic",
+ "voterCompensations",
+ "communityReviewCompensations",
+ "communityModeratorCompensations",
+ "onboardingCompensations",
+ "projectAccountabilityManagementComp",
+ "currentInsightSharingStart",
+ "currentProposalSubmissionStart",
+ "currentRefineProposalsStart",
+ "currentFinalizeProposalsStart",
+ "currentProposalAssessment",
+ "currentAssessmentQaStart"
+ ],
+ "definitions": {
+ "booleanParameter": {
+ "type": "boolean",
+ "title": "Boolean Parameter",
+ "x-note": "A true/false value."
+ },
+ "stringParameter": {
+ "type": "string",
+ "title": "String Parameter",
+ "x-note": "A plain text value."
+ },
+ "adaAmount": {
+ "type": "integer",
+ "title": "ADA Amount",
+ "x-note": "Amount in ADA."
+ },
+ "lovelaceAmount": {
+ "type": "integer",
+ "title": "Lovelace Amount",
+ "x-note": "Amount in Lovelace."
+ },
+ "integerParameter": {
+ "type": "integer",
+ "title": "Integer Parameter",
+ "x-note": "An integer value."
+ },
+ "dateParameter": {
+ "type": "string",
+ "format": "date",
+ "title": "Date Parameter",
+ "x-note": "A date value (YYYY-MM-DD)."
+ },
+ "datetimeParameter": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Datetime Parameter",
+ "x-note": "A datetime value (ISO 8601)."
+ },
+ "ratioFormula": {
+ "type": "string",
+ "title": "Ratio / Formula",
+ "x-note": "A ratio or formula expression."
+ },
+ "percentageParameter": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "title": "Percentage Parameter",
+ "x-note": "A percentage value (0-100)."
+ },
+ "currencyAmount": {
+ "type": ["string", "number"],
+ "title": "Currency Amount or String"
+ },
+ "stringRule": {
+ "type": "string",
+ "title": "String / Rule"
+ },
+ "percentageOrAda": {
+ "oneOf": [
+ { "$ref": "#/definitions/percentageParameter" },
+ { "$ref": "#/definitions/adaAmount" }
+ ],
+ "title": "Percentage or ADA Amount"
+ },
+ "listParameter": {
+ "type": "array",
+ "items": { "type": "string" },
+ "title": "List Parameter"
+ }
+ }
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/category_parameter.example.json b/specs/signed_docs/docs/payload_schemas/category_parameter.example.json
new file mode 100644
index 0000000000..4aecdefd1d
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/category_parameter.example.json
@@ -0,0 +1,8 @@
+{
+ "campaignTitle": "Cardano Open Innovation",
+ "minimumBudgetRequestPerProposal": 15000,
+ "maximumBudgetRequestPerProposal": "200000 (variable per challenge)",
+ "proposalFundingLogic": "top N by votes",
+ "proposalAcceptanceThreshold": 60,
+ "votingOptions": ["Yes", "No", "Abstain"]
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/category_parameters.schema.json b/specs/signed_docs/docs/payload_schemas/category_parameters.schema.json
new file mode 100644
index 0000000000..a193c96a64
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/category_parameters.schema.json
@@ -0,0 +1,117 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/main/specs/signed_docs/docs/payload_schemas/category_parameters.schema.json",
+ "title": "Category Parameters",
+ "description": "Schema for defining Catalyst category-level parameters, with UI/UX metadata and logical grouping.",
+ "type": "object",
+ "properties": {
+ "campaignTitle": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Campaign (Challenge) Title"
+ },
+ "minimumBudgetRequestPerProposal": {
+ "$ref": "#/definitions/adaAmount",
+ "title": "Minimum Budget Request Per Proposal"
+ },
+ "maximumBudgetRequestPerProposal": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Maximum Budget Request Per Proposal"
+ },
+ "proposalFundingLogic": {
+ "$ref": "#/definitions/stringRule",
+ "title": "Proposal Funding logic (winner selection)"
+ },
+ "proposalAcceptanceThreshold": {
+ "$ref": "#/definitions/percentageParameter",
+ "title": "Proposal acceptance threshold"
+ },
+ "votingOptions": {
+ "$ref": "#/definitions/listParameter",
+ "title": "Voting options"
+ }
+ },
+ "required": [
+ "campaignTitle",
+ "minimumBudgetRequestPerProposal",
+ "maximumBudgetRequestPerProposal"
+ ],
+ "x-order": [
+ "campaignTitle",
+ "minimumBudgetRequestPerProposal",
+ "maximumBudgetRequestPerProposal",
+ "proposalFundingLogic",
+ "proposalAcceptanceThreshold",
+ "votingOptions"
+ ],
+ "definitions": {
+ "booleanParameter": {
+ "type": "boolean",
+ "title": "Boolean Parameter",
+ "x-note": "A true/false value."
+ },
+ "stringParameter": {
+ "type": "string",
+ "title": "String Parameter",
+ "x-note": "A plain text value."
+ },
+ "adaAmount": {
+ "type": "integer",
+ "title": "ADA Amount",
+ "x-note": "Amount in ADA."
+ },
+ "lovelaceAmount": {
+ "type": "integer",
+ "title": "Lovelace Amount",
+ "x-note": "Amount in Lovelace."
+ },
+ "integerParameter": {
+ "type": "integer",
+ "title": "Integer Parameter",
+ "x-note": "An integer value."
+ },
+ "dateParameter": {
+ "type": "string",
+ "format": "date",
+ "title": "Date Parameter",
+ "x-note": "A date value (YYYY-MM-DD)."
+ },
+ "datetimeParameter": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Datetime Parameter",
+ "x-note": "A datetime value (ISO 8601)."
+ },
+ "ratioFormula": {
+ "type": "string",
+ "title": "Ratio / Formula",
+ "x-note": "A ratio or formula expression."
+ },
+ "percentageParameter": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "title": "Percentage Parameter",
+ "x-note": "A percentage value (0-100)."
+ },
+ "currencyAmount": {
+ "type": ["string", "number"],
+ "title": "Currency Amount or String"
+ },
+ "stringRule": {
+ "type": "string",
+ "title": "String / Rule"
+ },
+ "percentageOrAda": {
+ "oneOf": [
+ { "$ref": "#/definitions/percentageParameter" },
+ { "$ref": "#/definitions/adaAmount" }
+ ],
+ "title": "Percentage or ADA Amount"
+ },
+ "listParameter": {
+ "type": "array",
+ "items": { "type": "string" },
+ "title": "List Parameter"
+ }
+ }
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/common_definitions.schema.json b/specs/signed_docs/docs/payload_schemas/common_definitions.schema.json
new file mode 100644
index 0000000000..e2b2ae1331
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/common_definitions.schema.json
@@ -0,0 +1,78 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/main/specs/signed_docs/docs/payload_schemas/common_definitions.schema.json",
+ "title": "Common Definitions for Catalyst Schemas",
+ "description": "Reusable definitions for all Catalyst parameter schemas.",
+ "type": "object",
+ "definitions": {
+ "booleanParameter": {
+ "type": "boolean",
+ "title": "Boolean Parameter",
+ "x-note": "A true/false value."
+ },
+ "stringParameter": {
+ "type": "string",
+ "title": "String Parameter",
+ "x-note": "A plain text value."
+ },
+ "adaAmount": {
+ "type": "integer",
+ "title": "ADA Amount",
+ "x-note": "Amount in ADA."
+ },
+ "lovelaceAmount": {
+ "type": "integer",
+ "title": "Lovelace Amount",
+ "x-note": "Amount in Lovelace."
+ },
+ "integerParameter": {
+ "type": "integer",
+ "title": "Integer Parameter",
+ "x-note": "An integer value."
+ },
+ "dateParameter": {
+ "type": "string",
+ "format": "date",
+ "title": "Date Parameter",
+ "x-note": "A date value (YYYY-MM-DD)."
+ },
+ "datetimeParameter": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Datetime Parameter",
+ "x-note": "A datetime value (ISO 8601)."
+ },
+ "ratioFormula": {
+ "type": "string",
+ "title": "Ratio / Formula",
+ "x-note": "A ratio or formula expression."
+ },
+ "percentageParameter": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "title": "Percentage Parameter",
+ "x-note": "A percentage value (0-100)."
+ },
+ "currencyAmount": {
+ "type": ["string", "number"],
+ "title": "Currency Amount or String"
+ },
+ "stringRule": {
+ "type": "string",
+ "title": "String / Rule"
+ },
+ "percentageOrAda": {
+ "oneOf": [
+ { "$ref": "#/definitions/percentageParameter" },
+ { "$ref": "#/definitions/adaAmount" }
+ ],
+ "title": "Percentage or ADA Amount"
+ },
+ "listParameter": {
+ "type": "array",
+ "items": { "type": "string" },
+ "title": "List Parameter"
+ }
+ }
+}
diff --git a/specs/signed_docs/docs/payload_schemas/decision_parameter.example.json b/specs/signed_docs/docs/payload_schemas/decision_parameter.example.json
new file mode 100644
index 0000000000..08f3548d3f
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/decision_parameter.example.json
@@ -0,0 +1,4 @@
+{
+ "votingPeriodStart": "2025-07-05T00:00:00Z",
+ "votingOptions": ["Yes", "No", "Abstain"]
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/decision_parameters.schema.json b/specs/signed_docs/docs/payload_schemas/decision_parameters.schema.json
new file mode 100644
index 0000000000..bb12f3d07a
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/decision_parameters.schema.json
@@ -0,0 +1,112 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/main/specs/signed_docs/docs/payload_schemas/decision_parameters.schema.json",
+ "title": "Decision Parameters",
+ "description": "Schema for defining Catalyst decision-level parameters, with UI/UX metadata and logical grouping.",
+ "type": "object",
+ "properties": {
+ "decisionTitle": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Decision Title"
+ },
+ "decisionType": {
+ "$ref": "#/definitions/stringParameter",
+ "title": "Decision Type"
+ },
+ "decisionDate": {
+ "$ref": "#/definitions/dateParameter",
+ "title": "Decision Date"
+ },
+ "votingOptions": {
+ "$ref": "#/definitions/listParameter",
+ "title": "Voting Options"
+ },
+ "acceptanceThreshold": {
+ "$ref": "#/definitions/percentageParameter",
+ "title": "Acceptance Threshold"
+ }
+ },
+ "required": [
+ "decisionTitle",
+ "decisionType",
+ "decisionDate"
+ ],
+ "x-order": [
+ "decisionTitle",
+ "decisionType",
+ "decisionDate",
+ "votingOptions",
+ "acceptanceThreshold"
+ ],
+ "definitions": {
+ "booleanParameter": {
+ "type": "boolean",
+ "title": "Boolean Parameter",
+ "x-note": "A true/false value."
+ },
+ "stringParameter": {
+ "type": "string",
+ "title": "String Parameter",
+ "x-note": "A plain text value."
+ },
+ "adaAmount": {
+ "type": "integer",
+ "title": "ADA Amount",
+ "x-note": "Amount in ADA."
+ },
+ "lovelaceAmount": {
+ "type": "integer",
+ "title": "Lovelace Amount",
+ "x-note": "Amount in Lovelace."
+ },
+ "integerParameter": {
+ "type": "integer",
+ "title": "Integer Parameter",
+ "x-note": "An integer value."
+ },
+ "dateParameter": {
+ "type": "string",
+ "format": "date",
+ "title": "Date Parameter",
+ "x-note": "A date value (YYYY-MM-DD)."
+ },
+ "datetimeParameter": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Datetime Parameter",
+ "x-note": "A datetime value (ISO 8601)."
+ },
+ "ratioFormula": {
+ "type": "string",
+ "title": "Ratio / Formula",
+ "x-note": "A ratio or formula expression."
+ },
+ "percentageParameter": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "title": "Percentage Parameter",
+ "x-note": "A percentage value (0-100)."
+ },
+ "currencyAmount": {
+ "type": ["string", "number"],
+ "title": "Currency Amount or String"
+ },
+ "stringRule": {
+ "type": "string",
+ "title": "String / Rule"
+ },
+ "percentageOrAda": {
+ "oneOf": [
+ { "$ref": "#/definitions/percentageParameter" },
+ { "$ref": "#/definitions/adaAmount" }
+ ],
+ "title": "Percentage or ADA Amount"
+ },
+ "listParameter": {
+ "type": "array",
+ "items": { "type": "string" },
+ "title": "List Parameter"
+ }
+ }
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/parameters.md b/specs/signed_docs/docs/payload_schemas/parameters.md
new file mode 100644
index 0000000000..f631497861
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/parameters.md
@@ -0,0 +1,55 @@
+# Catalyst Signed Document Parameters
+
+## Brand Parameters
+
+- directVotingPrivacyState
+- brandName
+- minimumBudgetRequestPerProposal
+- maximumBudgetRequestPerProposal
+- maximumProposalsPerProposer
+- communityReviewerRegistration
+- votingPowerThreshold
+- tallyingOptimization
+- proposalAcceptanceThreshold
+
+## Campaign Parameters
+
+- fundName
+- fundSize
+- campaignTitle
+- campaignBudget
+- proposalSubmissionFee
+- compensationsDistributionDate
+- proposalsRegistrationOnChain
+- drepDeadlineDate
+- registrationDeadlineDate
+- votingPeriodStart
+- votingPeriodEnd
+- startOfTallying
+- endOfTallying
+- proposalFundingLogic
+- voterCompensations
+- communityReviewCompensations
+- communityModeratorCompensations
+- onboardingCompensations
+- projectAccountabilityManagementComp
+- currentInsightSharingStart
+- currentProposalSubmissionStart
+- currentRefineProposalsStart
+- currentFinalizeProposalsStart
+- currentProposalAssessment
+- currentAssessmentQaStart
+
+## Category Parameters
+
+- campaignTitle
+- minimumBudgetRequestPerProposal
+- maximumBudgetRequestPerProposal
+- proposalFundingLogic
+- proposalAcceptanceThreshold
+- votingOptions
+
+## Contest Parameters
+
+- votingPeriodStart
+- votingOptions
diff --git a/specs/signed_docs/docs/payload_schemas/proposal_submission_action.draft.example.json b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.draft.example.json
new file mode 100644
index 0000000000..747d3b6ec7
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.draft.example.json
@@ -0,0 +1,3 @@
+{
+ "action": "draft"
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/proposal_submission_action.final.example.json b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.final.example.json
new file mode 100644
index 0000000000..bfbf15e59d
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.final.example.json
@@ -0,0 +1,3 @@
+{
+ "action": "final"
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/proposal_submission_action.hide.example.json b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.hide.example.json
new file mode 100644
index 0000000000..e6f023094f
--- /dev/null
+++ b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.hide.example.json
@@ -0,0 +1,3 @@
+{
+ "action": "hide"
+}
\ No newline at end of file
diff --git a/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json
index 965b66f37a..f7c7494c20 100644
--- a/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json
+++ b/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json
@@ -3,12 +3,10 @@
"$id": "https://raw.githubusercontent.com/input-output-hk/catalyst-libs/refs/heads/main/specs/signed_docs/docs/payload_schemas/proposal_submission_action.schema.json",
"title": "Proposal Submission Action Payload Schema",
"description": "Structure of the payload of a Proposal Submission Action.",
- "maintainers": [
- {
- "name": "Catalyst Team",
- "url": "https://projectcatalyst.io/"
- }
- ],
+ "maintainers": [{
+ "name": "Catalyst Team",
+ "url": "https://projectcatalyst.io/"
+ }],
"x-changelog": {
"2025-03-01": [
"First Version Created."
diff --git a/specs/signed_docs/docs/proposal_submission_action.cue b/specs/signed_docs/docs/proposal_submission_action.cue
index 1db5557848..6d09f9a7fd 100644
--- a/specs/signed_docs/docs/proposal_submission_action.cue
+++ b/specs/signed_docs/docs/proposal_submission_action.cue
@@ -92,6 +92,33 @@ docs: #DocumentDefinitions & {
for a collaborator it identified that they do not wish to be listed as a `collaborator`.
"""
schema: _ @embed(file="payload_schemas/proposal_submission_action.schema.json")
+ examples: [
+ {
+ title: "Final Proposal Submission"
+ description: """
+ This document indicates the linked proposal is final and requested to proceed for further consideration.
+ """
+ example: _ @embed(file="payload_schemas/proposal_submission_action.final.example.json")
+ },
+ {
+ title: "Draft Proposal Submission"
+ description: """
+ This document indicates the linked proposal is no longer final and should not proceed for further consideration.
+ It is also used by collaborators to accept that they are a collaborator on a document.
+ """
+ example: _ @embed(file="payload_schemas/proposal_submission_action.draft.example.json")
+ },
+ {
+ title: "Hidden Proposal Submission"
+ description: """
+ If submitted by the proposal author the document is hidden, it is still public but not shown as
+ a proposal being drafted.
+ If submitted by a collaborator, that collaborator is declaring they do not wish to be listed as
+ a collaborator on the proposal.
+ """
+ example: _ @embed(file="payload_schemas/proposal_submission_action.hide.example.json")
+ },
+ ]
}
"signers": {
diff --git a/specs/signed_docs/documentation_links.cue b/specs/signed_docs/documentation_links.cue
index 4083dd2d34..ff9f1bc98d 100644
--- a/specs/signed_docs/documentation_links.cue
+++ b/specs/signed_docs/documentation_links.cue
@@ -24,15 +24,16 @@ import (
documentationLinks: #namedLink
documentationLinks: {
- "RFC3629": "https://datatracker.ietf.org/doc/html/rfc3629" // UTF-8
- "RFC3986": "https://datatracker.ietf.org/doc/html/rfc3986" // URI
- "RFC9562": "https://www.rfc-editor.org/rfc/rfc9562.html" // UUID
- "RFC9562-V4": "https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-4" // UUID V4
- "RFC9562-V7": "https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7" // UUID V7
- "CC-BY-4.0": "https://creativecommons.org/licenses/by/4.0/legalcode" // CC BY 4.0
- "IPFS-CID": "https://docs.ipfs.tech/concepts/content-addressing/#what-is-a-cid" // IPFS Content Identifier
- "CBOR-TAG-42": "https://github.com/ipld/cid-cbor/"
- "CBOR-TAG-37": "https://github.com/lucas-clemente/cbor-specs/blob/master/uuid.md" // IPLD content identifiers (CIDs) in CBOR
+ "RFC3629": "https://datatracker.ietf.org/doc/html/rfc3629" // UTF-8
+ "RFC3986": "https://datatracker.ietf.org/doc/html/rfc3986" // URI
+ "RFC9562": "https://www.rfc-editor.org/rfc/rfc9562.html" // UUID
+ "RFC9562-V4": "https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-4" // UUID V4
+ "RFC9562-V7": "https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7" // UUID V7
+ "CC-BY-4.0": "https://creativecommons.org/licenses/by/4.0/legalcode" // CC BY 4.0
+ "IPFS-CID": "https://docs.ipfs.tech/concepts/content-addressing/#what-is-a-cid" // IPFS Content Identifier
+ "CBOR-TAG-42": "https://github.com/ipld/cid-cbor/" // IPLD content identifiers (CIDs) in CBOR
+ "CBOR-TAG-37": "https://github.com/lucas-clemente/cbor-specs/blob/master/uuid.md" // UUID Tag for CBOR
+ "CBOR-LFD-ENCODING": "https://www.rfc-editor.org/rfc/rfc8949.html#section-4.2.3" // CBOR length-first core deterministic encoding requirements
}
#allLinkNames: or([
@@ -52,4 +53,5 @@ linkAKA: {
"UTF-8": "RFC3629"
"CBOR Encoded IPLD Content Identifier": "CBOR-TAG-42"
"IPFS CID": "IPFS-CID"
+ "CBOR Deterministic Encoding": "CBOR-LFD-ENCODING"
}
diff --git a/specs/signed_docs/payload.cue b/specs/signed_docs/payload.cue
index f2dcbec41c..b7e1a379df 100644
--- a/specs/signed_docs/payload.cue
+++ b/specs/signed_docs/payload.cue
@@ -1,5 +1,19 @@
package signed_docs
+import (
+ "list"
+)
+
+// Individual Payload Example
+#payloadExample: {
+ // Title of the example
+ title: string
+ // Expanded description of what the example shows.
+ description: string
+ // Example data that matches the payload schema.
+ example: _
+}
+
// Payload definition
_payload: {
// Description of the payload
@@ -7,4 +21,7 @@ _payload: {
// Optional fixed schema for the payload.
// A URI or inline JSON Schema that the payload must validate against.
schema?: _
+ // Examples of the schema.
+ examples?: list.UniqueItems
+ examples?: [...#payloadExample] | *[]
}