Overview

Namespace URI:
https://ns.cascadeprotocol.org/clinical/v1#
Preferred Prefix:
clinical:
Version:
1.17
Status:
Stable
Schema File:
clinical.ttl (Turtle/RDF)
SHACL Shapes:
clinical.shapes.ttl

The Clinical Vocabulary provides a comprehensive schema for representing clinical documents and structured health records imported from EHR systems via Apple HealthKit. It supports both narrative clinical documents (progress notes, discharge summaries) and structured records (medications, allergies, lab results, conditions, immunizations, procedures, and vital signs).

All classes align with HL7 FHIR resources and use standard healthcare terminologies including LOINC, SNOMED CT, RxNorm, and ICD-10.

Download TTL Download SHACL Back to Documentation

Document Classes

Classes for representing clinical documents and their structure.

clinical:ClinicalDocument

owl:Class

Clinical documentation imported from EHR systems, including narratives and structured data.

Subclass of: fhir:DocumentReference, prov:Entity

clinical:ProgressNote

owl:Class

Provider progress note documenting a patient encounter.

Subclass of: clinical:ClinicalDocument

LOINC: 11506-3

clinical:DischargeSummary

owl:Class

Hospital discharge summary document.

Subclass of: clinical:ClinicalDocument

LOINC: 18842-5

clinical:LaboratoryReport

owl:Class

Laboratory test results with narrative interpretation.

Subclass of: clinical:ClinicalDocument, fhir:DiagnosticReport

clinical:ClinicalSection

owl:Class

Section within a clinical document (e.g., History of Present Illness, Assessment, Plan).

Structured Record Classes

Classes for representing discrete clinical data elements from EHR systems.

clinical:Medication

owl:Class

Medication record from EHR MedicationStatement or MedicationRequest resource.

Subclass of: fhir:MedicationStatement, prov:Entity

Key Properties: drugName, dosage, route, frequency, rxNormCode, prescriber, indication, courseOfTherapyType

FHIR-Enriched Properties (v1.3): medicationForm, activeIngredient, ingredientStrength, asNeeded, refillsAllowed, supplyDurationDays, dispensedQuantity, prescriptionCategory, provenanceClass, sourceFhirResourceType, clinicalIntent

New Properties (v1.5): administrationRoute

clinical:Allergy

owl:Class Deprecated v1.13

Deprecated in favour of health:AllergyRecord, which is the type every import path already emits and which health v2.5 defines and shapes. Retained, not removed: the pod export path is still this class's sole emitter and existing pods contain it. Readers must accept both spellings.

Allergy or intolerance record from EHR AllergyIntolerance resource.

Subclass of: fhir:AllergyIntolerance, prov:Entity

Key Properties: allergen, reaction, severity, criticality

clinical:LabResult

owl:Class Deprecated v1.13

Deprecated in favour of health:LabResultRecord, which is the type every import path already emits and which health v2.5 defines and shapes. Retained, not removed: the pod export path is still this class's sole emitter and existing pods contain it. Readers must accept both spellings.

Laboratory test result from EHR Observation resource.

Subclass of: fhir:Observation, prov:Entity

Key Properties: testName, value, unit, referenceRange, interpretation, loincCode

New Properties (v1.4): orderingProvider, performingLab, observationStatus, sourceRecordId, panelMembership, referenceRangeLow, referenceRangeHigh, referenceRangeText, issuedDate

clinical:Condition

owl:Class Deprecated v1.13

Deprecated in favour of health:ConditionRecord, which is the type every import path already emits and which health v2.5 defines and shapes. Retained, not removed: the pod export path is still this class's sole emitter and existing pods contain it. Readers must accept both spellings.

Medical condition or diagnosis from EHR Condition resource.

Subclass of: fhir:Condition, prov:Entity

Key Properties: conditionName, onsetDate, clinicalStatus, icd10Code, snomedCode

clinical:Immunization

owl:Class Deprecated v1.13

Deprecated in favour of health:ImmunizationRecord, which is the type every import path already emits and which health v2.5 defines and shapes. Retained, not removed: the pod export path is still this class's sole emitter and existing pods contain it. Readers must accept both spellings.

Vaccination record from EHR Immunization resource.

Subclass of: fhir:Immunization, prov:Entity

Key Properties: vaccineName, vaccineCode, lotNumber, manufacturer, doseNumber

clinical:Procedure

owl:Class

Medical procedure record from EHR Procedure resource.

Subclass of: fhir:Procedure, prov:Entity

Key Properties: procedureName, procedureDate, bodySite, cptCode, snomedCode

New Properties (v1.5): procedureStatus, procedureCategory, procedureSnomedCode

clinical:VitalSign

owl:Class

Vital sign observation (heart rate, blood pressure, temperature, etc.) from EHR.

Subclass of: fhir:Observation, prov:Entity

Key Properties: vitalType, value, unit, systolicValue, diastolicValue

clinical:CoverageRecord v1.5 Deprecated

owl:Class · owl:deprecated true

Deprecation Notice: Use coverage:InsurancePlan from coverage.ttl for new insurance data. This class is retained for backward compatibility with existing EHR import pipeline data. See Coverage Vocabulary v1.0 for the replacement.

Insurance coverage record imported from EHR. Layer 2 representation of patient insurance data with FHIR Coverage alignment.

Subclass of: prov:Entity

FHIR Alignment: rdfs:seeAlso fhir:Coverage

