UJG / Editor's Draft /
GitHub
Table of Contents
  • 1Overview
  • 2Terminology
  • 3TokenSource
  • 4Component
  • 5Slot
  • 6Template
  • 7SlotBinding
  • 8SurfaceRealization
  • 9DesignSystem
  • 10Realization Model
  • 11DesignSystem Catalog
  • 12Templates And Slots
  • 13Normative Artifacts
    • 13.1Ontology
    • 13.2JSON-LD Context
    • 13.3Validation
  • 14MCP And Tooling Resolution
  • 15Relationship To Core Extensions
  • 16Examples
    • 16.1Example A: Surface Without Realization
    • 16.2Example B: Component Realization
    • 16.3Example C: Template Realization
    • 16.4Example D: Composite Surface With Child Surfaces
    • 16.5Example E: Multiple Design Systems
W3C Community Group Draft Report

Design System

draft

Status of this Document

This report was published by the User Journal Graph Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups .

Last Update
2026-07-13
Editors
  • Seva Dolgopolov
Group
User Journal Graph Community Group
Repository
View Source
License
W3C-Software-and-Document

1. Overview

This optional module defines a graph-native vocabulary for describing how design-system artifacts realize Surface resources.

The module is intentionally second-level. It depends on the Surface layer as the bridge between Graph topology and user-facing materialization. Graph nodes do not point to design-system artifacts, and Surface resources remain design-system-agnostic.

The DesignSystem module introduces SurfaceRealization as the design-system-side bridge. A SurfaceRealization references exactly one Surface and then identifies either a Component or a Template as the primary realization. When a template is used, the realization may reference SlotBinding nodes that fill template-declared Slot nodes.

This module is optional. It annotates the shared graph with interoperable design-system realization resources, but it does not change graph topology, traversal rules, Surface attachment rules, import resolution, rendering behavior, or runtime semantics.

2. Terminology

  • DesignSystem: A graph-native catalog or scope for design-system artifacts available to realize surfaces.

  • TokenSource: An addressable token source, package, manifest, or token set. The internal token format is external to UJG.

  • Component: An addressable design-system artifact that can realize a surface or fill a slot.

  • Template: A reusable design-system artifact that declares slots.

  • Slot: An addressable slot declaration owned by or referenced from a template.

  • SurfaceRealization: A design-system-side node that references one surface and describes its primary component or template realization.

  • SlotBinding: A realization-local binding from a template slot to one presentation target.

3. TokenSource

A TokenSource identifies a token source, token package, token manifest, or token set. The internal token format is external to UJG.

classDiagram
  class TokenSource {
    id
  }

Example JSON node:

json
{
  "@type": "TokenSource",
  "@id": "urn:ujg:tokens:brand"
}
{
  "@type": "TokenSource",
  "@id": "urn:ujg:tokens:brand"
}

4. Component

A Component is an addressable design-system artifact that can directly realize a Surface or fill a template slot.

classDiagram
  class Component {
    id
  }

Example JSON node:

json
{
  "@type": "Component",
  "@id": "urn:ujg:component:CheckoutForm"
}
{
  "@type": "Component",
  "@id": "urn:ujg:component:CheckoutForm"
}

5. Slot

A Slot is an addressable slot declaration used by a Template.

classDiagram
  class Slot {
    id
  }

Example JSON node:

json
{
  "@type": "Slot",
  "@id": "urn:ujg:slot:checkout-main"
}
{
  "@type": "Slot",
  "@id": "urn:ujg:slot:checkout-main"
}

6. Template

A Template is a reusable design-system artifact that declares zero or more Slots.

classDiagram
  class Slot
  class Template {
    id
    slotRefs
  }
  Template --> "0..*" Slot : slotRefs

Example JSON node:

json
{
  "@type": "Template",
  "@id": "urn:ujg:template:checkout-layout",
  "slotRefs": ["urn:ujg:slot:checkout-main"]
}
{
  "@type": "Template",
  "@id": "urn:ujg:template:checkout-layout",
  "slotRefs": ["urn:ujg:slot:checkout-main"]
}

7. SlotBinding

A SlotBinding fills one declared Slot with exactly one target: either a Surface or a Component.

classDiagram
  class Slot
  class Surface
  class Component
  class SlotBinding {
    id
    slotRef
    targetSurfaceRef
    targetComponentRef
  }
  SlotBinding --> Slot : slotRef
  SlotBinding --> Surface : targetSurfaceRef
  SlotBinding --> Component : targetComponentRef

Example JSON node:

json
{
  "@type": "SlotBinding",
  "@id": "urn:ujg:slot-binding:checkout-main",
  "slotRef": "urn:ujg:slot:checkout-main",
  "targetSurfaceRef": "urn:ujg:surface:checkout-form"
}
{
  "@type": "SlotBinding",
  "@id": "urn:ujg:slot-binding:checkout-main",
  "slotRef": "urn:ujg:slot:checkout-main",
  "targetSurfaceRef": "urn:ujg:surface:checkout-form"
}

8. SurfaceRealization

A SurfaceRealization links one Surface to its primary design-system realization, either a Component or a Template. Template-backed realizations may also reference SlotBindings.

classDiagram
  class Surface
  class Component
  class Template
  class SlotBinding
  class SurfaceRealization {
    id
    surfaceRef
    componentRef
    templateRef
    slotBindingRefs
  }
  SurfaceRealization --> Surface : surfaceRef
  SurfaceRealization --> Component : componentRef
  SurfaceRealization --> Template : templateRef
  SurfaceRealization --> "0..*" SlotBinding : slotBindingRefs

