@adobe/design-data-spec 0.0.1 → 0.1.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.
Files changed (124) hide show
  1. package/conformance/README.md +82 -10
  2. package/conformance/diff/cross-format/expected.json +27 -0
  3. package/conformance/diff/cross-format/new/tokens.tokens.json +8 -0
  4. package/conformance/diff/cross-format/old/tokens.json +7 -0
  5. package/conformance/diff/deprecated-new-token/expected.json +13 -0
  6. package/conformance/diff/deprecated-new-token/new/tokens.tokens.json +8 -0
  7. package/conformance/diff/deprecated-new-token/old/tokens.tokens.json +1 -0
  8. package/conformance/diff/deprecated-set-level/expected.json +13 -0
  9. package/conformance/diff/deprecated-set-level/new/tokens.tokens.json +10 -0
  10. package/conformance/diff/deprecated-set-level/old/tokens.tokens.json +1 -0
  11. package/conformance/diff/identical-tokens/expected.json +8 -0
  12. package/conformance/diff/identical-tokens/new/tokens.tokens.json +12 -0
  13. package/conformance/diff/identical-tokens/old/tokens.tokens.json +12 -0
  14. package/conformance/diff/matched-gaining-deprecated/expected.json +20 -0
  15. package/conformance/diff/matched-gaining-deprecated/new/tokens.tokens.json +8 -0
  16. package/conformance/diff/matched-gaining-deprecated/old/tokens.tokens.json +7 -0
  17. package/conformance/diff/property-nested-change/expected.json +27 -0
  18. package/conformance/diff/property-nested-change/new/tokens.tokens.json +10 -0
  19. package/conformance/diff/property-nested-change/old/tokens.tokens.json +10 -0
  20. package/conformance/diff/property-value-update/expected.json +21 -0
  21. package/conformance/diff/property-value-update/new/tokens.tokens.json +7 -0
  22. package/conformance/diff/property-value-update/old/tokens.tokens.json +7 -0
  23. package/conformance/diff/rename-by-uuid/expected.json +22 -0
  24. package/conformance/diff/rename-by-uuid/new/tokens.tokens.json +7 -0
  25. package/conformance/diff/rename-by-uuid/old/tokens.tokens.json +7 -0
  26. package/conformance/diff/rename-with-property-changes/expected.json +28 -0
  27. package/conformance/diff/rename-with-property-changes/new/tokens.tokens.json +7 -0
  28. package/conformance/diff/rename-with-property-changes/old/tokens.tokens.json +7 -0
  29. package/conformance/diff/replaced-by-pairing/expected.json +43 -0
  30. package/conformance/diff/replaced-by-pairing/new/tokens.tokens.json +7 -0
  31. package/conformance/diff/replaced-by-pairing/old/tokens.tokens.json +10 -0
  32. package/conformance/diff/reverted-token/expected.json +13 -0
  33. package/conformance/diff/reverted-token/new/tokens.tokens.json +7 -0
  34. package/conformance/diff/reverted-token/old/tokens.tokens.json +8 -0
  35. package/conformance/diff/simple-add-delete/expected.json +18 -0
  36. package/conformance/diff/simple-add-delete/new/tokens.tokens.json +7 -0
  37. package/conformance/diff/simple-add-delete/old/tokens.tokens.json +7 -0
  38. package/conformance/diff/uuid-backfill/expected.json +20 -0
  39. package/conformance/diff/uuid-backfill/new/tokens.tokens.json +7 -0
  40. package/conformance/diff/uuid-backfill/old/tokens.tokens.json +6 -0
  41. package/conformance/invalid/SPEC-008/dimension.json +5 -0
  42. package/conformance/invalid/SPEC-008/expected-errors.json +10 -0
  43. package/conformance/invalid/SPEC-008/tokens.tokens.json +15 -0
  44. package/conformance/invalid/SPEC-010/expected-errors.json +10 -0
  45. package/conformance/invalid/SPEC-010/tokens.tokens.json +9 -0
  46. package/conformance/invalid/SPEC-011/expected-errors.json +10 -0
  47. package/conformance/invalid/SPEC-011/tokens.tokens.json +22 -0
  48. package/conformance/invalid/SPEC-012/expected-errors.json +10 -0
  49. package/conformance/invalid/SPEC-012/tokens.tokens.json +13 -0
  50. package/conformance/invalid/SPEC-013/expected-errors.json +10 -0
  51. package/conformance/invalid/SPEC-013/tokens.tokens.json +8 -0
  52. package/conformance/query/and-conditions/expected.json +1 -0
  53. package/conformance/query/and-conditions/input/tokens.tokens.json +17 -0
  54. package/conformance/query/and-conditions/query.txt +1 -0
  55. package/conformance/query/and-or-precedence/expected.json +1 -0
  56. package/conformance/query/and-or-precedence/input/tokens.tokens.json +22 -0
  57. package/conformance/query/and-or-precedence/query.txt +1 -0
  58. package/conformance/query/empty-matches-all/expected.json +1 -0
  59. package/conformance/query/empty-matches-all/input/tokens.tokens.json +17 -0
  60. package/conformance/query/empty-matches-all/query.txt +1 -0
  61. package/conformance/query/negation/expected.json +1 -0
  62. package/conformance/query/negation/input/tokens.tokens.json +17 -0
  63. package/conformance/query/negation/query.txt +1 -0
  64. package/conformance/query/no-matches/expected.json +1 -0
  65. package/conformance/query/no-matches/input/tokens.tokens.json +7 -0
  66. package/conformance/query/no-matches/query.txt +1 -0
  67. package/conformance/query/or-conditions/expected.json +1 -0
  68. package/conformance/query/or-conditions/input/tokens.tokens.json +17 -0
  69. package/conformance/query/or-conditions/query.txt +1 -0
  70. package/conformance/query/schema-key/expected.json +1 -0
  71. package/conformance/query/schema-key/input/tokens.tokens.json +14 -0
  72. package/conformance/query/schema-key/query.txt +1 -0
  73. package/conformance/query/single-field/expected.json +1 -0
  74. package/conformance/query/single-field/input/tokens.tokens.json +17 -0
  75. package/conformance/query/single-field/query.txt +1 -0
  76. package/conformance/query/wildcard-prefix/expected.json +1 -0
  77. package/conformance/query/wildcard-prefix/input/tokens.tokens.json +17 -0
  78. package/conformance/query/wildcard-prefix/query.txt +1 -0
  79. package/conformance/query/wildcard-suffix/expected.json +1 -0
  80. package/conformance/query/wildcard-suffix/input/tokens.tokens.json +17 -0
  81. package/conformance/query/wildcard-suffix/query.txt +1 -0
  82. package/conformance/resolution/alias-resolved-after-cascade/dimensions/color-scheme.json +5 -0
  83. package/conformance/resolution/alias-resolved-after-cascade/expected.json +5 -0
  84. package/conformance/resolution/alias-resolved-after-cascade/input/tokens.tokens.json +12 -0
  85. package/conformance/resolution/alias-resolved-after-cascade/query.json +4 -0
  86. package/conformance/resolution/base-fallback/dimensions/color-scheme.json +5 -0
  87. package/conformance/resolution/base-fallback/expected.json +5 -0
  88. package/conformance/resolution/base-fallback/input/tokens.tokens.json +7 -0
  89. package/conformance/resolution/base-fallback/query.json +4 -0
  90. package/conformance/resolution/specificity-wins/dimensions/color-scheme.json +5 -0
  91. package/conformance/resolution/specificity-wins/expected.json +5 -0
  92. package/conformance/resolution/specificity-wins/input/tokens.tokens.json +12 -0
  93. package/conformance/resolution/specificity-wins/query.json +4 -0
  94. package/fields/anatomy.json +15 -0
  95. package/fields/color-scheme.json +15 -0
  96. package/fields/component.json +15 -0
  97. package/fields/contrast.json +15 -0
  98. package/fields/density.json +15 -0
  99. package/fields/object.json +15 -0
  100. package/fields/orientation.json +15 -0
  101. package/fields/position.json +15 -0
  102. package/fields/property.json +15 -0
  103. package/fields/scale.json +15 -0
  104. package/fields/shape.json +15 -0
  105. package/fields/size.json +15 -0
  106. package/fields/state.json +15 -0
  107. package/fields/structure.json +15 -0
  108. package/fields/substructure.json +15 -0
  109. package/fields/variant.json +15 -0
  110. package/package.json +3 -1
  111. package/rules/rules.yaml +56 -2
  112. package/schemas/cascade-file.schema.json +10 -0
  113. package/schemas/field.schema.json +85 -0
  114. package/schemas/manifest.schema.json +55 -1
  115. package/schemas/token.schema.json +89 -18
  116. package/spec/cascade.md +18 -2
  117. package/spec/diff.md +97 -0
  118. package/spec/dimensions.md +15 -6
  119. package/spec/evolution.md +98 -0
  120. package/spec/index.md +11 -8
  121. package/spec/manifest.md +15 -0
  122. package/spec/query.md +135 -0
  123. package/spec/taxonomy.md +173 -0
  124. package/spec/token-format.md +114 -19
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "scale",
5
+ "description": "Platform density scale dimension (e.g. desktop, mobile). Drives cascade resolution.",
6
+ "kind": "dimension",
7
+ "registry": null,
8
+ "validation": "strict",
9
+ "serialization": {
10
+ "position": 14
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "shape",
5
+ "description": "Overall component shape qualifier (e.g. uniform, rounded).",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/shapes.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 11
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "size",
5
+ "description": "Relative t-shirt sizing of a component or token (e.g. small, medium, large, extra-large). Distinct from dimension scale.",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/sizes.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 9
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "state",
5
+ "description": "Interactive or semantic state (e.g. hover, focus, disabled, selected). Compound states use hyphenation (e.g. selected-hover).",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/states.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 12
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "structure",
5
+ "description": "Reusable visual pattern that occurs across many components (e.g. drop-shadow, overlay). Distinct from component.",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/structures.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 2
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "substructure",
5
+ "description": "Child element within a parent structure (e.g. item within list-item, cell within table).",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/substructures.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 3
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
3
+ "specVersion": "1.0.0-draft",
4
+ "name": "variant",
5
+ "description": "Primary color or semantic variant (e.g. accent, negative, informative, neutral). Not for visual style treatment — see style field for that.",
6
+ "kind": "semantic",
7
+ "registry": "packages/design-system-registry/registry/variants.json",
8
+ "validation": "advisory",
9
+ "serialization": {
10
+ "position": 0
11
+ },
12
+ "scope": null,
13
+ "required": false,
14
+ "valueType": "string"
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-spec",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for Spectrum design data",
5
5
  "type": "module",
6
6
  "repository": {
@@ -23,6 +23,7 @@
23
23
  "./package.json": "./package.json",
24
24
  "./schemas/token.schema.json": "./schemas/token.schema.json",
25
25
  "./schemas/dimension.schema.json": "./schemas/dimension.schema.json",
26
+ "./schemas/field.schema.json": "./schemas/field.schema.json",
26
27
  "./schemas/manifest.schema.json": "./schemas/manifest.schema.json",
27
28
  "./schemas/value-types/color.schema.json": "./schemas/value-types/color.schema.json",
28
29
  "./rules/rules.yaml": "./rules/rules.yaml"
@@ -30,6 +31,7 @@
30
31
  "files": [
31
32
  "spec",
32
33
  "schemas",
34
+ "fields",
33
35
  "rules",
34
36
  "conformance",
35
37
  "README.md"
package/rules/rules.yaml CHANGED
@@ -51,8 +51,8 @@ rules:
51
51
  name: specificity-correctness
52
52
  severity: warning
53
53
  category: type-safety
54
- assert: When two tokens from the same layer match a context, the more specific name object MUST win; ties MUST be reported.
55
- message: "Ambiguous cascade resolution (specificity tie) for context {context}"
54
+ assert: When two tokens from the same layer match a context with equal specificity, the tie MUST be broken by document order (earlier in file wins; lexicographically earlier file path wins across files). Ties MUST be reported as warnings.
55
+ message: "Ambiguous cascade resolution (specificity tie) between {token_a} and {token_b} for context {context}; resolved by document order"
56
56
  spec_ref: spec/cascade.md#semantic-specificity
57
57
  introduced_in: "1.0.0-draft"
58
58
 
@@ -64,3 +64,57 @@ rules:
64
64
  message: "Token '{token}' does not roundtrip through name-object generation rules"
65
65
  spec_ref: spec/token-format.md#name-object
66
66
  introduced_in: "1.0.0-draft"
67
+
68
+ - id: SPEC-008
69
+ name: cascade-completeness
70
+ severity: warning
71
+ category: completeness
72
+ assert: For every cascade token that has a non-default mode variant, a base/default variant (name object with no dimension fields for that dimension, or explicitly the default mode value) MUST also exist in the dataset. Ensures all consumers can resolve without a fallback gap.
73
+ message: "Token property '{property}' has mode variant '{mode}' but no base/default variant"
74
+ spec_ref: spec/cascade.md#coverage
75
+ introduced_in: "1.0.0-draft"
76
+
77
+ - id: SPEC-009
78
+ name: name-field-enum-sync
79
+ severity: warning
80
+ category: naming-consistency
81
+ assert: Recognized name object fields (component, state, variant, etc.) SHOULD use values drawn from the corresponding design-system-registry enums when those enums are available.
82
+ message: "Token name field '{field}' value '{value}' is not in the design-system-registry enum for '{field}'"
83
+ spec_ref: spec/token-format.md#name-object
84
+ introduced_in: "1.0.0-draft"
85
+
86
+ - id: SPEC-010
87
+ name: replaced-by-target-exists
88
+ severity: error
89
+ category: reference-integrity
90
+ assert: Every UUID in replaced_by MUST resolve to an existing token in the dataset.
91
+ message: "replaced_by target UUID not found: {uuid}"
92
+ spec_ref: spec/token-format.md#lifecycle-and-metadata
93
+ introduced_in: "1.0.0-draft"
94
+
95
+ - id: SPEC-011
96
+ name: replaced-by-array-requires-comment
97
+ severity: error
98
+ category: completeness
99
+ assert: When replaced_by is an array, deprecated_comment MUST be present to explain which replacement applies in which context.
100
+ message: "replaced_by is an array but deprecated_comment is missing on token {token}"
101
+ spec_ref: spec/token-format.md#lifecycle-and-metadata
102
+ introduced_in: "1.0.0-draft"
103
+
104
+ - id: SPEC-012
105
+ name: replaced-by-requires-deprecated
106
+ severity: error
107
+ category: completeness
108
+ assert: If replaced_by is present, deprecated MUST also be present.
109
+ message: "Token {token} has replaced_by but is not marked deprecated"
110
+ spec_ref: spec/token-format.md#lifecycle-and-metadata
111
+ introduced_in: "1.0.0-draft"
112
+
113
+ - id: SPEC-013
114
+ name: planned-removal-requires-deprecated
115
+ severity: error
116
+ category: completeness
117
+ assert: If plannedRemoval is present, deprecated MUST also be present.
118
+ message: "Token {token} has plannedRemoval but is not marked deprecated"
119
+ spec_ref: spec/token-format.md#lifecycle-and-metadata
120
+ introduced_in: "1.0.0-draft"
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/cascade-file.schema.json",
4
+ "title": "Cascade token file",
5
+ "description": "Layer 1 — document envelope for cascade-format tokens. A cascade file is an ordered array of token objects; document order determines tie-breaking during cascade resolution.",
6
+ "type": "array",
7
+ "items": {
8
+ "$ref": "token.schema.json"
9
+ }
10
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
4
+ "title": "Name-object field declaration",
5
+ "description": "Declares a single field on the token name object — its kind, vocabulary source, validation severity, and serialization position. Design systems provide a catalog of these declarations to make the name object schema configurable rather than hardcoded.",
6
+ "type": "object",
7
+ "required": ["name", "kind", "validation", "serialization"],
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string"
11
+ },
12
+ "specVersion": {
13
+ "const": "1.0.0-draft"
14
+ },
15
+ "name": {
16
+ "type": "string",
17
+ "minLength": 1,
18
+ "description": "Field key on the name object (e.g. 'property', 'component', 'scaleIndex')."
19
+ },
20
+ "description": {
21
+ "type": "string",
22
+ "description": "Human-readable description of the field's purpose."
23
+ },
24
+ "kind": {
25
+ "type": "string",
26
+ "enum": ["semantic", "dimension"],
27
+ "description": "Whether this field participates in cascade resolution. 'dimension' fields drive cascade specificity; 'semantic' fields describe identity only."
28
+ },
29
+ "registry": {
30
+ "oneOf": [
31
+ {
32
+ "type": "string",
33
+ "minLength": 1,
34
+ "description": "Path to the registry file containing valid values for this field (relative to the design system root)."
35
+ },
36
+ {
37
+ "type": "null",
38
+ "description": "No registry — field accepts free-form values."
39
+ }
40
+ ]
41
+ },
42
+ "validation": {
43
+ "type": "string",
44
+ "enum": ["strict", "advisory", "none"],
45
+ "description": "Validation severity when a value is not found in the registry. 'strict' = error, 'advisory' = warning, 'none' = no check."
46
+ },
47
+ "serialization": {
48
+ "type": "object",
49
+ "required": ["position"],
50
+ "properties": {
51
+ "position": {
52
+ "type": "integer",
53
+ "minimum": 0,
54
+ "description": "Default position in the serialized name string (0-based). Used when the platform manifest does not specify a custom conceptOrder."
55
+ }
56
+ },
57
+ "additionalProperties": false
58
+ },
59
+ "scope": {
60
+ "oneOf": [
61
+ {
62
+ "type": "string",
63
+ "minLength": 1,
64
+ "description": "Restrict this field to a specific token type scope (e.g. 'typography', 'color'). Null = universal."
65
+ },
66
+ {
67
+ "type": "null",
68
+ "description": "Field applies to all token types."
69
+ }
70
+ ]
71
+ },
72
+ "required": {
73
+ "type": "boolean",
74
+ "description": "Whether this field must be present on every name object. Default: false.",
75
+ "default": false
76
+ },
77
+ "valueType": {
78
+ "type": "string",
79
+ "enum": ["string", "integer"],
80
+ "description": "Type of the field value. Default: 'string'.",
81
+ "default": "string"
82
+ }
83
+ },
84
+ "additionalProperties": false
85
+ }
@@ -64,7 +64,61 @@
64
64
  },