Key Properties: providerName, memberId, groupNumber, planName, planType, coverageType, relationship, effectivePeriodStart, effectivePeriodEnd, payorName, subscriberId

Layer Mapping: Layer 2 (clinical:CoverageRecord) complements Layer 3 (checkup:InsuranceInfo) for patient-facing summaries. New data should use coverage:InsurancePlan (Layer 2) instead.

Longitudinal Record Classes v1.2

Classes for tracking health data over time with reconciliation and episode management.

clinical:MedicationUseEpisode

owl:Class

Canonical longitudinal record of patient's relationship with a medication over time. Derived from one or more source records via reconciliation. Episodes represent continuous periods of use—a gap beyond threshold (90 days) creates a new episode.

Subclass of: prov:Entity

Key Properties: canonicalName, episodeFirstSeenDate, episodeLastSeenDate, currentDose, inferredStatus, statusConfidence, usePattern, therapeuticClass

clinical:LabTestSeries v1.4

owl:Class

Longitudinal record of repeated measurements of the same laboratory test (identified by LOINC code) over time. The lab equivalent of MedicationUseEpisode. Unlike medication episodes where a 90-day gap creates a new episode, lab tests have no gap concept — one series per LOINC code per patient.

Subclass of: prov:Entity

Identity Properties: canonicalTestName, testLoincCode, testConceptUri, seriesCategory

Longitudinal Tracking: firstResultDate, lastResultDate, resultCount

Current State: latestValue, latestUnit, latestInterpretation

Trend Inference: trendDirection, trendConfidence, trendReason

Reference Range: currentReferenceRange, currentReferenceRangeLow, currentReferenceRangeHigh

Source Linkage: derivedFromRecord, hasAbnormalHistory, hasUnresolvedConflicts, seriesPanelMembership

clinical:Supplement

owl:Class

Dietary supplement, OTC product, or herbal remedy with explicit regulatory status. Separate from Medication class due to different regulatory status and evidence requirements.

Subclass of: prov:Entity

Key Properties: supplementName, regulatoryStatus, evidenceStrength, brand, form, dsldId, reasonForUse

Note: Supplements do NOT create episodes (different regulatory status from FDA-approved medications).

Encounter and Participation v1.16

Through v1.15 clinical:Encounter carried a class code, a status, a type, two dates, a facility and one provider name. FHIR R4 Encounter carries considerably more, and US Core marks much of it Must Support. These terms close the gap. Every one of them is an element a conformant server sends and that this vocabulary previously gave an importer no way to record.

Participation is a structure in FHIR, and it is a structure here. The alternative considered and rejected was a flat family of role-qualified predicates on the encounter — an attending name, a referrer name, and so on. It fails on both axes of real data: the role vocabulary is extensible, so a fixed family of predicates silently drops the local roles a server may conformantly send, and a visit routinely carries two participants in the same role, which one-predicate-per-role cannot represent without reintroducing the single-value loss it was meant to fix. A name stored with no role attached is not a smaller fact than a name with one; it is a fact a reader cannot tell is wrong.

clinical:encounterReason v1.16

owl:DatatypeProperty

Why the visit happened, in the chart's own words. FHIR alignment: Encounter.reasonCode, CodeableConcept 0..*, preferred binding; US Core Must Support. Value is CodeableConcept.text where the source states it, otherwise the first coding's display: the reason as written, not a normalization of it.

Domain: clinical:Encounter · Range: xsd:string · repeatable, because the source element is

No value set is bound, to the property or its shape. The FHIR binding is preferred, the weakest binding that still names a value set, and real exports carry local, free-text and SNOMED CT reasons in the same field; an enum here would reject conformant data.

clinical:admitSource v1.16

owl:DatatypeProperty

Where the patient came from before this encounter. FHIR alignment: Encounter.hospitalization.admitSource, CodeableConcept 0..1, preferred binding. The presence of an Encounter.hospitalization element is itself the structured signal that an encounter was an admission rather than an office visit, and through v1.15 that distinction was unrecoverable from the pod.

Domain: clinical:Encounter · Range: xsd:string · at most one · no value set bound

clinical:dischargeDisposition v1.16

owl:DatatypeProperty

Where the patient went after this encounter. FHIR alignment: Encounter.hospitalization.dischargeDisposition, CodeableConcept 0..1. The R4 base binding is example strength; US Core marks the element Must Support and binds it preferred to its own value set. Values are verbatim: “Home or Self Care”, “Non-Healthcare Facility Point of Origin”.

Domain: clinical:Encounter · Range: xsd:string · at most one · no value set bound, and an example-strength binding is the clearest possible case for not binding one

clinical:encounterClassDisplay v1.16

owl:DatatypeProperty

Human-readable display of Encounter.class, verbatim from Coding.display. Added alongside, never instead of, clinical:encounterClass: the code stays because it is what a round-trip export must restore, and the display is stored because Encounter.class is bound only extensibly, so a local code such as "5" is unreadable without it.

Domain: clinical:Encounter · Range: xsd:string · at most one

clinical:encounterClassSystem v1.16

owl:DatatypeProperty

The code system Encounter.class's code is drawn from, verbatim from Coding.system — typically http://terminology.hl7.org/CodeSystem/v3-ActCode, or a urn:oid: URI where the source used a local system. Stored because it is the only thing that distinguishes a ratified ActEncounterCode from a locally-numbered category that happens to look like one, and so the only thing that tells a consumer whether a stored class code is safe to map.

