@adobe/design-data-spec 2.0.0 → 2.2.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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": [
4
+ {
5
+ "rule_id": "SPEC-044",
6
+ "severity": "warning",
7
+ "message_pattern": ".*components/.*contains no.*json.*"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": [
4
+ {
5
+ "rule_id": "SPEC-044",
6
+ "severity": "error",
7
+ "message_pattern": ".*tokens/.*not found.*"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$id": "https://opensource.adobe.com/spectrum-design-data/conformance/valid/SPEC-044/button.json",
3
+ "name": "button",
4
+ "displayName": "Button",
5
+ "meta": {
6
+ "category": "actions",
7
+ "documentationUrl": "https://spectrum.adobe.com/page/button/"
8
+ }
9
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": []
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-spec",
3
- "version": "2.0.0",
3
+ "version": "2.2.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": {
@@ -30,7 +30,8 @@
30
30
  "./schemas/state-declaration.schema.json": "./schemas/state-declaration.schema.json",
31
31
  "./rules/rules.yaml": "./rules/rules.yaml",
32
32
  "./schemas/registry-value.json": "./schemas/registry-value.json",
33
- "./schemas/platform-extension.json": "./schemas/platform-extension.json"
33
+ "./schemas/platform-extension.json": "./schemas/platform-extension.json",
34
+ "./schemas/dataset.schema.json": "./schemas/dataset.schema.json"
34
35
  },
35
36
  "files": [
36
37
  "conformance",
package/rules/rules.yaml CHANGED
@@ -477,3 +477,22 @@ rules:
477
477
  message: "{domain} token has a name object but no domain-identifying field — add at least one of: {required_fields}"
478
478
  spec_ref: spec/taxonomy.md#token-type-taxonomies
479
479
  introduced_in: "1.0.0-draft"
480
+
481
+ - id: SPEC-044
482
+ name: dataset-structure
483
+ severity: error
484
+ layer: 2
485
+ category: structure
486
+ assert: >
487
+ A conformant dataset MUST contain a `tokens/` directory holding at least one
488
+ `*.tokens.json` file. This structural pre-check fires before token- and
489
+ component-level rules so that downstream rules can assume the dataset structure
490
+ is present, and an incomplete dataset produces a clear "structure is incomplete"
491
+ diagnostic rather than a cascade of confusing per-file errors. A registered
492
+ optional directory (`components/`, `fields/`, `mode-sets/`, `registry/`) that is
493
+ present SHOULD contain at least one conformant `*.json` file; an empty registered
494
+ directory is reported as a warning. Because this rule inspects the on-disk
495
+ directory layout it runs as a filesystem pre-pass, not against the in-memory graph.
496
+ message: "Dataset structure incomplete: {detail}"
497
+ spec_ref: spec/dataset-layout.md#structural-validation
498
+ introduced_in: "1.0.0-draft"
@@ -0,0 +1,39 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/dataset.schema.json",
4
+ "title": "Dataset root descriptor",
5
+ "description": "Optional root descriptor (dataset.json) a design-data dataset MAY carry to declare which optional directories are present, pin the targeted spec version, and override default discovery paths. Absence of this file is not an error; see spec/dataset-layout.md.",
6
+ "type": "object",
7
+ "properties": {
8
+ "specVersion": {
9
+ "type": "string",
10
+ "minLength": 1,
11
+ "description": "The spec version this dataset targets (e.g. \"1.0.0-draft\")."
12
+ },
13
+ "directories": {
14
+ "type": "object",
15
+ "description": "Declares which registered directories the dataset provides. List a directory key with the value true to declare it present and authoritative; omit the key otherwise. The value is constrained to true so the flag cannot be used to negate a directory's presence (in particular it cannot waive the required tokens/ directory).",
16
+ "properties": {
17
+ "tokens": { "const": true },
18
+ "components": { "const": true },
19
+ "fields": { "const": true },
20
+ "modeSets": { "const": true },
21
+ "registry": { "const": true }
22
+ },
23
+ "additionalProperties": false
24
+ },
25
+ "paths": {
26
+ "type": "object",
27
+ "description": "Optional overrides for the default discovery paths, relative to the dataset root. When omitted, tooling uses the conventional directory names defined in spec/dataset-layout.md.",
28
+ "properties": {
29
+ "tokens": { "type": "string", "minLength": 1 },
30
+ "components": { "type": "string", "minLength": 1 },
31
+ "fields": { "type": "string", "minLength": 1 },
32
+ "modeSets": { "type": "string", "minLength": 1 },
33
+ "registry": { "type": "string", "minLength": 1 }
34
+ },
35
+ "additionalProperties": false
36
+ }
37
+ },
38
+ "additionalProperties": false
39
+ }
@@ -6,6 +6,10 @@
6
6
  "type": "object",
7
7
  "required": ["name", "modes", "default"],
8
8
  "properties": {
9
+ "$schema": {
10
+ "type": "string",
11
+ "format": "uri"
12
+ },
9
13
  "specVersion": {
10
14
  "const": "1.0.0-draft"
11
15
  },
@@ -0,0 +1,72 @@
1
+ # Dataset layout
2
+
3
+ **Spec version:** `1.0.0-draft` (see [Overview](index.md))
4
+
5
+ This document defines the normative **directory layout** of a conformant design-data **dataset**: which directories are required, which are optional but registered, how files in each directory are named and validated, how tooling **discovers** a dataset on disk, and the optional root **descriptor** a dataset MAY carry.
6
+
7
+ A **dataset** is a directory tree that holds design tokens and the optional catalogs (components, fields, mode sets, registry vocabulary) that describe them. The Spectrum foundation dataset lives at `packages/design-data/`, but any design system MAY publish a dataset in this layout.
8
+
9
+ ## Directory layout
10
+
11
+ A dataset is rooted at a single **dataset root** directory. The following table defines the directories tooling recognizes:
12
+
13
+ | Directory | Status | Contents | Schema |
14
+ | ------------- | --------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------- |
15
+ | `tokens/` | **Required** | Cascade-format token files, named `*.tokens.json`. | [`cascade-file.schema.json`](../schemas/cascade-file.schema.json) |
16
+ | `components/` | Optional (registered) | One component declaration per `*.json` file. | [`component.schema.json`](../schemas/component.schema.json) |
17
+ | `fields/` | Optional (registered) | Name-object field declarations, one or more `*.json` files. | [`field.schema.json`](../schemas/field.schema.json) |
18
+ | `mode-sets/` | Optional (registered) | Mode set declarations, one per `*.json` file. | [`mode-set.schema.json`](../schemas/mode-set.schema.json) |
19
+ | `registry/` | Optional (registered) | Registry value collections (vocabulary), one or more `*.json` files. | [`registry-value.json`](../schemas/registry-value.json) |
20
+
21
+ **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
+ **NORMATIVE:** When a **registered** directory name (`components/`, `fields/`, `mode-sets/`, `registry/`) is present, the files it contains **MUST** validate against the schema named above. Tooling validating a dataset **MUST** validate the files in every registered directory that is present.
24
+
25
+ **RECOMMENDED:** A registered directory that exists **SHOULD** contain at least one conformant `*.json` file. An empty registered directory is permitted but **SHOULD** produce a warning, since it usually indicates incomplete data rather than intent.
26
+
27
+ **NORMATIVE:** Directory names not listed above carry no special meaning and are ignored by dataset-layout validation. Tooling **MUST NOT** treat an unrecognized sibling directory as an error.
28
+
29
+ ### File-naming patterns
30
+
31
+ | Directory | Pattern | Notes |
32
+ | ------------- | ------------------ | ------------------------------------------------------------------------------ |
33
+ | `tokens/` | `**/*.tokens.json` | May be nested in subdirectories; only `*.tokens.json` files are token sources. |
34
+ | `components/` | `*.json` | One declaration per file. |
35
+ | `fields/` | `*.json` | The catalog MAY be split across multiple files. |
36
+ | `mode-sets/` | `*.json` | One declaration per file. |
37
+ | `registry/` | `*.json` | One value collection per file. |
38
+
39
+ ## Dataset discovery
40
+
41
+ Tooling that operates on "the current dataset" (rather than an explicit path) **MUST** resolve the dataset root using the following precedence. The first match wins; later tiers are only consulted when an earlier tier does not resolve a value.
42
+
43
+ 1. **Explicit override** — a path passed directly by the caller (CLI positional argument or `--*-path` flag, environment variable). Explicit overrides always win.
44
+ 2. **Config file** — a `.design-data.toml` discovered by walking **up** the ancestor chain from the working directory. A `[source]` block of `type = "path"` names the dataset root (resolved relative to the config file's directory). This is the explicit, portable way to point a project at a dataset outside its own tree.
45
+ 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
+ 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
+
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.
49
+
50
+ 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
+
52
+ ## Root descriptor
53
+
54
+ A dataset **MAY** carry a root **descriptor** to make its structure and target spec version explicit. Two forms are recognized:
55
+
56
+ * **`.design-data.toml`** — a project-level config (TOML) that primarily declares where the dataset lives (`[source]`) and cache overrides. It is consumed during [discovery](#dataset-discovery) tier 2.
57
+ * **`dataset.json`** — an OPTIONAL JSON descriptor placed at the dataset root that **MAY** declare which optional directories are present, pin the spec version the dataset targets, and override default discovery paths. It **MUST** conform to [`dataset.schema.json`](../schemas/dataset.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/dataset.schema.json`).
58
+
59
+ **NORMATIVE:** Neither descriptor is required. A dataset with a conformant `tokens/` directory and no descriptor is fully conformant. When a `dataset.json` is present it **MUST** validate against `dataset.schema.json`, but its absence **MUST NOT** be treated as an error.
60
+
61
+ ## Structural validation
62
+
63
+ **NORMATIVE:** Validators implementing rule **`SPEC-044`** (`dataset-structure`) **MUST** report an **error** when a dataset path lacks a `tokens/` directory containing at least one `*.tokens.json` file. The check **MUST** fire **before** token- and component-level rules so that downstream rules can assume the dataset structure is present, and so that an incomplete dataset produces a clear "dataset structure is incomplete" diagnostic rather than a cascade of confusing per-file errors.
64
+
65
+ **RECOMMENDED:** Validators implementing `SPEC-044` **SHOULD** emit a **warning** when a registered optional directory is present but contains no conformant `*.json` file. See `rules/rules.yaml` for the full rule definition.
66
+
67
+ ## References
68
+
69
+ * [#1114 — Define normative dataset-directory layout and add SPEC-044 structural pre-check](https://github.com/adobe/spectrum-design-data/issues/1114)
70
+ * [#1113 — Consolidate Spectrum design data into a single package](https://github.com/adobe/spectrum-design-data/pull/1113)
71
+ * [#714 — Design Data Specification (umbrella)](https://github.com/adobe/spectrum-design-data/discussions/714)
72
+ * [#715 — Distributed Design Data Architecture](https://github.com/adobe/spectrum-design-data/discussions/715)
package/spec/index.md CHANGED
@@ -25,6 +25,7 @@ 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
29
 
29
30
  ## Conformance
30
31
 
@@ -77,6 +78,7 @@ Full governance (compatibility tiers, migration, CLI `--spec-version`) is discus
77
78
  | [Document blocks](document-blocks.md) | Typed prose blocks (purpose, guideline, accessibility, do-dont, examples) attachable to any entity. |
78
79
  | [Agent-readable surface](agent-surface.md) | Transport contracts (CLI, MCP, Agent Skill) and operation catalog for AI agents consuming spec-conformant design data. |
79
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. |
80
82
 
81
83
  ## JSON Schema `$id` and versioning
82
84
 
package/spec/taxonomy.md CHANGED
@@ -104,15 +104,16 @@ Example: `colorFamily=blue` + `scaleIndex=100` → `blue-100`.
104
104
 
105
105
  Typography tokens describe typeface attributes: family, weight, style, and numeric scale. Their name objects use `scope: "typography"` fields alongside the universal `property` field.
106
106
 
107
- **NORMATIVE:** Typography tokens SHOULD include at least one of `family`, `weight`, or `style`. Tokens missing all three are flagged by rule SPEC-043 (`domain-required-fields`, warning).
108
-
109
- | Category | Name object field | Answers | Description |
110
- | --------- | ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
111
- | Family | `family` | What? | Type family of the token (e.g. `sans-serif`, `serif`, `cjk`, `code`). Values come from [`typography-families.json`](../../packages/design-data/registry/typography-families.json). |
112
- | Weight | `weight` | How? | Typographic weight (e.g. `regular`, `bold`, `light`, `black`). Values come from [`typography-weights.json`](../../packages/design-data/registry/typography-weights.json). |
113
- | Style | `style` | How? | Typographic style (e.g. `italic`, `oblique`, `normal`). Include `normal` when the token explicitly declares a normal style (e.g. a reset). Values come from [`typography-styles.json`](../../packages/design-data/registry/typography-styles.json). |
114
- | Alignment | `alignment` | How? | Horizontal text-alignment direction (e.g. `start`, `center`, `end`). Corresponds to the CSS `text-align` axis. Values come from [`alignments.json`](../../packages/design-data/registry/alignments.json). |
115
- | Scale | `scaleIndex` | Which? | Numeric size scale step (e.g. `75`, `100`, `200`). Shared with other token types; not scope-restricted. |
107
+ **NORMATIVE:** Typography tokens SHOULD include at least one of `family`, `weight`, `style`, `scaleIndex`, or `structure`. Tokens missing all five are flagged by rule SPEC-043 (`domain-required-fields`, warning). `family`, `weight`, and `style` are the primary identifiers; `scaleIndex` and `structure` satisfy the rule for scale-indexed and structural typography tokens respectively.
108
+
109
+ | Category | Name object field | Answers | Description |
110
+ | --------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
111
+ | Family | `family` | What? | Type family of the token (e.g. `sans-serif`, `serif`, `cjk`, `code`). Values come from [`typography-families.json`](../../packages/design-data/registry/typography-families.json). |
112
+ | Weight | `weight` | How? | Typographic weight (e.g. `regular`, `bold`, `light`, `black`). Values come from [`typography-weights.json`](../../packages/design-data/registry/typography-weights.json). |
113
+ | Style | `style` | How? | Typographic style (e.g. `italic`, `oblique`, `normal`). Include `normal` when the token explicitly declares a normal style (e.g. a reset). Values come from [`typography-styles.json`](../../packages/design-data/registry/typography-styles.json). |
114
+ | Alignment | `alignment` | How? | Horizontal text-alignment direction (e.g. `start`, `center`, `end`). Corresponds to the CSS `text-align` axis. Values come from [`alignments.json`](../../packages/design-data/registry/alignments.json). |
115
+ | Scale | `scaleIndex` | Which? | Numeric size scale step (e.g. `75`, `100`, `200`). Shared with other token types; not scope-restricted. |
116
+ | Structure | `structure` | Where? | Structural typography scale this token belongs to (e.g. `body`, `detail`, `heading`). Used for tokens that apply within a named typographic structure rather than a specific family/weight/style axis. Values come from [`structures.json`](../../packages/design-data/registry/structures.json). |
116
117
 
117
118
  **Default serialization order for typography tokens:**
118
119