Example JSON node:

json
{
  "@type": "SurfaceRealization",
  "@id": "urn:ujg:realization:checkout-form",
  "surfaceRef": "urn:ujg:surface:checkout-form",
  "componentRef": "urn:ujg:component:CheckoutForm"
}
{
  "@type": "SurfaceRealization",
  "@id": "urn:ujg:realization:checkout-form",
  "surfaceRef": "urn:ujg:surface:checkout-form",
  "componentRef": "urn:ujg:component:CheckoutForm"
}

9. DesignSystem

A DesignSystem is a catalog or scope for token sources, components, templates, and surface realizations.

classDiagram
  class TokenSource
  class Component
  class Template
  class SurfaceRealization
  class DesignSystem {
    id
    tokenSourceRefs
    componentRefs
    templateRefs
    surfaceRealizationRefs
  }
  DesignSystem --> "0..*" TokenSource : tokenSourceRefs
  DesignSystem --> "0..*" Component : componentRefs
  DesignSystem --> "0..*" Template : templateRefs
  DesignSystem --> "0..*" SurfaceRealization : surfaceRealizationRefs

Example JSON node:

json
{
  "@type": "DesignSystem",
  "@id": "urn:ujg:design-system:shop",
  "tokenSourceRefs": ["urn:ujg:tokens:brand"],
  "componentRefs": ["urn:ujg:component:CheckoutForm"],
  "templateRefs": ["urn:ujg:template:checkout-layout"],
  "surfaceRealizationRefs": ["urn:ujg:realization:checkout-form"]
}
{
  "@type": "DesignSystem",
  "@id": "urn:ujg:design-system:shop",
  "tokenSourceRefs": ["urn:ujg:tokens:brand"],
  "componentRefs": ["urn:ujg:component:CheckoutForm"],
  "templateRefs": ["urn:ujg:template:checkout-layout"],
  "surfaceRealizationRefs": ["urn:ujg:realization:checkout-form"]
}

10. Realization Model

A Surface is a design-system-agnostic materialized boundary for exactly one supported Graph node. Surface defines the relation from Surface to that supported Graph node. Graph nodes do not point to design-system artifacts or depend on Surface. This module does not add properties to Surface and does not make Surface depend on design-system artifacts.

Design-system realization is expressed by SurfaceRealization nodes:

  • A DesignSystem MAY reference SurfaceRealization nodes through surfaceRealizationRefs.

  • A SurfaceRealization MUST reference exactly one Surface.

  • A SurfaceRealization MUST reference exactly one primary realization, either componentRef or templateRef.

  • A Template MAY declare Slot nodes through slotRefs.

  • A template-backed SurfaceRealization MAY reference SlotBinding nodes through slotBindingRefs.

  • A SlotBinding MUST reference exactly one Slot and exactly one target.

This shape allows multiple design systems to realize the same surface independently without changing the surface or assigning multiple surfaces to the same supported Graph node.

11. DesignSystem Catalog

A DesignSystem groups design-system artifacts and realizations available in a design-system context. It is not a renderer and does not define component internals, layout rules, or token syntax.

The catalog properties are:

  • tokenSourceRefs: references zero or more TokenSource nodes.

  • componentRefs: references zero or more Component nodes.

  • templateRefs: references zero or more Template nodes.

  • surfaceRealizationRefs: references zero or more SurfaceRealization nodes.

TokenSource identifies a token source, token package, token manifest, or token set. Individual token names, token paths, token groups, token values, aliases, and inheritance rules are outside this module.

12. Templates And Slots

A Template declares reusable slots with slotRefs. A template MUST NOT hard-code concrete surfaces, components, transitions, or outgoing transitions into those slots.

A SurfaceRealization that uses a Template references SlotBinding nodes. Each SlotBinding references one declared slot and one target.

Allowed slot binding targets are:

  • targetSurfaceRef

  • targetComponentRef

When a SlotBinding targets a Surface, the target surface is composed into the slot for presentation purposes only. The binding MUST NOT imply graph traversal, state activation, transition validity, composite-state containment, execution order, or lifecycle semantics. A renderer, MCP server, skill, or design-system resolver MAY resolve the graph-level subject associated with a target surface through the Surface layer.

If a transition, outgoing transition, or outgoing-transition group affordance belongs in a slot, model a Surface that references that Graph node through the Surface layer and target that surface with targetSurfaceRef.

13. Normative Artifacts

This module is published through the following artifacts:

  • design-system.ttl: ontology, published at https://ujg.specs.openuji.org/ed/ns/design-system

  • design-system.context.jsonld: JSON-LD term mappings, published at https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld

  • design-system.shape.ttl: SHACL validation rules, published at https://ujg.specs.openuji.org/ed/ns/design-system.shape

Examples in this page compose the Core, Graph, Surface, and Design System contexts explicitly.

Non-goals:

  • This module does not define component implementation APIs, component props, component variants, or component lifecycle.

  • This module does not define layout algorithms, rendering engines, framework adapters, responsive behavior, hydration behavior, or platform-specific UI behavior.

  • This module does not define design-token syntax, token inheritance, token value resolution, or token path semantics.

  • This module does not define accessibility implementation rules.

  • This module does not introduce graph traversal, state activation, transition validity, composite-state containment, execution order, or lifecycle semantics.

13.1. Ontology

