@prefix sh: . @prefix xsd: . @prefix rdfs: . @prefix skos: . @prefix dcterms: . @prefix owl: . @prefix vann: . @prefix am4: . @prefix ap: . @prefix acme: . @prefix acmetax: . @prefix : . ## ═══════════════════════════════════════════════════════════════════════════════ ## ACME Corp SHACL Shapes ## ## Encodes governance rules from Part 4 as machine-enforceable constraints. ## Severity levels map to completeness criteria from Part 2: ## sh:Violation — Minimum Viable (blocks submission) ## sh:Warning — Complete (blocks approval) ## sh:Info — Gold Standard (advisory) ## ═══════════════════════════════════════════════════════════════════════════════ a owl:Ontology ; vann:preferredNamespaceUri "https://example.com/acme/shapes#" ; vann:preferredNamespacePrefix "acmesh" ; dcterms:title "ACME Corp Validation Shapes"@en ; dcterms:description '''SHACL shapes for validating ACME Corp architecture instances. Encodes completeness, consistency, and governance constraints.'''@en ; dcterms:created "2026-06-16"^^xsd:date ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## APPLICATION COMPONENT — Completeness Shapes ## ═══════════════════════════════════════════════════════════════════════════════ :ApplicationComponentShape a sh:NodeShape ; sh:targetClass am4:ApplicationComponent ; rdfs:label "Application Component Completeness"@en ; ## rdfs:comment, not sh:description — SHACL declares sh:description with ## rdfs:domain sh:PropertyShape, so using it on a sh:NodeShape makes strict ## engines (RDF4J ShaclSail) reject the shape as having conflicting types. rdfs:comment "Every application component must have a label, owner, and lifecycle stage."@en ; ## ─── Minimum Viable (sh:Violation) ───────────────────────────────────── sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Application component must have a name (skos:prefLabel)."@en ; ] ; sh:property [ sh:path acme:ownedBy ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Application component must have an owning team (acme:ownedBy)."@en ; ] ; sh:property [ sh:path ap:atLifecycleStage ; sh:minCount 1 ; sh:maxCount 1 ; sh:severity sh:Violation ; sh:message "Application component must have exactly one lifecycle stage (ap:atLifecycleStage)."@en ; ] ; ## Stage must come from ACME's AssetLifecycle stage vocabulary sh:property [ sh:path ap:atLifecycleStage ; sh:in ( acmetax:Planned acmetax:Current acmetax:PhaseOut acmetax:Retired ) ; sh:severity sh:Violation ; sh:message "Lifecycle stage must be one of: Planned, Current, Phase-out, Retired."@en ; ] ; ## ─── Complete (sh:Warning) ───────────────────────────────────────────── sh:property [ sh:path skos:definition ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Application component should have a description (skos:definition)."@en ; ] ; sh:property [ sh:path am4:realizes ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Application component should realize at least one service."@en ; ] ; ## ─── Gold Standard (sh:Info) ─────────────────────────────────────────── sh:property [ sh:path dcterms:modified ; sh:minCount 1 ; sh:severity sh:Info ; sh:message "Application component should have a last-modified date for staleness tracking."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## TECHNOLOGY COMPONENT — Governance Shapes ## ## "Technology component" is Acme's own term for a technology-radar entry. ArchiMate ## has no TechnologyComponent element, so these are typed am4:SystemSoftware — the ## technology-layer active structure element for platforms, runtimes, middleware and ## database managers, which is what every radar entry here is. ## ═══════════════════════════════════════════════════════════════════════════════ :TechnologyComponentShape a sh:NodeShape ; sh:targetClass am4:SystemSoftware ; rdfs:label "Technology Component Governance"@en ; ## Must have a name sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Technology component must have a name."@en ; ] ; ## Must have an adoption recommendation from the controlled vocabulary sh:property [ sh:path acme:hasRecommendation ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Technology component must have an adoption recommendation (Adopt/Trial/Hold/Retire)."@en ; ] ; ## Recommendation must be from the AdoptionLevels scheme sh:property [ sh:path acme:hasRecommendation ; sh:class skos:Concept ; sh:severity sh:Violation ; sh:message "Adoption recommendation must be a concept from the AdoptionLevels vocabulary."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## CAPABILITY — Strategy Shapes ## ═══════════════════════════════════════════════════════════════════════════════ :CapabilityShape a sh:NodeShape ; sh:targetClass am4:Capability ; rdfs:label "Business Capability Completeness"@en ; sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Capability must have a name."@en ; ] ; sh:property [ sh:path skos:definition ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Capability should have a definition explaining what it means."@en ; ] ; sh:property [ sh:path acme:hasMaturity ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Capability should have a maturity assessment for the heat map."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## DATA OBJECT — Compliance Shapes ## ═══════════════════════════════════════════════════════════════════════════════ :DataObjectShape a sh:NodeShape ; sh:targetClass am4:DataObject ; rdfs:label "Data Object Compliance"@en ; sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Data object must have a name."@en ; ] ; ## GDPR: every data object must have a sensitivity classification sh:property [ sh:path acme:hasClassification ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Data object must have a data classification (Personal/Internal/Public/Special Category)."@en ; ] ; ## GDPR: personal data must have a processing purpose ## (This is a conditional — ideally expressed with sh:if/sh:then but simplified here) sh:property [ sh:path acme:processedFor ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Data object should declare its processing purpose (required for personal data under GDPR)."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## PROCESSING PURPOSE — Legal Basis Requirement ## ═══════════════════════════════════════════════════════════════════════════════ :ProcessingPurposeShape a sh:NodeShape ; sh:targetClass acme:ProcessingPurpose ; rdfs:label "Processing Purpose Completeness"@en ; sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Processing purpose must have a name."@en ; ] ; sh:property [ sh:path acme:hasLegalBasis ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Processing purpose must declare a legal basis (GDPR Art. 6)."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## INTEGRATION POINT — Relationship Completeness ## ═══════════════════════════════════════════════════════════════════════════════ :IntegrationPointShape a sh:NodeShape ; sh:targetClass acme:IntegrationPoint ; rdfs:label "Integration Point Completeness"@en ; sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Integration point must have a name (e.g., API path or event topic)."@en ; ] ; sh:property [ sh:path acme:exposedBy ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Integration point must declare which application exposes it."@en ; ] ; sh:property [ sh:path acme:carriesData ; sh:minCount 1 ; sh:severity sh:Warning ; sh:message "Integration point should declare what data it carries (for data flow tracking)."@en ; ] ; . ## ═══════════════════════════════════════════════════════════════════════════════ ## TEAM — Ownership Shapes ## ═══════════════════════════════════════════════════════════════════════════════ :TeamShape a sh:NodeShape ; sh:targetClass acme:Team ; rdfs:label "Team Completeness"@en ; sh:property [ sh:path skos:prefLabel ; sh:minCount 1 ; sh:severity sh:Violation ; sh:message "Team must have a name."@en ; ] ; .