šŸ“ SHACL Validation

Graph integrity checking with SHACL shapes.


Overview

SHACL (Shapes Constraint Language) validates the Knowledge Graph structure and data integrity. Shapes are generated from DomainForgeā„¢ policies and manually authored for complex constraints.


Validation Endpoint

1
2
3
4
5
POST /graph/shacl/validate
{
  "targetGraph": "production",
  "shapes": "customer-validation-shapes"
}

Response

1
2
3
4
5
6
7
8
9
10
11
{
  "valid": false,
  "violations": [
    {
      "node": "http://example.org/customer/123",
      "constraint": "email-format",
      "message": "Invalid email format",
      "severity": "Violation"
    }
  ]
}

Shape Types

Node Shape

Validates nodes of a specific type:

1
2
3
4
5
6
7
8
9
ex:EntityShape
    a sh:NodeShape ;
    sh:targetClass sea:Entity ;
    sh:property [
        sh:path rdfs:label ;
        sh:minCount 1 ;
        sh:datatype xsd:string ;
        sh:message "Entity must have a label" ;
    ] .

Property Shape

Validates specific properties:

1
2
3
4
5
6
ex:FlowQuantityShape
    a sh:PropertyShape ;
    sh:path sea:quantity ;
    sh:datatype xsd:decimal ;
    sh:minInclusive 0 ;
    sh:message "Flow quantity must be non-negative" .

Common Shapes

Required Fields

1
2
3
4
5
6
7
8
9
10
11
ex:RequiredFieldsShape
    a sh:NodeShape ;
    sh:targetClass sea:Entity ;
    sh:property [
        sh:path rdfs:label ;
        sh:minCount 1 ;
    ] ;
    sh:property [
        sh:path sea:inContext ;
        sh:minCount 1 ;
    ] .

Unique Constraint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ex:UniqueNameShape
    a sh:NodeShape ;
    sh:targetClass sea:Entity ;
    sh:sparql [
        sh:message "Entity name must be unique within namespace" ;
        sh:select """
            SELECT $this ?name
            WHERE {
                $this rdfs:label ?name ;
                      sea:inContext ?ctx .
                ?other rdfs:label ?name ;
                       sea:inContext ?ctx .
                FILTER ($this != ?other)
            }
        """ ;
    ] .

Referential Integrity

1
2
3
4
5
6
7
8
9
10
11
12
13
ex:FlowReferenceShape
    a sh:NodeShape ;
    sh:targetClass sea:Flow ;
    sh:property [
        sh:path sea:from ;
        sh:class sea:Entity ;
        sh:message "Flow 'from' must reference an existing Entity" ;
    ] ;
    sh:property [
        sh:path sea:to ;
        sh:class sea:Entity ;
        sh:message "Flow 'to' must reference an existing Entity" ;
    ] .

Severity Levels

Level Description Action
Violation Must fix Block deployment
Warning Should fix Log warning
Info Informational Track only

Running Validation

CLI

1
2
3
4
5
# Validate graph against shapes
sea graph validate --shapes shapes/entity-shapes.ttl

# Validate specific graph
sea graph validate --graph production --shapes shapes/

Python

1
2
3
4
5
6
7
8
9
10
from pyshacl import validate

result = validate(
    data_graph,
    shacl_graph=shapes_graph,
    inference='rdfs',
    abort_on_first=False,
)
conforms, graph, report_text = result
print(report_text)

Troubleshooting

Common Errors

Error Cause Fix
Missing required property Node lacks required field Add missing property
Datatype mismatch Wrong value type Convert to correct type
Cardinality violated Too few/many values Adjust data
Class constraint failed Reference wrong type Fix reference target