The normative DesignSystem ontology is defined below and is published at https://ujg.specs.openuji.org/ed/ns/design-system. It is the authoritative structural definition for the classes and properties declared by this module.

turtle
@prefix ujg: <https://ujg.specs.openuji.org/ed/ns/core#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/ed/ns/surface#> .
@prefix ujgds: <https://ujg.specs.openuji.org/ed/ns/design-system#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dct: <http://purl.org/dc/terms/> .

<https://ujg.specs.openuji.org/ed/ns/design-system#> a owl:Ontology ;
  rdfs:label "UJG Design System Editor's Draft Vocabulary"@en ;
  dct:description "UJG Design System ontology declaration" .

### Classes

ujgds:DesignSystem a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:TokenSource a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Component a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Template a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Slot a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:SurfaceRealization a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:SlotBinding a owl:Class ;
  rdfs:subClassOf ujg:Node .

### Properties

ujgds:tokenSourceRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:TokenSource .

ujgds:componentRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:Component .

ujgds:templateRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:Template .

ujgds:surfaceRealizationRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:SurfaceRealization .

ujgds:surfaceRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgsurface:Surface .

ujgds:componentRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:Component .

ujgds:templateRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:Template .

ujgds:slotBindingRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:SlotBinding .

ujgds:slotRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:Template ;
  rdfs:range ujgds:Slot .

ujgds:slotRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgds:Slot .

ujgds:targetSurfaceRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgsurface:Surface .

ujgds:targetComponentRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgds:Component .
@prefix ujg: <https://ujg.specs.openuji.org/ed/ns/core#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/ed/ns/surface#> .
@prefix ujgds: <https://ujg.specs.openuji.org/ed/ns/design-system#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dct: <http://purl.org/dc/terms/> .

<https://ujg.specs.openuji.org/ed/ns/design-system#> a owl:Ontology ;
  rdfs:label "UJG Design System Editor's Draft Vocabulary"@en ;
  dct:description "UJG Design System ontology declaration" .

### Classes

ujgds:DesignSystem a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:TokenSource a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Component a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Template a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:Slot a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:SurfaceRealization a owl:Class ;
  rdfs:subClassOf ujg:Node .

ujgds:SlotBinding a owl:Class ;
  rdfs:subClassOf ujg:Node .

### Properties

ujgds:tokenSourceRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:TokenSource .

ujgds:componentRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:Component .

ujgds:templateRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:Template .

ujgds:surfaceRealizationRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:DesignSystem ;
  rdfs:range ujgds:SurfaceRealization .

ujgds:surfaceRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgsurface:Surface .

ujgds:componentRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:Component .

ujgds:templateRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:Template .

ujgds:slotBindingRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:SurfaceRealization ;
  rdfs:range ujgds:SlotBinding .

ujgds:slotRefs a owl:ObjectProperty ;
  rdfs:domain ujgds:Template ;
  rdfs:range ujgds:Slot .

ujgds:slotRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgds:Slot .

ujgds:targetSurfaceRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgsurface:Surface .

ujgds:targetComponentRef a owl:ObjectProperty ;
  rdfs:domain ujgds:SlotBinding ;
  rdfs:range ujgds:Component .

13.2. JSON-LD Context

The normative DesignSystem JSON-LD context is defined below and is published at https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld. It provides compact JSON-LD term mappings and coercions for DesignSystem-specific properties and classes.

Surface uses graphNodeRef for graph-node attachment. This module keeps a separate, type-scoped surfaceRef on SurfaceRealization, where it means realization-to-Surface. Surface also defines surfaceRef on SurfaceInstance, where it means surface-instance-to-Surface. Design System realization and slot-binding references continue to target stable Surface nodes, not SurfaceInstance nodes.

