@canonical/anatomy-dsl 0.2.2 → 0.5.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.
@@ -1,16 +1,25 @@
1
- @prefix anatomy: <http://anatomy-dsl.example.org/ontology#> .
1
+ @prefix anatomy: <https://anatomy.canonical.com/> .
2
2
  @prefix owl: <http://www.w3.org/2002/07/owl#> .
3
3
  @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4
4
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
5
5
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
6
6
  @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
7
+ @prefix graphql: <https://pragma.canonical.com/graphql#> .
8
+ # The two graphs this one is read beside. `dt:` is the token graph
9
+ # (@canonical/token-ontology): a style value's symbols are dt:TokenSymbol
10
+ # individuals, and anatomy:consumes names them. `ds:` is the design system
11
+ # graph (canonical/design-system), whose ds:TokenBinding record reuses
12
+ # anatomy:styleKey and anatomy:styleState — which is why neither carries an
13
+ # rdfs:domain any more.
14
+ @prefix dt: <https://dt.canonical.com/> .
15
+ @prefix ds: <https://ds.canonical.com/> .
7
16
 
8
17
  # ═══════════════════════════════════════════════════════════════
9
18
  # ONTOLOGY DECLARATION
10
19
  # ═══════════════════════════════════════════════════════════════
11
20
 
12
- <http://anatomy-dsl.example.org/ontology> a owl:Ontology ;
13
- owl:versionInfo "0.2.0" ;
21
+ <https://anatomy.canonical.com/> a owl:Ontology ;
22
+ owl:versionInfo "0.4.0" ;
14
23
  rdfs:label "Anatomy DSL Ontology" ;
15
24
  rdfs:comment "Compliant with OWL DL profile" ;
16
25
  skos:definition """Meta-model for the Anatomy DSL — a YAML-based language
@@ -19,11 +28,20 @@
19
28
  Models anatomy files as trees of nodes connected by reified edges.
20
29
  Inspired by the Relay GraphQL connection pattern.
21
30
 
22
- Consolidates WD404 (core) and WD404.1 (addendum 1).
31
+ Consolidates WD404 (core), WD404.1 (addendum 1), projections
32
+ (addendum 2): fragment-style bindings of nodes and relations to
33
+ graph data, prop pinning (addendum 3): fixed prop values on
34
+ referenced components, and interaction states (addendum 4):
35
+ state-scoped style values.
23
36
 
24
37
  OUT OF SCOPE (matching the DSL itself):
25
- - Prop mapping
26
- - State or state machines
38
+ - Prop surface definition — names, types, and optionality of a
39
+ component's props live in the design system ontology. Pinned prop
40
+ VALUES are in scope as of addendum 3.
41
+ - State MACHINES — transitions, triggers, and interaction logic.
42
+ Appearance PER interaction state is in scope as of addendum 4
43
+ (styleState); structural state variation remains the Switch
44
+ construct's job.
27
45
  - Modifier descriptions (only token references)
28
46
 
29
47
  Validation shapes defined in shapes.ttl.""" .
@@ -62,6 +80,23 @@ anatomy:Style a owl:Class ;
62
80
  rdfs:label "Style" ;
63
81
  skos:definition "A single style declaration binding a property key to a value." .
64
82
 
83
+ anatomy:Projection a owl:Class ;
84
+ rdfs:label "Projection" ;
85
+ skos:definition """Fragment-style binding to graph data, after the Relay
86
+ colocation pattern. On a node it declares a type condition (like a
87
+ fragment's 'on') and/or the field the node renders; on a relation it
88
+ declares the traversal that populates the slot.""" .
89
+
90
+ anatomy:Prop a owl:Class ;
91
+ rdfs:label "Prop" ;
92
+ skos:definition """A pinned property value: the anatomy fixes one prop of
93
+ the referenced component at this tree position (e.g. the icon component's
94
+ 'icon' prop pinned to 'chevron-down' for an intrinsic chevron). References
95
+ a property defined in the design system ontology — the DSL never defines
96
+ the prop surface itself. Whether the pinned prop exists on the component,
97
+ and whether the value is admissible, is validated by consumers holding
98
+ the design system graph.""" .
99
+
65
100
  # ═══════════════════════════════════════════════════════════════
