SHACL Shapes
https://meta.linked.archi/archimate/principle-shapes#
SHACL shapes encoding common enterprise architecture principles and best practices as executable constraints. These shapes validate architecture models against governance patterns such as redundancy avoidance, single authoritative source, separation of concerns, stewardship, and technology standardization. Inspired by the ontology-based EA principle validation approach described in: Montecchiari, D.; Hinkelmann, K. (2026) "Ontology-Based Validation of Enterprise Architecture Principles", Applied Sciences, 16(7):3352. These shapes are designed to be loaded alongside the standard ArchiMate element and relationship shapes. They operate on instance data (architecture models) and detect violations of common governance principles. All shapes use sh:severity sh:Warning by default — organizations should promote specific shapes to sh:Violation based on their governance policies. Usage: ./validate.sh --shacl archimate-principles Or load manually alongside other shapes: core-shapes.ttl + archimate3.2-principle-shapes.ttl + your-model-data.ttl
SELECT $this
WHERE {
$this a am:ApplicationComponent .
FILTER NOT EXISTS {
{
?actor am:assignedTo $this .
?actor rdf:type/rdfs:subClassOf* am:ActiveStructureElement .
?actor rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
} UNION {
$this am:assignedTo ?actor .
?actor rdf:type/rdfs:subClassOf* am:ActiveStructureElement .
?actor rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
}
}
}
SELECT $this
WHERE {
$this a am:ApplicationComponent .
FILTER NOT EXISTS {
$this am:realizes ?svc .
?svc a am:ApplicationService .
}
}
SELECT $this
WHERE {
$this a am:ApplicationService .
FILTER NOT EXISTS {
?app am:realizes $this .
?app a am:ApplicationComponent .
}
}
SELECT $this ?app1 ?app2
WHERE {
$this rdf:type/rdfs:subClassOf* am:BehaviorElement .
$this rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
?app1 a am:ApplicationComponent ;
am:realizes $this .
?app2 a am:ApplicationComponent ;
am:realizes $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:BusinessFunction .
?app1 a am:ApplicationComponent ;
am:realizes $this .
?app2 a am:ApplicationComponent ;
am:realizes $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?tech
WHERE {
$this a am:BusinessProcess .
{
?tech am:serves $this .
} UNION {
?tech am:realizes $this .
}
?tech rdf:type/rdfs:subClassOf* am:TechnologyLayerElement .
}
SELECT $this
WHERE {
$this a am:BusinessProcess .
FILTER NOT EXISTS {
?role rdf:type/rdfs:subClassOf* am:ActiveStructureElement .
?role rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
?role am:assignedTo $this .
}
}
SELECT $this
WHERE {
$this a am:BusinessService .
FILTER NOT EXISTS {
?behavior am:realizes $this .
?behavior rdf:type/rdfs:subClassOf* am:BehaviorElement .
?behavior rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
}
}
SELECT $this
WHERE {
$this a am:Capability .
FILTER NOT EXISTS {
?behavior am:realizes $this .
?behavior rdf:type/rdfs:subClassOf* am:BehaviorElement .
?behavior rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
}
}
SELECT $this
WHERE {
$this a am:Capability .
FILTER NOT EXISTS {
{
$this am:realizes ?goal .
{ ?goal a am:Goal . } UNION { ?goal a am:Outcome . }
} UNION {
?goal am:serves $this .
{ ?goal a am:Goal . } UNION { ?goal a am:Outcome . }
} UNION {
$this am:associatedWith ?goal .
{ ?goal a am:Goal . } UNION { ?goal a am:Outcome . }
}
}
}
SELECT $this ?node
WHERE {
$this a am:ApplicationComponent .
?node am:assignedTo $this .
?node a am:Node .
FILTER NOT EXISTS {
?node2 am:assignedTo $this .
?node2 a am:Node .
FILTER(?node2 != ?node)
}
}
SELECT $this
WHERE {
$this a am:DataObject .
FILTER NOT EXISTS {
?app a am:ApplicationComponent .
{
?app am:accesses $this .
} UNION {
?app am:realizes $this .
}
}
}
SELECT $this ?target
WHERE {
$this a am:ApplicationComponent .
$this am:serves ?target .
?target a am:ApplicationComponent .
}
SELECT $this (COUNT(DISTINCT ?node) AS ?nodeCount)
WHERE {
$this a am:ApplicationService .
?app am:realizes $this .
?app a am:ApplicationComponent .
?node am:assignedTo ?app .
?node rdf:type/rdfs:subClassOf* am:TechnologyLayerElement .
}
GROUP BY $this
HAVING (COUNT(DISTINCT ?node) > 3)
SELECT $this
WHERE {
$this a/rdfs:subClassOf* arch:Element .
FILTER NOT EXISTS {
{ $this ?p ?other . ?other a/rdfs:subClassOf* arch:Element . }
UNION
{ ?other ?p $this . ?other a/rdfs:subClassOf* arch:Element . }
}
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:ApplicationService .
?app1 a am:ApplicationComponent ;
am:realizes $this .
?app2 a am:ApplicationComponent ;
am:realizes $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:BusinessProcess .
?app1 a am:ApplicationComponent ;
am:serves $this .
?app2 a am:ApplicationComponent ;
am:serves $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:BusinessFunction .
?app1 a am:ApplicationComponent ;
am:serves $this .
?app2 a am:ApplicationComponent ;
am:serves $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this
WHERE {
$this a am:Requirement .
FILTER NOT EXISTS {
?element am:realizes $this .
FILTER NOT EXISTS {
?element rdf:type/rdfs:subClassOf* am:MotivationElement .
}
}
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:BusinessObject .
?app1 a am:ApplicationComponent ;
am:accesses $this .
?app2 a am:ApplicationComponent ;
am:accesses $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?app1 ?app2
WHERE {
$this a am:DataObject .
?app1 a am:ApplicationComponent ;
am:accesses $this .
?app2 a am:ApplicationComponent ;
am:accesses $this .
FILTER(STR(?app1) < STR(?app2))
}
SELECT $this ?app
WHERE {
$this a am:BusinessService .
?app am:realizes $this .
?app a am:ApplicationComponent .
FILTER NOT EXISTS {
?app2 am:realizes $this .
?app2 a am:ApplicationComponent .
FILTER(?app2 != ?app)
}
}
SELECT $this ?biz
WHERE {
$this a am:Node .
$this am:serves ?biz .
?biz rdf:type/rdfs:subClassOf* am:BusinessLayerElement .
}