Graph consistency
What this is
Validate relationships across linked entities, not only one node in isolation.
When to use it
Use graph consistency when correctness depends on references and cross-node context:
- operation <-> equipment tag alignment
- work-order link completeness
- cross-model semantic agreement
Industrial examples
- An operation tag on a work order must also exist on its linked equipment object.
- If a pump references a parent unit, the parent unit must exist and be in the same site hierarchy.
- A functional location relation must point to a valid location node, not a missing external reference.
Cross-property / cross-node semantic agreement is typically implemented as sh:sparql constraints over linked nodes.
Related nodes must be auto-loaded
SPARQL that walks a direct relation (for example $this op:equipment ?equipment then properties or rdf:type on ?equipment) only sees neighbours that are already in the validation graph. Forward auto-load requires sh:node on that path; reverse auto-load requires neat:reverseDirectRelation. Raising auto_load_depth alone does not load undeclared targets. See SHACL and CDF Data Models — Auto-load.
Typed edge cardinality (MultiEdgeConnection / EdgeConnection min/max counts) uses a different executor: dqs:edgeExistenceConstraint. Node-only SHACL often cannot see those edges on the node dump. See Edge existence.
Example (SHACL + SPARQL)
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix op: <http://purl.org/cognite/my_space/Operation/> .
@prefix eq: <http://purl.org/cognite/my_space/Equipment/> .
eq:EquipmentStubShape
a sh:NodeShape ;
sh:targetClass eq:Equipment ;
sh:name "Equipment" .
op:OperationTagConsistencyShape
a sh:NodeShape ;
sh:targetClass op:Operation ;
sh:property [
sh:path op:equipment ;
sh:node eq:EquipmentStubShape ; # required so ?equipment is auto-loaded
sh:sparql [
sh:message "Operation tag must exist on linked equipment." ;
sh:select """
PREFIX op: <http://purl.org/cognite/my_space/Operation/>
SELECT $this ?opTag WHERE {
$this op:tag ?opTag ;
op:equipment ?equipment .
FILTER NOT EXISTS {
?equipment op:tag ?eqTag .
FILTER(?eqTag = ?opTag)
}
}
""" ;
] ;
] .
Without sh:node, the same SPARQL often false-fails every populated op:equipment link because the equipment node was never retrieved into the graph.
Related guides
- Atlas rule-authoring agent — deploy the packaged skill/agent that drafts Consistency
sh:node+ SPARQL rules in Flows chat - Edge existence
- SHACL and CDF Data Models