66
101
  # SWITCH CONSTRUCT
67
102
  # ═══════════════════════════════════════════════════════════════
@@ -74,6 +109,57 @@ anatomy:SwitchCase a owl:Class ;
74
109
  rdfs:label "Switch Case" ;
75
110
  skos:definition "One alternative within a Switch." .
76
111
 
112
+ # ═══════════════════════════════════════════════════════════════
113
+ # THE STYLE-KEY REGISTRY
114
+ # ═══════════════════════════════════════════════════════════════
115
+ #
116
+ # The individuals live in registry.ttl, projected from the roster in
117
+ # style-keys.yaml by `bun run generate:registry`; the same roster closes
118
+ # anatomy:styleKey's sh:in in shapes.ttl. The vocabulary was open until
119
+ # 0.4.0 — "about 14 keys" documented against 39 the corpus used — and an
120
+ # open roster is what admitted `background.color` on a component whose
121
+ # stylesheet says `background-color`.
122
+
123
+ anatomy:StyleKey a owl:Class ;
124
+ rdfs:label "Style Key" ;
125
+ skos:definition """One canonical style key: a platform-agnostic property
126
+ the anatomy may bind. The roster was measured, not designed: it is the
127
+ right-hand column of a table whose left-hand column was every CSS property
128
+ the reference implementations bind, so a key exists because an
129
+ implementation binds the property, never because the vocabulary looked
130
+ incomplete. registry.ttl states where that measurement lives.""" ;
131
+ skos:example "appearance.background" ,
132
+ "spacing.internal.inline.start" ,
133
+ "typography.color" .
134
+
135
+ anatomy:valueKind a owl:DatatypeProperty ;
136
+ rdfs:label "value kind" ;
137
+ rdfs:domain anatomy:StyleKey ;
138
+ rdfs:range xsd:string ;
139
+ skos:definition """What the key admits: "token" (a symbol, or a list of
140
+ symbols ending at most in one primitive), "primitive" (a literal the
141
+ implementation writes as it stands), or "either". Measured from the
142
+ reference declarations mapped onto the key when the roster was taken —
143
+ all reading a var() is token, none is primitive, mixed is either. An
144
+ "either" key compiles to an sh:or in StyleShape: it carries
145
+ anatomy:consumes, or it carries a primitive styleValue.""" ;
146
+ skos:example "token" , "primitive" , "either" .
147
+
148
+ anatomy:tokenNamespace a owl:DatatypeProperty ;
149
+ rdfs:label "token namespace" ;
150
+ rdfs:domain anatomy:StyleKey ;
151
+ rdfs:range xsd:string ;
152
+ skos:definition """A dotted prefix, ending in a dot, whose symbols the key
153
+ admits — matched against a symbol's dotted NAME with STRSTARTS, never
154
+ against its IRI. Multi-valued, and a key whose base namespace is `N.`
155
+ carries `N.`, `modifier.N.` and `surface.N.`: a channel of a symbol in
156
+ `N.` is exactly what the anatomy consumes where the implementation reads
157
+ the channel, so without the channel spellings every channel binding in
158
+ the corpus would be a namespace violation. It is the single declaration of
159
+ which symbols a key admits, and the inverse question — which keys admit
160
+ this symbol — is the query over it (dt:appliesTo is retired).""" ;
161
+ skos:example "color." , "modifier.color." , "spacing." .
162
+
77
163
  # ═══════════════════════════════════════════════════════════════
78
164
  # OBJECT PROPERTIES
79
165
  # ═══════════════════════════════════════════════════════════════
@@ -126,12 +212,56 @@ anatomy:hasStyle a owl:ObjectProperty ;
126
212
  rdfs:range anatomy:Style ;
127
213
  skos:definition "Attaches a style declaration to a node." .
128
214
 
