Cuddler Data Specification
Version 1.0.0-draft.6 defines a data-first document standard where a Cuddler document instance validates against a strict Document Template schema, then passes semantic checks before any exporter treats it as valid output-ready data.
Templates, UI layout, styling, pagination, and runtime renderer APIs are out of scope for v1.
Document Template schemas MUST define both machine constraints and generator-readable intent through required descriptions.
Document Template schemas MUST declare output metadata so exporters can enforce supported content types.
Conformance Targets
- Conforming document instance: matches the canonical envelope, passes JSON Schema validation, and passes semantic checks.
- Conforming Document Template schema: follows the v1 authoring profile, including required intent documentation, section intent modeling, and
cuddler.outputmetadata. - Conforming validator: enforces Draft 2020-12 validation plus semantic rules, and returns deterministic pass/fail results.
- Conforming exporter: validates input first, follows no-silent-fallback behavior, and supports the template's primary declared output type.
Canonical Envelope and Identity
A conforming document instance MUST be a strict top-level object with only these properties:
{
"$schema": "optional absolute URI",
"meta": {},
"content": {},
"assets": {},
"references": [],
"annotations": []
}
Identity semantics are strict:
- IDs are UUID strings (RFC 4122): for
meta.documentId,block.blockId, asset IDs, and reference IDs. - Keys are kebab-case stable identifiers: for
meta.documentTypeId,section.key, and table column keys. - Kebab-case normalization MUST follow the six-step algorithm in Section 6.2 and match
^[a-z][a-z0-9-]{2,62}$.
Document Structures
| Structure | Requirements | Notes |
|---|---|---|
meta |
Strict object with required identity/version/timestamps/authorship fields. | schemaVersion and documentTypeId MUST be constrained via const in Document Template schemas. |
content |
Strict object with required sections[]; optional typed documentModel. |
If documentModel exists, it MUST be strict and MUST NOT be an unconstrained dictionary. |
sections[] |
Each section requires key, heading, blocks[]; optional subsections[]. |
Top-level required section keys MUST be enforced using contains + minContains. |
blocks[] |
Each block requires kind and blockId (UUID). |
v1 kinds are fixed: text, bullets, table, asset. |
assets |
Strict object with library[] of typed Asset objects. |
Visual assets MUST include altText. |
references |
Array of reference objects with required id, title, locator. |
Optional kind and notes. |
annotations |
Optional integration metadata array. | Values are scalar only; namespaced keys are recommended. |
Validation and Failure Rules
Validation is two-phase and normative:
- Run JSON Schema validation first (Draft 2020-12, including
contains,minContains, andunevaluatedPropertiesbehavior where composition is used). - Treat
date-time,email,uri, anduri-referenceas assertions, not informational annotations. - Only after schema success, run required semantic checks.
Required semantic checks:
- Asset integrity: every
assetblockassetIdexists inassets.library[].id. - Identifier uniqueness: asset IDs, reference IDs, and all
blockIdvalues are unique (including nested subsections). - Section-key uniqueness within each sibling
sections[]array. - Table coherence: each row length equals columns length.
- Timestamp consistency:
meta.updatedAt(if present) must be greater than or equal tometa.createdAt.
If any schema or semantic rule fails, validators MUST return failure and exporters MUST NOT emit normal output artifacts.
Document Template Schema Authoring Profile
- Use Draft 2020-12 and an immutable versioned schema
$id:https://www.cuddler.dev/schemas/<documentTypeId>/<schemaVersion>/data.schema.json. - Enforce strictness on all instance-visible objects with
additionalProperties: falseand preserve strictness through composition usingunevaluatedProperties: falsewhere needed. - Enforce canonical envelope shape and
constconstraints formeta.documentTypeIdandmeta.schemaVersion. - Require non-empty generator-readable
descriptionvalues for all instance-visible properties (directly or via$reftarget). - Model section intent using a
oneOfunion of section variants, each with akeyconst, non-emptytitle/description, and optional block restrictions.
Template Output Metadata
Draft 6 requires a top-level cuddler metadata object in each Document Template schema:
"cuddler": {
"specVersion": "1.0.0-draft.6",
"documentTypeId": "<kebab-case>",
"schemaVersion": "<semver>",
"output": {
"primaryContentType": "application/pdf",
"supportedContentTypes": ["application/pdf"]
}
}
output.primaryContentTypeis REQUIRED and identifies the template's minimum conforming output.output.supportedContentTypesis OPTIONAL; when present it MUST include the primary content type and only unique values.- This metadata does not alter validation behavior, but it is normative for generator/exporter interoperability.
Security Considerations
- Exporters MUST treat all text as untrusted input.
- When rendering markdown text blocks, exporters MUST sanitize output and disable raw HTML by default.
- Exporters SHOULD NOT fetch remote asset URIs by default; if enabled, they MUST apply scheme and host allowlists.
- Exporters MUST NOT execute active content from document fields (scripts, event handlers, iframes, or similar content).
Draft 6 Artifacts
The source draft folder specification/v1/d6/ includes:
cuddler.spec.1.0.0-draft.6-document-templates.md(normative specification text)cuddler.base.defs.schema.1.0.0-draft.6-document-templates.json(base$defslibrary)data.schema.prompt.1.0.0-draft.6-document-templates.txtanddata.example.prompt.1.0.0-draft.6-document-templates.txt(prompt assets)
Base definitions URI for this draft: https://www.cuddler.dev/spec/1.0.0-draft.6/cuddler.base.defs.schema.json.
