Overview

Namespace URI:
https://ns.cascadeprotocol.org/health/v1#
Preferred Prefix:
health:
Version:
2.12
Status:
Stable
Imports:
cascade: (Core Vocabulary v1)
Schema File:
health.ttl (Turtle/RDF)

The Health Vocabulary provides a comprehensive schema for representing consumer-generated wellness observations from wearable devices and Apple HealthKit. It maps Cascade wellness properties to established SNOMED CT and LOINC codes following the three-layer ontology architecture.

Wellness vital sign readings are serialized using flat health: properties directly on health:VitalSignReading blank nodes (Pattern A). Time-series history containers are linked from health:HealthProfile via ObjectProperties such as health:restingHeartRateHistory. Activity and sleep metrics use composite snapshot classes (ActivitySnapshot, SleepSnapshot) that subclass prov:Entity.

Three-Layer Architecture: This is a Layer 2 vocabulary. Layer 1 uses established standards (SNOMED CT, LOINC). Layer 2 (this vocabulary) defines domain-specific properties linking to Layer 1 codes. Layer 3 (Checkup Vocabulary) provides patient-facing summaries.
Download TTL Back to Documentation

Composite Classes

Aggregate snapshot classes for activity and sleep data collected over a measurement period.

health:ActivitySnapshot

owl:Class

Aggregated activity metrics over a measurement period (typically 7 days). Includes steps, active energy, exercise minutes, and stand hours.

Subclass of: prov:Entity

health:SleepSnapshot

owl:Class

Aggregated sleep metrics over a measurement period (typically 7 days). Includes duration and quality assessment.

Subclass of: prov:Entity

health:MetricTrend v1.5

owl:Class

A time-bounded trend for a single wellness metric, computed from a series of observations. Captures direction, magnitude, and comparison period. Designed for continuous daily observations from consumer devices.

Subclass of: prov:Entity

health:VO2MaxStatistics v1.7

owl:Class

Statistical summary of VO2 Max readings over a measurement period (typically 180 days). Provides trend analysis, fitness classification, and min/max/mean calculations. Designed for dual-path UI display: rich statistics view when available, fallback to single VO2 Max value otherwise.

Subclass of: prov:Entity

health:HRVStatistics v1.7

owl:Class

Statistical summary of Heart Rate Variability (SDNN) readings over a measurement period. Provides trend analysis and min/max/mean calculations.

Subclass of: prov:Entity

health:BPStatistics v1.8

owl:Class

Statistical summary of blood pressure readings over a measurement period. Provides mean, min, max for systolic and diastolic values, plus AHA category classification.

Subclass of: prov:Entity

Cardiac Properties

Heart rate and heart rate variability observations from wearable devices.

health:restingHeartRate

owl:DatatypeProperty

Average resting heart rate from wearable device.

Domain: fhir:Observation

Range: xsd:double

Unit: beats/min (UCUM: /min)

SNOMED CT: 364075005 (Heart rate)

LOINC: 40443-4 (Heart rate — resting)

health:walkingHeartRate

owl:DatatypeProperty

Average heart rate during walking from wearable device.

Domain: fhir:Observation

Range: xsd:double

Unit: beats/min (UCUM: /min)

SNOMED CT: 364075005 (Heart rate)

LOINC: 89270-3 (Heart rate — walking exercise)

health:heartRateVariability

owl:DatatypeProperty

Standard deviation of normal-to-normal R-R intervals (SDNN) from wearable device.

Domain: fhir:Observation

Range: xsd:double

Unit: ms (UCUM: ms)

SNOMED CT: 80404004 (Heart rate variability)

LOINC: 80404-7 (R-R interval standard deviation)

Cardiovascular Properties

Blood pressure observations with systolic and diastolic components.

health:bloodPressure

owl:ObjectProperty

Blood pressure panel observation with systolic and diastolic components.

Domain: fhir:Observation

SNOMED CT: 75367002 (Blood pressure)

LOINC: 85354-9 (Blood pressure panel)

health:systolicBP

owl:DatatypeProperty

Systolic blood pressure component.

Domain: fhir:Observation

Range: xsd:double

Unit: mmHg (UCUM: mm[Hg])

SNOMED CT: 271649006 (Systolic blood pressure)

LOINC: 8480-6 (Systolic blood pressure)

health:diastolicBP

owl:DatatypeProperty

Diastolic blood pressure component.

Domain: fhir:Observation

Range: xsd:double

Unit: mmHg (UCUM: mm[Hg])

SNOMED CT: 271650006 (Diastolic blood pressure)

LOINC: 8462-4 (Diastolic blood pressure)

Respiratory & Fitness Properties

health:respiratoryRate

owl:DatatypeProperty

Average respiratory rate from wearable device.

Domain: fhir:Observation

Range: xsd:double

Unit: breaths/min (UCUM: /min)

SNOMED CT: 86290005 (Respiratory rate)

LOINC: 9279-1 (Respiratory rate)

health:vo2Max

owl:DatatypeProperty

Estimated maximal oxygen consumption (cardiorespiratory fitness).

Domain: fhir:Observation

Range: xsd:double

Unit: mL/kg/min (UCUM: mL/kg/min)

SNOMED CT: 251880009 (Aerobic capacity)

LOINC: — (none; 60842-2 was removed in v2.12 because it is oxygen consumption in mL/min, not VO2 max per kilogram, and no code for an estimated VO2 max was found)

Method (v2.12): each VO2 max reading carries clinical:measurementMethod (FHIR Observation.method), the source's own method value under a source namespace, from the closed set health:MeasurementMethodShape binds: the HealthKit HKVO2MaxTestType cases, the Health Connect Vo2MaxRecord methods, and Google's two daily series. Measured or estimated follows from the value; a reading with no method is not assumed measured.

Walking Steadiness

health:walkingSteadiness

owl:DatatypeProperty

Apple Health walking steadiness classification (OK / Low / Very Low). Maps to nearest SNOMED balance concept. No LOINC equivalent exists for this consumer-device metric.

Domain: fhir:Observation

Range: xsd:string

SNOMED CT: 364832000 (Balance finding)

LOINC: — (no equivalent)

Note: SNOMED mapping is approximate. Alternatives considered: 250043000 (Gait finding — too broad), 282097004 (Ability to walk — functional assessment, not a measurement). Apple's OK/Low/Very Low classification is proprietary.

Body Measurement Properties v1.8

Body measurement observations with SNOMED CT and LOINC standard code mappings.

health:bodyMass

owl:DatatypeProperty

Body weight measurement.

Domain: fhir:Observation

Range: xsd:double

Unit: kg (UCUM: kg)

SNOMED CT: 27113001 (Body weight)

LOINC: 29463-7 (Body weight)

Trend Polarity: neutral

health:bodyHeight

