@adobe/design-data-spec 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -186,7 +186,7 @@ file or class name and description of purpose be included on the
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
189
+ Copyright 2026 Adobe
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -0,0 +1,22 @@
1
+ {
2
+ "tokens": [],
3
+ "guidelines": [
4
+ {
5
+ "$id": "https://opensource.adobe.com/spectrum-design-data/guidelines/spacing.json",
6
+ "name": "spacing",
7
+ "title": "Spacing",
8
+ "category": "designing",
9
+ "status": "published",
10
+ "documentBlocks": [
11
+ {
12
+ "type": "guideline",
13
+ "content": "Use the spacing scale tokens to maintain consistent rhythm across layouts. Avoid hard-coded pixel values."
14
+ },
15
+ {
16
+ "type": "guideline",
17
+ "content": "Compact density reduces spacing values proportionally to fit more content in constrained viewports."
18
+ }
19
+ ]
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": [
4
+ {
5
+ "rule_id": "SPEC-045",
6
+ "severity": "warning",
7
+ "message_pattern": ".*no purpose block.*"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "tokens": [],
3
+ "guidelines": [
4
+ {
5
+ "$id": "https://opensource.adobe.com/spectrum-design-data/guidelines/motion.json",
6
+ "name": "motion",
7
+ "title": "Motion",
8
+ "category": "designing",
9
+ "status": "published",
10
+ "related": [{ "ref": "nonexistent-guideline", "kind": "guideline" }],
11
+ "documentBlocks": [
12
+ {
13
+ "type": "purpose",
14
+ "content": "Motion in Spectrum 2 communicates state changes, spatial relationships, and system feedback through purposeful animation."
15
+ }
16
+ ]
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": [
4
+ {
5
+ "rule_id": "SPEC-046",
6
+ "severity": "warning",
7
+ "message_pattern": ".*not a known component or guideline.*"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "description": "An alias whose $ref target is absent from the dataset MUST NOT panic. resolve_reference MUST return a result with no terminal value (value absent) and a partial chain containing at least the starting slug.",
3
+ "resolved": true,
4
+ "expected_has_value": false,
5
+ "expected_chain_min_length": 1,
6
+ "expected_chain_0": "{accent-color-dangling}"
7
+ }
@@ -0,0 +1,8 @@
1
+ [
2
+ {
3
+ "name": { "property": "accent-color-dangling" },
4
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/alias.json",
5
+ "$ref": "00000000-0000-0000-0000-000000000000",
6
+ "uuid": "ref-dangling-alias-0000-000000000001"
7
+ }
8
+ ]
@@ -0,0 +1,4 @@
1
+ {
2
+ "ref": "{accent-color-dangling}",
3
+ "context": {}
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "description": "A set-level alias ($ref targeting a set_uuid) MUST resolve to the mode-appropriate child. Under colorScheme=dark, accent-color-900 → blue-900 dark (different value from light).",
3
+ "resolved": true,
4
+ "expected_value": "rgb(75, 117, 255)",
5
+ "expected_chain_length": 3,
6
+ "expected_chain_0": "{accent-color-900}",
7
+ "expected_chain_last": "rgb(75, 117, 255)"
8
+ }
@@ -0,0 +1,32 @@
1
+ [
2
+ {
3
+ "name": {
4
+ "property": "color",
5
+ "colorFamily": "blue",
6
+ "scaleIndex": 900,
7
+ "colorScheme": "light"
8
+ },
9
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/color.json",
10
+ "value": "rgb(59, 99, 251)",
11
+ "uuid": "ref-blue900-light-0000-000000000002",
12
+ "set_uuid": "ref-blue900-set-000-0000-000000000002"
13
+ },
14
+ {
15
+ "name": {
16
+ "property": "color",
17
+ "colorFamily": "blue",
18
+ "scaleIndex": 900,
19
+ "colorScheme": "dark"
20
+ },
21
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/color.json",
22
+ "value": "rgb(75, 117, 255)",
23
+ "uuid": "ref-blue900-dark-0000-000000000002",
24
+ "set_uuid": "ref-blue900-set-000-0000-000000000002"
25
+ },
26
+ {
27
+ "name": { "property": "accent-color-900" },
28
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/alias.json",
29
+ "$ref": "ref-blue900-set-000-0000-000000000002",
30
+ "uuid": "ref-accent-color-900-0000-000000000002"
31
+ }
32
+ ]
@@ -0,0 +1,4 @@
1
+ {
2
+ "ref": "{accent-color-900}",
3
+ "context": { "colorScheme": "dark" }
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "description": "A set-level alias ($ref targeting a set_uuid) MUST resolve to the mode-appropriate child. Under colorScheme=light, accent-color-900 → blue-900 light.",
3
+ "resolved": true,
4
+ "expected_value": "rgb(59, 99, 251)",
5
+ "expected_chain_length": 3,
6
+ "expected_chain_0": "{accent-color-900}",
7
+ "expected_chain_last": "rgb(59, 99, 251)"
8
+ }
@@ -0,0 +1,32 @@
1
+ [
2
+ {
3
+ "name": {
4
+ "property": "color",
5
+ "colorFamily": "blue",
6
+ "scaleIndex": 900,
7
+ "colorScheme": "light"
8
+ },
9
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/color.json",
10
+ "value": "rgb(59, 99, 251)",
11
+ "uuid": "ref-blue900-light-0000-000000000001",
12
+ "set_uuid": "ref-blue900-set-000-0000-000000000001"
13
+ },
14
+ {
15
+ "name": {
16
+ "property": "color",
17
+ "colorFamily": "blue",
18
+ "scaleIndex": 900,
19
+ "colorScheme": "dark"
20
+ },
21
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/color.json",
22
+ "value": "rgb(75, 117, 255)",
23
+ "uuid": "ref-blue900-dark-0000-000000000001",
24
+ "set_uuid": "ref-blue900-set-000-0000-000000000001"
25
+ },
26
+ {
27
+ "name": { "property": "accent-color-900" },
28
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/token-types/alias.json",
29
+ "$ref": "ref-blue900-set-000-0000-000000000001",
30
+ "uuid": "ref-accent-color-900-0000-000000000001"
31
+ }
32
+ ]
@@ -0,0 +1,4 @@
1
+ {
2
+ "ref": "{accent-color-900}",
3
+ "context": { "colorScheme": "light" }
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "description": "A slug that matches no token in the dataset MUST cause resolve_reference to return None.",
3
+ "resolved": false
4
+ }
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "name": { "property": "color", "colorFamily": "blue" },
4
+ "value": "blue",
5
+ "uuid": "ref-other-token-0000-000000000001"
6
+ }
7
+ ]
@@ -0,0 +1,4 @@
1
+ {
2
+ "ref": "{totally-made-up}",
3
+ "context": {}
4
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "tokens": [],
3
+ "guidelines": [
4
+ {
5
+ "$id": "https://opensource.adobe.com/spectrum-design-data/guidelines/colors.json",
6
+ "name": "colors",
7
+ "title": "Colors",
8
+ "category": "designing",
9
+ "sourceUrl": "https://s2.spectrum.corp.adobe.com/page/colors/",
10
+ "lastUpdated": "2026-02-02",
11
+ "status": "published",
12
+ "tags": ["designing", "color"],
13
+ "related": [{ "ref": "grays", "kind": "guideline" }],
14
+ "documentBlocks": [
15
+ {
16
+ "type": "purpose",
17
+ "content": "The Spectrum 2 color system defines a perceptually balanced, accessible palette with semantically named tokens for surfaces, text, icons, and interactive elements across light and dark schemes."
18
+ },
19
+ {
20
+ "type": "guideline",
21
+ "content": "Accent colors establish hierarchy by drawing attention to the highest-priority interactive element. Limit accent usage to one element per focal area."
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "$id": "https://opensource.adobe.com/spectrum-design-data/guidelines/grays.json",
27
+ "name": "grays",
28
+ "title": "Grays",
29
+ "category": "designing",
30
+ "status": "published",
31
+ "documentBlocks": [
32
+ {
33
+ "type": "purpose",
34
+ "content": "Gray tokens provide neutral surface, text, and border colors that adapt to light and dark color schemes."
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-spec",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for the design data format",
5
5
  "type": "module",
6
6
  "repository": {
@@ -31,7 +31,8 @@
31
31
  "./rules/rules.yaml": "./rules/rules.yaml",
32
32
  "./schemas/registry-value.json": "./schemas/registry-value.json",
33
33
  "./schemas/platform-extension.json": "./schemas/platform-extension.json",
34
- "./schemas/dataset.schema.json": "./schemas/dataset.schema.json"
34
+ "./schemas/dataset.schema.json": "./schemas/dataset.schema.json",
35
+ "./schemas/guideline.schema.json": "./schemas/guideline.schema.json"
35
36
  },
36
37
  "files": [
37
38
  "conformance",
package/rules/rules.yaml CHANGED
@@ -496,3 +496,34 @@ rules:
496
496
  message: "Dataset structure incomplete: {detail}"
497
497
  spec_ref: spec/dataset-layout.md#structural-validation
498
498
  introduced_in: "1.0.0-draft"
499
+
500
+ - id: SPEC-045
501
+ name: guideline-missing-purpose
502
+ severity: warning
503
+ layer: 2
504
+ category: completeness
505
+ assert: >
506
+ A guideline document SHOULD include at least one `documentBlocks` block with
507
+ type `purpose`. A purpose block explains the design intent of the topic and
508
+ is the primary entry point for agents and designers querying the guidance
509
+ corpus. This mirrors SPEC-029 (document-block-missing-purpose) but is scoped
510
+ specifically to the guideline entity.
511
+ message: "Guideline '{name}' has documentBlocks but no purpose block — add a block with type 'purpose'"
512
+ spec_ref: spec/guideline-format.md#spec-rules
513
+ introduced_in: "1.0.0-draft"
514
+
515
+ - id: SPEC-046
516
+ name: guideline-related-resolves
517
+ severity: warning
518
+ layer: 2
519
+ category: completeness
520
+ assert: >
521
+ Every entry in a guideline document's `related` array SHOULD resolve to a known
522
+ entity: when `kind` is `"component"`, the `ref` MUST match a component `name` in
523
+ the dataset; when `kind` is `"guideline"`, the `ref` MUST match a guideline `name`
524
+ in the dataset; when `kind` is absent, the `ref` SHOULD match either a component
525
+ or a guideline `name`. Dangling references are advisory (warning) to allow
526
+ incremental migration where some targets may not yet be present.
527
+ message: "Guideline '{name}' references '{ref}' which is not a known component or guideline"
528
+ spec_ref: spec/guideline-format.md#related-references
529
+ introduced_in: "1.0.0-draft"
@@ -18,7 +18,8 @@
18
18
  "components": { "const": true },
19
19
  "fields": { "const": true },
20
20
  "modeSets": { "const": true },
21
- "registry": { "const": true }
21
+ "registry": { "const": true },
22
+ "guidelines": { "const": true }
22
23
  },
23
24
  "additionalProperties": false
24
25
  },
@@ -30,7 +31,8 @@
30
31
  "components": { "type": "string", "minLength": 1 },
31
32
  "fields": { "type": "string", "minLength": 1 },
32
33
  "modeSets": { "type": "string", "minLength": 1 },
33
- "registry": { "type": "string", "minLength": 1 }
34
+ "registry": { "type": "string", "minLength": 1 },
35
+ "guidelines": { "type": "string", "minLength": 1 }
34
36
  },
35
37
  "additionalProperties": false
36
38
  }
@@ -0,0 +1,93 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/guideline.schema.json",
4
+ "title": "Design data guideline document",
5
+ "description": "Layer 1 structural schema for a standalone foundation/guideline document — a non-component Spectrum guidance page such as color, typography, motion, spacing, principles, or app-frame. Body prose is modeled as document blocks. See spec/guideline-format.md.",
6
+ "type": "object",
7
+ "required": ["$id", "name", "title", "category", "documentBlocks"],
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string",
11
+ "format": "uri"
12
+ },
13
+ "specVersion": {
14
+ "type": "string",
15
+ "description": "Spec version this document targets (e.g. '1.0.0-draft')."
16
+ },
17
+ "$id": {
18
+ "type": "string",
19
+ "format": "uri",
20
+ "description": "Canonical identifier for this guideline document."
21
+ },
22
+ "name": {
23
+ "type": "string",
24
+ "pattern": "^[a-z][a-z0-9-]*$",
25
+ "minLength": 1,
26
+ "description": "Machine identifier (kebab-case slug). Matches the filename (e.g. 'colors', 'app-frame-overview')."
27
+ },
28
+ "title": {
29
+ "type": "string",
30
+ "minLength": 1,
31
+ "description": "Human-readable page title (e.g. 'Colors')."
32
+ },
33
+ "category": {
34
+ "type": "string",
35
+ "enum": ["designing", "fundamentals", "developing", "support"],
36
+ "description": "High-level category classifying the guideline within the guidance corpus."
37
+ },
38
+ "sourceUrl": {
39
+ "type": "string",
40
+ "format": "uri",
41
+ "description": "Canonical URL of the upstream source page (e.g. 'https://s2.spectrum.corp.adobe.com/page/colors/')."
42
+ },
43
+ "lastUpdated": {
44
+ "type": "string",
45
+ "format": "date",
46
+ "description": "ISO 8601 date of the most recent source-page update (e.g. '2026-02-02')."
47
+ },
48
+ "status": {
49
+ "type": "string",
50
+ "minLength": 1,
51
+ "description": "Publication status of this guideline (e.g. 'published'). Left as an open string — not an enum — to accommodate future status values without a schema change."
52
+ },
53
+ "tags": {
54
+ "type": "array",
55
+ "items": { "type": "string", "minLength": 1 },
56
+ "uniqueItems": true,
57
+ "description": "Free-form tags for discovery and filtering."
58
+ },
59
+ "related": {
60
+ "type": "array",
61
+ "items": { "$ref": "#/$defs/relatedReference" },
62
+ "uniqueItems": true,
63
+ "description": "Related entities. A reference MAY target a component (by name) or another guideline document (by name). Targets are not required to resolve at Layer 1; SPEC-046 advisorily warns on dangling references."
64
+ },
65
+ "documentBlocks": {
66
+ "type": "array",
67
+ "items": { "$ref": "document-block.schema.json" },
68
+ "minItems": 1,
69
+ "description": "Typed prose blocks that form the body of this guideline. See spec/document-blocks.md (Phase 9)."
70
+ }
71
+ },
72
+ "additionalProperties": false,
73
+ "$defs": {
74
+ "relatedReference": {
75
+ "type": "object",
76
+ "required": ["ref"],
77
+ "properties": {
78
+ "ref": {
79
+ "type": "string",
80
+ "pattern": "^[a-z][a-z0-9-]*$",
81
+ "minLength": 1,
82
+ "description": "kebab-case name of the related component or guideline."
83
+ },
84
+ "kind": {
85
+ "type": "string",
86
+ "enum": ["component", "guideline"],
87
+ "description": "Optional hint for what 'ref' targets. When omitted, tooling resolves against both catalogs."
88
+ }
89
+ },
90
+ "additionalProperties": false
91
+ }
92
+ }
93
+ }
@@ -17,6 +17,7 @@ A dataset is rooted at a single **dataset root** directory. The following table
17
17
  | `fields/` | Optional (registered) | Name-object field declarations, one or more `*.json` files. | [`field.schema.json`](../schemas/field.schema.json) |
18
18
  | `mode-sets/` | Optional (registered) | Mode set declarations, one per `*.json` file. | [`mode-set.schema.json`](../schemas/mode-set.schema.json) |
19
19
  | `registry/` | Optional (registered) | Registry value collections (vocabulary), one or more `*.json` files. | [`registry-value.json`](../schemas/registry-value.json) |
20
+ | `guidelines/` | Optional (registered) | One guideline document per `*.json` file. | [`guideline.schema.json`](../schemas/guideline.schema.json) |
20
21
 
21
22
  **NORMATIVE:** A conformant dataset **MUST** contain a `tokens/` directory holding at least one `*.tokens.json` file. A dataset with no `tokens/` directory, or a `tokens/` directory containing no `*.tokens.json` file, is **not** conformant.
22
23
 
@@ -35,6 +36,7 @@ A dataset is rooted at a single **dataset root** directory. The following table
35
36
  | `fields/` | `*.json` | The catalog MAY be split across multiple files. |
36
37
  | `mode-sets/` | `*.json` | One declaration per file. |
37
38
  | `registry/` | `*.json` | One value collection per file. |
39
+ | `guidelines/` | `*.json` | One declaration per file. |
38
40
 
39
41
  ## Dataset discovery
40
42
 
@@ -45,7 +47,7 @@ Tooling that operates on "the current dataset" (rather than an explicit path) **
45
47
  3. **In-repo probing** — when running inside a monorepo checkout, probe for the standard layout relative to the working directory (`packages/design-data/tokens` and one level up). This preserves the in-repo workflow with zero configuration.
46
48
  4. **Embedded snapshot** — when no dataset is found on disk, tooling MAY fall back to a snapshot of the foundation dataset embedded in the binary, materialized to a local cache directory.
47
49
 
48
- **NORMATIVE:** The required directory (`tokens/`) and registered optional directories are resolved **relative to the dataset root** determined above. A discovery tier that resolves a dataset root **MUST** look for `tokens/`, `components/`, `fields/`, `mode-sets/`, and `registry/` directly under that root.
50
+ **NORMATIVE:** The required directory (`tokens/`) and registered optional directories are resolved **relative to the dataset root** determined above. A discovery tier that resolves a dataset root **MUST** look for `tokens/`, `components/`, `fields/`, `mode-sets/`, `registry/`, and `guidelines/` directly under that root.
49
51
 
50
52
  The reference implementation of this algorithm lives in the SDK at `sdk/core/src/data_source/mod.rs` (`resolve`, `from_root`, and `probe_cwd`).
51
53
 
@@ -0,0 +1,122 @@
1
+ # Guideline format
2
+
3
+ **Spec version:** `1.0.0-draft` (see [Overview](index.md))
4
+
5
+ This document defines **guideline documents**: standalone JSON files representing non-component Spectrum guidance pages — topics like color, typography, motion, spacing, principles, and the S2 app frame. Each guideline wraps page metadata and a `documentBlocks` body, making design guidance machine-readable and queryable by agents alongside components and tokens.
6
+
7
+ Guideline documents live in the `guidelines/` directory of a dataset (one file per page, named `<slug>.json`) and conform to [`guideline.schema.json`](../schemas/guideline.schema.json).
8
+
9
+ Scoped under Phase 10. See also [Document blocks](document-blocks.md) for the block shape used as the body.
10
+
11
+ ## Guideline document shape
12
+
13
+ A guideline document is a JSON object conforming to [`guideline.schema.json`](../schemas/guideline.schema.json). It is a **root document** (carries `$id` + optional `specVersion`, like a component declaration) residing one-per-file in `guidelines/`.
14
+
15
+ ### Required fields
16
+
17
+ | Field | Type | Description |
18
+ | ---------------- | ------------------------ | ---------------------------------------------------------------------------------- |
19
+ | `$id` | string (uri) | Canonical identifier for this guideline document. |
20
+ | `name` | string (kebab-case) | Machine identifier matching the filename (e.g. `colors`, `app-frame-overview`). |
21
+ | `title` | string | Human-readable page title (e.g. `"Colors"`). |
22
+ | `category` | string (enum) | High-level category — one of `designing`, `fundamentals`, `developing`, `support`. |
23
+ | `documentBlocks` | array of document blocks | Body prose (minimum 1 block). See [Document blocks](document-blocks.md). |
24
+
25
+ ### Optional fields
26
+
27
+ | Field | Type | Description |
28
+ | ------------- | ------------------- | ---------------------------------------------------------------------------------------------------------- |
29
+ | `$schema` | string (uri) | JSON Schema reference for authoring tool support. |
30
+ | `specVersion` | string | Spec version this document targets (e.g. `"1.0.0-draft"`). RECOMMENDED for self-identification. |
31
+ | `sourceUrl` | string (uri) | Canonical URL of the upstream source page. |
32
+ | `lastUpdated` | string (date) | ISO 8601 date of the most recent source-page update. |
33
+ | `status` | string | Publication status (e.g. `"published"`). Open string — not constrained to an enum. |
34
+ | `tags` | string\[] | Free-form tags for discovery and filtering. Unique items. |
35
+ | `related` | relatedReference\[] | Cross-references to related components or other guidelines. See [Related references](#related-references). |
36
+
37
+ ### `category` enum
38
+
39
+ | Value | Meaning |
40
+ | -------------- | ---------------------------------------------------------------------------------------------- |
41
+ | `designing` | Visual and interaction design guidance (colors, typography, motion, spacing, app frame, etc.). |
42
+ | `fundamentals` | Foundation principles and introduction to the design system. |
43
+ | `developing` | Developer-focused onboarding and technical overview. |
44
+ | `support` | FAQs, resources, and supplemental support content. |
45
+
46
+ **NORMATIVE:** The `category` field MUST be one of the four values above. A guideline with an unknown category value MUST fail Layer 1 schema validation.
47
+
48
+ ## Related references
49
+
50
+ The `related` array holds cross-references to entities that are semantically related to this guideline. Each entry is a `relatedReference` object:
51
+
52
+ | Field | Type | Required | Description |
53
+ | ------ | -------------- | -------- | ---------------------------------------------------------------------------------------------------- |
54
+ | `ref` | string (kebab) | Yes | The `name` of the related component or guideline document. |
55
+ | `kind` | string (enum) | No | Optional hint: `"component"` or `"guideline"`. When omitted, tooling resolves against both catalogs. |
56
+
57
+ **NORMATIVE:** Layer 1 does NOT require `related[].ref` values to resolve to existing entities. A guideline document that references a slug not yet present in the dataset is still a conformant Layer 1 document. Tooling SHOULD warn on dangling references (see SPEC-046).
58
+
59
+ **Rationale:** `related` slugs may point at another guideline page, a component, or a page not yet migrated to the structured format. Making resolution a warning (not an error) prevents authoring friction during incremental migration.
60
+
61
+ ## `documentBlocks` body
62
+
63
+ **NORMATIVE:** Every guideline document MUST carry a `documentBlocks` array with at least one block (`minItems: 1`). A guideline file with an empty or absent `documentBlocks` array MUST fail Layer 1 schema validation.
64
+
65
+ **Rationale:** A guideline document whose sole purpose is to carry prose guidance is meaningless with zero blocks. This is a stricter constraint than the embedded `documentBlocks` property on tokens and components (which is optional), because a guideline file — unlike a token or component — has no other structured content to offer.
66
+
67
+ **RECOMMENDED:** A guideline document SHOULD include at least one block of type `purpose` that explains the design intent of the topic (see SPEC-045).
68
+
69
+ See [Document blocks](document-blocks.md) for the full block shape and type descriptions.
70
+
71
+ ## Example guideline document
72
+
73
+ ```json
74
+ {
75
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/guideline.schema.json",
76
+ "specVersion": "1.0.0-draft",
77
+ "$id": "https://opensource.adobe.com/spectrum-design-data/guidelines/colors.json",
78
+ "name": "colors",
79
+ "title": "Colors",
80
+ "category": "designing",
81
+ "sourceUrl": "https://s2.spectrum.corp.adobe.com/page/colors/",
82
+ "lastUpdated": "2026-02-02",
83
+ "status": "published",
84
+ "tags": ["designing", "design-tokens", "color"],
85
+ "related": [
86
+ { "ref": "grays", "kind": "guideline" },
87
+ { "ref": "background-layers", "kind": "guideline" }
88
+ ],
89
+ "documentBlocks": [
90
+ {
91
+ "type": "purpose",
92
+ "content": "The Spectrum 2 color system defines a perceptually balanced, accessible palette with semantically named tokens for surfaces, text, icons, and interactive elements across light and dark schemes.",
93
+ "agents": "Use Spectrum color tokens — not raw hex values — for all UI elements. The system ensures accessible contrast ratios and consistent brand expression across themes."
94
+ },
95
+ {
96
+ "type": "guideline",
97
+ "content": "Accent colors establish hierarchy by drawing attention to the highest-priority interactive element in a focal area. Limit accent usage to one element per region to preserve signal strength."
98
+ }
99
+ ]
100
+ }
101
+ ```
102
+
103
+ ## File naming and placement
104
+
105
+ **NORMATIVE:** Each guideline document MUST be placed in the `guidelines/` directory of the dataset root and named `<name>.json`, where `<name>` matches the document's `name` field (kebab-case slug). One file per guideline; the `guidelines/` directory MUST NOT be nested.
106
+
107
+ **NORMATIVE:** The `guidelines/` directory is an **optional registered** directory in the dataset layout. When present, every `*.json` file it contains MUST conform to `guideline.schema.json`. When absent, no error is produced. See [Dataset layout](dataset-layout.md) for directory registration rules.
108
+
109
+ ## SPEC rules
110
+
111
+ | Rule ID | Severity | Name | Assert |
112
+ | -------- | -------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
113
+ | SPEC-045 | warning | guideline-missing-purpose | A guideline document SHOULD include at least one `documentBlocks` block of type `purpose`. |
114
+ | SPEC-046 | warning | guideline-related-resolves | Every `related[].ref` SHOULD resolve to a known component or guideline `name` in the dataset. When `kind` is set, resolve only against that catalog. |
115
+
116
+ Both rules are `warning` severity and do not block validation. See `rules/rules.yaml` for full rule definitions.
117
+
118
+ ## References
119
+
120
+ * [Document blocks](document-blocks.md) — the `documentBlocks` block shape reused by guideline documents.
121
+ * [Dataset layout](dataset-layout.md) — normative directory structure including the registered `guidelines/` directory.
122
+ * [`guideline.schema.json`](../schemas/guideline.schema.json) — Layer 1 JSON Schema.
package/spec/index.md CHANGED
@@ -25,7 +25,8 @@ The specification defines:
25
25
  11. **Document blocks** — typed prose blocks attachable to tokens, components, and anatomy parts; makes design guidance machine-readable and agent-queryable ([Document blocks](document-blocks.md)).
26
26
  12. **Agent-readable surface** — operations and transport contracts (CLI, MCP server, Agent Skill) for AI agents consuming spec-conformant design data; covers session primer, token resolution, validation, query, and component description ([Agent-readable surface](agent-surface.md)).
27
27
  13. **Evolution** — deprecation lifecycle, migration windows, change classification, and legacy format contract ([Evolution](evolution.md)).
28
- 14. **Dataset layout** — normative directory structure of a dataset (`tokens/`, `components/`, `fields/`, `mode-sets/`, `registry/`), discovery algorithm, and optional root descriptor ([Dataset layout](dataset-layout.md)).
28
+ 14. **Dataset layout** — normative directory structure of a dataset (`tokens/`, `components/`, `fields/`, `mode-sets/`, `registry/`, `guidelines/`), discovery algorithm, and optional root descriptor ([Dataset layout](dataset-layout.md)).
29
+ 15. **Guideline documents** — standalone JSON files representing non-component design guidance pages (color, typography, motion, spacing, principles, etc.); each wraps page metadata and a `documentBlocks` body ([Guideline format](guideline-format.md)).
29
30
 
30
31
  ## Conformance
31
32
 
@@ -59,26 +60,27 @@ Full governance (compatibility tiers, migration, CLI `--spec-version`) is discus
59
60
 
60
61
  ## Normative references (sibling documents)
61
62
 
62
- | Document | Role |
63
- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
64
- | [Token format](token-format.md) | Token `name`, `value` / `$ref`, value types, lifecycle metadata. |
65
- | [Taxonomy](taxonomy.md) | Concept categories, vocabulary, formatting, anatomy vs objects. |
66
- | [Registry](registry.md) | Named value collections for vocabulary validation; three-registry boundary (anatomy, token objects, categories) and packaging. |
67
- | [Component format](component-format.md) | Component declaration: options, slots, anatomy (→ anatomy-format.md), states (→ state-model.md), lifecycle. |
68
- | [Anatomy format](anatomy-format.md) | Anatomy part declarations: field constraints, canonical vocabulary, SPEC-020/SPEC-023/SPEC-024/SPEC-025. |
69
- | [State model](state-model.md) | State declarations: trigger semantics, precedence algorithm, canonical vocabulary, SPEC-022/SPEC-026. |
70
- | [Cascade](cascade.md) | Layers, specificity, resolution algorithm. |
71
- | [Mode Sets](mode-sets.md) | Mode set declarations, built-in mode sets, coverage. |
72
- | [Manifest](manifest.md) | Platform manifest fields and validation expectations. |
73
- | [Product context](product-context.md) | Product-layer context document: rationale, overrides, and extensions. |
74
- | [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
75
- | [Query](query.md) | Filter notation for selecting tokens by structured fields. |
76
- | [Accessibility](accessibility.md) | Component accessibility vocabulary: role, intents, focusable, keyboardIntents, wcag, and state-level AT fields (SPEC-030/031). |
77
- | [Accessibility adapters](accessibility-adapters.md) | Informative platform adapter contracts mapping foundation accessibility vocabulary to Web/ARIA, iOS, Android, and voice surfaces. |
78
- | [Document blocks](document-blocks.md) | Typed prose blocks (purpose, guideline, accessibility, do-dont, examples) attachable to any entity. |
79
- | [Agent-readable surface](agent-surface.md) | Transport contracts (CLI, MCP, Agent Skill) and operation catalog for AI agents consuming spec-conformant design data. |
80
- | [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
81
- | [Dataset layout](dataset-layout.md) | Normative dataset directory structure, discovery algorithm, optional root descriptor, and SPEC-044 structural pre-check. |
63
+ | Document | Role |
64
+ | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
65
+ | [Token format](token-format.md) | Token `name`, `value` / `$ref`, value types, lifecycle metadata. |
66
+ | [Taxonomy](taxonomy.md) | Concept categories, vocabulary, formatting, anatomy vs objects. |
67
+ | [Registry](registry.md) | Named value collections for vocabulary validation; three-registry boundary (anatomy, token objects, categories) and packaging. |
68
+ | [Component format](component-format.md) | Component declaration: options, slots, anatomy (→ anatomy-format.md), states (→ state-model.md), lifecycle. |
69
+ | [Anatomy format](anatomy-format.md) | Anatomy part declarations: field constraints, canonical vocabulary, SPEC-020/SPEC-023/SPEC-024/SPEC-025. |
70
+ | [State model](state-model.md) | State declarations: trigger semantics, precedence algorithm, canonical vocabulary, SPEC-022/SPEC-026. |
71
+ | [Cascade](cascade.md) | Layers, specificity, resolution algorithm. |
72
+ | [Mode Sets](mode-sets.md) | Mode set declarations, built-in mode sets, coverage. |
73
+ | [Manifest](manifest.md) | Platform manifest fields and validation expectations. |
74
+ | [Product context](product-context.md) | Product-layer context document: rationale, overrides, and extensions. |
75
+ | [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
76
+ | [Query](query.md) | Filter notation for selecting tokens by structured fields. |
77
+ | [Accessibility](accessibility.md) | Component accessibility vocabulary: role, intents, focusable, keyboardIntents, wcag, and state-level AT fields (SPEC-030/031). |
78
+ | [Accessibility adapters](accessibility-adapters.md) | Informative platform adapter contracts mapping foundation accessibility vocabulary to Web/ARIA, iOS, Android, and voice surfaces. |
79
+ | [Document blocks](document-blocks.md) | Typed prose blocks (purpose, guideline, accessibility, do-dont, examples) attachable to any entity. |
80
+ | [Agent-readable surface](agent-surface.md) | Transport contracts (CLI, MCP, Agent Skill) and operation catalog for AI agents consuming spec-conformant design data. |
81
+ | [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
82
+ | [Dataset layout](dataset-layout.md) | Normative dataset directory structure, discovery algorithm, optional root descriptor, and SPEC-044 structural pre-check. |
83
+ | [Guideline format](guideline-format.md) | Standalone guideline document shape: metadata fields, `category` enum, `related` cross-references, and required `documentBlocks` body (SPEC-045/046). |
82
84
 
83
85
  ## JSON Schema `$id` and versioning
84
86