Artifact
draftStatus 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 .
1. Overview
This optional module defines a minimal vocabulary for addressable artifacts that can participate as resources in a journey.
An artifact is a portable identity for a file, media object, archive, token, invite, report,
protocol object, generated document, or other resource that participates in a journey. An
Artifact is a concrete [UJG Effect] EffectResource, so effects can reference artifacts through
generic producedRefs and consumedRefs. An artifact can also identify the source and target
touchpoints where that resource is produced and consumed, and it can reference a localized
human-facing name. The module does not define storage backends, transfer protocols, upload widgets,
media processing, or artifact lifecycle state. Modules and profiles can specialize Artifact when
they need more domain-specific semantics.
2. Terminology
Artifact: An addressable resource that may be produced, consumed, exchanged, or referenced during a journey.
Artifact name: A localized MessageMeta referenced by an artifact as its human-facing name.
Produced artifact: An artifact created, emitted, prepared, exported, generated, or made available by an Effect.
Consumed artifact: An artifact accepted, imported, read, redeemed, or otherwise used by an Effect.
Artifact source touchpoint: The touchpoint where an artifact is produced, exported, or made available.
Artifact target touchpoint: A touchpoint where an artifact is consumed, imported, redeemed, or otherwise used.
3. Artifact
An Artifact is an addressable portable resource identity and a concrete EffectResource. It can be referenced by producing or consuming effects, and it can identify source and target touchpoints when the resource crosses touchpoint boundaries. It does not define transfer, storage, rendering, security, or lifecycle semantics.
An Artifact MUST be identified by an IRI.
An Artifact MAY declare at most one
nameRef.Every
nameRefvalue MUST reference a MessageMeta.An Artifact MAY declare at most one
sourceTouchpointRef.Every
sourceTouchpointRefvalue MUST reference a Touchpoint.An Artifact MAY declare one or more
targetTouchpointRefs.Every
targetTouchpointRefsvalue MUST reference a Touchpoint.nameRef,sourceTouchpointRef, andtargetTouchpointRefsMUST NOT create hidden Graph edges, change traversal behavior, assert delivery, or change Runtime event ordering.
classDiagram
class Touchpoint
class MessageMeta
class EffectResource
class Artifact {
id
nameRef
sourceTouchpointRef
targetTouchpointRefs
}
EffectResource <|-- Artifact
Artifact --> MessageMeta : nameRef
Artifact --> Touchpoint : sourceTouchpointRef
Artifact --> "0..*" Touchpoint : targetTouchpointRefs Example JSON node:
{
"@id": "urn:artifact:account-archive",
"@type": "Artifact",
"nameRef": "urn:l10n:message-meta:account-archive-name",
"sourceTouchpointRef": "urn:touchpoint:old-server",
"targetTouchpointRefs": ["urn:touchpoint:new-server"]
} {
"@id": "urn:artifact:account-archive",
"@type": "Artifact",
"nameRef": "urn:l10n:message-meta:account-archive-name",
"sourceTouchpointRef": "urn:touchpoint:old-server",
"targetTouchpointRefs": ["urn:touchpoint:new-server"]
} 4. Localized Names
artifact:nameRef links an Artifact to one MessageMeta that provides the artifact's
human-facing name. Locale-specific Message nodes MAY use opaque values and argumentNames.
nameRef is descriptive metadata on the artifact. It does not determine production, consumption,
transfer, storage, availability, rendering, or lifecycle state.
5. Effect Integration
The Artifact module introduces artifact-owned references:
artifact:nameReflinks an Artifact to the localized MessageMeta used as its human-facing name.artifact:sourceTouchpointReflinks an Artifact to the Touchpoint where it is produced, exported, or made available.artifact:targetTouchpointRefslinks an Artifact to one or more Touchpoints where it is consumed, imported, redeemed, or otherwise used.
Production and consumption relationships are defined by [UJG Effect], not by this module. Effects
use producedRefs and consumedRefs to point to Artifact nodes. Producers SHOULD NOT use those
references to create hidden Graph traversal or to replace Graph Transition semantics.
Touchpoint metadata belongs to the Artifact, not the producing or consuming Effect. Effects
declare only producedRefs and consumedRefs; the referenced artifact declares where it crosses
touchpoint boundaries.
6. Non-Goals
Artifact does not define:
upload, download, or preview presentation
media-kind taxonomies
storage, CDN, filesystem, or database details
protocol delivery semantics
artifact lifecycle, freshness, or cache policy
validation of artifact payload contents
cross-touchpoint effect semantics beyond artifact-owned touchpoint metadata
The archived artifact implementation extension remains useful for generator-specific upload and preview hints, but those hints are not part of this module.
7. Normative Artifacts
This module is published through the following artifacts:
artifact.ttl: ontology, published athttps://ujg.specs.openuji.org/tr/1.0/ns/artifactartifact.context.jsonld: JSON-LD term mappings, published athttps://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonldartifact.shape.ttl: SHACL validation rules, published athttps://ujg.specs.openuji.org/tr/1.0/ns/artifact.shape
Examples in this page compose the Core context with the Artifact context. Examples that use effects
also compose the Effect context; examples that use touchpoint metadata also compose the Surface
context; examples that use nameRef also compose the Localization context.
7.1. Ontology
The normative Artifact ontology is defined below and is published at
https://ujg.specs.openuji.org/tr/1.0/ns/artifact.
@prefix ujg: <https://ujg.specs.openuji.org/tr/1.0/ns/core#> .
@prefix ujgartifact: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/tr/1.0/ns/effect#> .
@prefix ujgl10n: <https://ujg.specs.openuji.org/tr/1.0/ns/l10n#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/tr/1.0/ns/surface#> .
@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/tr/1.0/ns/artifact#> a owl:Ontology ;
rdfs:label "UJG Artifact 1.0 Vocabulary"@en ;
dct:description "UJG Artifact ontology declaration" .
### Classes
ujgartifact:Artifact a owl:Class ;
rdfs:subClassOf ujg:Node, ujgeffect:EffectResource .
### Properties
ujgartifact:nameRef a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgl10n:MessageMeta ;
rdfs:label "name ref" ;
rdfs:comment "References localized MessageMeta used as the artifact's human-facing name." .
ujgartifact:sourceTouchpointRef a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgsurface:Touchpoint ;
rdfs:label "source touchpoint ref" ;
rdfs:comment "References the Touchpoint where this artifact is produced, exported, or made available." .
ujgartifact:targetTouchpointRefs a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgsurface:Touchpoint ;
rdfs:label "target touchpoint refs" ;
rdfs:comment "References Touchpoints where this artifact is consumed, imported, redeemed, or otherwise used." . @prefix ujg: <https://ujg.specs.openuji.org/tr/1.0/ns/core#> .
@prefix ujgartifact: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/tr/1.0/ns/effect#> .
@prefix ujgl10n: <https://ujg.specs.openuji.org/tr/1.0/ns/l10n#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/tr/1.0/ns/surface#> .
@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/tr/1.0/ns/artifact#> a owl:Ontology ;
rdfs:label "UJG Artifact 1.0 Vocabulary"@en ;
dct:description "UJG Artifact ontology declaration" .
### Classes
ujgartifact:Artifact a owl:Class ;
rdfs:subClassOf ujg:Node, ujgeffect:EffectResource .
### Properties
ujgartifact:nameRef a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgl10n:MessageMeta ;
rdfs:label "name ref" ;
rdfs:comment "References localized MessageMeta used as the artifact's human-facing name." .
ujgartifact:sourceTouchpointRef a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgsurface:Touchpoint ;
rdfs:label "source touchpoint ref" ;
rdfs:comment "References the Touchpoint where this artifact is produced, exported, or made available." .
ujgartifact:targetTouchpointRefs a owl:ObjectProperty ;
rdfs:domain ujgartifact:Artifact ;
rdfs:range ujgsurface:Touchpoint ;
rdfs:label "target touchpoint refs" ;
rdfs:comment "References Touchpoints where this artifact is consumed, imported, redeemed, or otherwise used." . 7.2. JSON-LD Context
The normative Artifact JSON-LD context is defined below and is published at
https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld.
{
"@context": {
"@version": 1.1,
"ujgartifact": "https://ujg.specs.openuji.org/tr/1.0/ns/artifact#",
"artifact": "https://ujg.specs.openuji.org/tr/1.0/ns/artifact#",
"Artifact": "ujgartifact:Artifact",
"nameRef": {
"@id": "ujgartifact:nameRef",
"@type": "@id"
},
"sourceTouchpointRef": {
"@id": "ujgartifact:sourceTouchpointRef",
"@type": "@id"
},
"targetTouchpointRefs": {
"@id": "ujgartifact:targetTouchpointRefs",
"@type": "@id",
"@container": "@set"
}
}
} {
"@context": {
"@version": 1.1,
"ujgartifact": "https://ujg.specs.openuji.org/tr/1.0/ns/artifact#",
"artifact": "https://ujg.specs.openuji.org/tr/1.0/ns/artifact#",
"Artifact": "ujgartifact:Artifact",
"nameRef": {
"@id": "ujgartifact:nameRef",
"@type": "@id"
},
"sourceTouchpointRef": {
"@id": "ujgartifact:sourceTouchpointRef",
"@type": "@id"
},
"targetTouchpointRefs": {
"@id": "ujgartifact:targetTouchpointRefs",
"@type": "@id",
"@container": "@set"
}
}
} 7.3. Validation
The normative Artifact SHACL shape is defined below and is published at
https://ujg.specs.openuji.org/tr/1.0/ns/artifact.shape.
@prefix ujgartifact: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact#> .
@prefix ujgartifactshape: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact.shape#> .
@prefix ujgl10n: <https://ujg.specs.openuji.org/tr/1.0/ns/l10n#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/tr/1.0/ns/surface#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ujgartifactshape:ArtifactShape a sh:NodeShape ;
sh:targetClass ujgartifact:Artifact ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgartifact:nameRef ;
sh:class ujgl10n:MessageMeta ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujgartifact:sourceTouchpointRef ;
sh:class ujgsurface:Touchpoint ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujgartifact:targetTouchpointRefs ;
sh:class ujgsurface:Touchpoint ;
sh:nodeKind sh:IRI ;
] .
ujgartifactshape:ArtifactTouchpointUsageShape a sh:NodeShape ;
sh:targetSubjectsOf ujgartifact:sourceTouchpointRef ;
sh:targetSubjectsOf ujgartifact:targetTouchpointRefs ;
sh:class ujgartifact:Artifact ;
sh:nodeKind sh:IRI .
ujgartifactshape:ArtifactNameUsageShape a sh:NodeShape ;
sh:targetSubjectsOf ujgartifact:nameRef ;
sh:class ujgartifact:Artifact ;
sh:nodeKind sh:IRI . @prefix ujgartifact: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact#> .
@prefix ujgartifactshape: <https://ujg.specs.openuji.org/tr/1.0/ns/artifact.shape#> .
@prefix ujgl10n: <https://ujg.specs.openuji.org/tr/1.0/ns/l10n#> .
@prefix ujgsurface: <https://ujg.specs.openuji.org/tr/1.0/ns/surface#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ujgartifactshape:ArtifactShape a sh:NodeShape ;
sh:targetClass ujgartifact:Artifact ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgartifact:nameRef ;
sh:class ujgl10n:MessageMeta ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujgartifact:sourceTouchpointRef ;
sh:class ujgsurface:Touchpoint ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path ujgartifact:targetTouchpointRefs ;
sh:class ujgsurface:Touchpoint ;
sh:nodeKind sh:IRI ;
] .
ujgartifactshape:ArtifactTouchpointUsageShape a sh:NodeShape ;
sh:targetSubjectsOf ujgartifact:sourceTouchpointRef ;
sh:targetSubjectsOf ujgartifact:targetTouchpointRefs ;
sh:class ujgartifact:Artifact ;
sh:nodeKind sh:IRI .
ujgartifactshape:ArtifactNameUsageShape a sh:NodeShape ;
sh:targetSubjectsOf ujgartifact:nameRef ;
sh:class ujgartifact:Artifact ;
sh:nodeKind sh:IRI . The rules below define the remaining module semantics beyond the structural constraints captured by the SHACL shape.
Identity only:
Artifactidentifies a resource; it does not define transfer, storage, rendering, security, or lifecycle semantics.Effect resource:
Artifactis a concrete EffectResource and MAY be referenced by EffectproducedRefsorconsumedRefs.Graph preservation: Artifact references MUST NOT create hidden graph edges or change Graph traversal behavior.
Localized artifact names:
nameRefbelongs on Artifact and references one MessageMeta. It is descriptive metadata and does not define rendering, transfer, storage, or lifecycle semantics.Artifact-owned touchpoint metadata:
sourceTouchpointRefandtargetTouchpointRefsbelong on Artifact, not onEffect; effects only produce or consume resources.Graceful degradation: Consumers that do not implement this module MAY ignore Artifact semantics, but SHOULD preserve recognized JSON-LD data during read-transform-write when possible.
8. Examples
8.1. Minimal Example
{
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/export.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:effect:prepare-export",
"@type": "Effect",
"producedRefs": ["urn:artifact:account-archive"]
},
{
"@id": "urn:artifact:account-archive",
"@type": "Artifact"
}
]
} {
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/export.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:effect:prepare-export",
"@type": "Effect",
"producedRefs": ["urn:artifact:account-archive"]
},
{
"@id": "urn:artifact:account-archive",
"@type": "Artifact"
}
]
} 8.2. Localized Name Example
{
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/l10n.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/named-report.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@type": "l10n:Locale",
"@id": "urn:l10n:locale:en",
"l10n:localeCode": "en"
},
{
"@type": "l10n:MessageMeta",
"@id": "urn:l10n:message-meta:artifact-display-name",
"l10n:argumentNames": ["fileName"],
"l10n:defaultLocaleRef": "urn:l10n:locale:en"
},
{
"@type": "l10n:Message",
"@id": "urn:l10n:message:artifact-display-name:en",
"l10n:messageMetaRef": "urn:l10n:message-meta:artifact-display-name",
"l10n:localeRef": "urn:l10n:locale:en",
"l10n:value": "Report: ${fileName}"
},
{
"@id": "urn:artifact:account-report",
"@type": "Artifact",
"nameRef": "urn:l10n:message-meta:artifact-display-name"
}
]
} {
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/l10n.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/named-report.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@type": "l10n:Locale",
"@id": "urn:l10n:locale:en",
"l10n:localeCode": "en"
},
{
"@type": "l10n:MessageMeta",
"@id": "urn:l10n:message-meta:artifact-display-name",
"l10n:argumentNames": ["fileName"],
"l10n:defaultLocaleRef": "urn:l10n:locale:en"
},
{
"@type": "l10n:Message",
"@id": "urn:l10n:message:artifact-display-name:en",
"l10n:messageMetaRef": "urn:l10n:message-meta:artifact-display-name",
"l10n:localeRef": "urn:l10n:locale:en",
"l10n:value": "Report: ${fileName}"
},
{
"@id": "urn:artifact:account-report",
"@type": "Artifact",
"nameRef": "urn:l10n:message-meta:artifact-display-name"
}
]
} 8.3. Cross-Touchpoint Artifact Example
This example models a federated share as the resource crossing touchpoints. Effects only declare whether they produce or consume that resource.
{
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/surface.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/federated-share.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:touchpoint:nextcloud-a",
"@type": "Touchpoint",
"label": "Nextcloud A"
},
{
"@id": "urn:touchpoint:nextcloud-b",
"@type": "Touchpoint",
"label": "Nextcloud B"
},
{
"@id": "urn:artifact:federated-share",
"@type": "Artifact",
"label": "Federated share for the test file",
"sourceTouchpointRef": "urn:touchpoint:nextcloud-a",
"targetTouchpointRefs": [
"urn:touchpoint:nextcloud-b"
]
},
{
"@id": "urn:effect:alice-confirm-share",
"@type": "Effect",
"label": "Alice confirms the remote share",
"producedRefs": [
"urn:artifact:federated-share"
]
},
{
"@id": "urn:effect:bob-accept-share",
"@type": "Effect",
"label": "Bob accepts the incoming remote share",
"consumedRefs": [
"urn:artifact:federated-share"
]
},
{
"@id": "urn:effect:bob-open-accepted-file",
"@type": "Effect",
"label": "Bob opens the accepted file",
"consumedRefs": [
"urn:artifact:federated-share"
]
}
]
} {
"@context": [
"https://ujg.specs.openuji.org/tr/1.0/ns/core.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/surface.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/tr/1.0/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/artifact/federated-share.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:touchpoint:nextcloud-a",
"@type": "Touchpoint",
"label": "Nextcloud A"
},
{
"@id": "urn:touchpoint:nextcloud-b",
"@type": "Touchpoint",
"label": "Nextcloud B"
},
{
"@id": "urn:artifact:federated-share",
"@type": "Artifact",
"label": "Federated share for the test file",
"sourceTouchpointRef": "urn:touchpoint:nextcloud-a",
"targetTouchpointRefs": [
"urn:touchpoint:nextcloud-b"
]
},
{
"@id": "urn:effect:alice-confirm-share",
"@type": "Effect",
"label": "Alice confirms the remote share",
"producedRefs": [
"urn:artifact:federated-share"
]
},
{
"@id": "urn:effect:bob-accept-share",
"@type": "Effect",
"label": "Bob accepts the incoming remote share",
"consumedRefs": [
"urn:artifact:federated-share"
]
},
{
"@id": "urn:effect:bob-open-accepted-file",
"@type": "Effect",
"label": "Bob opens the accepted file",
"consumedRefs": [
"urn:artifact:federated-share"
]
}
]
}