owl:DatatypeProperty

Body height measurement.

Domain: fhir:Observation

Range: xsd:double

Unit: cm (UCUM: cm)

SNOMED CT: 50373000 (Body height)

LOINC: 8302-2 (Body height)

Trend Polarity: neutral

health:bodyMassIndex

owl:DatatypeProperty

Computed body mass index (weight/height squared).

Domain: fhir:Observation

Range: xsd:double

Unit: kg/m2 (UCUM: kg/m2)

SNOMED CT: 60621009 (Body mass index)

LOINC: 39156-5 (Body mass index)

Trend Polarity: neutral

health:bodyTemperature

owl:DatatypeProperty

Body temperature measurement.

Domain: fhir:Observation

Range: xsd:double

Unit: degC (UCUM: Cel)

SNOMED CT: 386725007 (Body temperature)

LOINC: 8310-5 (Body temperature)

Trend Polarity: neutral

health:oxygenSaturation

owl:DatatypeProperty

Blood oxygen saturation (SpO2) from pulse oximeter.

Domain: fhir:Observation

Range: xsd:double

Unit: % (UCUM: %)

SNOMED CT: 431314004 (Oxygen saturation)

LOINC: 2708-6 (Oxygen saturation)

Trend Polarity: higher_is_better

health:bloodGlucose

owl:DatatypeProperty

Blood glucose measurement.

Domain: fhir:Observation

Range: xsd:double

Unit: mg/dL (UCUM: mg/dL)

SNOMED CT: 33747003 (Blood glucose)

LOINC: 2339-0 (Blood glucose)

Trend Polarity: neutral

health:bloodType v1.9

owl:DatatypeProperty

ABO blood group and Rh factor. Sourced from HealthKit (HKCharacteristicType.bloodType) or manual entry.

Domain: health:HealthProfile

Range: xsd:string

Values: aPositive, aNegative, bPositive, bNegative, abPositive, abNegative, oPositive, oNegative

SNOMED CT: 365637002 (Finding of ABO blood group)

LOINC: 882-1 (ABO group [Type] in Blood)

Note: This is a patient characteristic, not a time-series observation. Domain is HealthProfile rather than fhir:Observation.

Activity Properties

Properties for the health:ActivitySnapshot class.

health:averageDailySteps

owl:DatatypeProperty

Average number of steps per day over measurement period.

Domain: health:ActivitySnapshot

Range: xsd:integer

Unit: steps

SNOMED CT: 68130003 (Physical activity)

LOINC: 41950-7 (Number of steps in 24 hour Measured)

health:activeEnergyBurnedKcal

owl:DatatypeProperty

Active energy expenditure in kilocalories (excludes basal metabolic rate).

Domain: health:ActivitySnapshot

Range: xsd:decimal

Unit: kcal (UCUM: kcal)

SNOMED CT: 251833007 (Energy expenditure)

LOINC: 41981-2 (Calories burned, of any kind: broader than this property, corrected in v2.12. Active versus basal is carried by the property, never by the code.)

health:exerciseMinutesWeekly

owl:DatatypeProperty

Total minutes of exercise activity per week.

Domain: health:ActivitySnapshot

Range: xsd:integer

Unit: min (UCUM: min)

SNOMED CT: 68130003 (Physical activity)

LOINC: 73985-4 (Exercise activity)

health:standHoursDaily

owl:DatatypeProperty

Number of hours per day with at least one minute of standing. Cascade-proprietary metric — no SNOMED CT or LOINC equivalent exists. Apple Health-specific activity ring metric.

Domain: health:ActivitySnapshot

Range: xsd:integer

Unit: hours

SNOMED CT: — (no equivalent)

LOINC: — (no equivalent)

health:basalEnergyKcal v2.12

owl:DatatypeProperty

Basal (resting) energy burned over a single day, in kilocalories: the energy the body spends to maintain itself at rest, which health:activeEnergyKcal excludes. Summed per source, device and day from HealthKit basalEnergyBurned samples, with cascade:statistic "sum". Energy, not a rate: a basal metabolic rate is never written here. A source that supplies only total and active energy supplies no basal value; total minus active is a derived view, never written here.

Domain: health:DailyActivitySnapshot

Range: xsd:decimal

Unit: kcal (UCUM: kcal)

LOINC: — (none: no LOINC code separates basal from active energy burned over an interval)

Sleep Properties

Properties for the health:SleepSnapshot class.

health:averageDurationHours

owl:DatatypeProperty

Average sleep duration in hours over measurement period.

Domain: health:SleepSnapshot

Range: xsd:decimal

Unit: hours (UCUM: h)

SNOMED CT: 248263006 (Duration of sleep)

LOINC: 93832-4 (Sleep duration)

health:sleepQuality

owl:DatatypeProperty

Qualitative sleep quality assessment derived from wearable sleep analysis.

Domain: health:SleepSnapshot

Range: xsd:string

health:isMainSleep v2.12

owl:DatatypeProperty

True when the source marks a sleep session as the main sleep of its night, false when the source marks it as not the main sleep (a nap). IEEE 1752.1 sleep-episode is_main_sleep. Written only where a source supplies the flag (Fitbit isMainSleep, verbatim; WHOOP nap, negated). Absent is not false. Apple supplies no such flag, so choosing the main sleep among an Apple date's sessions is a derived view, never a value written on the session.

Domain: health:SleepSession

Range: xsd:boolean

Metric Trend Properties v1.5

Properties for the health:MetricTrend class. Captures time-bounded wellness trends with direction, magnitude, confidence, and baseline/current values.

health:trendMetric

owl:ObjectProperty

The wellness property this trend describes (e.g., health:restingHeartRate).

Domain: health:MetricTrend

health:trendDirection

owl:DatatypeProperty

Direction of change: increasing, decreasing, stable, or insufficient_data. Matches clinical:trendDirection values for cross-domain consistency.

Domain: health:MetricTrend

Range: xsd:string

health:trendMagnitude

owl:DatatypeProperty

Percentage change between comparison periods (e.g., -5.6 means a 5.6% decrease).

Domain: health:MetricTrend

Range: xsd:decimal

health:trendPeriodStart

owl:DatatypeProperty

Start of the trend measurement period.

Domain: health:MetricTrend

Range: xsd:dateTime

health:trendPeriodEnd

owl:DatatypeProperty

End of the trend measurement period.

Domain: health:MetricTrend

Range: xsd:dateTime

health:trendBaselineValue

owl:DatatypeProperty

The reference value (e.g., 90-day average) this trend is compared against.

Domain: health:MetricTrend

Range: xsd:decimal

health:trendCurrentValue

owl:DatatypeProperty

The current period average (e.g., 7-day average).

Domain: health:MetricTrend

Range: xsd:decimal

health:trendConfidence