65
65
  "extensions": {
66
66
  "type": "object",
67
- "description": "Platform-local tokens or dimensions; structure validated by separate documents.",
67
+ "description": "Platform-local tokens, dimensions, and formatting rules.",
68
+ "properties": {
69
+ "formatting": {
70
+ "type": "object",
71
+ "description": "Rules for serializing structured name objects into platform-specific token name strings.",
72
+ "properties": {
73
+ "conceptOrder": {
74
+ "type": "array",
75
+ "items": {
76
+ "type": "string",
77
+ "enum": [
78
+ "variant",
79
+ "component",
80
+ "structure",
81
+ "substructure",
82
+ "anatomy",
83
+ "object",
84
+ "property",
85
+ "orientation",
86
+ "position",
87
+ "size",
88
+ "density",
89
+ "shape",
90
+ "state"
91
+ ]
92
+ },
93
+ "uniqueItems": true,
94
+ "description": "Ordered list of field names for serialization. Values must match declared field names from the design system's field catalog (field.schema.json declarations). Replaces the default serialization.position order from each field declaration."
95
+ },
96
+ "casing": {
97
+ "type": "string",
98
+ "enum": [
99
+ "kebab-case",
100
+ "camelCase",
101
+ "PascalCase",
102
+ "SCREAMING_SNAKE_CASE"
103
+ ],
104
+ "description": "Casing style for serialized token names. Default: kebab-case."
105
+ },
106
+ "delimiter": {
107
+ "type": "string",
108
+ "minLength": 1,
109
+ "description": "Character(s) separating concepts in the serialized string. Default: -."
110
+ },
111
+ "abbreviations": {
112
+ "type": "object",
113
+ "additionalProperties": {
114
+ "type": "string"
115
+ },
116
+ "description": "Map of full term to abbreviated form, applied after ordering and before casing."
117
+ }
118
+ },
119
+ "additionalProperties": false
120
+ }
121
+ },
68
122
  "additionalProperties": true
69
123
  }