json-ld
{
  "@context": {
    "@version": 1.1,

    "ujgds": "https://ujg.specs.openuji.org/ed/ns/design-system#",
    "designSystem": "https://ujg.specs.openuji.org/ed/ns/design-system#",
    "surface": "https://ujg.specs.openuji.org/ed/ns/surface#",

    "DesignSystem": "ujgds:DesignSystem",
    "TokenSource": "ujgds:TokenSource",
    "Component": "ujgds:Component",
    "Template": "ujgds:Template",
    "Slot": "ujgds:Slot",
    "SurfaceRealization": {
      "@id": "ujgds:SurfaceRealization",
      "@context": {
        "surfaceRef": {
          "@id": "ujgds:surfaceRef",
          "@type": "@id"
        }
      }
    },
    "SlotBinding": "ujgds:SlotBinding",

    "tokenSourceRefs": {
      "@id": "ujgds:tokenSourceRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "componentRefs": {
      "@id": "ujgds:componentRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "templateRefs": {
      "@id": "ujgds:templateRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "surfaceRealizationRefs": {
      "@id": "ujgds:surfaceRealizationRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "componentRef": {
      "@id": "ujgds:componentRef",
      "@type": "@id"
    },
    "templateRef": {
      "@id": "ujgds:templateRef",
      "@type": "@id"
    },
    "slotBindingRefs": {
      "@id": "ujgds:slotBindingRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "slotRefs": {
      "@id": "ujgds:slotRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "slotRef": {
      "@id": "ujgds:slotRef",
      "@type": "@id"
    },
    "targetSurfaceRef": {
      "@id": "ujgds:targetSurfaceRef",
      "@type": "@id"
    },
    "targetComponentRef": {
      "@id": "ujgds:targetComponentRef",
      "@type": "@id"
    }
  }
}
{
  "@context": {
    "@version": 1.1,

    "ujgds": "https://ujg.specs.openuji.org/ed/ns/design-system#",
    "designSystem": "https://ujg.specs.openuji.org/ed/ns/design-system#",
    "surface": "https://ujg.specs.openuji.org/ed/ns/surface#",

    "DesignSystem": "ujgds:DesignSystem",
    "TokenSource": "ujgds:TokenSource",
    "Component": "ujgds:Component",
    "Template": "ujgds:Template",
    "Slot": "ujgds:Slot",
    "SurfaceRealization": {
      "@id": "ujgds:SurfaceRealization",
      "@context": {
        "surfaceRef": {
          "@id": "ujgds:surfaceRef",
          "@type": "@id"
        }
      }
    },
    "SlotBinding": "ujgds:SlotBinding",

    "tokenSourceRefs": {
      "@id": "ujgds:tokenSourceRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "componentRefs": {
      "@id": "ujgds:componentRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "templateRefs": {
      "@id": "ujgds:templateRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "surfaceRealizationRefs": {
      "@id": "ujgds:surfaceRealizationRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "componentRef": {
      "@id": "ujgds:componentRef",
      "@type": "@id"
    },
    "templateRef": {
      "@id": "ujgds:templateRef",
      "@type": "@id"
    },
    "slotBindingRefs": {
      "@id": "ujgds:slotBindingRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "slotRefs": {
      "@id": "ujgds:slotRefs",
      "@type": "@id",
      "@container": "@set"
    },
    "slotRef": {
      "@id": "ujgds:slotRef",
      "@type": "@id"
    },
    "targetSurfaceRef": {
      "@id": "ujgds:targetSurfaceRef",
      "@type": "@id"
    },
    "targetComponentRef": {
      "@id": "ujgds:targetComponentRef",
      "@type": "@id"
    }
  }
}

13.3. Validation

The normative DesignSystem SHACL shape is defined below and is published at https://ujg.specs.openuji.org/ed/ns/design-system.shape. It is the authoritative validation artifact for DesignSystem structural constraints.

turtle
@prefix ujgds: <https://ujg.specs.openuji.org/ed/ns/design-system#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/ed/ns/surface#> .
@prefix ujgdsshape: <https://ujg.specs.openuji.org/ed/ns/design-system.shape#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

ujgdsshape:DesignSystemShape a sh:NodeShape ;
  sh:targetClass ujgds:DesignSystem ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:tokenSourceRefs ;
    sh:class ujgds:TokenSource ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:componentRefs ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:templateRefs ;
    sh:class ujgds:Template ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:surfaceRealizationRefs ;
    sh:class ujgds:SurfaceRealization ;
    sh:nodeKind sh:IRI ;
  ] .

ujgdsshape:TokenSourceShape a sh:NodeShape ;
  sh:targetClass ujgds:TokenSource ;
  sh:nodeKind sh:IRI .

ujgdsshape:ComponentShape a sh:NodeShape ;
  sh:targetClass ujgds:Component ;
  sh:nodeKind sh:IRI .

ujgdsshape:TemplateShape a sh:NodeShape ;
  sh:targetClass ujgds:Template ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:slotRefs ;
    sh:class ujgds:Slot ;
    sh:nodeKind sh:IRI ;
  ] .

ujgdsshape:SlotShape a sh:NodeShape ;
  sh:targetClass ujgds:Slot ;
  sh:nodeKind sh:IRI .

ujgdsshape:SurfaceRealizationShape a sh:NodeShape ;
  sh:targetClass ujgds:SurfaceRealization ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:surfaceRef ;
    sh:class ujgsurface:Surface ;
    sh:nodeKind sh:IRI ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:componentRef ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:templateRef ;
    sh:class ujgds:Template ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:slotBindingRefs ;
    sh:class ujgds:SlotBinding ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SurfaceRealization must reference exactly one primary realization through componentRef or templateRef." ;
    sh:select """
      SELECT $this
      WHERE {
        BIND (EXISTS { $this ujgds:componentRef ?component . } AS ?hasComponent)
        BIND (EXISTS { $this ujgds:templateRef ?template . } AS ?hasTemplate)
        FILTER ((?hasComponent && ?hasTemplate) || (!?hasComponent && !?hasTemplate))
      }
    """ ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SurfaceRealization may reference slotBindingRefs only when templateRef is present." ;
    sh:select """
      SELECT $this
      WHERE {
        $this ujgds:slotBindingRefs ?slotBinding .
        FILTER (NOT EXISTS { $this ujgds:templateRef ?template . })
      }
    """ ;
  ] .

ujgdsshape:SlotBindingShape a sh:NodeShape ;
  sh:targetClass ujgds:SlotBinding ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:slotRef ;
    sh:class ujgds:Slot ;
    sh:nodeKind sh:IRI ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:targetSurfaceRef ;
    sh:class ujgsurface:Surface ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:targetComponentRef ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SlotBinding must reference exactly one target." ;
    sh:select """
      SELECT $this
      WHERE {
        BIND (EXISTS { $this ujgds:targetSurfaceRef ?surface . } AS ?hasSurface)
        BIND (EXISTS { $this ujgds:targetComponentRef ?component . } AS ?hasComponent)
        BIND (
          IF(?hasSurface, 1, 0) +
          IF(?hasComponent, 1, 0)
          AS ?targetCount
        )
        FILTER (?targetCount != 1)
      }
    """ ;
  ] .
