diff --git a/technical-reports/resolver/bundling.md b/technical-reports/resolver/bundling.md
index 98899a0..7a39c07 100644
--- a/technical-reports/resolver/bundling.md
+++ b/technical-reports/resolver/bundling.md
@@ -37,7 +37,7 @@ Given a resolver that references 5 files:
}
}
},
- "composition": [
+ "resolutionOrder": [
{ "$ref": "#/sets/foundation" },
{ "$ref": "#/modifiers/theme" }
]
@@ -85,7 +85,7 @@ One could inline the contents, resulting in:
}
}
},
- "composition": [
+ "resolutionOrder": [
{ "$ref": "#/sets/foundation" },
{ "$ref": "#/modifiers/theme" }
]
@@ -100,9 +100,11 @@ Note that `foundation/colors.json` was referenced 3 times in the document, so in
## Using $defs for files
-As described in [$defs](#defs), `$defs` don’t have defined behavior in a resolver document. But they are valid pointers for [reference objects](#reference-objects). This strategy involves creating a top-level `$defs` key, with each top-level key containing the contents for that file.
+As described in [$defs](#defs), `$defs` don’t have defined behavior in a resolver document. They may only be used if a tool decides to support this feature of JSON Schema.
-There is no downside to using `$defs` other than the possibility of some tools not supporting it, since `$defs` is not a requirement of this spec.
+This strategy involves creating a top-level `$defs` key, with each top-level key containing the contents for that file.
+
+The only downside of using `$defs` is some tools may choose to ignore it, as it is not a minimum requirement of a resolver document.
@@ -133,7 +135,7 @@ Given the same resolver [from the inlining section](#inlining-files), we can cre
}
}
},
- "composition": [
+ "resolutionOrder": [
{ "$ref": "#/sets/foundation" },
{ "$ref": "#/modifiers/theme" }
],
diff --git a/technical-reports/resolver/inputs.md b/technical-reports/resolver/inputs.md
index f73e467..6b0339f 100644
--- a/technical-reports/resolver/inputs.md
+++ b/technical-reports/resolver/inputs.md
@@ -12,7 +12,7 @@ Given the following modifiers:
```json
{
- "composition": [
+ "resolutionOrder": [
{
"type": "modifier",
"name": "theme",
diff --git a/technical-reports/resolver/resolution-logic.md b/technical-reports/resolver/resolution-logic.md
index 3ca1734..d432ad3 100644
--- a/technical-reports/resolver/resolution-logic.md
+++ b/technical-reports/resolver/resolution-logic.md
@@ -3,7 +3,7 @@
Tools MUST handle the resolution stages in order to produce the correct output.
1. [Input validation](#input-validation): verifying the [input](#inputs) is valid for the given resolver document.
-2. [Composition](#composition-0): tracing the `composition` order to produce the final tokens structure.
+2. [Ordering](#ordering): tracing the `resolutionOrder` array to produce the final tokens structure.
3. [Aliases](#aliases): resolving token aliases in the final tokens structure.
4. [Resolution](#resolution-0): the final end result
@@ -11,7 +11,7 @@ Tools MUST handle the resolution stages in order to produce the correct output.
Tools MUST require all [=inputs=] match the provided [modifier](#modifiers) contexts.
-If a resolver does NOT declare any modifiers, skip this step and proceed to [Composition](#composition-0).
+If a resolver does NOT declare any modifiers, skip this step and proceed to [ordering](#ordering).
1. For every key in the input object:
1. Verify it corresponds with a valid modifier. If it does not, throw an error.
@@ -19,16 +19,16 @@ If a resolver does NOT declare any modifiers, skip this step and proceed to [Com
2. For every modifier in the resolver:
1. If that resolver does NOT declare a default value, verify a key is provided in the input. If not, throw an error.
-## Composition
+## Ordering
-Tools MUST iterate over the [composition](#composition) array in order.
+Tools MUST iterate over the [resolutionOrder](#resolution-order) array in order.
1. For every item in the array, determine whether it’s a [set](#sets) or [modifier](#modifiers), flattening into a single tokens structure in array order.
1. If the item is a set, combine the `sources` in array order to produce a single tokens structure.
1. Otherwise, if the item is a modifier, select only the `context` that matches the [input](#inputs), combining the array in order to produce a single tokens structure.
1. In case of a conflict, take the most recent occurrence in the array.
-1. Repeat until you’ve reached the end of the composition array.
+1. Repeat until you’ve reached the end of the `resolutionOrder` array.
The final result will be a tokens structure that behaves the same as if it were one source to begin with.
@@ -65,7 +65,7 @@ The final result will be a tokens structure that behaves the same as if it were
]
}
},
- "composition": [{ "$ref": "#/sets/foundation" }]
+ "resolutionOrder": [{ "$ref": "#/sets/foundation" }]
}
```
@@ -90,7 +90,7 @@ Here, two `color.text.default` tokens were encountered. Since order matters, the
Aliases MUST NOT be resolved until this step.
-After the [composition](#composition-0) has been flattened into a single tokens structure, the only remaining step is resolving aliases. Aliases are resolved the exact same way as outlined in the [format](../format/#aliases-references):
+After the [ordering](#ordering) has been flattened into a single tokens structure, the only remaining step is resolving aliases. Aliases are resolved the exact same way as outlined in the [format](../format/#aliases-references):
- Deep aliases are allowed, so long as they’re not circular
- An alias must point to the correct `$type`.
@@ -128,7 +128,7 @@ Resolver
}
}
},
- "composition": [
+ "resolutionOrder": [
{ "$ref": "#/sets/foundation" },
{ "$ref": "#/sets/components" },
{ "$ref": "#/modifiers/theme" }
@@ -184,7 +184,7 @@ themes/dark.json
1. Input Validation
1. Verify that `theme` is a defined modifier (it passes).
1. Verify that `dark` is a valid value for the `theme` modifier (it passes).
-1. Composition
+1. Ordering
1. The first item is the `foundation` set, providing `color.brand.primary`.
2. The second item is the `components` set, providing `button.background` and `button.padding`.
3. The third and final item is the `theme` modifier, providing `theme.accent`.
diff --git a/technical-reports/resolver/syntax.md b/technical-reports/resolver/syntax.md
index 8642122..52e8653 100644
--- a/technical-reports/resolver/syntax.md
+++ b/technical-reports/resolver/syntax.md
@@ -4,14 +4,14 @@
A resolver document contains the following properties at the root level:
-| Name | Type | Required | Description |
-| :------------------------------ | :--------------------- | :------: | :---------------------------------------------- |
-| [**name**](#name) | `string` | | A short, human-readable name for the document. |
-| [**version**](#version) | `YYYY-MM-DD` | Y | Version. Must be `2025-10-01`. |
-| [**description**](#description) | `string` | | A human-readable description for this document. |
-| [**sets**](#sets) | Map[`string`, Set] | | Definition of sets. |
-| [**modifiers**](#modifiers) | Map[`string, Modifier] | | Definition of modifiers. |
-| [**composition**](#composition) | `ReferenceObject[]` | Y | Resolution of sets and modifiers. |
+| Name | Type | Required | Description |
+| :-------------------------------------- | :--------------------------------------- | :------: | :---------------------------------------------- |
+| [**name**](#name) | `string` | | A short, human-readable name for the document. |
+| [**version**](#version) | `YYYY-MM-DD` | Y | Version. Must be `2025-10-01`. |
+| [**description**](#description) | `string` | | A human-readable description for this document. |
+| [**sets**](#sets) | Map[`string`, Set] | | Definition of sets. |
+| [**modifiers**](#modifiers) | Map[`string, Modifier] | | Definition of modifiers. |
+| [**resolutionOrder**](#resolutionOrder) | `(ReferenceObject \| Set \| Modifier)[]` | Y | Resolution of sets and modifiers. |
### Name
@@ -200,13 +200,13 @@ The number of possible [=resolutions=] a document may generate may be predicted
-### Composition
+### Resolution Order
-The `composition` key is an array of [sets](#sets) and [modifiers](#modifiers) ordered to produce the final result of tokens. The order is significant, with tokens later in the array overriding any tokens that came before them, in case of conflict.
+The `resolutionOrder` key is an array of [sets](#sets) and [modifiers](#modifiers) ordered to produce the final result of tokens. The order is significant, with tokens later in the array overriding any tokens that came before them, in case of conflict.
-Given a `composition` that consists of multiple sets and modifiers:
+Given a `resolutionOrder` that consists of multiple sets and modifiers:
```json
{
@@ -239,7 +239,7 @@ Given a `composition` that consists of multiple sets and modifiers:
"default": "light"
}
},
- "composition": [
+ "resolutionOrder": [
{ "$ref": "#/sets/size" },
{ "$ref": "#/sets/typography" },
{ "$ref": "#/sets/animation" },
@@ -328,7 +328,7 @@ Modifiers MAY contain empty context arrays:
}
}
},
- "composition": [
+ "resolutionOrder": [
// …
{ "$ref": "#/modifiers/debug" }
]
@@ -341,26 +341,26 @@ This would then load an additional `debug.json` file if it received a `{ "debug"
#### Inline sets and modifiers
-In `composition`, a [set](#sets) or [modifier](#modifiers) MAY be declared inline, so long as `name` and `type` keys are added to the object:
+In `resolutionOrder`, a [set](#sets) or [modifier](#modifiers) MAY be declared inline, so long as `name` and `type` keys are added to the object:
-| Property | Type | Required | Description |
-| :------- | :-------------------- | :------: | :---------------------------------------------------------------------------- |
-| **name** | `string` | Y | A unique name that MUST NOT conflict with any other `name` in `compositions`. |
-| **type** | `"set" \| "modifier"` | Y | MUST be `"set"` or `"modifier"` according to the type. |
+| Property | Type | Required | Description |
+| :------- | :-------------------- | :------: | :------------------------------------------------------------------------------- |
+| **name** | `string` | Y | A unique name that MUST NOT conflict with any other `name` in `resolutionOrder`. |
+| **type** | `"set" \| "modifier"` | Y | MUST be `"set"` or `"modifier"` according to the type. |
Tools MUST throw an error in the case where `name` or `type` are missing from an inline object, or if `name` is duplicated among any objects.
-When sets and modifiers appear in their respective root level `sets` and `modifiers` keys, it is valid for a set to share a name with a modifier. It is only invalid to duplicate a `name` inside the `composition` array.
+When sets and modifiers appear in their respective root level `sets` and `modifiers` keys, it is valid for a set to share a name with a modifier. It is only invalid to duplicate a `name` inside the `resolutionOrder` array.
-
+
```json
{
- "composition": [
+ "resolutionOrder": [
{
"type": "set",
"name": "Size",
@@ -400,17 +400,17 @@ When sets and modifiers appear in their respective root level `sets` and `modifi
-Inline sets and modifiers MUST NOT be referenced in any way. Tools SHOULD throw an error when a [reference object](#reference-objects) points to a composition item.
+Inline sets and modifiers MUST NOT be referenced in any way. Tools SHOULD throw an error when a [reference object](#reference-objects) points to a resolution order item.
The following [reference object](#reference-objects) pointer is invalid regardless of where it appears:
```json
-{ "$ref": "#/composition/4" }
+{ "$ref": "#/resolutionOrder/4" }
```
-This is very likely to create an invalid reference, no matter if it appears in [sets](#sets) (circular dependency), [modifiers](#modifiers) (circular dependency), or in another place in the [composition](#composition) array (infinite recursion). The times where this would not cause an invalid reference are rare, and the slightest change may turn it into a circular reference.
+This is very likely to create an invalid reference, no matter if it appears in [sets](#sets) (circular dependency), [modifiers](#modifiers) (circular dependency), or in another place in the [resolutionOrder](#resolution-order) array (infinite recursion). The times where this would not cause an invalid reference are rare, and the slightest change may turn it into a circular reference.
@@ -418,7 +418,7 @@ This is very likely to create an invalid reference, no matter if it appears in [
#### Ordering of sets and modifiers
-The `composition` array allows for any ordering of sets and modifiers to the user’s choosing. However, in the scenario that many sets must appear after the modifiers to resolve conflicts, it is likely a [smell](https://en.wikipedia.org/wiki/Code_smell) of unpredictable and brittle token organization. Ideally, modifiers handle conditional values so well they require few or no overrides (see [orthogonality](#orthogonal-orthogonality)). In practical terms, this means that
+The `resolutionOrder` array allows for any ordering of sets and modifiers to the user’s choosing. However, in the scenario that many sets must appear after the modifiers to resolve conflicts, it is likely a [smell](https://en.wikipedia.org/wiki/Code_smell) of unpredictable and brittle token organization. Ideally, modifiers handle conditional values so well they require few or no overrides (see [orthogonality](#orthogonal-orthogonality)). In practical terms, this means that
@@ -430,11 +430,13 @@ Tools MUST resolve all reference objects in a resolver document.
Reference objects MUST NOT be circular, neither referencing other pointers that reference itself, nor referencing any parent node of the reference object.
+Tools MUST support same-document reference objects, as that is the minimum requirement to support this resolver module. Beyond that, tools may make individual decisions to not support some URI types such as importing files on a local file system, or remote URIs over TCP/IP.
+
Common examples of reference objects include:
-Code Result
+Code Result Required Support
```json
{ "$ref": "#/sets/MySet" }
@@ -444,7 +446,7 @@ Common examples of reference objects include:
References `sets/MySet` within the same document.
-
+ Y
```json
{ "$ref": "path/to/example.json" }
@@ -454,7 +456,7 @@ References `sets/MySet` within the same document.
References the entire contents of `./path/to/example.json`, relative to this document.
-
+
```json
{ "$ref": "example.json#sets/MySet" }
@@ -464,7 +466,7 @@ References the entire contents of `./path/to/example.json`, relative to this doc
References only a part of `example.json`: `sets/MySet`.
-
+
```json
{ "$ref": "https://my-server.com/tokens.json" }
@@ -474,7 +476,7 @@ References only a part of `example.json`: `sets/MySet`.
References a remote file hosted at a publicly-available URL.
-
+
@@ -511,10 +513,10 @@ A single reference object that references its parent is invalid because it will
A pointer MAY point anywhere within the same document, with the exception of the following:
-1. Only [composition](#composition) may reference a modifier (`#/modifiers/…`). Sets and modifiers MUST NOT reference another modifier.
+1. Only [resolutionOrder](#resolution-order) may reference a modifier (`#/modifiers/…`). Sets and modifiers MUST NOT reference another modifier.
- Referencing a modifier from a set could cause [inputs](#inputs) to apply conditional logic to a structure that can’t support it, therefore it’s not allowed.
- Referencing a modifier from another modifier would mean a single input applies to unexpected modifiers, therefore it’s not allowed.
-1. A reference object MUST NOT point to anything in the [composition](#composition) array (`#/composition/…`). Composition, by its nature, references many other parts of the document. Duplicating any part of composition will produce complex, hard-to-predict chains.
+1. A reference object MUST NOT point to anything in the [resolutionOrder](#resolution-order) array (`#/resolutionOrder/…`). Resolution ordering, by its nature, references many other parts of the document. Duplicating any part of this will produce complex, hard-to-predict chains.
Tools MUST throw an error if encountering any invalid pointers.
@@ -589,7 +591,7 @@ Here is an example where a set contains arbitrary metadata for the `figma.com` v
## $defs
-Tools MAY allow defining structures in JSON Schema [$defs](https://json-schema.org/understanding-json-schema/structuring#defs) but is not a requirement, and ultimately is up to the tool to decide.
+Tools MAY allow defining structures in JSON Schema [$defs](https://json-schema.org/understanding-json-schema/structuring#defs) but is not a requirement. However, tools MUST NOT throw an error when encountering `$defs`, and MUST ignore the key if it is not supported.
diff --git a/technical-reports/resolver/terminology.md b/technical-reports/resolver/terminology.md
index 5aa9d12..9c6126a 100644
--- a/technical-reports/resolver/terminology.md
+++ b/technical-reports/resolver/terminology.md
@@ -2,7 +2,7 @@
-## Resolution
+## Permutation
-A resolution is a single possible permutation of a resolver document. A resolution maps 1:1 to an [input](#inputs), but the difference is the “input” refers to the [modifier](#modifiers) contexts used, whereas “resolution” refers to the final set of tokens and token values produced.
+A permutation is a single possible permutation of a resolver document. A permutation maps 1:1 to an [input](#inputs), but the term “input” emphasizes the [modifier](#modifiers) contexts used, where “permutation” emphasizes the final set of tokens.