70
124
  },
@@ -15,30 +15,73 @@
15
15
  "$defs": {
16
16
  "nameObject": {
17
17
  "type": "object",
18
- "description": "Structured token identity; additional dimension keys MUST be strings.",
18
+ "description": "Structured token identity. Semantic fields describe identity and structure; dimension fields drive cascade resolution. See spec/taxonomy.md and spec/token-format.md. Additional dimension keys MUST be strings.",
19
19
  "required": ["property"],
20
20
  "properties": {
21
21
  "property": {
22
22
  "type": "string",
23
- "minLength": 1
23
+ "minLength": 1,
24
+ "description": "Semantic: the stylistic attribute being defined (e.g. color, width, padding, gap)."
24
25
  },
25
26
  "component": {
26
- "type": "string"
27
+ "type": "string",
28
+ "description": "Semantic: component scope (e.g. button, checkbox)."
29
+ },
30
+ "structure": {
31
+ "type": "string",
32
+ "description": "Semantic: reusable visual pattern (e.g. base, container, list). Distinct from component."
33
+ },
34
+ "substructure": {
35
+ "type": "string",
36
+ "description": "Semantic: child within a parent structure (e.g. item in list-item)."
37
+ },
38
+ "anatomy": {
39
+ "type": "string",
40
+ "description": "Semantic: visible named part of a component (e.g. handle, icon, label)."
41
+ },
42
+ "object": {
43
+ "type": "string",
44
+ "description": "Semantic: styling surface (e.g. background, border, edge, visual)."
27
45
  },
28
46
  "variant": {
29
- "type": "string"
47
+ "type": "string",
48
+ "description": "Semantic: variant within a component (e.g. accent, negative, primary)."
30
49
  },
31
50
  "state": {
32
- "type": "string"
51
+ "type": "string",
52
+ "description": "Semantic: interactive or semantic state (e.g. hover, focus, disabled)."
53
+ },
54
+ "orientation": {
55
+ "type": "string",
56
+ "description": "Semantic: direction or order (e.g. vertical, horizontal)."
57
+ },
58
+ "position": {
59
+ "type": "string",
60
+ "description": "Semantic: location relative to another object (e.g. affixed, top, bottom)."
61
+ },
62
+ "size": {
63
+ "type": "string",
64
+ "description": "Semantic: relative t-shirt sizing (e.g. small, medium, large). Distinct from dimension scale."
65
+ },
66
+ "density": {
67
+ "type": "string",
68
+ "description": "Semantic: space within or around component parts (e.g. spacious, compact)."
69
+ },
70
+ "shape": {
71
+ "type": "string",
72
+ "description": "Semantic: overall component shape (e.g. uniform)."
33
73
  },
34
74
  "colorScheme": {
35
- "type": "string"
75
+ "type": "string",
76
+ "description": "Dimension: color scheme mode (e.g. light, dark, wireframe)."
36
77
  },
37
78
  "scale": {
38
- "type": "string"
79
+ "type": "string",
80
+ "description": "Dimension: platform density scale (e.g. desktop, mobile)."
39
81
  },
40
82
  "contrast": {
41
- "type": "string"
83
+ "type": "string",
84
+ "description": "Dimension: contrast level (e.g. regular, high)."
42
85
  }
43
86
  },
44
87
  "additionalProperties": {
@@ -89,19 +132,33 @@
89
132
  "type": "string"
90
133
  },
91
134
  "deprecated": {
92
- "type": "boolean"
135
+ "type": "string",
136
+ "description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
93
137
  },
94
138
  "deprecated_comment": {
95
139
  "type": "string"
96
140
  },
97
- "status": {
98
- "type": "string"
141
+ "replaced_by": {
142
+ "oneOf": [
143
+ { "type": "string", "format": "uuid" },
144
+ {
145
+ "type": "array",
146
+ "items": { "type": "string", "format": "uuid" },
147
+ "minItems": 1
148
+ }
149
+ ],
150
+ "description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
99
151
  },
100
- "renamed": {
101
- "type": "string"
152
+ "plannedRemoval": {
153
+ "type": "string",
154
+ "description": "Spec version when token will be removed."
102
155
  },
103
156
  "private": {
104
157
  "type": "boolean"
158
+ },
159
+ "description": {
160
+ "type": "string",
161
+ "description": "Plain text describing the token's purpose (aligns with DTCG $description)."
105
162
  }
106
163
  },
107
164
  "additionalProperties": false
@@ -132,19 +189,33 @@
132
189
  "type": "string"
133
190
  },
134
191
  "deprecated": {
135
- "type": "boolean"
192
+ "type": "string",
193
+ "description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
136
194
  },
137
195
  "deprecated_comment": {
138
196
  "type": "string"
139
197
  },
140
- "status": {
141
- "type": "string"
198
+ "replaced_by": {
199
+ "oneOf": [
200
+ { "type": "string", "format": "uuid" },
201
+ {
202
+ "type": "array",
203
+ "items": { "type": "string", "format": "uuid" },
204
+ "minItems": 1
205
+ }
206
+ ],
207
+ "description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
142
208
  },
143
- "renamed": {
144
- "type": "string"
209
+ "plannedRemoval": {
210
+ "type": "string",
211
+ "description": "Spec version when token will be removed."
145
212
  },
146
213
  "private": {
147
214
  "type": "boolean"
215
+ },
216
+ "description": {
217
+ "type": "string",
218
+ "description": "Plain text describing the token's purpose (aligns with DTCG $description)."
148
219
  }
149
220
  },
150
221
  "additionalProperties": false
package/spec/cascade.md CHANGED
@@ -26,7 +26,12 @@ Design data is organized in three layers, ordered from lowest to highest precede
26
26
 
27
27
  **NORMATIVE:** When two candidates from the **same layer** match the context, the candidate with **higher** specificity **MUST** win.
28
28
 
29
- **NORMATIVE:** Ties on layer and specificity **MUST** be broken by a deterministic **document order** rule defined by the manifest or dataset index (implementation-defined in this draft; validators **SHOULD** emit a warning on ambiguous ties).
29
+ **NORMATIVE:** Ties on layer and specificity **MUST** be broken by **document order**:
30
+
31
+ 1. Within a single source file, the token that appears **earlier** in the array **MUST** win.
32
+ 2. Across multiple files, the file with the **lexicographically earlier path** within the dataset **MUST** win.
33
+
34
+ **NORMATIVE:** Validators **MUST** emit a SPEC-006 warning when a tie is detected, as ties indicate potential authoring mistakes.
30
35
 
31
36
  ## Context
32
37
 
@@ -40,10 +45,19 @@ The following outline is **RECOMMENDED** for conforming resolvers:
40
45
  2. Filter to candidates at or below the requested layer.
41
46
  3. Select the maximum **layer** precedence.
42
47
  4. Within that layer, select the maximum **specificity**.
43
- 5. Break remaining ties by deterministic ordering.
48
+ 5. Break remaining ties by document order (earlier in file wins; lexicographically earlier file path wins across files). Emit SPEC-006 warning.
49
+ 6. If the winning candidate is an alias (`$ref`), **resolve the alias chain** to a literal value (see [Alias resolution](#alias-resolution)).
44
50
 
45
51
  Exact matching rules for omitted dimensions are defined alongside dimension declarations in [Dimensions](dimensions.md).
46
52
 
53
+ ## Alias resolution
54
+
55
+ **NORMATIVE:** Alias (`$ref`) resolution **MUST** occur **after** cascade selection. The resolution algorithm selects the winning candidate using layer, specificity, and tie-breaking rules before any alias chain is followed.
56
+
57
+ **NORMATIVE:** If the winning candidate is an alias, its `$ref` chain **MUST** be resolved to a literal value using the standard alias-resolution rules (SPEC-001 through SPEC-003 in `rules/rules.yaml`). The alias target is resolved within the same dataset (i.e. the same merged layer stack), not relative to any single layer.
58
+
59
+ **RATIONALE:** Aliases participate in cascade as opaque references — their target values are not examined during specificity calculation or layer comparison. This keeps resolution deterministic and allows aliases to be valid candidates at any specificity level.
60
+
47
61
  ## Cross-dimensional overrides
48
62
 
49
63
  **NORMATIVE:** Overrides that combine multiple dimensions in a way not expressible by a single name object alone **MUST** use **explicit combination tokens** (tokens whose name object sets multiple non-default dimensions) as defined in the dataset; magic merging of unrelated tokens is **NOT** allowed.
@@ -52,3 +66,5 @@ Exact matching rules for omitted dimensions are defined alongside dimension decl
52
66
 
53
67
  * [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
54
68
  * [#714 — Design Data Specification](https://github.com/adobe/spectrum-design-data/discussions/714)
69
+ * [#757 — Phase 2: Cascade tie-breaking rule](https://github.com/adobe/spectrum-design-data/issues/757)
70
+ * [#758 — Phase 2: Alias resolution ordering in cascade context](https://github.com/adobe/spectrum-design-data/issues/758)