@prefix ujgds: <https://ujg.specs.openuji.org/ed/ns/design-system#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/ed/ns/surface#> .
@prefix ujgdsshape: <https://ujg.specs.openuji.org/ed/ns/design-system.shape#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

ujgdsshape:DesignSystemShape a sh:NodeShape ;
  sh:targetClass ujgds:DesignSystem ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:tokenSourceRefs ;
    sh:class ujgds:TokenSource ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:componentRefs ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:templateRefs ;
    sh:class ujgds:Template ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:property [
    sh:path ujgds:surfaceRealizationRefs ;
    sh:class ujgds:SurfaceRealization ;
    sh:nodeKind sh:IRI ;
  ] .

ujgdsshape:TokenSourceShape a sh:NodeShape ;
  sh:targetClass ujgds:TokenSource ;
  sh:nodeKind sh:IRI .

ujgdsshape:ComponentShape a sh:NodeShape ;
  sh:targetClass ujgds:Component ;
  sh:nodeKind sh:IRI .

ujgdsshape:TemplateShape a sh:NodeShape ;
  sh:targetClass ujgds:Template ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:slotRefs ;
    sh:class ujgds:Slot ;
    sh:nodeKind sh:IRI ;
  ] .

ujgdsshape:SlotShape a sh:NodeShape ;
  sh:targetClass ujgds:Slot ;
  sh:nodeKind sh:IRI .

ujgdsshape:SurfaceRealizationShape a sh:NodeShape ;
  sh:targetClass ujgds:SurfaceRealization ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:surfaceRef ;
    sh:class ujgsurface:Surface ;
    sh:nodeKind sh:IRI ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:componentRef ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:templateRef ;
    sh:class ujgds:Template ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:slotBindingRefs ;
    sh:class ujgds:SlotBinding ;
    sh:nodeKind sh:IRI ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SurfaceRealization must reference exactly one primary realization through componentRef or templateRef." ;
    sh:select """
      SELECT $this
      WHERE {
        BIND (EXISTS { $this ujgds:componentRef ?component . } AS ?hasComponent)
        BIND (EXISTS { $this ujgds:templateRef ?template . } AS ?hasTemplate)
        FILTER ((?hasComponent && ?hasTemplate) || (!?hasComponent && !?hasTemplate))
      }
    """ ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SurfaceRealization may reference slotBindingRefs only when templateRef is present." ;
    sh:select """
      SELECT $this
      WHERE {
        $this ujgds:slotBindingRefs ?slotBinding .
        FILTER (NOT EXISTS { $this ujgds:templateRef ?template . })
      }
    """ ;
  ] .

ujgdsshape:SlotBindingShape a sh:NodeShape ;
  sh:targetClass ujgds:SlotBinding ;
  sh:nodeKind sh:IRI ;

  sh:property [
    sh:path ujgds:slotRef ;
    sh:class ujgds:Slot ;
    sh:nodeKind sh:IRI ;
    sh:minCount 1 ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:targetSurfaceRef ;
    sh:class ujgsurface:Surface ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:property [
    sh:path ujgds:targetComponentRef ;
    sh:class ujgds:Component ;
    sh:nodeKind sh:IRI ;
    sh:maxCount 1 ;
  ] ;

  sh:sparql [
    a sh:SPARQLConstraint ;
    sh:message "A SlotBinding must reference exactly one target." ;
    sh:select """
      SELECT $this
      WHERE {
        BIND (EXISTS { $this ujgds:targetSurfaceRef ?surface . } AS ?hasSurface)
        BIND (EXISTS { $this ujgds:targetComponentRef ?component . } AS ?hasComponent)
        BIND (
          IF(?hasSurface, 1, 0) +
          IF(?hasComponent, 1, 0)
          AS ?targetCount
        )
        FILTER (?targetCount != 1)
      }
    """ ;
  ] .

The rules below define the remaining module semantics beyond the structural constraints captured by the SHACL shape.

  1. Surface purity: DesignSystem properties MUST NOT change Surface attachment semantics or make a Surface depend on design-system artifacts.

  2. Realization bridge: A SurfaceRealization MUST reference exactly one Surface.

  3. Primary realization: A SurfaceRealization MUST reference exactly one primary realization, either a Component or a Template.

  4. Template-only bindings: slotBindingRefs MUST be used only by a SurfaceRealization that references a Template.

  5. Slot declaration vs binding: Template slot references are declarations. SurfaceRealization slot bindings are concrete assembly for that realization.

  6. Single binding target: A SlotBinding MUST reference exactly one target, either a Surface or a Component.

  7. Presentation only: A slot binding to a surface MUST NOT imply graph traversal, state activation, transition validity, composite-state containment, execution order, or lifecycle semantics.

  8. Graceful degradation: A consumer that does not implement this module MAY ignore DesignSystem semantics, but it SHOULD preserve recognized JSON-LD data during read-transform-write when possible.

  9. Private details: Component internals, token syntax, framework adapters, render plans, and platform-specific behavior SHOULD remain outside this module unless a future module defines them as interoperable vocabulary.

14. MCP And Tooling Resolution

MCP servers, skills, AI tooling, design-system resolvers, and renderers MAY use referenced node IDs plus active graph context to fetch implementation details. Those details can include framework components, source files, Storybook entries, token files, runtime render plans, or platform adapters.

This module intentionally standardizes only the graph-native references needed for interoperability. It does not duplicate design-system implementation catalogs or renderer configuration.

15. Relationship To Core Extensions

Core extensions remains available for vendor-private, non-interoperable payloads. Component, template, slot, slot-binding, surface-realization, and token-source relationships intended for interoperability SHOULD use this module instead of opaque extension payloads.

16. Examples

16.1. Example A: Surface Without Realization

json
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld"
  ],
  "@id": "https://example.com/ujg/surface-only.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:cart",
      "@type": "State",
      "label": "Cart"
    },
    {
      "@id": "urn:surface:cart",
      "@type": "Surface",
      "graphNodeRef": "urn:state:cart"
    }
  ]
}
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld"
  ],
  "@id": "https://example.com/ujg/surface-only.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:cart",
      "@type": "State",
      "label": "Cart"
    },
    {
      "@id": "urn:surface:cart",
      "@type": "Surface",
      "graphNodeRef": "urn:state:cart"
    }
  ]
}