owl:DatatypeProperty

Confidence in the trend: high (>30 days data), medium (14-30 days), low (<14 days).

Domain: health:MetricTrend

Range: xsd:string

health:trendSource

owl:ObjectProperty

The data source (device, app, or system) that produced the underlying observations.

Domain: health:MetricTrend

Range: cascade:DataSource

VO2 Max Statistics Properties v1.7

Properties for the health:VO2MaxStatistics class. Statistical analysis of VO2 Max readings with trend detection and fitness classification.

health:vo2Mean

owl:DatatypeProperty

Average VO2 Max over measurement period.

Domain: health:VO2MaxStatistics

Range: xsd:double

Unit: mL/kg/min (UCUM: mL/kg/min)

health:vo2Min

owl:DatatypeProperty

Lowest VO2 Max reading in measurement period.

Domain: health:VO2MaxStatistics

Range: xsd:double

Unit: mL/kg/min

health:vo2MaxValue

owl:DatatypeProperty

Highest VO2 Max reading in measurement period.

Domain: health:VO2MaxStatistics

Range: xsd:double

Unit: mL/kg/min

health:vo2SampleCount

owl:DatatypeProperty

Number of VO2 Max measurements in the period.

Domain: health:VO2MaxStatistics

Range: xsd:integer

health:vo2DaysCovered

owl:DatatypeProperty

Number of unique days with VO2 Max measurements.

Domain: health:VO2MaxStatistics

Range: xsd:integer

health:vo2TrendDirection

owl:DatatypeProperty

Trend direction: improving, declining, stable, or unknown. Uses 3% threshold.

Domain: health:VO2MaxStatistics

Range: xsd:string

health:vo2PercentageChange

owl:DatatypeProperty

Percentage change from oldest to newest reading period.

Domain: health:VO2MaxStatistics

Range: xsd:double

health:fitnessClassification

owl:DatatypeProperty

Cardiorespiratory fitness level based on mean VO2 Max: veryPoor, poor, fair, good, excellent, superior.

Domain: health:VO2MaxStatistics

Range: xsd:string

health:isSparseData

owl:DatatypeProperty

True when measurements are limited (< 3 samples or < 30 days covered).

Domain: health:VO2MaxStatistics

Range: xsd:boolean

HRV Statistics Properties v1.7

Properties for the health:HRVStatistics class. Statistical analysis of Heart Rate Variability (SDNN) readings with trend detection.

health:hrvSampleCount v1.8

owl:DatatypeProperty

Number of HRV readings in the period.

Domain: health:HRVStatistics

Range: xsd:integer

health:hrvDaysCovered v1.8

owl:DatatypeProperty

Number of unique days with HRV measurements.

Domain: health:HRVStatistics

Range: xsd:integer

health:hrvMean v1.8

owl:DatatypeProperty

Average HRV (SDNN) over the measurement period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvMedian v1.8

owl:DatatypeProperty

Median HRV (SDNN) over the measurement period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvStdDev v1.8

owl:DatatypeProperty

Standard deviation of HRV readings over the measurement period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvMin v1.8

owl:DatatypeProperty

Lowest HRV reading in the period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvMax v1.8

owl:DatatypeProperty

Highest HRV reading in the period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvPercentile25 v1.8

owl:DatatypeProperty

25th percentile of HRV readings over the measurement period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvPercentile75 v1.8

owl:DatatypeProperty

75th percentile of HRV readings over the measurement period.

Domain: health:HRVStatistics

Range: xsd:double

Unit: ms

health:hrvTrendDirection v1.8

owl:DatatypeProperty

Trend direction for HRV: improving, declining, stable, or unknown.

Domain: health:HRVStatistics

Range: xsd:string

Blood Pressure Statistics Properties v1.8

Properties for the health:BPStatistics class. Statistical summary of blood pressure readings with AHA category classification.

health:bpSampleCount

owl:DatatypeProperty

Number of blood pressure readings in the period.

Domain: health:BPStatistics

Range: xsd:integer

health:bpMeanSystolic

owl:DatatypeProperty

Average systolic blood pressure over the measurement period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpMeanDiastolic

owl:DatatypeProperty

Average diastolic blood pressure over the measurement period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpMinSystolic

owl:DatatypeProperty

Lowest systolic blood pressure reading in the period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpMaxSystolic

owl:DatatypeProperty

Highest systolic blood pressure reading in the period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpMinDiastolic

owl:DatatypeProperty

Lowest diastolic blood pressure reading in the period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpMaxDiastolic

owl:DatatypeProperty

Highest diastolic blood pressure reading in the period.

Domain: health:BPStatistics

Range: xsd:double

Unit: mmHg

health:bpCategory

owl:DatatypeProperty

AHA blood pressure category based on mean values: normal, elevated, hypertension_stage1, hypertension_stage2, hypertensive_crisis.

Domain: health:BPStatistics

Range: xsd:string

Shared Temporal Properties v1.8

Temporal properties shared across statistics classes (BPStatistics, HRVStatistics, VO2MaxStatistics).

health:periodStart

owl:DatatypeProperty

Start date of the statistical measurement period.

Range: xsd:dateTime

health:periodEnd

owl:DatatypeProperty

End date of the statistical measurement period.

Range: xsd:dateTime

Pattern A Flat Properties v2.3

Flat health: properties used directly on health:VitalSignReading blank nodes emitted by HealthProfileSerializer (BUG-006 Pattern A standardization). These replace the previous fhir:Observation nesting pattern.

health:value

owl:DatatypeProperty

The numeric measurement value for a wellness vital sign reading.

Domain: health:VitalSignReading

Range: xsd:double

health:date

owl:DatatypeProperty

The effective date/time of a wellness vital sign reading.

Domain: health:VitalSignReading

Range: xsd:dateTime

health:sdnn

owl:DatatypeProperty

Heart rate variability measured as standard deviation of NN intervals (SDNN), in milliseconds.

Range: xsd:double

Unit: ms

health:systolic

owl:DatatypeProperty

Systolic blood pressure value in mmHg.

Range: xsd:double

Unit: mmHg

health:diastolic

owl:DatatypeProperty

Diastolic blood pressure value in mmHg.

Range: xsd:double

Unit: mmHg

health:walkingSteadinessLevel

owl:ObjectProperty

Apple Walking Steadiness classification. Values: health:OK, health:Low, health:VeryLow, health:Unknown.

Social History v2.4

Consumer-reported social history observations (smoking, alcohol, exercise, occupation), added for EHR import reconciliation (P1-C). Distinct from clinical:SocialHistoryRecord, which is EHR-extracted and governed by 42 CFR Part 2.

health:SocialHistoryRecord

owl:Class

A social history observation about a patient, including smoking status, alcohol use, exercise, occupation, and other lifestyle factors.

