Cascade Advisory Patch Shape
type: NodeShape
target class: CascadeAdvisoryPatch
comment: Validation constraints for the envelope of a CAP file (advisory:CascadeAdvisoryPatch). Implements the required-envelope-metadata clause of PROFILE.md C6 and the closed-enumeration constraints on advisory:advisoryClass and advisory:cadence. Trusted-issuer membership is NOT validated here — see the file-level comment about D-Q3.
property:
  path: humanSummary
  datatype: string
  min count: 1
  max count: 1
  min length: 1
  severity: Violation
  name: Human Summary
  message: CascadeAdvisoryPatch must carry exactly one non-empty advisory:humanSummary (PROFILE.md C6)
property:
  path: advisoryClass
  min count: 1
  max count: 1
  in: SafetyCritical
  in: VariantReclassification
  in: DrugInteraction
  in: LabReferenceRangeUpdate
  in: SurveillanceGuidelineUpdate
  in: CarrierFrequencyUpdate
  severity: Violation
  name: Advisory Class
  message: CascadeAdvisoryPatch must declare advisory:advisoryClass as one of the six published advisory:AdvisoryClass named individuals (SafetyCritical, VariantReclassification, DrugInteraction, LabReferenceRangeUpdate, SurveillanceGuidelineUpdate, CarrierFrequencyUpdate)
property:
  path: issuer
  min count: 1
  max count: 1
  node kind: IRI
  severity: Violation
  name: Issuer
  message: CascadeAdvisoryPatch must declare advisory:issuer as a single IRI. Per-pod issuer-trust enforcement (D-Q3) is a runtime concern handled by the CAP applier reading <pod>/trust/issuers.ttl, not this shape.
property:
  path: issuedAt
  datatype: dateTime
  min count: 1
  max count: 1
  severity: Violation
  name: Issued At
  message: CascadeAdvisoryPatch must declare exactly one advisory:issuedAt xsd:dateTime
property:
  path: advisoryId
  max count: 1
  node kind: IRI
  severity: Warning
  name: Advisory ID
  message: advisory:advisoryId is recommended so later advisories can target this one via advisory:supersedes
property:
  path: supersedes
  node kind: IRI
  class: CascadeAdvisoryPatch
  severity: Warning
  name: Supersedes
  message: advisory:supersedes must reference an advisory:CascadeAdvisoryPatch IRI
property:
  path: applicableUntil
  datatype: dateTime
  max count: 1
  severity: Info
  name: Applicable Until
  message: advisory:applicableUntil should be an xsd:dateTime; absence means open-ended applicability
property:
  path: profileVersion
  datatype: string
  max count: 1
  severity: Warning
  name: Profile Version
  message: advisory:profileVersion is recommended (e.g. "0.1") so the applier can reject unsupported profile versions
property:
  path: issuerName
  datatype: string
  max count: 1
  severity: Info
  name: Issuer Display Name
property:
  path: evidenceUrl
  node kind: IRI
  max count: 1
  severity: Info
  name: Evidence URL
  message: advisory:evidenceUrl should be an IRI pointing at publicly-citable supporting evidence
property:
  path: appliesToActiveOnly
  datatype: boolean
  max count: 1
  severity: Info
  name: Applies To Active Only
property:
  path: cadence
  max count: 1
  in: EveryAppOpen
  in: Daily
  in: Weekly
  in: Monthly
  in: Quarterly
  in: Annually
  severity: Violation
  name: Cadence
  message: advisory:cadence, if present, must be one of the six published advisory:Cadence named individuals (EveryAppOpen, Daily, Weekly, Monthly, Quarterly, Annually)
property:
  path: signature
  datatype: string
  max count: 1
  severity: Warning
  name: Signature
  message: advisory:signature (detached JWS, RFC 7515) is strongly recommended; absence forces the applier to queue the patch for explicit user trust review (PROFILE.md §Profile validation step 4)
property:
  path: signatureIssuer
  datatype: string
  max count: 1
  severity: Info
  name: Signature Issuer (iss)
property:
  path: signatureIssuedAt
  datatype: long
  max count: 1
  severity: Info
  name: Signature Issued At (iat)