Domain: clinical:Encounter · Range: xsd:anyURI · at most one (the shape accepts xsd:anyURI or xsd:string)

clinical:EncounterParticipant v1.16

owl:Class

One participation in an encounter: a named person together with the role they played in that visit, and their specialty where the source states it. Mirrors the FHIR R4 Encounter.participant BackboneElement. Modelled with no rdfs:subClassOf, matching clinical:ClinicalSection and clinical:ClinicalNarrative: a participation is not an entity in the PROV sense and is not asserted to be one.

Properties: clinical:participantName, clinical:participantRole, clinical:participantRoleCode, clinical:participantSpecialty

The node deliberately holds the participant's display name rather than a reference to a practitioner record. This vocabulary defines no practitioner class, and inventing one to hold a display string would be a larger claim than the source supports; the exports these records are converted from carry participant.individual.display and nothing resolvable behind it.

clinical:hasParticipant v1.16

owl:ObjectProperty

Links an encounter to one of its participations. An encounter commonly carries an attender, a referrer and an authorizing physician at once, and which of them actually saw the patient is only answerable if all of them are kept with their roles attached.

Domain: clinical:Encounter · Range: clinical:EncounterParticipant · repeatable, matching Encounter.participant 0..*

clinical:participantName v1.16

owl:DatatypeProperty

Display name of the person who participated, verbatim from Encounter.participant.individual.display.

Domain: clinical:EncounterParticipant · Range: xsd:string · at most one

clinical:participantRole v1.16

owl:DatatypeProperty

Human-readable role this participant played, from Encounter.participant.type CodeableConcept.text or the first coding's display: “attender”, “referrer”, “consultant”. The label is what makes a stored name interpretable; a name recorded with no role is indistinguishable from a treating clinician's and cannot be corrected by a reader.

Domain: clinical:EncounterParticipant · Range: xsd:string · at most one

clinical:participantRoleCode v1.16

owl:DatatypeProperty

Coded role from Encounter.participant.type, verbatim. FHIR R4 binds the element extensibly to encounter-participant-type, which draws twelve concepts from http://terminology.hl7.org/CodeSystem/v3-ParticipationType (ATND, PPRF, SPRF, CON, ADM, DIS, REF, CALLBCK, ESC, PART) and http://terminology.hl7.org/CodeSystem/participant-type (translator, emergency).

Domain: clinical:EncounterParticipant · Range: xsd:string · repeatable, because the source element is

No sh:in is bound, in either direction: the binding is extensible, so a server may send a local role code and remain conformant, and rejecting one would discard the participant along with it.

clinical:participantSpecialty v1.16

owl:DatatypeProperty

The clinical specialty this participant acted in during the encounter, as a display string: “Dermatology”, “Sleep Medicine”. Standards basis: PractitionerRole.specialty, CodeableConcept 0..*, preferred binding. Recorded on the participation rather than on a person because in FHIR specialty is a property of the role: the same clinician has different specialties in different roles, and it is the one they acted in on this visit that describes the visit.

Domain: clinical:EncounterParticipant · Range: xsd:string · at most one · no value set bound

Identity and Document Attribution v1.16

Migration. clinical:sourceRecordId now states that it holds the server-assigned logical id only. A converter that has been writing a business identifier into it must move that value to clinical:businessIdentifier. The two predicates are not interchangeable and a consumer cannot tell them apart after the fact, so the move belongs in the same change as the emission, not a later one.

clinical:businessIdentifier v1.16

owl:DatatypeProperty

An identifier the source system publishes for the real-world thing a record describes, as opposed to the server row it happens to live in. FHIR alignment: the .identifier element (Identifier 0..*) carried by every FHIR resource; on an encounter, Encounter.identifier, which US Core marks Must Support, whose ordinary value is a visit or contact serial number.

Domain: deliberately absent — the source element exists on every FHIR resource, so restricting it to encounters would be false · Range: xsd:string · repeatable

Value form. Where the source states an Identifier.system, the value is written in the ratified FHIR token form {system}|{value}, which is what makes two identifiers comparable across transports without a side table. Where the source states no system, the bare value is written. An implementation MUST NOT invent a system.

Why it is separate from clinical:sourceRecordId. FHIR distinguishes Resource.id, the server-assigned logical id, from .identifier, the business identifier the source publishes for the real-world thing. The two id spaces do not join: the same string in the two spaces means nothing in common. One predicate holding both made a stored value uninterpretable.

clinical:documentReferenceStatus v1.16

owl:DatatypeProperty

Status of the reference to a document: whether this pod entry is the current pointer, has been replaced by a later one, or was created in error. FHIR alignment: DocumentReference.status, 1..1, required binding — current | superseded | entered-in-error.

Domain: clinical:ClinicalDocument · Range: xsd:string · at most one · value set bound at sh:Warning

Distinct from clinical:status, which on a document carries DocumentReference.docStatus, the status of the underlying document. A document can be a final, unamended clinical note whose reference has since been superseded by a corrected filing. Folding them onto one predicate is not merely lossy, it is ambiguous in the one case where ambiguity is most costly: entered-in-error appears in both value sets, and means the reference was filed in error in one and the clinical content is repudiated in the other.

clinical:documentAuthorName v1.16

owl:DatatypeProperty

Name of a party responsible for the content of a document. FHIR alignment: DocumentReference.author, 0..*. A note co-signed by a resident and an attending has two authors; through v1.15 the only predicate available was clinical:providerName, which the document shapes constrain to sh:maxCount 1, so every author after the first was discarded on import with nothing recording that it had happened.