health:smokingStatus

owl:DatatypeProperty

Patient's smoking status. Common values: current-smoker, former-smoker, never-smoker.

Domain: health:SocialHistoryRecord

Range: xsd:string

health:alcoholUse

owl:DatatypeProperty

Patient's alcohol consumption description.

Domain: health:SocialHistoryRecord

Range: xsd:string

health:exerciseFrequency

owl:DatatypeProperty

Patient's reported exercise frequency.

Domain: health:SocialHistoryRecord

Range: xsd:string

health:occupationalExposure

owl:DatatypeProperty

Occupational exposures relevant to patient health.

Domain: health:SocialHistoryRecord

Range: xsd:string

Annotation Properties

Metadata annotations linking wellness properties to established standard codes.

health:snomedCode

owl:AnnotationProperty

Links a wellness property to its SNOMED CT concept.

health:loincCode

owl:AnnotationProperty

Links a wellness property to its LOINC observation code.

health:unit

owl:AnnotationProperty

Human-readable unit of measurement.

health:ucumCode

owl:AnnotationProperty

Unified Code for Units of Measure (UCUM) code.

health:trendPolarity v1.6

owl:AnnotationProperty

Whether an increase in this metric is generally favorable (higher_is_better), unfavorable (lower_is_better), or context-dependent (neutral). Used by presentation layers to determine trend arrow color semantics.

Standard Code Mappings

Complete mapping of all health vocabulary properties to established clinical terminologies.

Metric Property SNOMED CT LOINC
Resting Heart Rate health:restingHeartRate 364075005 40443-4
Walking Heart Rate health:walkingHeartRate 364075005 89270-3
HRV (SDNN) health:heartRateVariability 80404004 80404-7
Blood Pressure health:bloodPressure 75367002 85354-9
Systolic BP health:systolicBP 271649006 8480-6
Diastolic BP health:diastolicBP 271650006 8462-4
Respiratory Rate health:respiratoryRate 86290005 9279-1
VO2 Max health:vo2Max 251880009 — (removed v2.12)
Walking Steadiness health:walkingSteadiness 364832000 —
Average Daily Steps health:averageDailySteps 68130003 41950-7
Active Energy Burned health:activeEnergyBurnedKcal 251833007 41981-2
Exercise Minutes health:exerciseMinutesWeekly 68130003 73985-4
Stand Hours health:standHoursDaily — —
Sleep Duration health:averageDurationHours 248263006 93832-4
Body Mass health:bodyMass 27113001 29463-7
Body Height health:bodyHeight 50373000 8302-2
Body Mass Index health:bodyMassIndex 60621009 39156-5
Body Temperature health:bodyTemperature 386725007 8310-5
Oxygen Saturation health:oxygenSaturation 431314004 2708-6
Blood Glucose health:bloodGlucose 33747003 2339-0
Blood Type health:bloodType 365637002 882-1

Usage Example

@prefix health: <https://ns.cascadeprotocol.org/health/v1#> .
@prefix cascade: <https://ns.cascadeprotocol.org/core/v1#> .
@prefix fhir: <http://hl7.org/fhir/> .
@prefix loinc: <https://loinc.org/rdf/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# Resting heart rate observation
<#rhr-reading-001> a fhir:Observation ;
    cascade:schemaVersion "1.4" ;
    cascade:dataProvenance cascade:ConsumerGenerated ;
    health:restingHeartRate "68.0"^^xsd:double ;
    cascade:loincCode loinc:40443-4 ;
    prov:wasAttributedTo <https://id.cascadeprotocol.org/users/abc123> .

# Activity snapshot
<#activity-2026-01> a health:ActivitySnapshot ;
    cascade:schemaVersion "1.4" ;
    cascade:dataProvenance cascade:ConsumerGenerated ;
    health:averageDailySteps "8500"^^xsd:integer ;
    health:activeEnergyBurnedKcal "450.0"^^xsd:decimal ;
    health:exerciseMinutesWeekly "185"^^xsd:integer ;
    health:standHoursDaily "11"^^xsd:integer .

# Sleep snapshot
<#sleep-2026-01> a health:SleepSnapshot ;
    cascade:schemaVersion "1.4" ;
    health:averageDurationHours "7.5"^^xsd:decimal ;
    health:sleepQuality "good" .

Data Provenance

All health vocabulary observations use cascade:ConsumerGenerated provenance to indicate device-generated wellness data:

  • Source: Apple HealthKit HKQuantityType / HKStatistics APIs
  • Origin: Apple Watch, iPhone, and compatible third-party devices
  • Classification: Consumer-generated, non-diagnostic
  • Privacy: Encrypted storage required, local-first architecture

Clinical Record Classes v2.5

These five classes have been emitted by Cascade serializers since schema version 1.3 but were not defined in this ontology until v2.5. Defining them is purely additive: no serializer changed, no rdf:type changed, and no pod was migrated. What changed is that the records became describable and, through health.shapes.ttl v1.2, checkable.

The health: / clinical: split is historical, not a provenance signal. Records typed health:LabResultRecord, health:ConditionRecord, health:AllergyRecord and health:ImmunizationRecord routinely carry EHR-sourced data, and clinical:VitalSign records routinely carry consumer-device data. Provenance is carried by cascade:dataProvenance, and only by it. Keying on the namespace of the rdf:type gives the wrong answer on real pods. The four clinical: classes that duplicate these are deprecated in clinical v1.13 but not removed; readers must accept both spellings and writers should prefer these.

health:LabResultRecord

owl:Class

A laboratory test result: the test performed, its value and unit, the reference range it is read against, and the specimen it came from. Emitted for both EHR-imported and patient-entered results.

Subclass of: fhir:Observation — FHIR R4: Observation

Properties: health:testName (required), health:resultValue, health:resultUnit, health:referenceRange, health:interpretation, health:performedDate, health:reportedDate, health:testCode, health:labCategory, health:specimenType, health:orderingProvider, health:performingLab

health:ConditionRecord

owl:Class

A diagnosed condition or problem-list entry, with its clinical status, onset and coding.

FHIR R4: Condition

Properties: health:conditionName (required), health:status, health:onsetDate, health:icd10Code, health:snomedCode, health:conditionClass, health:monitoredVitalSigns

health:AllergyRecord

owl:Class

An allergy or intolerance: the allergen, the reaction it provokes, and the severity of that reaction.

FHIR R4: AllergyIntolerance

Properties: health:allergen (required), health:reaction (repeatable), health:allergySeverity, health:allergyCategory, health:onsetDate

health:ImmunizationRecord

owl:Class

An administered vaccine dose, with product identification, lot, route, site and administering party.

FHIR R4: Immunization