This example assigns a state to a surface. It does not declare any design-system realization.

16.2. Example B: Component Realization

json
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/cart-component.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:cart",
      "@type": "State",
      "label": "Cart"
    },
    {
      "@id": "urn:surface:cart",
      "@type": "Surface",
      "graphNodeRef": "urn:state:cart"
    },
    {
      "@id": "urn:ds:acme",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:CartView"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:cart-web"
      ]
    },
    {
      "@id": "urn:component:CartView",
      "@type": "Component"
    },
    {
      "@id": "urn:realization:cart-web",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:cart",
      "componentRef": "urn:component:CartView"
    }
  ]
}
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/cart-component.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:cart",
      "@type": "State",
      "label": "Cart"
    },
    {
      "@id": "urn:surface:cart",
      "@type": "Surface",
      "graphNodeRef": "urn:state:cart"
    },
    {
      "@id": "urn:ds:acme",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:CartView"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:cart-web"
      ]
    },
    {
      "@id": "urn:component:CartView",
      "@type": "Component"
    },
    {
      "@id": "urn:realization:cart-web",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:cart",
      "componentRef": "urn:component:CartView"
    }
  ]
}

The surface remains unchanged. The design system owns the realization node that points to the surface.

16.3. Example C: Template Realization

json
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/refund-template.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:refund",
      "@type": "State",
      "label": "Refund request"
    },
    {
      "@id": "urn:surface:refund",
      "@type": "Surface",
      "graphNodeRef": "urn:state:refund"
    },
    {
      "@id": "urn:transition:submit-refund",
      "@type": "Transition",
      "from": "urn:state:refund",
      "to": "urn:state:refund-submitted"
    },
    {
      "@id": "urn:surface:submit-refund",
      "@type": "Surface",
      "graphNodeRef": "urn:transition:submit-refund"
    },
    {
      "@id": "urn:ds:acme",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:RefundForm"
      ],
      "templateRefs": [
        "urn:template:FormShell"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:refund-form"
      ]
    },
    {
      "@id": "urn:component:RefundForm",
      "@type": "Component"
    },
    {
      "@id": "urn:template:FormShell",
      "@type": "Template",
      "slotRefs": [
        "urn:slot:main",
        "urn:slot:submit"
      ]
    },
    {
      "@id": "urn:slot:main",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:submit",
      "@type": "Slot"
    },
    {
      "@id": "urn:binding:refund-main",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:main",
      "targetComponentRef": "urn:component:RefundForm"
    },
    {
      "@id": "urn:binding:refund-submit",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:submit",
      "targetSurfaceRef": "urn:surface:submit-refund"
    },
    {
      "@id": "urn:realization:refund-form",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:refund",
      "templateRef": "urn:template:FormShell",
      "slotBindingRefs": [
        "urn:binding:refund-main",
        "urn:binding:refund-submit"
      ]
    }
  ]
}
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/refund-template.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:refund",
      "@type": "State",
      "label": "Refund request"
    },
    {
      "@id": "urn:surface:refund",
      "@type": "Surface",
      "graphNodeRef": "urn:state:refund"
    },
    {
      "@id": "urn:transition:submit-refund",
      "@type": "Transition",
      "from": "urn:state:refund",
      "to": "urn:state:refund-submitted"
    },
    {
      "@id": "urn:surface:submit-refund",
      "@type": "Surface",
      "graphNodeRef": "urn:transition:submit-refund"
    },
    {
      "@id": "urn:ds:acme",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:RefundForm"
      ],
      "templateRefs": [
        "urn:template:FormShell"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:refund-form"
      ]
    },
    {
      "@id": "urn:component:RefundForm",
      "@type": "Component"
    },
    {
      "@id": "urn:template:FormShell",
      "@type": "Template",
      "slotRefs": [
        "urn:slot:main",
        "urn:slot:submit"
      ]
    },
    {
      "@id": "urn:slot:main",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:submit",
      "@type": "Slot"
    },
    {
      "@id": "urn:binding:refund-main",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:main",
      "targetComponentRef": "urn:component:RefundForm"
    },
    {
      "@id": "urn:binding:refund-submit",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:submit",
      "targetSurfaceRef": "urn:surface:submit-refund"
    },
    {
      "@id": "urn:realization:refund-form",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:refund",
      "templateRef": "urn:template:FormShell",
      "slotBindingRefs": [
        "urn:binding:refund-main",
        "urn:binding:refund-submit"
      ]
    }
  ]
}

The template declares slots. The realization binds those slots for this surface.