property:
  path: signatureExpiresAt
  datatype: long
  max count: 1
  severity: Info
  name: Signature Expires At (exp)
property:
  path: signatureContentType
  datatype: string
  max count: 1
  severity: Info
  name: Signature Content Type (cty)
  message: advisory:signatureContentType, if present, should be "application/x-cascade-advisory-patch" for v0.1

Trusted Issuer Shape
type: NodeShape
target class: TrustedIssuer
comment: Validation constraints for advisory:TrustedIssuer records. These records live per-pod (typically at <pod>/trust/issuers.ttl) — the protocol does NOT operate a centralized registry. How the record entered the pod's trust graph is captured by advisory:trustSource.
property:
  path: trustedIssuerId
  datatype: anyURI
  min count: 1
  max count: 1
  severity: Violation
  name: Trusted Issuer ID
  message: TrustedIssuer must carry exactly one advisory:trustedIssuerId (xsd:anyURI). It MUST equal advisory:issuer on any patch this issuer signs.
property:
  path: trustedIssuerPublicKey
  datatype: string
  min count: 1
  max count: 1
  min length: 1
  severity: Violation
  name: Trusted Issuer Public Key
  message: TrustedIssuer must carry exactly one advisory:trustedIssuerPublicKey (Ed25519, JWK string or multibase-encoded raw bytes) for signature verification
property:
  path: trustSource
  min count: 1
  max count: 1
  in: RecommendedStarterList
  in: UserAdded
  in: ImportedFromRegistry
  in: VerifiedViaDID
  severity: Violation
  name: Trust Source
  message: TrustedIssuer must declare advisory:trustSource as one of the four published advisory:TrustSourceEnum named individuals (RecommendedStarterList, UserAdded, ImportedFromRegistry, VerifiedViaDID)
property:
  path: trustedIssuerName
  datatype: string
  max count: 1
  severity: Warning
  name: Trusted Issuer Display Name
  message: advisory:trustedIssuerName is recommended for human-readable UI display
property:
  path: trustAddedAt
  datatype: dateTime
  max count: 1
  severity: Info
  name: Trust Added At

Auto-Apply Policy Shape
type: NodeShape
target class: AutoApplyPolicy
comment: Validation constraints for advisory:AutoApplyPolicy records. Auto-apply is opt-in by default; the user adds policy records explicitly. Each policy MUST link to at least one advisory:AutoApplyScope tuple.
property:
  path: appliesTo
  min count: 1
  class: AutoApplyScope
  severity: Violation
  name: Applies To (Auto-Apply Scope)
  message: AutoApplyPolicy must link to at least one advisory:AutoApplyScope via advisory:appliesTo
property:
  path: effectiveFrom
  datatype: dateTime
  max count: 1
  severity: Info
  name: Effective From
property:
  path: effectiveUntil
  datatype: dateTime
  max count: 1
  severity: Info
  name: Effective Until
property:
  path: requiresQuorum
  datatype: boolean
  max count: 1
  severity: Info
  name: Requires Quorum
  message: advisory:requiresQuorum is a v1.0 forward-compat hook; v0.1 appliers MUST treat it as if absent

Auto-Apply Scope Shape
type: NodeShape
target class: AutoApplyScope
comment: Validation constraints for advisory:AutoApplyScope tuples. Each scope MUST pair exactly one trusted issuer with exactly one advisory class — the auto-apply matcher fires only when a patch's (advisory:issuer, advisory:advisoryClass) equals at least one scope.
property:
  path: scopeIssuer
  min count: 1
  max count: 1
  class: TrustedIssuer
  severity: Violation
  name: Scope Issuer
  message: AutoApplyScope must declare exactly one advisory:scopeIssuer referencing an advisory:TrustedIssuer record
property:
  path: scopeAdvisoryClass
  min count: 1
  max count: 1
  in: SafetyCritical
  in: VariantReclassification
  in: DrugInteraction
  in: LabReferenceRangeUpdate
  in: SurveillanceGuidelineUpdate
  in: CarrierFrequencyUpdate
  severity: Violation
  name: Scope Advisory Class
  message: AutoApplyScope must declare exactly one advisory:scopeAdvisoryClass drawn from the six published advisory:AdvisoryClass named individuals