Properties: health:vaccineName (required), health:administrationDate, health:status, health:vaccineCode, health:manufacturer, health:lotNumber, health:doseQuantity, health:route, health:site, health:administeringProvider, health:administeringLocation

health:FamilyHistoryRecord

owl:Class

A condition recorded for a relative of the patient, with the relationship and the relative's age at onset.

FHIR R4: FamilyMemberHistory

Properties: health:conditionName (required), clinical:relationship (required, shared with coverage records), health:onsetAge

health:sourceRecordId and health:notes are shared by all five. Domains on shared properties are unions rather than a single class: a single-class rdfs:domain on a property that several classes use is an assertion the data falsifies.

Wellness Container Classes v2.5

The wellness partition of a pod stores each metric family in its own container resource. The six container types are declared rdfs:subClassOf health:HealthProfile.

health:ActivityData

owl:Class

Wellness container for daily activity history: steps, active energy, exercise minutes and stand hours. Subclass of health:HealthProfile.

health:SleepData

owl:Class

Wellness container for nightly sleep history: duration and quality. Subclass of health:HealthProfile.

health:HeartRateData

owl:Class

Wellness container for resting and walking heart rate history. Subclass of health:HealthProfile.

health:BloodPressureData

owl:Class

Wellness container for blood pressure history from home monitors. Subclass of health:HealthProfile.

health:HRVData

owl:Class

Wellness container for heart rate variability (SDNN) history. Subclass of health:HealthProfile.

health:BodyMeasurements

owl:Class

Wellness container for body mass and related anthropometric history. Subclass of health:HealthProfile.

The subclass declarations do two things and require no code change. They make the rdfs:domain health:HealthProfile already asserted on the eight history properties (health:restingHeartRateHistory and siblings) true rather than contradicted by every pod ever written, and they bring the containers under health:HealthProfileShape. The shapes file additionally names each container as an explicit sh:targetClass, so coverage does not depend on a validator performing subclass inference.

SHACL Validation Shapes

Validation shapes for this vocabulary are defined in health.shapes.ttl (v1.10).

Shapes defined:

  • health:SelfReportShape — Validates SelfReport instances with required report date and type
  • health:VO2MaxStatisticsShape — Validates VO2 Max statistical summaries with mean, sample count, and period
  • health:HRVStatisticsShape — Validates HRV statistical summaries with mean, sample count, and period
  • health:BPStatisticsShape — Validates blood pressure statistical summaries with systolic/diastolic means and sample count
  • health:MetricTrendShape — Validates MetricTrend instances with metric reference, direction, and period
  • health:ActivitySnapshotShape — Validates ActivitySnapshot instances (7-day aggregate) with steps, energy, exercise, and stand hours
  • health:SleepSnapshotShape — Validates SleepSnapshot instances (7-day aggregate) with duration and quality
  • health:HealthProfileShape — Validates HealthProfile instances with blood type; also targets the six wellness container classes (v1.2)
  • health:SocialHistoryRecordShape — Validates SocialHistoryRecord instances
  • health:LabResultRecordShape — Requires health:testName; constrains health:interpretation to normal/high/low/abnormal/critical; sh:maxCount 1 on health:resultValue (v1.2). From v1.5 it also binds clinical:status to the 8 codes of FHIR R4 Observation.status, at sh:Warning
  • health:ConditionRecordShape — Requires health:conditionName; constrains health:status to the six FHIR clinical-status values (v1.2)
  • health:AllergyRecordShape — Requires health:allergen; constrains severity to mild/moderate/severe and category to the four FHIR values (v1.2). From v1.5 it also binds clinical:status to the 3 codes of AllergyIntolerance.clinicalStatus and clinical:verificationStatus to the 4 codes of AllergyIntolerance.verificationStatus, both at sh:Warning
  • health:ImmunizationRecordShape — Requires health:vaccineName; constrains health:status to completed/entered-in-error/not-done (v1.2)
  • health:FamilyHistoryRecordShape — Requires health:conditionName and clinical:relationship; health:onsetAge 0–130 (v1.2)
  • health:DailyVitalReadingShape — Requires cascade:date; cascade:sampleCount ≥ 0 (v1.2)
  • health:DailyActivitySnapshotShape — Requires cascade:date; exercise minutes 0–1440, stand hours 0–24 (v1.2)
  • health:DailySleepSnapshotShape — Requires cascade:date; duration 0–24 hours; quality from the four named individuals (v1.2)
  • health:AggregateReadingShape: on the three daily aggregate classes, the UTC interval (health:periodStart, health:periodEnd), a cascade:statistic, the zone the day was cut in (health:timeZone) and the device link, all at sh:Warning, because these classes existed before v2.10 and existing pods carry none of it (v1.8). From v1.10 it also binds health:sourceIdSpace to the closed set, at most one value
  • health:WorkoutShape: requires health:activityType, health:periodStart and health:periodEnd; constrains the datatype and range of every workout total, the route and the device edge, at sh:Violation (v1.8)
  • health:SleepSessionShape: requires health:periodStart and health:periodEnd; constrains the algorithm version, the score (0 to 100) and the seven stage totals, at sh:Violation (v1.8)
  • health:SessionSoftShape: on both session classes, the zone and offset forms, the closed set of health:sourceIdSpace, and the UTC form of the interval, at sh:Warning (v1.8)
  • health:DeviceShape: requires health:deviceName; constrains the device attributes, at sh:Violation (v1.8)
  • health:SleepQualitySpellingShape: reports each use of the deprecated health:sleepQuality at sh:Warning, the migration signal (v1.8)
  • health:SleepSessionSoftShape: health:isMainSleep, one xsd:boolean, at sh:Warning; kept off health:SleepSessionShape, which carries sh:Violation (v1.10)
  • health:DailyActivitySoftShape: health:basalEnergyKcal, one non-negative xsd:decimal, at sh:Warning (v1.10)
  • health:BloodPressureReadingShape: one paired reading per record. Targets the subjects of health:systolic and of health:diastolic, so a node carrying either component must carry exactly one of each, as an xsd:double, at sh:Warning (v1.10)
  • health:MeasurementMethodShape: targets the subjects of clinical:measurementMethod and, on any node that is not a clinical:VitalSign, requires one value from the closed set of source-namespaced method values, at sh:Warning (v1.10)
A validation finding after upgrading means the validator improved, not that the data degraded. Before v1.2, records of the five record classes and the six wellness containers matched no shape, so a validator reported PASS because zero constraints applied — not because the record conformed. Those records are now actually checked, most of them for the first time.

Changelog