Domain: clinical:ClinicalDocument · Range: xsd:string · repeatable

clinical:providerName is retained and unchanged: on a document it holds the single name an application displays as the responsible provider. documentAuthorName holds every author the source stated, including that one.

clinical:authenticatorName v1.16

owl:DatatypeProperty

Name of the person or organization that attested a document: who signed it, as opposed to who wrote it. FHIR alignment: DocumentReference.authenticator, 0..1; the same fact is Composition.attester.party in a Composition and legalAuthenticator in a C-CDA header. A resident authors, an attending signs; recording only the author loses the signature, which is the part of a note that carries clinical and legal weight.

Domain: clinical:ClinicalDocument · Range: xsd:string · at most one

Not modelled this release: Composition.attester's mode and time. DocumentReference, which is what both import paths actually read, carries a bare authenticator reference with neither, and a predicate whose only possible value would be invented is worse than its absence.

Key Data Properties

Document Metadata

clinical:importedAt

owl:DatatypeProperty

ISO 8601 timestamp when document was imported from Apple Health.

Range: xsd:dateTime

clinical:sourceEHR

owl:DatatypeProperty

Name of the source EHR system (e.g., 'Epic MyChart', 'Cerner').

Range: xsd:string

clinical:fhirResourceId

owl:DatatypeProperty

Original FHIR resource identifier from the source system.

Range: xsd:string

Terminology Codes

clinical:loincCode

owl:DatatypeProperty

LOINC code for the clinical concept.

Example: "2085-9" (HDL Cholesterol)

clinical:snomedCode

owl:DatatypeProperty

SNOMED CT code for the clinical concept.

Example: "73211009" (Diabetes mellitus)

clinical:icd10Code

owl:DatatypeProperty

ICD-10-CM diagnosis code.

Example: "E11.9" (Type 2 diabetes without complications)

clinical:rxNormCode

owl:DatatypeProperty

RxNorm code for medications.

Example: "197361" (Metformin 500mg)

Typed Code Properties v1.6

These typed code properties were aligned to the clinical: namespace in v1.6 as part of the typed code alignment (Task A2). Previously, some Checkup summary classes used checkup:-namespaced code properties; these now uniformly use clinical: predicates per the mixed namespace pattern.

clinical:cvxCode v1.6

owl:DatatypeProperty • Domain: clinical:Immunization

CDC CVX (Vaccine Administered) code. Preferred over legacy clinical:vaccineCode for new serialization. Used in checkup:ImmunizationSummary via mixed namespace pattern.

Example: "140" (Influenza, seasonal, injectable, preservative free)

clinical:linkedConditionIds v1.6

owl:DatatypeProperty • Domain: clinical:Condition

Space-separated UUIDs of related ConditionSummary records (e.g., linking a complication to its root condition). Enables graph traversal between related diagnoses in Health Map.

Range: xsd:string

CoverageRecord Properties v1.5 Deprecated

Deprecation Notice: clinical:CoverageRecord and its properties are deprecated. Use coverage:InsurancePlan from coverage.ttl for new insurance data. These properties remain defined for backward compatibility with existing EHR import pipeline data.

Properties for representing insurance coverage data imported from EHR systems. Maps to fhir:Coverage resource.

clinical:providerName

owl:DatatypeProperty

Insurance company or plan provider name.

Range: xsd:string

clinical:memberId

owl:DatatypeProperty

Insurance member/subscriber identifier.

Range: xsd:string

clinical:groupNumber

owl:DatatypeProperty

Employer group number for employer-sponsored plans.

Range: xsd:string

clinical:planName

owl:DatatypeProperty

Name of the insurance plan.

Range: xsd:string

clinical:planType

owl:DatatypeProperty

Type of insurance plan: hmo, ppo, epo, pos, hdhp, medicare, medicaid, tricare, other.

Range: xsd:string

clinical:coverageType

owl:DatatypeProperty

Classification of coverage: medical, dental, vision, prescription, mental_health.

Range: xsd:string

clinical:relationship

owl:DatatypeProperty

Beneficiary relationship to subscriber: self, spouse, child, parent, other.

Range: xsd:string

clinical:effectivePeriodStart

owl:DatatypeProperty

Start date of coverage period.

Range: xsd:date

clinical:effectivePeriodEnd

owl:DatatypeProperty

End date of coverage period.

Range: xsd:date

clinical:payorName

owl:DatatypeProperty

Name of the organization paying for coverage.

Range: xsd:string

clinical:subscriberId

owl:DatatypeProperty

Identifier for the policy holder from the insurer.

Range: xsd:string

Usage Example

@prefix clinical: <https://ns.cascadeprotocol.org/clinical/v1#> .
@prefix cascade: <https://ns.cascadeprotocol.org/core/v1#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# Medication record example (v1.3 — full FHIR enrichment)
<#med-metformin-123> a clinical:Medication ;
    cascade:schemaVersion "1.3" ;
    cascade:dataProvenance cascade:ClinicalGenerated ;
    clinical:drugName "Metformin HCl 500 MG Oral Tablet" ;
    clinical:dosage "500 mg" ;
    clinical:route "oral" ;
    clinical:frequency "twice daily" ;
    clinical:rxNormCode "197361" ;
    clinical:status "active" ;
    clinical:prescriber "Dr. Sarah Johnson" ;
    clinical:indication "Type 2 Diabetes" ;
    clinical:courseOfTherapyType "continuous" ;
    clinical:medicationForm "Tablet" ;
    clinical:activeIngredient "Metformin hydrochloride" ;
    clinical:ingredientStrength "500 mg" ;
    clinical:asNeeded false ;
    clinical:refillsAllowed 3 ;
    clinical:supplyDurationDays 90 ;
    clinical:dispensedQuantity "90 tablets" ;
    clinical:prescriptionCategory "community" ;
    clinical:provenanceClass "healthKitFHIR" ;
    clinical:sourceFhirResourceType "MedicationRequest" ;
    clinical:clinicalIntent "prescribed" ;
    clinical:sourceEHR "Epic MyChart" ;
    prov:wasAttributedTo <https://id.cascadeprotocol.org/users/abc123> .