16.4. Example D: Composite Surface With Child Surfaces

json
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/product-discovery.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:product-discovery",
      "@type": "CompositeState",
      "label": "Product discovery",
      "subjourneyId": "urn:journey:product-discovery"
    },
    {
      "@id": "urn:journey:product-discovery",
      "@type": "Journey",
      "defaultEntryRef": "urn:entry:product-discovery-default",
      "entryRefs": [
        "urn:entry:product-discovery-default"
      ],
      "stateRefs": [
        "urn:state:search-query",
        "urn:state:filters",
        "urn:state:results",
        "urn:state:product-preview"
      ],
      "transitionRefs": [
        "urn:transition:search-to-filters",
        "urn:transition:filters-to-results",
        "urn:transition:results-to-preview"
      ]
    },
    {
      "@type": "JourneyEntry",
      "@id": "urn:entry:product-discovery-default",
      "stateRef": "urn:state:search-query"
    },
    {
      "@id": "urn:state:search-query",
      "@type": "State",
      "label": "Search query"
    },
    {
      "@id": "urn:state:filters",
      "@type": "State",
      "label": "Filters"
    },
    {
      "@id": "urn:state:results",
      "@type": "State",
      "label": "Results"
    },
    {
      "@id": "urn:state:product-preview",
      "@type": "State",
      "label": "Product preview"
    },
    {
      "@id": "urn:transition:search-to-filters",
      "@type": "Transition",
      "from": "urn:state:search-query",
      "to": "urn:state:filters",
      "label": "Refine"
    },
    {
      "@id": "urn:transition:filters-to-results",
      "@type": "Transition",
      "from": "urn:state:filters",
      "to": "urn:state:results",
      "label": "Apply filters"
    },
    {
      "@id": "urn:transition:results-to-preview",
      "@type": "Transition",
      "from": "urn:state:results",
      "to": "urn:state:product-preview",
      "label": "Preview product"
    },
    {
      "@id": "urn:surface:product-discovery",
      "@type": "Surface",
      "graphNodeRef": "urn:state:product-discovery"
    },
    {
      "@id": "urn:surface:search-query",
      "@type": "Surface",
      "graphNodeRef": "urn:state:search-query"
    },
    {
      "@id": "urn:surface:filters",
      "@type": "Surface",
      "graphNodeRef": "urn:state:filters"
    },
    {
      "@id": "urn:surface:results",
      "@type": "Surface",
      "graphNodeRef": "urn:state:results"
    },
    {
      "@id": "urn:surface:product-preview",
      "@type": "Surface",
      "graphNodeRef": "urn:state:product-preview"
    },
    {
      "@id": "urn:template:ProductDiscovery",
      "@type": "Template",
      "slotRefs": [
        "urn:slot:search",
        "urn:slot:filters",
        "urn:slot:results",
        "urn:slot:preview"
      ]
    },
    {
      "@id": "urn:slot:search",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:filters",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:results",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:preview",
      "@type": "Slot"
    },
    {
      "@id": "urn:binding:search",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:search",
      "targetSurfaceRef": "urn:surface:search-query"
    },
    {
      "@id": "urn:binding:filters",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:filters",
      "targetSurfaceRef": "urn:surface:filters"
    },
    {
      "@id": "urn:binding:results",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:results",
      "targetSurfaceRef": "urn:surface:results"
    },
    {
      "@id": "urn:binding:preview",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:preview",
      "targetSurfaceRef": "urn:surface:product-preview"
    },
    {
      "@id": "urn:realization:product-discovery",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:product-discovery",
      "templateRef": "urn:template:ProductDiscovery",
      "slotBindingRefs": [
        "urn:binding:search",
        "urn:binding:filters",
        "urn:binding:results",
        "urn:binding:preview"
      ]
    },
    {
      "@id": "urn:ds:commerce",
      "@type": "DesignSystem",
      "templateRefs": [
        "urn:template:ProductDiscovery"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:product-discovery"
      ]
    }
  ]
}
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/product-discovery.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:product-discovery",
      "@type": "CompositeState",
      "label": "Product discovery",
      "subjourneyId": "urn:journey:product-discovery"
    },
    {
      "@id": "urn:journey:product-discovery",
      "@type": "Journey",
      "defaultEntryRef": "urn:entry:product-discovery-default",
      "entryRefs": [
        "urn:entry:product-discovery-default"
      ],
      "stateRefs": [
        "urn:state:search-query",
        "urn:state:filters",
        "urn:state:results",
        "urn:state:product-preview"
      ],
      "transitionRefs": [
        "urn:transition:search-to-filters",
        "urn:transition:filters-to-results",
        "urn:transition:results-to-preview"
      ]
    },
    {
      "@type": "JourneyEntry",
      "@id": "urn:entry:product-discovery-default",
      "stateRef": "urn:state:search-query"
    },
    {
      "@id": "urn:state:search-query",
      "@type": "State",
      "label": "Search query"
    },
    {
      "@id": "urn:state:filters",
      "@type": "State",
      "label": "Filters"
    },
    {
      "@id": "urn:state:results",
      "@type": "State",
      "label": "Results"
    },
    {
      "@id": "urn:state:product-preview",
      "@type": "State",
      "label": "Product preview"
    },
    {
      "@id": "urn:transition:search-to-filters",
      "@type": "Transition",
      "from": "urn:state:search-query",
      "to": "urn:state:filters",
      "label": "Refine"
    },
    {
      "@id": "urn:transition:filters-to-results",
      "@type": "Transition",
      "from": "urn:state:filters",
      "to": "urn:state:results",
      "label": "Apply filters"
    },
    {
      "@id": "urn:transition:results-to-preview",
      "@type": "Transition",
      "from": "urn:state:results",
      "to": "urn:state:product-preview",
      "label": "Preview product"
    },
    {
      "@id": "urn:surface:product-discovery",
      "@type": "Surface",
      "graphNodeRef": "urn:state:product-discovery"
    },
    {
      "@id": "urn:surface:search-query",
      "@type": "Surface",
      "graphNodeRef": "urn:state:search-query"
    },
    {
      "@id": "urn:surface:filters",
      "@type": "Surface",
      "graphNodeRef": "urn:state:filters"
    },
    {
      "@id": "urn:surface:results",
      "@type": "Surface",
      "graphNodeRef": "urn:state:results"
    },
    {
      "@id": "urn:surface:product-preview",
      "@type": "Surface",
      "graphNodeRef": "urn:state:product-preview"
    },
    {
      "@id": "urn:template:ProductDiscovery",
      "@type": "Template",
      "slotRefs": [
        "urn:slot:search",
        "urn:slot:filters",
        "urn:slot:results",
        "urn:slot:preview"
      ]
    },
    {
      "@id": "urn:slot:search",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:filters",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:results",
      "@type": "Slot"
    },
    {
      "@id": "urn:slot:preview",
      "@type": "Slot"
    },
    {
      "@id": "urn:binding:search",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:search",
      "targetSurfaceRef": "urn:surface:search-query"
    },
    {
      "@id": "urn:binding:filters",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:filters",
      "targetSurfaceRef": "urn:surface:filters"
    },
    {
      "@id": "urn:binding:results",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:results",
      "targetSurfaceRef": "urn:surface:results"
    },
    {
      "@id": "urn:binding:preview",
      "@type": "SlotBinding",
      "slotRef": "urn:slot:preview",
      "targetSurfaceRef": "urn:surface:product-preview"
    },
    {
      "@id": "urn:realization:product-discovery",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:product-discovery",
      "templateRef": "urn:template:ProductDiscovery",
      "slotBindingRefs": [
        "urn:binding:search",
        "urn:binding:filters",
        "urn:binding:results",
        "urn:binding:preview"
      ]
    },
    {
      "@id": "urn:ds:commerce",
      "@type": "DesignSystem",
      "templateRefs": [
        "urn:template:ProductDiscovery"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:product-discovery"
      ]
    }
  ]
}