215
+ anatomy:hasProjection a owl:ObjectProperty ;
216
+ rdfs:label "has projection" ;
217
+ rdfs:domain [ a owl:Class ; owl:unionOf ( anatomy:Node anatomy:Relation ) ] ;
218
+ rdfs:range anatomy:Projection ;
219
+ skos:definition "Attaches a graph-data projection to a node or relation." .
220
+
221
+ anatomy:hasProp a owl:ObjectProperty ;
222
+ rdfs:label "has prop" ;
223
+ rdfs:domain anatomy:NamedNode ;
224
+ rdfs:range anatomy:Prop ;
225
+ skos:definition "Attaches a pinned prop value to a named node. Named nodes only: anonymous nodes have no prop surface to pin." .
226
+
227
+ anatomy:consumes a owl:ObjectProperty ;
228
+ rdfs:label "consumes" ;
229
+ rdfs:domain anatomy:Style ;
230
+ rdfs:range rdf:List ;
231
+ skos:definition """The token symbols this style binding consumes, as an
232
+ ordered rdf:List whose elements are dt:TokenSymbol individuals in FALLBACK
233
+ ORDER: rdf:first is the primary symbol, and each rest is what the
234
+ implementation falls back to when the one before it is undefined. It is
235
+ the RDF form of the authored value — a one-to-one transcription of the
236
+ implementation's `var(a, var(b, …))` chain — and the reason the list and
237
+ not a single symbol is that the fallback is a per-slot choice: a
238
+ component's background and its text fall back differently, so no rule
239
+ declared once on a symbol can carry it.
240
+
241
+ A slot consumes a CHANNEL by name where the implementation reads the
242
+ channel (`modifier.color.text`) and the semantic token by name where it
243
+ reads the token; nothing is inferred from the spelling. A terminal
244
+ literal the chain ends in (`currentColor`, `0`, `1em`) is NOT an element
245
+ here — it resolves against nothing by design — and is carried in
246
+ anatomy:styleValue, which keeps the authored spelling verbatim as
247
+ evidence. Whether a key carries this at all is anatomy:valueKind's
248
+ business, and whether a symbol RESOLVES is the consumer's: a name no
249
+ stratum declares is kept as consumed with a register row.""" ;
250
+ skos:example "( dt:modifier.color.text dt:color.text )" .
251
+
129
252
  # ═══════════════════════════════════════════════════════════════
130
253
  # DATATYPE PROPERTIES
131
254
  # ═══════════════════════════════════════════════════════════════
132
255
 
133
256
  anatomy:uri a owl:DatatypeProperty ;
134
257
  rdfs:label "uri" ;
258
+ # `uri` is the structural primary key of every node in a GraphQL projection
259
+ # of this ontology (one absolute IRI per entity), so an ontology property of
260
+ # the same name collides with it. The projection names this one
261
+ # `anatomyUri`; the RDF term is unchanged and every SPARQL query keeps
262
+ # working. See canonical/pragma-adrs session/B (ruling R-4: a collision is
263
+ # an error, never a silent rename).
264
+ graphql:name "anatomyUri" ;
135
265
  rdfs:domain anatomy:NamedNode ;
136
266
  rdfs:range xsd:string ;
137
267
  skos:definition "Unique identifier for a named node within the design system." ;
@@ -171,11 +301,17 @@ anatomy:slotName a owl:DatatypeProperty ;
171
301
 
172
302
  anatomy:styleKey a owl:DatatypeProperty ;
173
303
  rdfs:label "style key" ;
174
- rdfs:domain anatomy:Style ;
304
+ # No rdfs:domain, deliberately. design-system's ds:TokenBinding record
305
+ # (one per consumed symbol per rank) carries the key and the state of the
306
+ # tuple it was derived from, so a domain of anatomy:Style would type every
307
+ # record an anatomy:Style. The constraint that a tuple carries exactly one
308
+ # key lives in shapes.ttl, where it belongs. Stays an
309
+ # owl:DatatypeProperty: pragma asserts every term a lookup selects is a
310
+ # declared datatype or object property.
175
311
  rdfs:range xsd:string ;
176
312
  skos:definition "Platform-agnostic style property identifier." ;
177
313
  skos:example "layout.type" ,
178
- "spacing.internal" ,
314
+ "spacing.internal.inline.start" ,
179
315
  "appearance.background" ,
180
316
  "typography.weight" .
181
317
 