# Lab result example (v1.4 — full metadata)
<#lab-a1c-456> a clinical:LabResult ;
    cascade:schemaVersion "1.4" ;
    cascade:dataProvenance cascade:ClinicalGenerated ;
    clinical:testName "Hemoglobin A1c" ;
    clinical:value "6.5" ;
    clinical:unit "%" ;
    clinical:referenceRange "4.0-5.6 %" ;
    clinical:referenceRangeLow "4.0"^^xsd:decimal ;
    clinical:referenceRangeHigh "5.6"^^xsd:decimal ;
    clinical:interpretation "H" ;
    clinical:observationStatus "final" ;
    clinical:loincCode "4548-4" ;
    clinical:effectiveDate "2025-12-15T08:30:00Z"^^xsd:dateTime ;
    clinical:issuedDate "2025-12-15T14:22:00Z"^^xsd:dateTime ;
    clinical:orderingProvider "Dr. Sarah Johnson" ;
    clinical:performingLab "Quest Diagnostics" ;
    clinical:sourceRecordId "obs-a1c-20251215-001" ;
    clinical:sourceEHR "Epic MyChart" ;
    clinical:provenanceClass "healthKitFHIR" .

# Lab test series example (v1.4 — longitudinal tracking)
<#series-a1c> a clinical:LabTestSeries ;
    cascade:schemaVersion "1.4" ;
    clinical:canonicalTestName "Hemoglobin A1C" ;
    clinical:testLoincCode "4548-4" ;
    clinical:seriesCategory "diabetes" ;
    clinical:firstResultDate "2024-06-15T08:00:00Z"^^xsd:dateTime ;
    clinical:lastResultDate "2025-12-15T08:30:00Z"^^xsd:dateTime ;
    clinical:resultCount "4"^^xsd:integer ;
    clinical:latestValue "6.5" ;
    clinical:latestUnit "%" ;
    clinical:latestInterpretation "H" ;
    clinical:trendDirection "increasing" ;
    clinical:trendConfidence "high" ;
    clinical:trendReason "3-point upward trend over 18 months" ;
    clinical:hasAbnormalHistory true ;
    clinical:currentReferenceRange "4.0-5.6 %" ;
    clinical:currentReferenceRangeLow "4.0"^^xsd:decimal ;
    clinical:currentReferenceRangeHigh "5.6"^^xsd:decimal ;
    clinical:derivedFromRecord <#lab-a1c-456> .

FHIR Alignment

The Clinical Vocabulary aligns with HL7 FHIR R4 resources to ensure interoperability with healthcare systems:

Clinical Class FHIR Resource
clinical:Medication MedicationStatement
clinical:Allergy AllergyIntolerance
clinical:LabResult Observation
clinical:Condition Condition
clinical:Immunization Immunization
clinical:Procedure Procedure
clinical:VitalSign Observation (vital-signs profile)
clinical:ClinicalDocument DocumentReference
clinical:MedicationUseEpisode v1.2 Derived from MedicationStatement
clinical:Supplement v1.2 No direct FHIR equivalent (non-prescription)
clinical:LabTestSeries v1.4 Derived from Observation (longitudinal grouping by LOINC code)
clinical:CoverageRecord v1.5 Coverage

SHACL Validation

The vocabulary includes SHACL shapes for data validation. Use the shapes file to validate clinical records:

  • Required property constraints (e.g., medications must have drugName)
  • Datatype constraints (e.g., dates must be xsd:dateTime)
  • Value range constraints (e.g., severity must be mild/moderate/severe)

Download SHACL shapes for integration with your validation pipeline.

Data Provenance

All clinical records use cascade:ClinicalGenerated provenance to indicate EHR-verified data:

  • Source: Apple HealthKit HKClinicalRecord API
  • Origin: Patient portals (Epic MyChart, Cerner, etc.)
  • Classification: Clinical-generated, EHR-verified
  • Privacy: May contain PHI - encrypted storage required

Changelog

Version 1.17 (2026-08-28)

  • Shapes-only release; no term added, removed or renamed. Stopped sh:node from escalating a nested sh:Warning into a sh:Violation: SHACL conformance is an empty validation result regardless of severity, so the clinical:status and clinical:documentReferenceStatus value-set warnings on clinical:ClinicalDocumentShape were rejecting the six document subtypes that reach it through sh:node. The two bindings now live on clinical:DocumentStatusShape and clinical:DocumentReferenceStatusShape, which reach all seven document classes by sh:targetClass. Strictly widening: nothing that validated under v1.16 stops validating, and six classes of previously-rejected conformant document now pass.

