Effect
incubatingStatus 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 graph-native vocabulary for attaching declared effects to Graph
Transition and OutgoingTransition nodes.
Without an effect primitive, implementations tend to hide form submission, API invocation, analytics events, generated data, or navigate-with-payload behavior in opaque extensions. That makes a graph appear to advance while the effect that caused or accompanies the transition remains non-portable.
This first version declares that an effective transition has an associated Effect. It also
defines generic produced and consumed resource references so an effect can point to concrete
resources from other modules, such as [UJG Artifact] Artifact, without the Effect module owning
those resource-specific semantics.
The module does not define transport protocols, API request formats, queues, form libraries, analytics payloads, backend workers, framework event handlers, or resource lifecycle semantics.
2. Terminology
Effect: An addressable declaration of a side effect associated with a Graph transition edge.
Effect attachment: The relation that assigns a transition to an effect declaration.
EffectResource: An abstract superclass for concrete resources that may be produced or consumed by an effect.
Produced resource: An
EffectResourcecreated, emitted, prepared, exported, generated, or made available by anEffect.Consumed resource: An
EffectResourceaccepted, imported, read, redeemed, or otherwise used by anEffect.
3. Effect
An Effect declares that a transition edge has an associated side effect. The effect is addressable, but this module does not define how the side effect is invoked.
An effect can reference produced or consumed resources through producedRefs and consumedRefs.
Those references point to concrete subclasses of EffectResource, not to arbitrary graph nodes.
classDiagram
class Effect {
id
producedRefs
consumedRefs
}
class EffectResource
Effect --> "0..*" EffectResource : producedRefs
Effect --> "0..*" EffectResource : consumedRefs Example JSON node:
{
"@id": "urn:effect:authorize-payment",
"@type": "Effect"
} {
"@id": "urn:effect:authorize-payment",
"@type": "Effect"
} 4. EffectResource
EffectResource is an abstract superclass for resources that can be produced or consumed by an
Effect. It gives the generic producedRefs and consumedRefs properties a shared range while
leaving concrete resource semantics to other modules.
Concrete modules specialize EffectResource. For example, [UJG Artifact] defines portable resources.
classDiagram class EffectResource class Artifact EffectResource <|-- Artifact
EffectResource should not be used as the only concrete type of a resource node in interoperable
examples. Use a concrete subclass such as Artifact.
5. Attachment Model
The module introduces one transition attachment and two resource references:
effect:effectReflinks a GraphTransitionorOutgoingTransitionto anEffect.effect:producedRefslinks anEffectto one or more produced EffectResource nodes.effect:consumedRefslinks anEffectto one or more consumed EffectResource nodes.
A transition without effectRef remains fully valid and traversable. Consumers MAY ignore this
module and still process the graph.
Resource-specific metadata belongs to the referenced resource, not the effect. For example,
sourceTouchpointRef and targetTouchpointRefs belong on an Artifact; an effect only declares
that it produces or consumes the artifact.
6. Normative Artifacts
This module is published through the following artifacts:
effect.ttl: ontology, published athttps://ujg.specs.openuji.org/ed/ns/effecteffect.context.jsonld: JSON-LD term mappings, published athttps://ujg.specs.openuji.org/ed/ns/effect.context.jsonldeffect.shape.ttl: SHACL validation rules, published athttps://ujg.specs.openuji.org/ed/ns/effect.shape
Examples in this page compose the shared baseline context
https://ujg.specs.openuji.org/ed/ns/context.jsonld with the Effect context. Examples that use
artifacts also compose the Artifact context; examples that reference touchpoints also compose the
Surface context.
6.1. Ontology
The normative Effect ontology is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/effect.
@prefix ujg: <https://ujg.specs.openuji.org/ed/ns/core#> .
@prefix ujggraph: <https://ujg.specs.openuji.org/ed/ns/graph#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/ed/ns/effect#> .
@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/effect#> a owl:Ontology ;
rdfs:label "UJG Effect Editor's Draft Vocabulary"@en ;
dct:description "UJG Effect ontology declaration" .
### Classes
ujgeffect:Effect a owl:Class ;
rdfs:subClassOf ujg:Node .
ujgeffect:EffectResource a owl:Class ;
rdfs:subClassOf ujg:Node .
### Properties
ujgeffect:effectRef a owl:ObjectProperty ;
rdfs:domain [
a owl:Class ;
owl:unionOf ( ujggraph:Transition ujggraph:OutgoingTransition )
] ;
rdfs:range ujgeffect:Effect .
ujgeffect:producedRefs a owl:ObjectProperty ;
rdfs:domain ujgeffect:Effect ;
rdfs:range ujgeffect:EffectResource .
ujgeffect:consumedRefs a owl:ObjectProperty ;
rdfs:domain ujgeffect:Effect ;
rdfs:range ujgeffect:EffectResource . @prefix ujg: <https://ujg.specs.openuji.org/ed/ns/core#> .
@prefix ujggraph: <https://ujg.specs.openuji.org/ed/ns/graph#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/ed/ns/effect#> .
@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/effect#> a owl:Ontology ;
rdfs:label "UJG Effect Editor's Draft Vocabulary"@en ;
dct:description "UJG Effect ontology declaration" .
### Classes
ujgeffect:Effect a owl:Class ;
rdfs:subClassOf ujg:Node .
ujgeffect:EffectResource a owl:Class ;
rdfs:subClassOf ujg:Node .
### Properties
ujgeffect:effectRef a owl:ObjectProperty ;
rdfs:domain [
a owl:Class ;
owl:unionOf ( ujggraph:Transition ujggraph:OutgoingTransition )
] ;
rdfs:range ujgeffect:Effect .
ujgeffect:producedRefs a owl:ObjectProperty ;
rdfs:domain ujgeffect:Effect ;
rdfs:range ujgeffect:EffectResource .
ujgeffect:consumedRefs a owl:ObjectProperty ;
rdfs:domain ujgeffect:Effect ;
rdfs:range ujgeffect:EffectResource . 6.2. JSON-LD Context
The normative Effect JSON-LD context is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/effect.context.jsonld.
{
"@context": {
"@version": 1.1,
"ujgeffect": "https://ujg.specs.openuji.org/ed/ns/effect#",
"effect": "https://ujg.specs.openuji.org/ed/ns/effect#",
"Effect": "ujgeffect:Effect",
"EffectResource": "ujgeffect:EffectResource",
"effectRef": {
"@id": "ujgeffect:effectRef",
"@type": "@id"
},
"producedRefs": {
"@id": "ujgeffect:producedRefs",
"@type": "@id",
"@container": "@set"
},
"consumedRefs": {
"@id": "ujgeffect:consumedRefs",
"@type": "@id",
"@container": "@set"
}
}
} {
"@context": {
"@version": 1.1,
"ujgeffect": "https://ujg.specs.openuji.org/ed/ns/effect#",
"effect": "https://ujg.specs.openuji.org/ed/ns/effect#",
"Effect": "ujgeffect:Effect",
"EffectResource": "ujgeffect:EffectResource",
"effectRef": {
"@id": "ujgeffect:effectRef",
"@type": "@id"
},
"producedRefs": {
"@id": "ujgeffect:producedRefs",
"@type": "@id",
"@container": "@set"
},
"consumedRefs": {
"@id": "ujgeffect:consumedRefs",
"@type": "@id",
"@container": "@set"
}
}
} 6.3. Validation
The normative Effect SHACL shape is defined below and is published at
https://ujg.specs.openuji.org/ed/ns/effect.shape.
@prefix ujggraph: <https://ujg.specs.openuji.org/ed/ns/graph#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/ed/ns/effect#> .
@prefix ujgeffectshape: <https://ujg.specs.openuji.org/ed/ns/effect.shape#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ujgeffectshape:TransitionEffectShape a sh:NodeShape ;
sh:targetClass ujggraph:Transition, ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgeffect:effectRef ;
sh:class ujgeffect:Effect ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] .
ujgeffectshape:EffectShape a sh:NodeShape ;
sh:targetClass ujgeffect:Effect ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgeffect:producedRefs ;
sh:class ujgeffect:EffectResource ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujgeffect:consumedRefs ;
sh:class ujgeffect:EffectResource ;
sh:nodeKind sh:IRI ;
] .
ujgeffectshape:EffectResourceShape a sh:NodeShape ;
sh:targetClass ujgeffect:EffectResource ;
sh:nodeKind sh:IRI .
ujgeffectshape:EffectReferenceHostShape a sh:NodeShape ;
sh:targetSubjectsOf ujgeffect:producedRefs ;
sh:targetSubjectsOf ujgeffect:consumedRefs ;
sh:class ujgeffect:Effect ;
sh:nodeKind sh:IRI . @prefix ujggraph: <https://ujg.specs.openuji.org/ed/ns/graph#> .
@prefix ujgeffect: <https://ujg.specs.openuji.org/ed/ns/effect#> .
@prefix ujgeffectshape: <https://ujg.specs.openuji.org/ed/ns/effect.shape#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ujgeffectshape:TransitionEffectShape a sh:NodeShape ;
sh:targetClass ujggraph:Transition, ujggraph:OutgoingTransition ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgeffect:effectRef ;
sh:class ujgeffect:Effect ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] .
ujgeffectshape:EffectShape a sh:NodeShape ;
sh:targetClass ujgeffect:Effect ;
sh:nodeKind sh:IRI ;
sh:property [
sh:path ujgeffect:producedRefs ;
sh:class ujgeffect:EffectResource ;
sh:nodeKind sh:IRI ;
] ;
sh:property [
sh:path ujgeffect:consumedRefs ;
sh:class ujgeffect:EffectResource ;
sh:nodeKind sh:IRI ;
] .
ujgeffectshape:EffectResourceShape a sh:NodeShape ;
sh:targetClass ujgeffect:EffectResource ;
sh:nodeKind sh:IRI .
ujgeffectshape:EffectReferenceHostShape a sh:NodeShape ;
sh:targetSubjectsOf ujgeffect:producedRefs ;
sh:targetSubjectsOf ujgeffect:consumedRefs ;
sh:class ujgeffect:Effect ;
sh:nodeKind sh:IRI . Effect validation depends on the Effect SHACL shape and the ontology graph for each composed
resource module. The producedRefs and consumedRefs sh:class constraints are evaluated against
the referenced resource node's concrete class and the resource module's subclass declarations.
Processors MUST NOT require documents to serialize EffectResource as an additional @type merely
to satisfy these constraints.
The rules below define the remaining module semantics beyond the structural constraints captured by the SHACL shape.
Declaration only: Effect describes that a transition edge has an associated side effect; it does not define how that effect is invoked.
Graph preservation:
effectRefMUST NOT create a hidden edge or change thefrom/tosemantics of the hostTransitionorOutgoingTransition.Resource boundary:
producedRefsandconsumedRefsMUST point to concrete resources that are subclasses of EffectResource. They MUST NOT be used to create hidden Graph traversal.Resource-owned metadata: Metadata about a produced or consumed resource belongs on the referenced resource node. For example, artifact touchpoint metadata belongs on
Artifact, not onEffect.Graceful degradation: Consumers that do not implement this module MAY ignore Effect semantics, but SHOULD preserve recognized JSON-LD data during read-transform-write when possible.
Private contracts: Transport, command, mutation, retry, idempotency, and result-handling details SHOULD remain in Core
extensionsunless a future optional module defines them as interoperable vocabulary.
7. Examples
7.1. Minimal Example
{
"@context": [
"https://ujg.specs.openuji.org/ed/ns/context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/effect.context.jsonld"
],
"@id": "https://example.com/ujg/effect/checkout.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:transition:submit-payment",
"@type": "Transition",
"from": "urn:state:payment",
"to": "urn:state:confirmation",
"effectRef": "urn:effect:authorize-payment"
},
{
"@id": "urn:effect:authorize-payment",
"@type": "Effect"
}
]
} {
"@context": [
"https://ujg.specs.openuji.org/ed/ns/context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/effect.context.jsonld"
],
"@id": "https://example.com/ujg/effect/checkout.jsonld",
"@type": "UJGDocument",
"nodes": [
{
"@id": "urn:transition:submit-payment",
"@type": "Transition",
"from": "urn:state:payment",
"to": "urn:state:confirmation",
"effectRef": "urn:effect:authorize-payment"
},
{
"@id": "urn:effect:authorize-payment",
"@type": "Effect"
}
]
} 7.2. Artifact Production And Consumption Example
This example shows a federated share represented as an artifact crossing touchpoints. Effects declare whether they produce or consume the artifact; the artifact declares source and target touchpoints.
{
"@context": [
"https://ujg.specs.openuji.org/ed/ns/context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/effect/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/ed/ns/context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/surface.context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/effect.context.jsonld",
"https://ujg.specs.openuji.org/ed/ns/artifact.context.jsonld"
],
"@id": "https://example.com/ujg/effect/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"
]
}
]
}