@@ -183,8 +319,65 @@ anatomy:styleValue a owl:DatatypeProperty ;
183
319
  rdfs:label "style value" ;
184
320
  rdfs:domain anatomy:Style ;
185
321
  rdfs:range xsd:string ;
186
- skos:definition "Value for a style property." ;
187
- skos:example "stack" ,
188
- "spacing/medium" ,
189
- "color/surface/primary" ,
190
- "color/surface/button?" .
322
+ skos:definition """The AUTHORED SPELLING of the value, verbatim: a scalar
323
+ as written, a sequence in its flow form. It is the evidence of what the
324
+ reference says, and it is kept even where anatomy:consumes carries the
325
+ same symbols in a form a query can walk — the terminal literal of a
326
+ fallback chain lives only here, because a literal is not a symbol.
327
+
328
+ A value is a symbol, a primitive, or a sequence whose elements are
329
+ symbols with at most one primitive and only as the last element. The
330
+ slash-delimited path and the trailing '?' marker are RETIRED: an element
331
+ that resolves nowhere is a register row and a comment, not a sigil.""" ;
332
+ skos:example "flow" ,
333
+ "dimension.100" ,
334
+ "[modifier.color.text, color.text]" ,
335
+ "[modifier.color.icon, modifier.color.text, currentColor]" .
336
+
337
+ anatomy:styleState a owl:DatatypeProperty ;
338
+ rdfs:label "style state" ;
339
+ # No rdfs:domain, for the reason anatomy:styleKey gives.
340
+ rdfs:range xsd:string ;
341
+ skos:definition """Interaction state this style value applies in. Absent
342
+ means the default state. Closed vocabulary (hover, active, focus,
343
+ disabled, selected), governed by registry — 'active' subsumes Material's
344
+ 'pressed' and Spectrum's 'down'; 'focus' maps to CSS :focus-visible
345
+ (Spectrum's 'key-focus'). States re-value style channels only: they never
346
+ add structure (that is the Switch construct) and never define transitions
347
+ or interaction logic (state machines stay out of scope). Authored as an
348
+ @state suffix on the style key.""" ;
349
+ skos:example "hover" , "active" , "focus" , "disabled" , "selected" .
350
+
351
+ anatomy:projectionType a owl:DatatypeProperty ;
352
+ rdfs:label "projection type" ;
353
+ rdfs:domain anatomy:Projection ;
354
+ rdfs:range xsd:string ;
355
+ skos:definition "GraphQL type condition, like a Relay fragment's 'on'. On a root node it establishes the data context for the tree; on a child it narrows the traversed entity's type, like an inline fragment." ;
356
+ skos:example "Component" ,
357
+ "OntologyClass" ,
358
+ "Pattern" .
359
+
360
+ anatomy:propName a owl:DatatypeProperty ;
361
+ rdfs:label "prop name" ;
362
+ rdfs:domain anatomy:Prop ;
363
+ rdfs:range xsd:string ;
364
+ skos:definition "Name of the pinned prop, as defined on the referenced component in the design system ontology." ;
365
+ skos:example "icon" .
366
+
367
+ anatomy:propValue a owl:DatatypeProperty ;
368
+ rdfs:label "prop value" ;
369
+ rdfs:domain anatomy:Prop ;
370
+ rdfs:range xsd:string ;
371
+ skos:definition "The fixed value the anatomy pins the prop to." ;
372
+ skos:example "chevron-down" ,
373
+ "checkmark" ,
374
+ "spinner" .
375
+
376
+ anatomy:projectionField a owl:DatatypeProperty ;
377
+ rdfs:label "projection field" ;
378
+ rdfs:domain anatomy:Projection ;
379
+ rdfs:range xsd:string ;
380
+ skos:definition "Dot-delimited GraphQL field path relative to the enclosing data context. On a node: the field the node renders. On a relation: the traversal populating the slot. Names the field only, never an unwrapping path like edges/node — whether a plural field is a connection or a plain list is a provider mechanism discovered from the schema. The relation's cardinality maps onto the field's shape: upper bound to multiplicity, lower bound to nullability." ;
381
+ skos:example "_meta.title" ,
382
+ "summary" ,
383
+ "documentationStages" .