Version 1.16 (2026-08-27)

  • Fifteen new terms (14 properties and one class), two domains dropped, one property deprecated, and the first per-class value sets on clinical:status. Everything here comes from a field-coverage measurement against real R4 exports: each term is a source element that a conformant server sends and this vocabulary had nowhere to put, so an importer dropped it. Every term cites the FHIR R4 element it mirrors by canonical URL.
  • Encounter. clinical:encounterReason, clinical:admitSource, clinical:dischargeDisposition, clinical:encounterClassDisplay, clinical:encounterClassSystem, and the participation structure clinical:EncounterParticipant (class) with clinical:hasParticipant, clinical:participantName, clinical:participantRole, clinical:participantRoleCode and clinical:participantSpecialty. See Encounter and Participation.
  • Identity. clinical:businessIdentifier, domain-free and repeatable, for the .identifier element every FHIR resource carries. clinical:sourceRecordId keeps its meaning and now states it: the server-assigned logical id (Resource.id). Migration: a converter that has been writing a business identifier to clinical:sourceRecordId must move it. The two predicates are not interchangeable and a reader cannot repair the confusion after the fact.
  • Documents. clinical:documentReferenceStatus for DocumentReference.status, which is a different assertion from the docStatus that clinical:status carries; clinical:authenticatorName for DocumentReference.authenticator, who signed a document rather than who wrote it; and repeatable clinical:documentAuthorName for DocumentReference.author 0..*.
  • A status nothing checked, on five record types. clinical:status is written onto lab results, vital signs, documents, laboratory reports and allergy records, and no shape declared it on any of them, so the per-class FHIR value sets were unenforced and validation passed in silence. Each shape now binds the value set its source resource binds, verbatim: Observation.status (8 codes) for vital signs and lab results, DiagnosticReport.status (10) for laboratory reports, AllergyIntolerance.clinicalStatus (3) for allergies, and the ten-code set for the base document shape — because clinical:LaboratoryReportShape reaches that shape through sh:node, composition-status is a strict subset of diagnostic-report-status, and the wider set is therefore the only one correct for every class beneath it. All five are sh:Warning, per the core v3.5 ratchet.
  • Two domains dropped. clinical:providerName declared rdfs:domain clinical:CoverageRecord while being written on every clinical record type, and clinical:verificationStatus declared rdfs:domain clinical:Condition while FHIR carries verificationStatus on AllergyIntolerance as well. Both are dropped rather than widened to a union, following the v1.11 treatment of clinical:indicationReference: a union on a cross-class predicate makes a reasoner infer that an allergy record is a Condition. No shape ever encoded either domain, so no pod is affected.
  • Deprecated: clinical:observationStatus, superseded by clinical:status. Defined in v1.4 with rdfs:domain clinical:LabResult — a class deprecated in v1.13 that no import path emits — bound by no shape and written by no converter. Retired rather than re-domained, because re-domaining it onto the class that is emitted would give an Observation-derived record two status predicates with one FHIR element behind both. Retained, not removed, on the v1.13 terms: any pod carrying it stays valid and readers must continue to accept it.
  • clinical.shapes.ttl v1.16 adds the new clinical:EncounterParticipantShape, declares the new encounter facts on clinical:EncounterShape and the new document and identifier properties on clinical:ClinicalDocumentShape. None of the source-text encounter properties carries a value set: FHIR binds reasonCode and admitSource preferred and dischargeDisposition example, and an enum over an example-strength binding rejects conformant data by construction.
  • Additive and strictly widening. Every graph that validated under v1.15 validates under v1.16 at the same severity, with new findings at sh:Warning only. No class or property is removed or renamed, and the one deprecation removes nothing.

Version 1.15 (2026-08-14)

  • clinical:VitalSignShape's clinical:interpretation is bound to the same value set the lab shapes use, at Warning severity. Through v1.14 the sh:in was on the LAB shapes only, so the identical predicate was checked on a lab result and unchecked on a vital sign. Warning first and Violation in a later version, once the warning is observably absent from conforming output, is the ratchet core v3.5 wrote down for a value that existing data carries.
  • Both interpretation value sets gain the fourteen data-absent-reason codes they did not carry, matching health v2.7 byte for byte. A C-CDA nullFlavor of NASK, ASKU and NAV are three different clinical facts and v1.14 flattened all of them to unknown.
  • Added clinical:interpretationSourceCode, kept semantically identical to health:interpretationSourceCode. These are two spellings of one record, and letting them drift is how one spelling silently becomes the lenient one.
  • clinical:ProcedureShape's name requirement becomes an sh:or over clinical:procedureName and the undefined health:procedureName that a C-CDA import path emits, plus the new warning-severity clinical:ProcedureNameSpellingShape. Every converted procedure previously failed the name requirement while carrying a name, on a predicate no shape targets, so the name itself was validated by nothing.
  • This is a MIGRATION WINDOW, not a ratified dual spelling. clinical:procedureName is canonical: it is the only spelling any Cascade vocabulary defines, the record is typed clinical:Procedure, and the health namespace has no procedure class at all. Producers write the canonical spelling only. Both the sh:or alternative and the warning shape are removed together in a later version. A consumer querying health:procedureName must add clinical:procedureName to its query now.
  • Additive and strictly widening. Every graph that validated under v1.14 validates under v1.15 at the same severity; the only new finding anywhere is the one Warning above.