The composite state's surface is realized as a shell. Child containment comes from the subjourney referenced by subjourneyId. The child surfaces are placed into slots for presentation only; Graph remains the source of containment and traversal semantics.

16.5. Example E: Multiple Design Systems

json
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/multiple-design-systems.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:checkout",
      "@type": "State",
      "label": "Checkout"
    },
    {
      "@id": "urn:surface:checkout",
      "@type": "Surface",
      "graphNodeRef": "urn:state:checkout"
    },
    {
      "@id": "urn:component:WebCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:component:KioskCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:component:CliCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:realization:checkout-web",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:WebCheckout"
    },
    {
      "@id": "urn:realization:checkout-kiosk",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:KioskCheckout"
    },
    {
      "@id": "urn:realization:checkout-cli",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:CliCheckout"
    },
    {
      "@id": "urn:ds:web",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:WebCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-web"
      ]
    },
    {
      "@id": "urn:ds:kiosk",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:KioskCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-kiosk"
      ]
    },
    {
      "@id": "urn:ds:cli",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:CliCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-cli"
      ]
    }
  ]
}
{
  "@context": [
    "https://ujg.specs.openuji.org/ed/ns/core.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/graph.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
    "https://ujg.specs.openuji.org/ed/ns/design-system.context.jsonld"
  ],
  "@id": "https://example.com/ujg/multiple-design-systems.jsonld",
  "@type": "UJGDocument",
  "nodes": [
    {
      "@id": "urn:state:checkout",
      "@type": "State",
      "label": "Checkout"
    },
    {
      "@id": "urn:surface:checkout",
      "@type": "Surface",
      "graphNodeRef": "urn:state:checkout"
    },
    {
      "@id": "urn:component:WebCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:component:KioskCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:component:CliCheckout",
      "@type": "Component"
    },
    {
      "@id": "urn:realization:checkout-web",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:WebCheckout"
    },
    {
      "@id": "urn:realization:checkout-kiosk",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:KioskCheckout"
    },
    {
      "@id": "urn:realization:checkout-cli",
      "@type": "SurfaceRealization",
      "surfaceRef": "urn:surface:checkout",
      "componentRef": "urn:component:CliCheckout"
    },
    {
      "@id": "urn:ds:web",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:WebCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-web"
      ]
    },
    {
      "@id": "urn:ds:kiosk",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:KioskCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-kiosk"
      ]
    },
    {
      "@id": "urn:ds:cli",
      "@type": "DesignSystem",
      "componentRefs": [
        "urn:component:CliCheckout"
      ],
      "surfaceRealizationRefs": [
        "urn:realization:checkout-cli"
      ]
    }
  ]
}

The same surface can be realized by several design systems. The surface identity remains stable.

Copyright © 2026 the Contributors to the ujg/modules/design-system, published by the User Journal Graph Community Group under the W3C Community Contributor License Agreement (CLA) . A human-readable summary is available.

generated by Speculator