Version 2.12 (2026-09-26)

  • The deferred wellness metrics. Sleep sessions assembled from stage segments, blood pressure, VO2 max and basal energy, each checked against the ratified standards (IEEE 1752.1, FHIR R4 vital signs, LOINC) and the platforms' published models before an importer writes it, plus two LOINC annotations that claimed more than their codes mean. Paired with clinical v1.21.
  • Added health:isMainSleep (xsd:boolean, domain health:SleepSession): IEEE 1752.1 sleep-episode is_main_sleep, written only where the source supplies the flag (Fitbit isMainSleep, WHOOP nap negated). Absent is not false; Apple supplies none, and the main sleep of an Apple date is a derived view.
  • Added health:basalEnergyKcal (xsd:decimal, domain health:DailyActivitySnapshot): basal (resting) energy burned over a day, summed per source, device and day from HealthKit basalEnergyBurned samples, cascade:statistic "sum". A distinct property because no LOINC code separates basal from active energy over an interval; no LOINC annotation. Energy, not a rate: a basal metabolic rate is never written here, and LOINC 50042-1 is not a metabolic rate.
  • Changed health:sourceIdSpace: rdfs:domain widens from health:Workout and health:SleepSession to the union with health:DailyVitalReading, health:DailyActivitySnapshot and health:DailySleepSnapshot, since the naming rule for wellness records carries the id space on every wellness record. The closed range (healthkit, google-health, fitbit) is unchanged.
  • Changed health:vo2Max: LOINC 60842-2 removed (it is oxygen consumption in mL/min, not VO2 max per kilogram) and no code substituted. The comment maps each source method value to measured or estimated.
  • Changed health:activeEnergyBurnedKcal: its LOINC 41981-2 annotation is kept but corrected: 41981-2 means "Calories burned" of any kind and is broader than the property. Active versus basal is carried by the property.
  • Changed the health:SleepSession comment: a night is dated by the day of waking in the session's recorded zone, falling back to the pod's cascade:dayZone; naps are separate sessions; a source's own sessions (Google, Fitbit, Health Connect) are never regrouped; Apple stage segments are grouped at a one-hour gap, with a run of awake of an hour or more counting as a gap; the raw segments are retained as the session's samples and linked by prov:wasDerivedFrom.
  • Changed the health:BloodPressureReading and health:BPStatistics comments: one paired reading per record (FHIR panel 85354-9, components 8480-6 and 8462-4), never bucketed by day; an average is a view, coded LOINC 96607-7 if ever stored. Comments on health:activeEnergyKcal, health:VitalSignReading, health:DailyVitalReading and health:DailyActivitySnapshot point to the above.
  • Reused, not minted. The VO2 max method is clinical:measurementMethod (FHIR Observation.method), whose rdfs:domain clinical:VitalSign clinical v1.21 drops. Values are the source's own, namespaced: the four HealthKit HKVO2MaxTestType cases, the six Health Connect Vo2MaxRecord methods, and Google's two daily series. The Apple sleep grouping rule is recorded as the session's generating activity's cascade:version ("{rule}/{version}"), the form the computed daily aggregates carry, rather than health:algorithmVersion (the source's own algorithm, verbatim), sosa:usedProcedure (how an observation is made, not how a record is assembled) or prov:hadPlan (reached only through a qualified association).
  • SHACL (health.shapes.ttl 1.9 to 1.10), all at sh:Warning: health:AggregateReadingShape binds health:sourceIdSpace; new health:SleepSessionSoftShape (isMainSleep), health:DailyActivitySoftShape (basalEnergyKcal), health:BloodPressureReadingShape (subjects of health:systolic / health:diastolic: exactly one of each) and health:MeasurementMethodShape (subjects of clinical:measurementMethod other than a clinical:VitalSign: the closed method set). The last two target a predicate rather than a class.
  • JSON-LD: isMainSleep and basalEnergyKcal in health.jsonld and the merged cascade.jsonld. measurementMethod was already mapped in clinical.jsonld and cascade.jsonld.
  • Additive. Nothing that validated under v2.11 stops validating; every new finding is at sh:Warning.

Version 2.11 (2026-09-25)

  • Comment hygiene: internal tracker references removed from comments. No term, range, shape or context change (health.shapes.ttl 1.9 likewise changes comments only).

Version 2.10 (2026-09-24)

  • Wellness and fitness records, measured before modelled. Two new session classes, one new device class, the interval and the statistic on every daily aggregate, and SOSA/SSN and OWL-Time alignment. Additive except for one deprecation, and paired with core v3.10, which adds cascade:statistic and cascade:dayZone. Every term is either adopted from a ratified standard or measured against two real exports (Apple Health: 10.2 million samples, two exports three months apart; Google Health Takeout: 3,985 files, two formats). Nothing that validated under v2.9 stops validating: every new finding on a class that existed in v2.9 is at sh:Warning, per the core v3.5 ratchet.
  • The interval. health:periodStart and health:periodEnd, declared in v1.8 with no rdfs:domain, are restated rather than redeclared, and widened in meaning to the three daily aggregate classes and the two session classes. Both are UTC instants, the interval is half-open, and the pair is the identity-bearing cut of a day. cascade:date stays, as the display date in the zone the aggregate was cut in. A sleep snapshot's interval is the local day the night ends in.
  • Zones. New health:timeZone (an IANA zone name: on an aggregate, the zone the period was cut in; on a session, the zone the source recorded) and health:utcOffset (the numeric offset a source such as Google supplies instead of a name, normalized to +HH:MM). A name and an offset are different facts: an offset cannot say which zone a later day belongs to. A Fitbit +00:00 placeholder is written as absent, never as UTC.
  • Devices. New health:Device (FHIR Device; a sosa:Platform), health:device (FHIR Observation.device) and six attributes: deviceName, deviceManufacturer, deviceModel, hardwareVersion, softwareVersion, serialNumber. A device is a record, not a label. Identity is the normalized name plus the hardware model where one exists, never the raw string Apple prints (it embeds a memory address that changes on every export), never the manufacturer (Apple prints both "Apple" and "Apple Inc."), never the software version.
  • Workouts. New health:Workout (FHIR Physical Activity IG; IEEE 1752.1 physical-activity), health:workoutHistory, health:activityType, health:workoutRoute, health:durationMinutes, health:distanceMeters, health:averageHeartRate, health:maximumHeartRate and health:indoor. The activity type is the source's own identifier under a source namespace (healthkit:, google-health:, fitbit:), with a SNOMED CT code optional beside it on health:snomedCode. The route is a cascade:Attachment, never parsed into triples, and optional, since Fitbit supplies none. health:activeEnergyKcal's domain widens to the union with health:Workout.
  • Sleep sessions. New health:SleepSession (IEEE 1752.1 sleep episode), health:sleepSessionHistory, health:algorithmVersion, health:sleepScore and seven per-stage minute totals: inBedMinutes, awakeMinutes, lightSleepMinutes, deepSleepMinutes, remSleepMinutes, restlessMinutes, asleepUnspecifiedMinutes. Each stage states its AASM mapping on itself (light is N1 plus N2, deep is N3, REM is R, awake is W; in bed and restless are not sleep stages). Two sessions one source recorded for one night are two records, told apart by health:algorithmVersion. health:sleepScore is a score the source supplied; nothing in Cascade computes one. health:DailySleepSnapshot remains, as the daily rollup of its sessions.
  • Deprecated health:sleepQuality and the four health:SleepQuality individuals (owl:deprecated true, not removed): a home-grown Excellent/Good/Fair/Poor enum with no standard behind it and no rule for how a value is reached, carried by neither measured export. Existing pods keep validating, and health:SleepQualitySpellingShape reports each use at sh:Warning.
  • Source ids. health:sourceRecordId's domain widens to the two session classes, and new health:sourceIdSpace names the id space from a closed set (healthkit, google-health, fitbit), because one Google Takeout holds two formats whose ids never coincide. Ids are always strings: 462 of 464 measured Google exercise ids exceed 253.
  • SOSA/SSN and OWL-Time alignment, additive axioms only. Every reading class and both session classes are rdfs:subClassOf sosa:Observation, and health:Device is rdfs:subClassOf sosa:Platform. health:device is deliberately not a subproperty of sosa:madeBySensor: the SSN cardinality restriction on that property would make a reasoner infer two devices on one aggregate to be the same device.
  • health:DailyActivitySnapshot documents where its values come from: one record per source and day, with Apple's own ActivitySummary treated as a source in its own right, never mixed with step counts aggregated per device.
  • SHACL (health.shapes.ttl 1.8): health:AggregateReadingShape, health:WorkoutShape, health:SleepSessionShape, health:SessionSoftShape, health:DeviceShape and health:SleepQualitySpellingShape. JSON-LD: health.jsonld gains the three classes and the datatype terms, and deliberately omits the four structured object properties (health:device, health:workoutRoute, health:workoutHistory, health:sleepSessionHistory); a JSON-LD writer uses full IRIs for those four.

Version 2.9 (2026-09-05)

  • Added health:allergenCode and health:manifestationCode on health:AllergyRecord. Both owl:ObjectProperty, both repeatable, both optional. Additive: nothing that validated under v2.8 stops validating, and every new SHACL finding is at sh:Warning per the core v3.5 ratchet.
  • Why. The canonical layer's external form is the HL7 FHIR International Patient Summary, whose Allergies and Intolerances section is one of the three required sections. The IPS AllergyIntolerance profile makes AllergyIntolerance.code 1..1 must-support and reaction.manifestation 1..* must-support. Through v2.8 this vocabulary could supply neither: health:allergen and health:reaction are display text and no term carried a code, so an importer discarded code.coding and reaction.manifestation.coding at import rather than storing them.
  • health:allergenCode is the coded substance, one IRI per AllergyIntolerance.code.coding, in the code system's own IRI space (SNOMED CT, RxNorm, UNII). Modelled on health:icd10Code: an IRI, no lexical pattern, repeatable because FHIR R4 CodeableConcept.coding is 0..* and a substance is routinely coded twice, an ingredient beside a product. health:allergen is unchanged, still required, and remains the display text.
  • health:manifestationCode is the coded manifestation, one IRI per reaction.manifestation.coding. health:reaction remains the display text beside it, and its comment now states what the shape has always permitted: one literal per manifestation, repeatable. An importer that joins several manifestations into one comma-separated literal destroys data the shape was already willing to hold.
  • The modelling is flat, deliberately. FHIR groups manifestation[] and severity inside each reaction[] element; here manifestations and one severity sit on the record. Flat loses the grouping in exactly one case, an allergy with two or more reactions whose severities differ, and is chosen because a layer 1 record is a named thing and a blank node inside one has no name of its own.

Version 2.8 (2026-08-27)

  • Shapes only. No class or property added, removed, renamed or deprecated in health.ttl. Two health: record shapes gain the value sets for a status their records already carry. Full detail is in health.shapes.ttl v1.5.
  • health:LabResultRecordShape declares clinical:status bound to the 8 codes of FHIR R4 Observation.status, required binding, verbatim and in the value set's own order. Naming the codes matters beyond conformance: amended and corrected are what distinguish a superseded result from the one that replaced it.
  • health:AllergyRecordShape declares clinical:status bound to the 3 codes of AllergyIntolerance.clinicalStatus. Three, not four: entered-in-error belongs to the verification axis, and admitting it here would merge “the patient no longer reacts to this” with “this allergy was never real”, which is the one pair a safety-relevant record must never conflate.
  • health:AllergyRecordShape also declares clinical:verificationStatus bound to the 4 codes of AllergyIntolerance.verificationStatus. The allergy set has no provisional and no differential, because a differential diagnosis is not a thing one has about an allergy. That the two classes bind the same predicate to two different value sets is why clinical v1.16 dropped that property's rdfs:domain clinical:Condition rather than widening it: it is a SHACL job, not an rdfs:domain one.
  • The predicates stay in the clinical: namespace deliberately. They are the domain-free carriers both import paths already write onto these records; a health: spelling would give one fact two predicates, which is the defect health v2.5 spent a release removing.
  • Through v2.7 an importer wrote these predicates onto these records and no shape declared them, so the value sets were unenforced and validation passed in silence. All three constraints are sh:Warning, per the core v3.5 ratchet: nothing that validated under v2.7 stops validating.

Version 2.7 (2026-08-14)

  • health:interpretation's value set is widened from the single data-absent-reason code unknown to all 15 codes of that code system: 60 values become 74. v2.6 accepted one code from the system, which made every reason for an absent interpretation identical. Putting a data-absent-reason coding INTO the CodeableConcept that is missing is FHIR's own idiom for an element absent for a stated reason, so this is deference rather than invention.
  • Added health:interpretationSourceCode: the source's verbatim interpretation code, written only when that code is a member of neither bound value set. A laboratory's local abnormality flag is the ordinary case. The alternative considered and rejected was accepting the loss with a warning: a closed value set plus a lossy importer means such a flag is either dropped on the floor or written into a field that then fails validation, and either way the Pod can no longer answer what the source actually said.
  • The property is deliberately unconstrained (no value set, no pattern, no case folding), because constraining a verbatim carbon copy recreates the loss it exists to prevent. A producer should also write its nearest ratified equivalent on health:interpretation, so a consumer reading only the bound property still gets a usable reading.
  • NOT changed, and stated so its absence is not read as an oversight: no interpretation constraint was added to health:DailyVitalReadingShape. health:interpretation's domain is health:LabResultRecord, and health:DailyVitalReading carries no interpretation predicate at all, so a shape there would constrain a triple no conforming record can write. The vital-sign binding added in the same release lives on clinical:VitalSignShape.
  • health.shapes.ttl v1.4. Strictly widening: every graph valid under v1.3 is valid under v1.4.

Version 2.6 (2026-08-08)

  • Shapes only. No class or property added, removed, renamed or deprecated, and nothing that validated under v2.5 stops validating. Real-world Epic FHIR exports were failing validation on records that are correct at source, because four constraints on health:LabResultRecordShape and health:ConditionRecordShape were narrower than the FHIR resource definitions the data is converted from.
  • health:interpretation is now bound to the HL7 v3 ObservationInterpretation code system (version 3.0.0), which is what FHIR R4 binds Observation.interpretation to: the 49 selectable codes, verbatim. The previous list was five words invented here (normal, high, low, abnormal, critical), so a laboratory reporting a susceptibility (S/I/R), detection (POS/NEG/DET/ND/IND), reactivity (RR/WR/NR) or change (B/D/U/W) result was rejected for being conformant. The eight abstract concepts are excluded because they are hierarchy nodes rather than values; the ten deprecated codes are included, because historical results carry them. The data-absent-reason code unknown is also accepted, for the common case of a source Observation carrying no interpretation. The ten v2.5 words are retained for backward compatibility and are not recommended for new writes.
  • health:labCategory is multi-valued, matching Observation.category (0..*). Real exports categorise one result several ways at once.
  • health:testCode, health:icd10Code and health:snomedCode are multi-valued, matching CodeableConcept.coding (0..*). Dual-coded problem-list entries and multi-coding lab observations are ordinary EHR output, and sh:maxCount 1 was rejecting records for preserving what the source sent.
  • Date properties carried over from a source document — health:performedDate, health:reportedDate, health:onsetDate, health:administrationDate — accept xsd:date alongside xsd:dateTime. FHIR's dateTime primitive is explicitly partial-precision (YYYY, YYYY-MM, YYYY-MM-DD or a full instant) and C-CDA effectiveTime commonly states a calendar day, so requiring an instant forced importers to invent a midnight the source never stated. Timestamps Cascade itself generates are unchanged. The JSON-LD terms no longer coerce to xsd:dateTime, so a producer states the precision it has.
  • No sh:pattern was added to any code property. ICD-10-CM permits a letter in any character position and SNOMED CT identifiers are 6-18 digit integers, so a lexical pattern would reject valid codes without catching anything a code system lookup would not.

Version 2.5 (2026-08-03)

  • Defined five clinical record classes that Cascade serializers have emitted since schema version 1.3 but that this ontology never declared: health:LabResultRecord, health:ConditionRecord, health:AllergyRecord, health:ImmunizationRecord, health:FamilyHistoryRecord. Added the 40 properties they use and 4 sleep-quality named individuals.
  • Defined six wellness container classes — health:ActivityData, health:SleepData, health:HeartRateData, health:BloodPressureData, health:HRVData, health:BodyMeasurements — as rdfs:subClassOf health:HealthProfile, which makes the rdfs:domain health:HealthProfile already asserted on the eight history properties true rather than contradicted.
  • Added a namespace-boundary note recording that the health: / clinical: split is historical rather than semantic, that provenance is carried by cascade:dataProvenance alone, and that health:SocialHistoryRecord and clinical:SocialHistoryRecord are both deliberately retained.
  • health.shapes.ttl v1.2 adds eight shapes: the five record classes and the three daily-snapshot classes (DailyVitalReading, DailyActivitySnapshot, DailySleepSnapshot). Required-property constraints are sh:Violation, lifted from the corresponding clinical: shapes and checked against the FHIR R4 resource definitions.
  • No serializer changes. Every term added was already being emitted.

Version 2.4 (2026-03-27)

  • EHR Import Reconciliation (P1-C). Added health:SocialHistoryRecord class for consumer-reported social history observations (smoking, alcohol, exercise, occupation).
  • Added 4 properties: health:smokingStatus, health:alcoholUse, health:exerciseFrequency, health:occupationalExposure.

Version 2.3 (2026-02-28)

  • BUG-006 Pattern A standardization: added 6 flat health: properties for VitalSignReading blank nodes emitted by HealthProfileSerializer: health:value, health:date, health:sdnn, health:systolic, health:diastolic, health:walkingSteadinessLevel. These replace the fhir:Observation nesting pattern (Pattern B) for wellness vital sign serialization.
  • Added health:OK, health:Low, health:VeryLow, health:Unknown named individuals for walkingSteadinessLevel values.
  • Added health:WalkingSteadinessUnknown to legacy steadiness individual set.

Version 1.9 (2026-02-17)

  • Added health:bloodType property for ABO blood group and Rh factor with SNOMED CT (365637002) and LOINC (882-1) mappings. Previously dark vocabulary emitted in QR payload. Part of Schema Refactoring Plan Phase 2.5 (PF4).

Version 1.8 (2026-02-10)

  • Added 6 body measurement properties with SNOMED CT and LOINC mappings: bodyMass, bodyHeight, bodyMassIndex, bodyTemperature, oxygenSaturation, bloodGlucose
  • Added BPStatistics class with 10 properties for blood pressure statistical summaries
  • Added shared temporal properties: periodStart, periodEnd
  • Completed HRVStatistics property definitions (10 properties)

Version 1.7 (2026-02-03)

  • Added VO2MaxStatistics class with 9 properties for VO2 Max trend analysis
  • Added HRVStatistics class for heart rate variability statistical summaries

Version 1.6 (2026-02-02)

  • Added trendPolarity annotation property for trend interpretation semantics (higher_is_better, lower_is_better, neutral)

Version 1.5 (2026-02-01)

  • Added MetricTrend class for wellness metric trend analysis with 9 properties

Version 1.4 (2026-01-29)

  • Initial release of the Health Vocabulary with SNOMED CT and LOINC mappings for all wellness metrics
  • 2 composite classes: ActivitySnapshot, SleepSnapshot
  • 14 wellness observation properties organized by category:
    • Cardiac: restingHeartRate, walkingHeartRate, heartRateVariability
    • Cardiovascular: bloodPressure, systolicBP, diastolicBP
    • Respiratory & Fitness: respiratoryRate, vo2Max
    • Walking Steadiness: walkingSteadiness
    • Activity: averageDailySteps, activeEnergyBurnedKcal, exerciseMinutesWeekly, standHoursDaily
    • Sleep: averageDurationHours, sleepQuality
  • 4 annotation properties: snomedCode, loincCode, unit, ucumCode
  • Three-layer ontology architecture documented (Layer 1: SNOMED/LOINC, Layer 2: health:, Layer 3: checkup:)
  • Walking Steadiness mapped to sct:364832000 (Balance finding) with documentation of alternative considerations
  • Stand Hours documented as Cascade-proprietary (no SNOMED CT or LOINC equivalent exists)