Version 1.14 (2026-08-08)

  • Shapes only. No class or property added, removed, renamed or deprecated. Apart from the new Encounter shape the change is strictly widening. Real-world Epic FHIR exports, and C-CDA documents through the same pipeline, were failing validation on records that are correct at source.
  • New clinical:EncounterShape and clinical:EncounterTemporalShape. clinical:Encounter has been defined since v1.7 and targeted by no shape, so validating an encounter evaluated zero constraints and returned PASS. That is the more dangerous kind of gap: not a failure, an unearned pass. The new shape is deliberately minimal — cardinality, datatype, provenance, and the IRI requirement the clinical:hasEncounter edge implies. It does not constrain what kind of visit an encounter may be: encounterClass gets no enum because FHIR binds Encounter.class extensibly and servers send either the abbreviation (AMB, EMER, IMP) or a display string, and the encounterStatus enum is the FHIR R4 EncounterStatus value set verbatim at sh:Warning. Having a position in time is a Warning, not a Violation, because Encounter.period is 0..1 and a planned encounter legitimately has none.
  • clinical:interpretation is bound to the HL7 v3 ObservationInterpretation code system (49 selectable codes, version 3.0.0), plus the data-absent-reason code unknown and the ten retained legacy words. Kept identical to health:interpretation, since these are two spellings of one record and letting them drift is how one spelling quietly becomes the lenient one.
  • clinical:snomedCode (four shapes) and clinical:icd10Code are multi-valued, matching CodeableConcept.coding (0..*).
  • clinical:cptCode accepted only five digits, which is CPT Category I. The AMA CPT code set also defines Category II (four digits + F), Category III (four digits + T) and Proprietary Laboratory Analyses (four digits + U) codes, all five characters. Pattern widened to ^[0-9]{4}[0-9FTU]$.
  • Date properties carried over from a source document — clinical:encounterDate, clinical:documentDate, clinical:onsetDate, clinical:procedureDate — accept xsd:date alongside xsd:dateTime, because FHIR's dateTime primitive is explicitly partial-precision and C-CDA effectiveTime commonly states a calendar day and nothing more. Timestamps Cascade itself generates (clinical:importedAt, the derived episode dates) are unchanged.

Version 1.13 (2026-08-03)

  • Deprecated four classes — clinical:LabResult, clinical:Condition, clinical:Allergy, clinical:Immunization — each with owl:deprecated true and rdfs:seeAlso pointing at its health: equivalent, which is the type every import path already emits and which health v2.5 defines and shapes. Retained, not removed: the pod export path remains their sole emitter and existing pods contain them. No emitter changed in this release.
  • Documented the intended FHIR R4 value sets on clinical:status and clinical:interpretation, and recorded why two of them are deliberately left unenforced. clinical:MedicationShape has no sh:in on status and clinical:VitalSignShape has none on interpretation, while sibling shapes do. Emitted data uses discontinued for medication status and elevated for vital-sign interpretation, neither of which is in the corresponding constrained set, so adding the constraints would be breaking for existing pods rather than clarifying. The ordered fix is to move emitters onto the FHIR values first, then tighten in a release explicitly flagged as tightening.
  • Added clinical:ConsultationNoteShape. clinical:ConsultationNote is one of six rdfs:subClassOf clinical:ClinicalDocument; the other five each carried an explicit sh:targetClass and this one did not. A subclass axiom does not inherit a shape, so consultation notes had been validating vacuously while every sibling document type was checked. Consequence: a consultation note missing importedAt, sourceEHR or fhirResourceId passed before and fails now.

Version 1.12 (2026-07-20)

  • Added clinical:parsedIndicationReference, an rdfs:subPropertyOf clinical:indicationReference recording an indication edge the importer derived by parsing a coded or free-text reason and matching it to a condition record in the same pod, as distinct from an explicit reasonReference the source carried. Modelled as a subproperty so traversal over the superproperty returns both families. Matching is code-first with a normalised-name fallback and unambiguous-only; ambiguous and unmatched are counted, never guessed.

Version 1.11 (2026-07-16)

  • Widened clinical:indicationReference by dropping its restrictive rdfs:domain clinical:Medication. FHIR carries reasonReference on Procedure, MedicationRequest, MedicationAdministration and Encounter, not only medications, and the old domain would have made a reasoner infer those Procedures are Medications. No SHACL change; existing pods unaffected.

Version 1.10 (2026-07-16)

  • Added three record-to-record edges: clinical:hasEncounter (range clinical:Encounter), clinical:indicationReference (open range, since FHIR permits Condition or Observation), and clinical:linkedCondition.
  • Deprecated clinical:linkedConditionIds, which packed related-condition UUIDs into one space-separated literal that no graph query can traverse. Retained for backward compatibility.
  • Corrected clinical:hasLabResult's rdfs:range from clinical:LabResult to health:LabResultRecord: both importer paths type panel members health:LabResultRecord, so the declared range described a class the data never uses.

Version 1.9 (2026-06-17)

  • Added cascade:AIExtracted to every cascade:dataProvenance sh:in enumeration in clinical.shapes.ttl. cascade:AIExtracted (a ClinicalGenerated subclass, declared in core v3.3) is now a permitted provenance value on all clinical record shapes, so records produced by an AI document-extraction pipeline (e.g. the Workbench) validate without error.
  • Shapes-only change; no new clinical classes or properties.

Version 1.8 (2026-03-28)

  • Added clinical:SocialHistoryRecord class for EHR-extracted social history observations (C-CDA Social History section, LOINC 29762-2). Distinct from health:SocialHistoryRecord (consumer-reported).
  • Added 5 properties: clinical:socialHistoryCategory (10-value set), clinical:packsPerYear, clinical:substanceType, clinical:frequencyDescription, clinical:socialHistoryConsent (links to cascade:SocialHistoryConsent for 42 CFR Part 2).

