# KGCS D3FEND SHACL Shapes v1.0
#
# Validates DefensiveTechnique nodes against the D3FEND ontology
# (standards/d3fend/d3fend-ontology-v1.0.owl).
#
# Source standard: MITRE D3FEND OWL ontology v1.3+
# Enforcement level: STRICT (reject at ingest)

@prefix sh:    <http://www.w3.org/ns/shacl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix kgcs:  <http://www.motherhacker.me/kgcs/ontology/core#> .
@prefix d3fend: <http://www.motherhacker.me/kgcs/ontology/d3fend#> .


# ---------------------------------------------------------------------------
# DefensiveTechnique node shape
#
# Every DefensiveTechnique node must carry:
#   - d3fendId: canonical D3FEND identifier (e.g. D3-PA, D3-SICA) — unique key
#   - name: human-readable technique name
#
# D3FEND technique IDs use the "D3-" prefix. They are extracted from the
# D3FEND OWL ontology's URI fragments and mapped through d3fend.json.
# ---------------------------------------------------------------------------

d3fend:DefensiveTechniqueShape
    a sh:NodeShape ;
    sh:targetClass kgcs:DefensiveTechnique ;

    # d3fendId: canonical D3FEND identifier — primary unique key
    sh:property [
        sh:path d3fend:d3fendId ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minLength 3 ;
        sh:message "DefensiveTechnique must have exactly one d3fendId." ;
        sh:severity sh:Violation ;
    ] ;

    # name: human-readable name from D3FEND label
    sh:property [
        sh:path d3fend:name ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:message "DefensiveTechnique must have a name." ;
        sh:severity sh:Warning ;
    ] .