Version 1.7 (2026-03-12)

  • Added clinical:Encounter class (fhir:Encounter alignment) with 6 properties: encounterClass, encounterStatus, encounterType, encounterStart, encounterEnd, facilityName
  • Added clinical:MedicationAdministration class (fhir:MedicationAdministration alignment) with 4 properties: administeredDate, administeredDose, administeredRoute, administrationStatus
  • Added clinical:ImplantedDevice class (fhir:Device alignment) with 5 properties: deviceType, implantDate, deviceManufacturer, udiCarrier, deviceStatus
  • Added clinical:ImagingStudy class (fhir:ImagingStudy alignment) with 6 properties: imagingModality, studyDescription, numberOfSeries, studyDate, dicomStudyUid
  • Added 3 clinical:LaboratoryReport properties: hasLabResult, panelName, reportCategory
  • Added SHACL shapes for all new classes in clinical.shapes.ttl (permissive, sh:minCount 0)

Version 1.6 (2026-02-22)

  • Added clinical:linkedConditionIds DatatypeProperty on clinical:Condition for linking related conditions via space-separated UUIDs (enables Health Map graph traversal)
  • Typed code alignment (Task A2): clinical:loincCode on LabResult, clinical:cvxCode preferred over legacy clinical:vaccineCode on Immunization, clinical:icd10Code and clinical:snomedCode on Condition and FamilyHistoryEntry, clinical:snomedCode and clinical:rxNormCode on AllergySummary
  • Annotated clinical:vaccineCode as legacy (retained for backward compatibility; use clinical:cvxCode for new serialization)
  • Part of Health Map v3 Pre-Phase Track A

Version 1.5 (2026-02-10)

  • Added CoverageRecord class for insurance coverage data (11 properties)
    • Maps to fhir:Coverage resource
    • Layer 2 complement to checkup:InsuranceInfo (Layer 3)
  • Added 3 new Procedure properties: procedureStatus, procedureCategory, procedureSnomedCode
  • Added administrationRoute property for Medication

Version 1.4 (2026-01-28)

  • Added 5 new lab result properties for enhanced metadata
    • orderingProvider, performingLab, observationStatus (clinical context)
    • sourceRecordId (FHIR traceability)
    • panelMembership (panel container back-reference)
  • Added structured reference range properties: referenceRangeLow, referenceRangeHigh, referenceRangeText
  • Added issuedDate for result issuance timestamp
  • Added clinical:LabTestSeries class for longitudinal lab result tracking
    • Lab equivalent of MedicationUseEpisode — one series per LOINC code per patient
    • 20 properties for identity, trending, reference ranges, and source linkage
    • Trend inference with confidence and explainable reason
    • No gap-based splitting (unlike medication episodes)
  • Extended derivedFromRecord, sourceExternalId, and hasUnresolvedConflicts domains to include LabTestSeries
  • Extended sourceEHR and provenanceClass domains to include LabResult

Version 1.3 (2026-01-26)

  • Added 14 medication enrichment properties from FHIR extraction pipeline
    • Tier 1 (Clinical Detail): prescriber, indication, courseOfTherapyType, asNeeded, medicationForm, activeIngredient, ingredientStrength
    • Tier 1 (Provenance): provenanceClass, sourceFhirResourceType, clinicalIntent
    • Tier 2 (Dispensing): refillsAllowed, supplyDurationDays, dispensedQuantity, prescriptionCategory
  • SHACL shapes with enumerated value constraints for courseOfTherapyType, provenanceClass, sourceFhirResourceType, clinicalIntent, prescriptionCategory
  • Full end-to-end FHIR extraction pipeline: JSON → MedicationSummary → MedicationRecord → TTL
  • Previously-defined but unpopulated terms (ndcCode, snomedCode) now extracted from FHIR

Version 1.2 (2026-01-15)

  • Added MedicationUseEpisode class for longitudinal medication tracking
    • Represents continuous periods of medication use
    • Links to source MedicationRecord(s) via derivedFromRecord
    • Includes inferred status with explainable confidence/reason
    • Supports multi-system drug coding (RxNorm, NDC, SNOMED, ATC)
  • Added Supplement class for dietary supplements and OTC products
    • Explicit regulatoryStatus (dietarySupplement, otcDrug, homeopathic, herbalRemedy)
    • evidenceStrength property for clinical evidence level
    • DSLD integration for NIH supplement database
  • Added ~25 new data properties for episode and supplement serialization
  • Episode identity rules: gap > 90 days creates new episode
  • Supplements intentionally do NOT create episodes (different regulatory status)

Version 1.1 (2026-01-01)

  • Added 7 structured clinical record classes: Medication, Allergy, LabResult, Condition, Immunization, Procedure, VitalSign
  • Added ~50 data properties for structured records
  • Added vital sign component properties for multi-value observations (blood pressure)
  • Added SHACL shapes for all structured record types
  • Validated with OWL-RL reasoner (no inconsistencies)
  • Validated with Apache Jena SHACL validator

Version 1.0 (2025-12-26)

  • Initial release with document-centric vocabulary
  • ClinicalDocument and subtypes (ProgressNote, DischargeSummary, etc.)
  • ClinicalSection for document structure
  • Document metadata properties (importedAt, sourceEHR, etc.)
  • Narrative content properties