Skip to content

W3DS Health: observation-model health ontologies (34 schemas) - #1099

Open
EgorPPS wants to merge 50 commits into
mainfrom
w3ds-health-ontologies
Open

W3DS Health: observation-model health ontologies (34 schemas)#1099
EgorPPS wants to merge 50 commits into
mainfrom
w3ds-health-ontologies

Conversation

@EgorPPS

@EgorPPS EgorPPS commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Registers the ontology family of W3DS Health — a post-platform that puts a person's health data (wearable exports: raw metric series, workouts with GPS routes, sleep, meals) on their own eVault.

Families

Family Schemas Cardinality
BiometricFact bloodTypeFact, biologicalSexFact, skinTypeFact, wheelchairUseFact 1 / person × source
Observation bodyMass, height, bloodPressure, bodyTemperature, bloodGlucose, vO2Max, restingHeartRate, bodyFatPercentage, leanBodyMass (×Observation) 1 / measurement
Series heartRate, heartRateVariability, step, walkingRunningDistance, cyclingDistance, activeEnergy, basalEnergy, exerciseMinutes, standMinutes, flightsClimbed, oxygenSaturation, respiratoryRate, wristTemperature, environmentalAudio, headphoneAudio (×Series) 1 / person × day × device
Event workout, sleepSession, meal, dailyActivitySummary 1 / event
Infrastructure device, deviceLink 1 / device

Design principles

  • Triple-like granularity — one ontology per parameter: a reader looking for heart rate queries HeartRateSeries only; a smart scale writes BodyMassObservation only.
  • No duplication of identity — name/birthDate stay in the shared user.json; a health profile is a documented view, not an ontology.
  • Multi-source by design — series envelopes are keyed per (person × day × device); a watch and a phone coexist without conflict.
  • Raw samples preserved (epoch-second precision); every derived block (stats) is explicitly documented as derived.
  • Private by default — ACL [@owner]; private bytes (meal photos, GPS polylines) live inside envelopes, never in public blob storage.
  • Devices are first-class — each device gets its own w3id + eVault with a device passport; person's envelopes reference it by w3id, so a device can be sold/re-owned without touching the person's data. For this we currently use the demo provisioner verificationId — a production verificationId for w3ds-health would be appreciated.

Live self-description (kept in lock-step with code): PlatformProfile envelope c46d5d86-c720-5278-9952-d006db9d0585 on platform vault @1a73617b-7b1d-56a8-88a9-963bcf9dfcc2.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added standardized JSON Schema contracts for many additional health and wellness ontology types, including new observation, fact, and time-series envelopes (e.g., energy/glucose measurements, blood pressure, VO2 max, sleep sessions).
    • Introduced a new optional provenance.platform field across multiple schemas to capture machine-readable authorship, and added registeredBy support on device-related schemas.
  • Enhancements

    • Strengthened validation consistency for units/sample types, timestamps, and derived stats requirements across the updated contracts.

BiometricFacts (4): BloodTypeFact, BiologicalSexFact, SkinTypeFact,
WheelchairUseFact — one self-sufficient biometric attribute per envelope;
identity fields (name, birthDate) deliberately stay in the shared User
ontology, nothing is duplicated.

Observations (9): BodyMass, Height, BloodPressure (systolic+diastolic as one
measurement event), BodyTemperature, BloodGlucose, VO2Max, RestingHeartRate,
BodyFatPercentage, LeanBodyMass — one envelope per measurement, so e.g. a
smart scale writes BodyMassObservation and nothing else.

Series (15): HeartRate, HeartRateVariability, Step, WalkingRunningDistance,
CyclingDistance, ActiveEnergy, BasalEnergy, ExerciseMinutes, StandMinutes,
FlightsClimbed, OxygenSaturation, RespiratoryRate, WristTemperature,
EnvironmentalAudio, HeadphoneAudio — RAW samples chunked one envelope per
(person x local day x device); multiple devices coexist as separate
envelopes; the stats block is documented as derived preview.

Events (4): Workout (GPS route as polyline5 INSIDE the private envelope),
SleepSession (neutral stages inBed/awake/light/deep/rem/asleep),
Meal (photo embedded; nutritionEstimate structurally labeled as an AI
estimate), DailyActivitySummary (source-computed totals + goals).

Infrastructure (2): Device — a device passport living on the DEVICE's OWN
eVault (each measuring device gets its own w3id via the provisioner);
DeviceLink — pure reference on the person's vault (signatureHash -> device
w3id). Health data always lives on the person's vault and references
devices by w3id, so device ownership can change hands without touching the
person's data.

All envelopes carry subject, provenance (vendor identity lives only here —
metric keys are vendor-neutral), dedupKey and contentHash for idempotent
re-imports. ACLs are [@owner] — health data is private by default.

Authored by W3DS Health (platform vault @1a73617b-7b1d-56a8-88a9-963bcf9dfcc2).
@EgorPPS
EgorPPS requested a review from coodos as a code owner July 28, 2026 21:43
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Draft-07 JSON Schemas for health measurements, metric series, facts, daily summaries, meals, sleep sessions, workouts, photos, and device identity records. Schemas define required fields, provenance, canonical units, timestamps, validation patterns, nested structures, and derived statistics.

Changes

Ontology schema contracts

Layer / File(s) Summary
Series measurement schemas
services/ontology/schemas/*Series.json
Adds daily metric series contracts with fixed units and sample types, date and UTC-offset patterns, numeric sample tuples, provenance platform fields, and derived statistics.
Observation and fact schemas
services/ontology/schemas/*Observation.json, services/ontology/schemas/*Fact.json
Adds single-measurement and categorical fact contracts with provenance, deduplication metadata, values, units, and timestamps.
Compound health records
services/ontology/schemas/dailyActivitySummary.json, services/ontology/schemas/healthPhoto.json, services/ontology/schemas/meal.json, services/ontology/schemas/sleepSession.json, services/ontology/schemas/workout.json
Adds schemas for daily summaries, health photos, meals with photo references and nutrition estimates, sleep stages and totals, and workouts with metrics and optional routes.
Device identity schemas
services/ontology/schemas/device.json, services/ontology/schemas/deviceLink.json
Adds device and device-link contracts with provisioning authorship, identity, hash, and reference fields.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Suggested reviewers: coodos

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers scope and design, but it misses required template sections like Issue Number, Type of change, testing, and checklist. Add the missing template sections and fill in the issue number, change type, testing details, and checklist items.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the new W3DS Health ontology schema family.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch w3ds-health-ontologies

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/ontology/schemas/activeEnergySeries.json`:
- Around line 12-18: Require the device property in the schemas’ required lists
so unknown devices must be represented explicitly as null. Apply this change to
activeEnergySeries.json, basalEnergySeries.json, cyclingDistanceSeries.json,
environmentalAudioSeries.json, exerciseMinutesSeries.json,
flightsClimbedSeries.json, headphoneAudioSeries.json, heartRateSeries.json,
heartRateVariabilitySeries.json, oxygenSaturationSeries.json, and
respiratoryRateSeries.json at lines 12-18; preserve the existing string-or-null
device type and description in each file.
- Around line 68-77: Update the samples item schemas in
services/ontology/schemas/activeEnergySeries.json (68-77),
services/ontology/schemas/basalEnergySeries.json (68-77),
services/ontology/schemas/cyclingDistanceSeries.json (68-77),
services/ontology/schemas/environmentalAudioSeries.json (68-77),
services/ontology/schemas/exerciseMinutesSeries.json (68-77),
services/ontology/schemas/flightsClimbedSeries.json (68-77),
services/ontology/schemas/headphoneAudioSeries.json (68-77),
services/ontology/schemas/heartRateSeries.json (68-77),
services/ontology/schemas/heartRateVariabilitySeries.json (68-77),
services/ontology/schemas/oxygenSaturationSeries.json (68-77), and
services/ontology/schemas/respiratoryRateSeries.json (68-77) to use Draft-07
tuple validation with an explicit items array and additionalItems false: require
three entries for interval series and two entries for point series, preserving
the documented numeric order and types.

In `@services/ontology/schemas/biologicalSexFact.json`:
- Around line 51-55: Update the value definition in the biological-sex fact
schema to remove the boolean type and accept only strings from the ontology’s
controlled biological-sex vocabulary. Preserve the existing schema structure
while enforcing the agreed enum values.

In `@services/ontology/schemas/bloodGlucoseObservation.json`:
- Around line 51-52: Update the numeric property definitions across the
specified schemas: in services/ontology/schemas/bloodGlucoseObservation.json
lines 51-52 and services/ontology/schemas/bloodPressureObservation.json lines
51-55, enforce non-negative values; in
services/ontology/schemas/dailyActivitySummary.json lines 55-71, enforce
non-negative totals and goals; in services/ontology/schemas/meal.json lines
79-83 and 109-125, require positive image dimensions and non-negative nutrition
values, and in lines 133-134 constrain confidence to [0,1]; in
services/ontology/schemas/sleepSession.json lines 94-110, enforce non-negative
duration totals; and in services/ontology/schemas/workout.json lines 61-77 and
114-115, enforce non-negative metrics and point counts.

In `@services/ontology/schemas/bloodTypeFact.json`:
- Around line 51-56: The categorical fact schemas use an overly broad shared
value union. In services/ontology/schemas/bloodTypeFact.json lines 51-56,
replace it with a string enum of supported blood types; in
services/ontology/schemas/skinTypeFact.json lines 51-56, use a string enum of
Fitzpatrick categories; and in services/ontology/schemas/wheelchairUseFact.json
lines 51-56, restrict value to boolean only.

In `@services/ontology/schemas/bodyFatPercentageObservation.json`:
- Around line 58-60: Enforce the ISO 8601 timestamp contract by adding the
date-time format constraint to the measuredAt property in
services/ontology/schemas/bodyFatPercentageObservation.json:58-60,
services/ontology/schemas/bodyMassObservation.json:58-60,
services/ontology/schemas/bodyTemperatureObservation.json:58-60,
services/ontology/schemas/heightObservation.json:58-60,
services/ontology/schemas/leanBodyMassObservation.json:58-60,
services/ontology/schemas/restingHeartRateObservation.json:58-60, and
services/ontology/schemas/vO2MaxObservation.json:58-60. Preserve the existing
string type and description in each schema.
- Around line 51-53: Update the value definitions in
services/ontology/schemas/bodyFatPercentageObservation.json (lines 51-53),
services/ontology/schemas/bodyMassObservation.json (lines 51-53),
services/ontology/schemas/heightObservation.json (lines 51-53),
services/ontology/schemas/leanBodyMassObservation.json (lines 51-53),
services/ontology/schemas/restingHeartRateObservation.json (lines 51-53), and
services/ontology/schemas/vO2MaxObservation.json (lines 51-53) with JSON Schema
numeric bounds: body fat must be 0–100 inclusive, body mass, lean body mass,
resting heart rate, and VO2 max must be nonnegative, and height must be strictly
positive.

In `@services/ontology/schemas/device.json`:
- Around line 51-56: The schemas currently define ambiguous deduplication and
hash fields without a shared contract. In services/ontology/schemas/device.json
lines 51-56, define the passport’s canonical deduplication key and constrain
hash values to the agreed SHA-256 representation; in
services/ontology/schemas/deviceLink.json lines 14-16, use that same canonical
key for the link’s signatureHash and validate its SHA-256 format; in
services/ontology/schemas/deviceLink.json lines 21-26, reconcile the duplicate
dedupKey definition and apply the same contentHash validation.
- Around line 48-59: Enforce the repository’s canonical date-time format on all
lifecycle timestamp properties: update registeredAt and updatedAt in
services/ontology/schemas/device.json (48-59), and linkedAt and updatedAt in
services/ontology/schemas/deviceLink.json (18-20, 27-29), by retaining their
string types while adding the date-time format constraint.
- Around line 8-10: Update the w3id and ownerEName schema properties to enforce
the ontology contracts’ canonical non-empty `@-prefixed` identifier grammar,
rather than accepting arbitrary strings. Reuse the existing canonical identifier
constraints or pattern used by the ontology schemas, ensuring invalid values
such as empty strings, "@" and "@ " fail validation while valid identifiers
remain accepted.

In `@services/ontology/schemas/deviceLink.json`:
- Around line 11-13: Update the device link schema property deviceEName to use
the contract’s w3id identifier, either by renaming it to w3id or explicitly
defining the schema alias/mapping to device.json’s w3id field. Ensure link
consumers can reliably dereference the device passport.

In `@services/ontology/schemas/standMinutesSeries.json`:
- Around line 68-77: Replace the generic sample-array schemas with Draft-07
positional tuple validation in services/ontology/schemas/standMinutesSeries.json
(68-77), stepSeries.json (68-77), walkingRunningDistanceSeries.json (68-77), and
wristTemperatureSeries.json (68-77). The first three files must enforce exactly
[startEpochSeconds, endEpochSeconds, value], with positional numeric schemas,
non-negative integer epoch/interval bounds where applicable, additionalItems
false, and minItems/maxItems 3; wristTemperatureSeries.json must enforce exactly
[epochSeconds, value] with the corresponding integer/non-negative epoch
constraint, additionalItems false, and minItems/maxItems 2.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8880be39-3e93-4ec9-976f-82b031778413

📥 Commits

Reviewing files that changed from the base of the PR and between 8a4fc83 and 14fae82.

📒 Files selected for processing (34)
  • services/ontology/schemas/activeEnergySeries.json
  • services/ontology/schemas/basalEnergySeries.json
  • services/ontology/schemas/biologicalSexFact.json
  • services/ontology/schemas/bloodGlucoseObservation.json
  • services/ontology/schemas/bloodPressureObservation.json
  • services/ontology/schemas/bloodTypeFact.json
  • services/ontology/schemas/bodyFatPercentageObservation.json
  • services/ontology/schemas/bodyMassObservation.json
  • services/ontology/schemas/bodyTemperatureObservation.json
  • services/ontology/schemas/cyclingDistanceSeries.json
  • services/ontology/schemas/dailyActivitySummary.json
  • services/ontology/schemas/device.json
  • services/ontology/schemas/deviceLink.json
  • services/ontology/schemas/environmentalAudioSeries.json
  • services/ontology/schemas/exerciseMinutesSeries.json
  • services/ontology/schemas/flightsClimbedSeries.json
  • services/ontology/schemas/headphoneAudioSeries.json
  • services/ontology/schemas/heartRateSeries.json
  • services/ontology/schemas/heartRateVariabilitySeries.json
  • services/ontology/schemas/heightObservation.json
  • services/ontology/schemas/leanBodyMassObservation.json
  • services/ontology/schemas/meal.json
  • services/ontology/schemas/oxygenSaturationSeries.json
  • services/ontology/schemas/respiratoryRateSeries.json
  • services/ontology/schemas/restingHeartRateObservation.json
  • services/ontology/schemas/skinTypeFact.json
  • services/ontology/schemas/sleepSession.json
  • services/ontology/schemas/standMinutesSeries.json
  • services/ontology/schemas/stepSeries.json
  • services/ontology/schemas/vO2MaxObservation.json
  • services/ontology/schemas/walkingRunningDistanceSeries.json
  • services/ontology/schemas/wheelchairUseFact.json
  • services/ontology/schemas/workout.json
  • services/ontology/schemas/wristTemperatureSeries.json

Comment on lines +12 to +18
"device": {
"type": [
"string",
"null"
],
"description": "w3id (@eName) of the measuring device's OWN eVault, where its Device passport lives; null if unknown"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require device to preserve the unknown-device contract.

The descriptions specify null when unknown, but omission is also valid. This makes device identity ambiguous and breaks the documented person × day × device partition.

  • services/ontology/schemas/activeEnergySeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/basalEnergySeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/cyclingDistanceSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/environmentalAudioSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/exerciseMinutesSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/flightsClimbedSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/headphoneAudioSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/heartRateSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/heartRateVariabilitySeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/oxygenSaturationSeries.json#L12-L18: add "device" to required.
  • services/ontology/schemas/respiratoryRateSeries.json#L12-L18: add "device" to required.
📍 Affects 11 files
  • services/ontology/schemas/activeEnergySeries.json#L12-L18 (this comment)
  • services/ontology/schemas/basalEnergySeries.json#L12-L18
  • services/ontology/schemas/cyclingDistanceSeries.json#L12-L18
  • services/ontology/schemas/environmentalAudioSeries.json#L12-L18
  • services/ontology/schemas/exerciseMinutesSeries.json#L12-L18
  • services/ontology/schemas/flightsClimbedSeries.json#L12-L18
  • services/ontology/schemas/headphoneAudioSeries.json#L12-L18
  • services/ontology/schemas/heartRateSeries.json#L12-L18
  • services/ontology/schemas/heartRateVariabilitySeries.json#L12-L18
  • services/ontology/schemas/oxygenSaturationSeries.json#L12-L18
  • services/ontology/schemas/respiratoryRateSeries.json#L12-L18
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/activeEnergySeries.json` around lines 12 - 18,
Require the device property in the schemas’ required lists so unknown devices
must be represented explicitly as null. Apply this change to
activeEnergySeries.json, basalEnergySeries.json, cyclingDistanceSeries.json,
environmentalAudioSeries.json, exerciseMinutesSeries.json,
flightsClimbedSeries.json, headphoneAudioSeries.json, heartRateSeries.json,
heartRateVariabilitySeries.json, oxygenSaturationSeries.json, and
respiratoryRateSeries.json at lines 12-18; preserve the existing string-or-null
device type and description in each file.

Comment on lines +68 to +77
"samples": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 3
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== schema snippets =="
for f in services/ontology/schemas/activeEnergySeries.json services/ontology/schemas/basalEnergySeries.json services/ontology/schemas/cyclingDistanceSeries.json services/ontology/schemas/environmentalAudioSeries.json services/ontology/schemas/exerciseMinutesSeries.json services/ontology/schemas/flightsClimbedSeries.json services/ontology/schemas/headphoneAudioSeries.json services/ontology/schemas/heartRateSeries.json services/ontology/schemas/heartRateVariabilitySeries.json services/ontology/schemas/oxygenSaturationSeries.json services/ontology/schemas/respiratoryRateSeries.json; do
  echo "--- $f"
  sed -n '55,85p' "$f"
done

echo
echo "== schema header/descriptors around samples =="
for f in services/ontology/schemas/activeEnergySeries.json services/ontology/schemas/basalEnergySeries.json services/ontology/schemas/cyclingDistanceSeries.json services/ontology/schemas/environmentalAudioSeries.json services/ontology/schemas/exerciseMinutesSeries.json services/ontology/schemas/flightsClimbedSeries.json services/ontology/schemas/headphoneAudioSeries.json services/ontology/schemas/heartRateSeries.json services/ontology/schemas/heartRateVariabilitySeries.json services/ontology/schemas/oxygenSaturationSeries.json services/ontology/schemas/respiratoryRateSeries.json; do
  echo "--- $f"
  sed -n '1,90p' "$f" | grep -n -A2 -B2 -i 'samples\|interval\|point\|series\|timestamp\|epoch\|value' || true
done

echo
echo "== references to samples or series schemas =="
rg -n 'samples|activeEnergySeries|basalEnergySeries|cyclingDistanceSeries|environmentalAudioSeries|exerciseMinutesSeries|flightsClimbedSeries|headphoneAudioSeries|heartRateSeries|heartRateVariabilitySeries|oxygenSaturationSeries|respiratoryRateSeries' services/ontology -g '!*.lock' | head -200

Repository: MetaState-Prototype-Project/prototype

Length of output: 30154


🌐 Web query:

JSON Schema draft-07 tuple validation extra items additionalItems false

💡 Result:

In JSON Schema draft-07, the "additionalItems" keyword is used to control whether an array can contain items beyond those defined in a tuple [1][2]. Tuple validation occurs when the "items" keyword is provided as an array of schemas, where each schema corresponds to an element at a specific index [2][3]. When using "items" as an array (a tuple): - The "items" keyword defines the schemas for the initial elements of the array [2][3]. - The "additionalItems" keyword defines the schema that any subsequent elements (those at indices greater than the number of schemas in the "items" array) must validate against [1][2]. - Setting "additionalItems" to false explicitly forbids any elements beyond the number of schemas defined in the "items" array [2]. For example, a schema defined as: { "$schema": "http://json-schema.org/draft-07/schema#", "items": [ { "type": "boolean" }, { "type": "number" } ], "additionalItems": false } will validate arrays like [true, 10] but will fail for arrays like [true, 10, "extra"] [2]. Note that "additionalItems" only has an effect when "items" is an array [2]. If "items" is a single schema (object form) or is omitted, "additionalItems" is ignored by the validator [2]. As of later versions of JSON Schema (starting with the 2020-12 specification), tuple validation is handled by the "prefixItems" keyword, and "additionalItems" has been replaced or restructured to clarify its behavior [4][5].

Citations:


Enforce the documented sample tuple arity.

The samples arrays are described as fixed-length tuples, but the schemas currently allow 2 or 3 numbers per sample. Use Draft-07 tuple validation with additionalItems: false: three entries for interval series ([startEpochSeconds, endEpochSeconds, value]) and two entries for point series ([epochSeconds, value]).

📍 Affects 11 files
  • services/ontology/schemas/activeEnergySeries.json#L68-L77 (this comment)
  • services/ontology/schemas/basalEnergySeries.json#L68-L77
  • services/ontology/schemas/cyclingDistanceSeries.json#L68-L77
  • services/ontology/schemas/environmentalAudioSeries.json#L68-L77
  • services/ontology/schemas/exerciseMinutesSeries.json#L68-L77
  • services/ontology/schemas/flightsClimbedSeries.json#L68-L77
  • services/ontology/schemas/headphoneAudioSeries.json#L68-L77
  • services/ontology/schemas/heartRateSeries.json#L68-L77
  • services/ontology/schemas/heartRateVariabilitySeries.json#L68-L77
  • services/ontology/schemas/oxygenSaturationSeries.json#L68-L77
  • services/ontology/schemas/respiratoryRateSeries.json#L68-L77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/activeEnergySeries.json` around lines 68 - 77,
Update the samples item schemas in
services/ontology/schemas/activeEnergySeries.json (68-77),
services/ontology/schemas/basalEnergySeries.json (68-77),
services/ontology/schemas/cyclingDistanceSeries.json (68-77),
services/ontology/schemas/environmentalAudioSeries.json (68-77),
services/ontology/schemas/exerciseMinutesSeries.json (68-77),
services/ontology/schemas/flightsClimbedSeries.json (68-77),
services/ontology/schemas/headphoneAudioSeries.json (68-77),
services/ontology/schemas/heartRateSeries.json (68-77),
services/ontology/schemas/heartRateVariabilitySeries.json (68-77),
services/ontology/schemas/oxygenSaturationSeries.json (68-77), and
services/ontology/schemas/respiratoryRateSeries.json (68-77) to use Draft-07
tuple validation with an explicit items array and additionalItems false: require
three entries for interval series and two entries for point series, preserving
the documented numeric order and types.

Comment on lines +51 to +55
"value": {
"type": [
"string",
"boolean"
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject boolean biological-sex values.

true/false have no interoperable biological-sex meaning. Restrict this to a controlled string vocabulary agreed by the ontology.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/biologicalSexFact.json` around lines 51 - 55,
Update the value definition in the biological-sex fact schema to remove the
boolean type and accept only strings from the ontology’s controlled
biological-sex vocabulary. Preserve the existing schema structure while
enforcing the agreed enum values.

Comment on lines +51 to +52
"value": {
"type": "number"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject impossible negative health quantities. These schemas accept negative glucose, blood pressure, durations, distances, calories, sleep totals, dimensions, and route point counts, allowing invalid records into the eVault.

  • services/ontology/schemas/bloodGlucoseObservation.json#L51-L52: require non-negative glucose values.
  • services/ontology/schemas/bloodPressureObservation.json#L51-L55: require non-negative pressure values.
  • services/ontology/schemas/dailyActivitySummary.json#L55-L71: require non-negative totals and goals.
  • services/ontology/schemas/meal.json#L79-L83,109-L125,133-L134: require positive image dimensions, non-negative nutrition values, and confidence in [0, 1].
  • services/ontology/schemas/sleepSession.json#L94-L110: require non-negative duration totals.
  • services/ontology/schemas/workout.json#L61-L77,114-L115: require non-negative workout metrics and point counts.
📍 Affects 6 files
  • services/ontology/schemas/bloodGlucoseObservation.json#L51-L52 (this comment)
  • services/ontology/schemas/bloodPressureObservation.json#L51-L55
  • services/ontology/schemas/dailyActivitySummary.json#L55-L71
  • services/ontology/schemas/meal.json#L79-L83
  • services/ontology/schemas/sleepSession.json#L94-L110
  • services/ontology/schemas/workout.json#L61-L77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/bloodGlucoseObservation.json` around lines 51 - 52,
Update the numeric property definitions across the specified schemas: in
services/ontology/schemas/bloodGlucoseObservation.json lines 51-52 and
services/ontology/schemas/bloodPressureObservation.json lines 51-55, enforce
non-negative values; in services/ontology/schemas/dailyActivitySummary.json
lines 55-71, enforce non-negative totals and goals; in
services/ontology/schemas/meal.json lines 79-83 and 109-125, require positive
image dimensions and non-negative nutrition values, and in lines 133-134
constrain confidence to [0,1]; in services/ontology/schemas/sleepSession.json
lines 94-110, enforce non-negative duration totals; and in
services/ontology/schemas/workout.json lines 61-77 and 114-115, enforce
non-negative metrics and point counts.

Comment on lines +51 to +56
"value": {
"type": [
"string",
"boolean"
]
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use domain-specific types for categorical facts. The shared union accepts values outside each fact’s declared domain.

  • services/ontology/schemas/bloodTypeFact.json#L51-L56: use a string enum for supported blood types.
  • services/ontology/schemas/skinTypeFact.json#L51-L56: use a string enum for Fitzpatrick categories.
  • services/ontology/schemas/wheelchairUseFact.json#L51-L56: use "type": "boolean" only.
📍 Affects 3 files
  • services/ontology/schemas/bloodTypeFact.json#L51-L56 (this comment)
  • services/ontology/schemas/skinTypeFact.json#L51-L56
  • services/ontology/schemas/wheelchairUseFact.json#L51-L56
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/bloodTypeFact.json` around lines 51 - 56, The
categorical fact schemas use an overly broad shared value union. In
services/ontology/schemas/bloodTypeFact.json lines 51-56, replace it with a
string enum of supported blood types; in
services/ontology/schemas/skinTypeFact.json lines 51-56, use a string enum of
Fitzpatrick categories; and in services/ontology/schemas/wheelchairUseFact.json
lines 51-56, restrict value to boolean only.

Comment on lines +8 to +10
"w3id": {
"type": "string",
"description": "the device's own @-prefixed w3id (self-reference)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg 'services/ontology/schemas/(device|deviceLink)\.json$|ontology' || true

echo "== device.json relevant =="
if [ -f services/ontology/schemas/device.json ]; then
  nl -ba services/ontology/schemas/device.json | sed -n '1,90p'
fi

echo "== deviceLink.json relevant =="
if [ -f services/ontology/schemas/deviceLink.json ]; then
  nl -ba services/ontology/schemas/deviceLink.json | sed -n '1,120p'
fi

echo "== related schema identifiers constraints =="
rg -n '"required"|propertyNames|pattern|description|"`@-prefixed`|prefixed|identifier|w3id|ownerEName"' services/ontology/schemas -g '*.json' || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 3470


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== device.json relevant =="
if [ -f services/ontology/schemas/device.json ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' services/ontology/schemas/device.json | sed -n '1,90p'
fi

echo "== deviceLink.json relevant =="
if [ -f services/ontology/schemas/deviceLink.json ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' services/ontology/schemas/deviceLink.json | sed -n '1,120p'
fi

echo "== related identifier/timestamp/hash constraints =="
rg -n 'propertyNames|pattern|minimumLength|maxLength|required|w3id|ownerEName|registeredAt|updatedAt|dedupKey|contentHash|`@-prefixed`|prefixed|identifier' services/ontology/schemas -g '*.json' || true

echo "== JSON parse and schema shape probe =="
python3 - <<'PY'
import json
for path in ["services/ontology/schemas/device.json", "services/ontology/schemas/deviceLink.json"]:
    print(f"\n@@ {path}")
    try:
        data=json.load(open(path))
    except Exception as e:
        print("JSON_ERROR", e)
        continue
    def prop(obj, k, d=""):
        return obj.get("properties", {}).get(k, d)
    for k in ["w3id","ownerEName","registeredAt","updatedAt","dedupKey","contentHash"]:
        p=prop(data,k)
        print(k, type(p).__name__, "required=", k in data.get("required",[]), p)
    def deep_find(prefix, obj, path=[]):
        if isinstance(obj, dict):
            if any(p.startswith(prefix) for p in ["pattern","minLength","maxLength","propertyNames"]):
                print("CONSTRAINT", "/".join(path), obj)
            for kk, vv in obj.items():
                deep_find(prefix, vv, path+[kk])
        elif isinstance(obj, list):
            for ii, vv in enumerate(obj):
                deep_find(prefix, vv, path+[str(ii)])
    deep_find("", data)
    print("has_propertyNames_propertyNames_constraint=", "propertyNames" in data.get("properties",{}))
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 50393


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== eName/w3id constraints with tight grep =="
rg -n '"properties"|\"eName\"|\"w3id\"|@|pattern|minLength|propertyNames' services/ontology/schemas/eName*.json services/ontology/schemas/w3id*.json services/ontology/schemas/*.json 2>/dev/null | rg 'eName|w3id|@[^\\s\\$]|pattern|minLength|propertyNames' || true

echo "== schema files that define eName directly =="
for f in services/ontology/schemas/*.json; do
  python3 - <<'PY' "$f"
import sys, json
p=sys.argv[1]
try:
    data=json.load(open(p))
except Exception as e:
    print("ERR", p, e)
    sys.exit(0)
props=data.get("properties",{})
if "eName" in props and ("propertyNames" in data or "pattern" in props.get("eName",{}) or "minLength" in props.get("eName",{})):
    print("MATCH", p, props.get("eName"))
    if "propertyNames" in data:
        print("  propertyNames", data["propertyNames"])
PY
done

echo "== any canonical grammar definitions by code =="
rg -n '@[^\\s\\$]|propertyNames|prefix|eName|w3id|MIN_LENGTH|MIN_LENGTH|pattern=|/eName|/w3id' services -g '*.ts' -g '*.js' -g '*.json' | head -n 200

Repository: MetaState-Prototype-Project/prototype

Length of output: 36014


Enforce the declared Identifier grammar.

w3id and ownerEName are documented as @-prefixed identifiers, but both are unconstrained strings, so values like "", "@", or "@ " pass validation. Add the canonical non-empty identifier constraints used by the ontology contracts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/device.json` around lines 8 - 10, Update the w3id
and ownerEName schema properties to enforce the ontology contracts’ canonical
non-empty `@-prefixed` identifier grammar, rather than accepting arbitrary
strings. Reuse the existing canonical identifier constraints or pattern used by
the ontology schemas, ensuring invalid values such as empty strings, "@" and "@
" fail validation while valid identifiers remain accepted.

Comment on lines +48 to +59
"registeredAt": {
"type": "string"
},
"dedupKey": {
"type": "string"
},
"contentHash": {
"type": "string"
},
"updatedAt": {
"type": "string"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files matching device/json schemas =="
git ls-files '*device*.json' services/ontology/schemas/deviceLink.json services/ontology/schemas/device.json 2>/dev/null || true

echo
echo "== device schema relevant sections =="
if [ -f services/ontology/schemas/device.json ]; then
  nl -ba services/ontology/schemas/device.json | sed -n '1,90p'
fi

echo
echo "== deviceLink schema relevant section =="
if [ -f services/ontology/schemas/deviceLink.json ]; then
  nl -ba services/ontology/schemas/deviceLink.json | sed -n '1,80p'
fi

echo
echo "== searches for timestamp validation/formats in ontology schemas =="
rg -n '"registeredAt"|"updatedAt"|"linkedAt"|format|regex|enum|patternType|typeCheck|deviceLink|device' services/ontology -S || true

echo
echo "== AST/lint references to lifecycle timestamp fields =="
rg -n '\.registeredAt|registeredAt|\.linkedAt|linkedAt|\.updatedAt|updatedAt|\$timestamp|time' services -S || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 381


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== schema files =="
git ls-files services/ontology/schemas/device.json services/ontology/schemas/deviceLink.json

echo
echo "== device schema relevant section =="
awk '{printf "%6d\t%s\n", NR, $0}' services/ontology/schemas/device.json | sed -n '1,90p'

echo
echo "== deviceLink schema relevant section =="
awk '{printf "%6d\t%s\n", NR, $0}' services/ontology/schemas/deviceLink.json | sed -n '1,80p'

echo
echo "== timestamp validation references =="
rg -n '"registeredAt"|"updatedAt"|"linkedAt"|format|regex|enum|patternType' services/ontology/schemas services -S || true

echo
echo "== timestamp field usages across repository =="
rg -n 'registeredAt|updatedAt|linkedAt' -S || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 38818


Enforce one canonical timestamp format across device records. These lifecycle fields are declared only as string, so malformed timestamp values can still pass validation and break temporal logic downstream. Use the repository’s date-time format for consistency.

  • services/ontology/schemas/device.json#L48-L59: constrain registeredAt and updatedAt.
  • services/ontology/schemas/deviceLink.json#L18-L20: constrain linkedAt.
  • services/ontology/schemas/deviceLink.json#L27-L29: constrain updatedAt.
📍 Affects 2 files
  • services/ontology/schemas/device.json#L48-L59 (this comment)
  • services/ontology/schemas/deviceLink.json#L18-L20
  • services/ontology/schemas/deviceLink.json#L27-L29
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/device.json` around lines 48 - 59, Enforce the
repository’s canonical date-time format on all lifecycle timestamp properties:
update registeredAt and updatedAt in services/ontology/schemas/device.json
(48-59), and linkedAt and updatedAt in services/ontology/schemas/deviceLink.json
(18-20, 27-29), by retaining their string types while adding the date-time
format constraint.

Comment on lines +51 to +56
"dedupKey": {
"type": "string"
},
"contentHash": {
"type": "string"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Tracked schema files:\n'
git ls-files | grep -E '(^|/)device(.*)?.json$|schema' | sed -n '1,120p'

printf '\nRelevant files context:\n'
for f in services/ontology/schemas/device.json services/ontology/schemas/deviceLink.json; do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    cat -n "$f" | sed -n '1,120p'
  else
    echo "MISSING $f"
  fi
done

printf '\nSearch for fields and usages:\n'
rg -n '"dedupKey"|"signatureHash"|"contentHash"|signatureHash|dedupKey|contentHash' services scripts public app src 2>/dev/null | sed -n '1,240p' || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 20706


Align the deduplication and hash contract across both schemas. The link calls signatureHash the dedup key while both schemas also expose separate dedupKey and contentHash fields, without defining equality or canonical encodings.

  • services/ontology/schemas/device.json#L51-L56: define the passport’s canonical dedup key and constrain hash values.
  • services/ontology/schemas/deviceLink.json#L14-L16: use the same canonical key as the passport and validate the SHA-256 representation.
  • services/ontology/schemas/deviceLink.json#L21-L26: reconcile the duplicate dedupKey and apply consistent content-hash validation.
📍 Affects 2 files
  • services/ontology/schemas/device.json#L51-L56 (this comment)
  • services/ontology/schemas/deviceLink.json#L14-L16
  • services/ontology/schemas/deviceLink.json#L21-L26
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/device.json` around lines 51 - 56, The schemas
currently define ambiguous deduplication and hash fields without a shared
contract. In services/ontology/schemas/device.json lines 51-56, define the
passport’s canonical deduplication key and constrain hash values to the agreed
SHA-256 representation; in services/ontology/schemas/deviceLink.json lines
14-16, use that same canonical key for the link’s signatureHash and validate its
SHA-256 format; in services/ontology/schemas/deviceLink.json lines 21-26,
reconcile the duplicate dedupKey definition and apply the same contentHash
validation.

Comment on lines +11 to +13
"deviceEName": {
"type": "string"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the device identifier promised by the contract.

The schema description says this record maps to the device’s w3id, and device.json exposes that value as w3id, but this property is named deviceEName. Rename or explicitly define the alias/mapping; otherwise link consumers cannot reliably dereference the passport.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/deviceLink.json` around lines 11 - 13, Update the
device link schema property deviceEName to use the contract’s w3id identifier,
either by renaming it to w3id or explicitly defining the schema alias/mapping to
device.json’s w3id field. Ensure link consumers can reliably dereference the
device passport.

Comment on lines +68 to +77
"samples": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 3
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repo files matching series schema names:"
fd '^(standMinutesSeries|stepSeries|walkingRunningDistanceSeries|wristTemperatureSeries)\.json$' services/ontology/schemas -x sh -c 'echo "--- $1"; wc -l "$1"; cat -n "$1"' sh {}

echo
echo "Search for documented sample tuple expectations / validation usage:"
rg -n "standMinutesSeries|stepSeries|walkingRunningDistanceSeries|wristTemperatureSeries|samples|startEpochSeconds|endEpochSeconds|epochSeconds" services docs README* 2>/dev/null || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 27250


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import json

target_names = [
    "standMinutesSeries.json",
    "stepSeries.json",
    "walkingRunningDistanceSeries.json",
    "wristTemperatureSeries.json",
]

for name in target_names:
    p = Path("services/ontology/schemas", name)
    schema = json.loads(p.read_text())
    items = schema["properties"]["samples"]["items"]["items"]
    assert items == {"type": "number"}
    items = schema["properties"]["samples"]["items"]
    assert items["type"] == "array" and items["minItems"] == 2 and items["maxItems"] == 3
    print(f"{name}: tuple schema min/max={items['minItems']}-{items['maxItems']} sampleShape={schema.get('sampleType')}; accepts invalid intervals: []",
          [[[]], [[1]], [[1, 2], [3]], [[0, 0.59], [1]], [[0, 2], -1]],
          [json.loads('[]')[0] in [True, False] for json.__doc__]))
PY

echo
echo "Read-only behavioral check using jsonschema package if installed:"
python3 - <<'PY'
try:
    import jsonschema
except Exception as exc:
    print("jsonschema_unavailable", type(exc).__name__, str(exc))
else:
    import json
    from pathlib import Path
    target_names = [
        "standMinutesSeries.json",
        "stepSeries.json",
        "walkingRunningDistanceSeries.json",
        "wristTemperatureSeries.json",
    ]
    validator_cls = jsonschema.validators.validator_for({"$schema": "http://json-schema.org/draft-07/schema#"})
    for name in target_names:
        p = Path("services/ontology/schemas", name)
        schema = json.loads(p.read_text())
        v = validator_cls(schema)
        invalid_samples = [
            {"samples": [[], [], [1, 2, 3]]},
            {"samples": [[1], [2], [2, 3, 4]]},
            {"samples": [[1, 2], [3], [2, 3, 4]]},
            {"samples": [[0, 0.59], [1]]},
            {"samples": [[0, 2], -1]},
        ]
        errors = []
        for value in invalid_samples:
            errors.extend([err.message for err in v.iter_errors(value)])
        print(f"{name}: invalid_samples_validated_as_ok={all(v.is_valid(value) for value in invalid_samples)}")
        if errors:
            for e in errors:
                print(f"  invalid sample rejected with message: {e}")
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 351


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path
import jsonschema

for name in [
    "standMinutesSeries.json",
    "stepSeries.json",
    "walkingRunningDistanceSeries.json",
    "wristTemperatureSeries.json",
]:
    schema_path = Path("services/ontology/schemas", name)
    schema = json.loads(schema_path.read_text())
    samples = schema["properties"]["samples"]
    print(f"{name}: samples.items={samples['items']}")

    invalid_samples = [
        {"samples": [[], [], [1, 2, 3]]},
        {"samples": [[1], [2], [2, 3, 4]]},
        {"samples": [[1, 2], [3], [2, 3, 4]]},
        {"samples": [[0, 0.59], [1]]},
        {"samples": [[0, 2], -1]},
    ]

    validator_cls = jsonschema.validators.validator_for(schema)
    v = validator_cls(schema)
    accepted = []
    rejected_msgs = []
    for value in invalid_samples:
        if v.is_valid(value):
            accepted.append(value)
        else:
            rejected_msgs.extend([err.message for err in v.iter_errors(value)])

    print(f"accepted_malformed: {accept accepted}")
    if rejected_msgs:
        print(f"rejected_malformed_messages: {rejected_msgs}")
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 275


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

for name in [
    "standMinutesSeries.json",
    "stepSeries.json",
    "walkingRunningDistanceSeries.json",
    "wristTemperatureSeries.json",
]:
    schema_path = Path("services/ontology/schemas", name)
    schema = json.loads(schema_path.read_text())
    samples = schema["properties"]["samples"]
    print(f"{name}: samples.items={samples['items']}")
PY

echo
pip3 install jsonschema -q
python3 - <<'PY'
import json
import jsonschema
from pathlib import Path

for name in [
    "standMinutesSeries.json",
    "stepSeries.json",
    "walkingRunningDistanceSeries.json",
    "wristTemperatureSeries.json",
]:
    schema_path = Path("services/ontology/schemas", name)
    schema = json.loads(schema_path.read_text())
    invalid_samples = [
        {"samples": [[], [], [1, 2, 3]]},
        {"samples": [[1], [2], [2, 3, 4]]},
        {"samples": [[1, 2], [3], [2, 3, 4]]},
        {"samples": [[0, 0.59], [1]]},
        {"samples": [[0, 2], -1]},
    ]

    validator_cls = jsonschema.validators.validator_for(schema)
    v = validator_cls(schema)
    accepted = []
    rejected_msgs = []
    for value in invalid_samples:
        if v.is_valid(value):
            accepted.append(value)
        else:
            rejected_msgs.extend([err.message for err in v.iter_errors(value)])

    print(f"{name}: accepted_malformed={accepted}")
    print(f"{name}: rejected_malformed_messages={rejected_msgs}")
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 1491


🌐 Web query:

JSON Schema Draft-07 tuple validation items array additionalItems false behavior

💡 Result:

In JSON Schema Draft 07, the "additionalItems" keyword is used to control validation for array elements that fall outside the range defined by a tuple (an "items" keyword provided as an array of schemas) [1][2][3]. When "items" is defined as an array of schemas, it performs tuple validation, where each schema in the array corresponds to the element at the same index in the instance array [1][4]. The "additionalItems" keyword then specifies a schema that must be satisfied by all remaining elements in the instance array (those at indices greater than or equal to the length of the "items" array) [1][4]. When "additionalItems" is set to false, it explicitly forbids any elements beyond the defined tuple [3]. If the instance array contains more items than there are schemas in the "items" array, validation will fail [3]. Key behaviors for "additionalItems" in Draft 07 include: 1. Prerequisite: "additionalItems" only has an effect if "items" is present and is defined as an array of schemas [3][5]. 2. Ignored when: If "items" is missing, is defined as a single schema (rather than an array), or is not present, "additionalItems" is ignored [3][4]. 3. Empty Case: "additionalItems" does not restrict the minimum number of items in the array; it only constrains items that exist beyond the tuple definition [2][3]. Example of restricting an array to exactly two items: { "$schema": "http://json-schema.org/draft-07/schema#", "items": [ { "type": "boolean" }, { "type": "number" } ], "additionalItems": false } In this example, the instance [true, 10] is valid, but [true, 10, "extra"] is invalid because "additionalItems" is false [3].

Citations:


Enforce the documented sample tuple shapes. The current items: {type: array, items: number, minItems: 2, maxItems: 3} shape is still a generic array schema, so malformed samples such as an incomplete 3-tuple, empty numbers, decimals for epoch seconds, or negative interval values can be accepted.

  • standMinutesSeries: enforce exactly [startEpochSeconds, endEpochSeconds, value].
  • stepSeries: enforce exactly [startEpochSeconds, endEpochSeconds, value].
  • walkingRunningDistanceSeries: enforce exactly [startEpochSeconds, endEpochSeconds, value].
  • wristTemperatureSeries: enforce exactly [epochSeconds, value].

Use Draft-07 tuple validation (items as a positional schema array, additionalItems: false, and minItems/maxItems equal to the tuple length); add integer/non-negative bounds to epoch and interval values where the contract expects them.

📍 Affects 4 files
  • services/ontology/schemas/standMinutesSeries.json#L68-L77 (this comment)
  • services/ontology/schemas/stepSeries.json#L68-L77
  • services/ontology/schemas/walkingRunningDistanceSeries.json#L68-L77
  • services/ontology/schemas/wristTemperatureSeries.json#L68-L77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/standMinutesSeries.json` around lines 68 - 77,
Replace the generic sample-array schemas with Draft-07 positional tuple
validation in services/ontology/schemas/standMinutesSeries.json (68-77),
stepSeries.json (68-77), walkingRunningDistanceSeries.json (68-77), and
wristTemperatureSeries.json (68-77). The first three files must enforce exactly
[startEpochSeconds, endEpochSeconds, value], with positional numeric schemas,
non-negative integer epoch/interval bounds where applicable, additionalItems
false, and minItems/maxItems 3; wristTemperatureSeries.json must enforce exactly
[epochSeconds, value] with the corresponding integer/non-negative epoch
constraint, additionalItems false, and minItems/maxItems 2.

…n (10 schemas)

Mobility (point series, 1/person x day x device): walkingSpeedSeries (km/h),
stepLengthSeries (cm), walkingDoubleSupportSeries (%), walkingAsymmetrySeries (%).

Nutrition intake (interval series — food-log entries): energyIntakeSeries (kcal),
proteinIntakeSeries (g), fatIntakeSeries (g), carbohydrateIntakeSeries (g),
waterIntakeSeries (mL).

Observation: walkingHeartRateObservation (device-computed daily value).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/ontology/schemas/carbohydrateIntakeSeries.json`:
- Around line 51-58: Update the date and utcOffset property patterns in
services/ontology/schemas/carbohydrateIntakeSeries.json:51-58,
services/ontology/schemas/energyIntakeSeries.json:51-58,
services/ontology/schemas/fatIntakeSeries.json:51-58,
services/ontology/schemas/proteinIntakeSeries.json:51-58,
services/ontology/schemas/stepLengthSeries.json:51-58,
services/ontology/schemas/walkingAsymmetrySeries.json:51-58,
services/ontology/schemas/walkingDoubleSupportSeries.json:51-58,
services/ontology/schemas/walkingSpeedSeries.json:51-58, and
services/ontology/schemas/waterIntakeSeries.json:51-58 so date accepts only real
calendar dates and utcOffset accepts only offsets with hours and minutes within
valid bounds.
- Around line 68-77: The samples tuple constraints are too permissive. Update
the samples item definitions in
services/ontology/schemas/carbohydrateIntakeSeries.json:68-77,
services/ontology/schemas/energyIntakeSeries.json:68-77,
services/ontology/schemas/fatIntakeSeries.json:68-77,
services/ontology/schemas/proteinIntakeSeries.json:68-77, and
services/ontology/schemas/waterIntakeSeries.json:68-77 to require exactly three
numeric items; update services/ontology/schemas/stepLengthSeries.json:68-77,
services/ontology/schemas/walkingAsymmetrySeries.json:68-77,
services/ontology/schemas/walkingDoubleSupportSeries.json:68-77, and
services/ontology/schemas/walkingSpeedSeries.json:68-77 to require exactly two
numeric items.

In `@services/ontology/schemas/walkingHeartRateObservation.json`:
- Around line 51-61: Update the value and measuredAt properties in the walking
heart rate observation schema: require value to be non-negative using the
appropriate numeric constraint, and enforce measuredAt as an ISO 8601 timestamp
with offset using the schema’s date-time format. Preserve the existing unit
constant and descriptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b46c8b24-1629-4e39-a5da-db87365b9a7e

📥 Commits

Reviewing files that changed from the base of the PR and between 14fae82 and eafaadf.

📒 Files selected for processing (10)
  • services/ontology/schemas/carbohydrateIntakeSeries.json
  • services/ontology/schemas/energyIntakeSeries.json
  • services/ontology/schemas/fatIntakeSeries.json
  • services/ontology/schemas/proteinIntakeSeries.json
  • services/ontology/schemas/stepLengthSeries.json
  • services/ontology/schemas/walkingAsymmetrySeries.json
  • services/ontology/schemas/walkingDoubleSupportSeries.json
  • services/ontology/schemas/walkingHeartRateObservation.json
  • services/ontology/schemas/walkingSpeedSeries.json
  • services/ontology/schemas/waterIntakeSeries.json

Comment on lines +51 to +58
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "local day — chunk key"
},
"utcOffset": {
"type": "string",
"pattern": "^[+-]\\d{2}:\\d{2}$"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject invalid local-day keys and UTC offsets.

The shared patterns validate 2026-99-99 and +99:99. Since date is the envelope chunk key, malformed values create records that cannot be reliably grouped or queried by day.

  • services/ontology/schemas/carbohydrateIntakeSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/energyIntakeSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/fatIntakeSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/proteinIntakeSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/stepLengthSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/walkingAsymmetrySeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/walkingDoubleSupportSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/walkingSpeedSeries.json#L51-L58: enforce a real calendar date and bounded offset.
  • services/ontology/schemas/waterIntakeSeries.json#L51-L58: enforce a real calendar date and bounded offset.
📍 Affects 9 files
  • services/ontology/schemas/carbohydrateIntakeSeries.json#L51-L58 (this comment)
  • services/ontology/schemas/energyIntakeSeries.json#L51-L58
  • services/ontology/schemas/fatIntakeSeries.json#L51-L58
  • services/ontology/schemas/proteinIntakeSeries.json#L51-L58
  • services/ontology/schemas/stepLengthSeries.json#L51-L58
  • services/ontology/schemas/walkingAsymmetrySeries.json#L51-L58
  • services/ontology/schemas/walkingDoubleSupportSeries.json#L51-L58
  • services/ontology/schemas/walkingSpeedSeries.json#L51-L58
  • services/ontology/schemas/waterIntakeSeries.json#L51-L58
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/carbohydrateIntakeSeries.json` around lines 51 -
58, Update the date and utcOffset property patterns in
services/ontology/schemas/carbohydrateIntakeSeries.json:51-58,
services/ontology/schemas/energyIntakeSeries.json:51-58,
services/ontology/schemas/fatIntakeSeries.json:51-58,
services/ontology/schemas/proteinIntakeSeries.json:51-58,
services/ontology/schemas/stepLengthSeries.json:51-58,
services/ontology/schemas/walkingAsymmetrySeries.json:51-58,
services/ontology/schemas/walkingDoubleSupportSeries.json:51-58,
services/ontology/schemas/walkingSpeedSeries.json:51-58, and
services/ontology/schemas/waterIntakeSeries.json:51-58 so date accepts only real
calendar dates and utcOffset accepts only offsets with hours and minutes within
valid bounds.

Comment on lines +68 to +77
"samples": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 3
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require the tuple shape declared by each schema.

The shared sample definition accepts both two- and three-value tuples. That admits interval records without a value and point records with an ambiguous extra value, breaking reader-side positional parsing.

  • services/ontology/schemas/carbohydrateIntakeSeries.json#L68-L77: require exactly three items for [startEpochSeconds, endEpochSeconds, value].
  • services/ontology/schemas/energyIntakeSeries.json#L68-L77: require exactly three items for [startEpochSeconds, endEpochSeconds, value].
  • services/ontology/schemas/fatIntakeSeries.json#L68-L77: require exactly three items for [startEpochSeconds, endEpochSeconds, value].
  • services/ontology/schemas/proteinIntakeSeries.json#L68-L77: require exactly three items for [startEpochSeconds, endEpochSeconds, value].
  • services/ontology/schemas/stepLengthSeries.json#L68-L77: require exactly two items for [epochSeconds, value].
  • services/ontology/schemas/walkingAsymmetrySeries.json#L68-L77: require exactly two items for [epochSeconds, value].
  • services/ontology/schemas/walkingDoubleSupportSeries.json#L68-L77: require exactly two items for [epochSeconds, value].
  • services/ontology/schemas/walkingSpeedSeries.json#L68-L77: require exactly two items for [epochSeconds, value].
  • services/ontology/schemas/waterIntakeSeries.json#L68-L77: require exactly three items for [startEpochSeconds, endEpochSeconds, value].
📍 Affects 9 files
  • services/ontology/schemas/carbohydrateIntakeSeries.json#L68-L77 (this comment)
  • services/ontology/schemas/energyIntakeSeries.json#L68-L77
  • services/ontology/schemas/fatIntakeSeries.json#L68-L77
  • services/ontology/schemas/proteinIntakeSeries.json#L68-L77
  • services/ontology/schemas/stepLengthSeries.json#L68-L77
  • services/ontology/schemas/walkingAsymmetrySeries.json#L68-L77
  • services/ontology/schemas/walkingDoubleSupportSeries.json#L68-L77
  • services/ontology/schemas/walkingSpeedSeries.json#L68-L77
  • services/ontology/schemas/waterIntakeSeries.json#L68-L77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/carbohydrateIntakeSeries.json` around lines 68 -
77, The samples tuple constraints are too permissive. Update the samples item
definitions in services/ontology/schemas/carbohydrateIntakeSeries.json:68-77,
services/ontology/schemas/energyIntakeSeries.json:68-77,
services/ontology/schemas/fatIntakeSeries.json:68-77,
services/ontology/schemas/proteinIntakeSeries.json:68-77, and
services/ontology/schemas/waterIntakeSeries.json:68-77 to require exactly three
numeric items; update services/ontology/schemas/stepLengthSeries.json:68-77,
services/ontology/schemas/walkingAsymmetrySeries.json:68-77,
services/ontology/schemas/walkingDoubleSupportSeries.json:68-77, and
services/ontology/schemas/walkingSpeedSeries.json:68-77 to require exactly two
numeric items.

Comment on lines +51 to +61
"value": {
"type": "number"
},
"unit": {
"type": "string",
"const": "count/min"
},
"measuredAt": {
"type": "string",
"description": "ISO 8601 with offset"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Constrain the measurement value and timestamp.

A negative heart rate and a non-timestamp measuredAt value both validate today. Require a non-negative value and enforce the declared timestamp contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/walkingHeartRateObservation.json` around lines 51 -
61, Update the value and measuredAt properties in the walking heart rate
observation schema: require value to be non-negative using the appropriate
numeric constraint, and enforce measuredAt as an ISO 8601 timestamp with offset
using the schema’s date-time format. Preserve the existing unit constant and
descriptions.

Egor Yakovlev and others added 24 commits July 29, 2026 09:38
EgorPPS added 24 commits July 29, 2026 23:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/ontology/schemas/healthPhoto.json`:
- Around line 48-50: Update the updatedAt and capturedAt schema properties to
include the JSON Schema "format": "date-time" constraint alongside their
existing string type, ensuring both timestamps reject malformed values.
- Around line 63-71: Update the byteSize, width, and height properties in the
health photo schema to require positive integers by adding a minimum value of 1
to each field, while preserving their existing integer types.
- Around line 44-46: Update the contentHash field and the other MD5 hash field
in healthPhoto.json to validate exactly 32 hexadecimal characters using the
schema’s pattern constraint, while preserving their existing string types and
descriptions.
- Around line 51-62: Constrain the dataUri property in the health photo schema
to a valid data URI containing base64-encoded image data, and ensure its MIME
prefix matches the declared mediaType enum value. Use schema pattern/conditional
validation tied to mediaType, preserving only the supported JPEG, PNG, and WebP
formats.
- Line 3: Replace the custom schemaId property in the healthPhoto schema with
the standard $id keyword, preserving the existing UUID and the Draft-07 $schema
declaration.

In `@services/ontology/schemas/meal.json`:
- Around line 67-74: Update the meal schema’s mealType/mealTypeSource definition
so every record containing mealType must also provide mealTypeSource, preserving
the existing user and inferred enum values and their provenance semantics. Use
the schema’s conditional required-property mechanism rather than changing
unrelated fields.
- Around line 151-153: Add a minimum constraint of 0 to the totalKcal property
in the meal schema, while preserving its existing number type, so negative
calorie totals are rejected.
- Around line 110-114: Update the nutritionEstimate schema around the method
enum to conditionally require provenance metadata for “ai-vision” estimates:
require model, derivedFrom linking the estimate to the meal photo when
applicable, and the total calorie/estimator metadata. Preserve existing
validation for “food-log” estimates and use Draft-07-compatible conditional
rules.
- Line 5: Update the schema object for the meal definition in meal.json to set
additionalProperties to false, rejecting undeclared fields such as embedded
photo data while preserving the existing declared properties.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a398d545-1c13-404e-b501-fa8d1decd72c

📥 Commits

Reviewing files that changed from the base of the PR and between eafaadf and c826c81.

📒 Files selected for processing (2)
  • services/ontology/schemas/healthPhoto.json
  • services/ontology/schemas/meal.json

@@ -0,0 +1,95 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"schemaId": "30b4bb28-494b-4d78-b99b-18f58a008da0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n '"schemaId"|"\\$id"' services/ontology/schemas

Repository: MetaState-Prototype-Project/prototype

Length of output: 7758


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== schema files mentioning schemaId or $id =="
rg -n '"schemaId"|"\\$id"' services/ontology/schemas || true

echo
echo "== healthPhoto.json =="
cat -n services/ontology/schemas/healthPhoto.json | sed -n '1,80p'

echo
echo "== files mentioning ontology schemaId/id validation/config =="
rg -n 'schemaId|\\$id|json.*schema|json-schema|validator|Schema|ontology' -S --glob '!services/ontology/schemas/*.json' | head -n 200

Repository: MetaState-Prototype-Project/prototype

Length of output: 210


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== schema files mentioning schemaId or $id =="
rg -n '"schemaId"|"\\$id"' services/ontology/schemas || true

echo
echo "== healthPhoto.json =="
cat -n services/ontology/schemas/healthPhoto.json | sed -n '1,80p'

echo
echo "== files mentioning ontology schemaId/id validation/config =="
rg -n 'schemaId|\\$id|json.*schema|json-schema|validator|Schema|ontology' -S --glob '!services/ontology/schemas/*.json' | head -n 200

Repository: MetaState-Prototype-Project/prototype

Length of output: 210


🏁 Script executed:

#!/bin/bash
set -u

echo "== schema files mentioning schemaId or $id =="
rg -n '"schemaId"|"\\$id"' services/ontology/schemas || true

echo
echo "== healthPhoto.json =="
cat -n services/ontology/schemas/healthPhoto.json | sed -n '1,80p'

echo
echo "== files mentioning ontology schemaId/id validation/config =="
rg -n 'schemaId|\\$id|json.*schema|json-schema|validator|Schema|ontology' -S --glob '!services/ontology/schemas/*.json' | head -n 200

Repository: MetaState-Prototype-Project/prototype

Length of output: 210


🏁 Script executed:

#!/bin/bash

echo "== schema files mentioning schemaId or $id =="
rg -n '"schemaId"|"\\$id"' services/ontology/schemas || true

echo
echo "== healthPhoto.json =="
cat -n services/ontology/schemas/healthPhoto.json | sed -n '1,80p'

echo
echo "== files mentioning ontology schemaId/id validation/config =="
rg -n 'schemaId|\\$id|json.*schema|json-schema|validator|Schema|ontology' -S --glob '!services/ontology/schemas/*.json' | head -n 200

Repository: MetaState-Prototype-Project/prototype

Length of output: 10730


🏁 Script executed:

#!/bin/bash

echo "== exact schemaId references outside schema files =="
rg -n 'schemaId|schema-id|schema_id' -S --glob '!services/ontology/schemas/*.json' --glob '!node_modules/**' || true

echo
echo "== exact $id references outside schema files =="
rg -n '"\\$id"|"\\$schema"|json-validator|jsonschema|ajv|zod|superjson|json.*schema' -S --glob '!services/ontology/schemas/*.json' --glob '!node_modules/**' | head -n 200 || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 228


🏁 Script executed:

#!/bin/bash

echo "== exact $id references outside schema files =="
rg -n '"\\$id"|"\\$schema"|json-validator|jsonschema|ajv|zod|superjson|json.*schema' -S --glob '!services/ontology/schemas/*.json' --glob '!node_modules/**' | head -n 200 || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 220


🌐 Web query:

JSON Schema Draft-07 id$ annotation schemaId keyword validator unrecognized keywords ignored

💡 Result:

In JSON Schema Draft-07, the $id keyword is the official standard for specifying a schema's base URI [1][2]. This was introduced in Draft-06 to replace the id keyword used in earlier versions (such as Draft-04), specifically to avoid conflicts with user-defined data fields named "id" [3]. Regarding your specific questions about Draft-07 behavior: 1. $id vs id: While $id is the standard for Draft-07, some validator implementations (such as Ajv) provide configuration options to maintain backward compatibility [4]. For example, these tools often allow you to specify whether they should ignore the legacy id keyword, treat it as an alias for $id, or enforce $id exclusively [4]. 2. Unrecognized Keywords: According to the JSON Schema specifications active through Draft-07, implementations are generally instructed to ignore keywords they do not recognize [5]. While later drafts (and associated tooling updates) evolved to restrict or formalize how unknown keywords are handled (e.g., collecting them as annotations [5][6]), the core behavior in Draft-07 implementations was to ensure they did not interfere with validation [5]. If you are encountering issues with unrecognized keywords or identifier conflicts, it is recommended to explicitly declare the $schema version in your document to ensure the validator applies the correct ruleset for Draft-07 [3]. If you are migrating or supporting multiple versions, check your specific validator's documentation for "schemaId" or similar configuration options that allow you to toggle the interpretation of id versus $id [4].

Citations:


Use the Schema dialect URI instead of schemaId.

services/ontology/schemas/healthPhoto.json:3 uses a custom schemaId keyword, while the document declares $schema: "http://json-schema.org/draft-07/schema#". Because the schema files do not actually reference "schemaId" and Draft-07 standardizes schema identifiers with "$id", move this UUID to "$id" or make it explicit that schemaId is intentionally non-standard tooling metadata.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/healthPhoto.json` at line 3, Replace the custom
schemaId property in the healthPhoto schema with the standard $id keyword,
preserving the existing UUID and the Draft-07 $schema declaration.

Comment on lines +44 to +46
"contentHash": {
"type": "string",
"description": "Writer-maintained md5 of the payload; recomputed on every rewrite"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Validate the MD5 formats.

Both fields are described as MD5 hashes but accept any string. Require 32 hexadecimal characters so deduplication and integrity consumers cannot treat malformed values as valid hashes.

Also applies to: 72-74

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/healthPhoto.json` around lines 44 - 46, Update the
contentHash field and the other MD5 hash field in healthPhoto.json to validate
exactly 32 hexadecimal characters using the schema’s pattern constraint, while
preserving their existing string types and descriptions.

Comment on lines +48 to +50
"updatedAt": {
"type": "string"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate timestamp formats.

updatedAt and capturedAt accept arbitrary strings. Add "format": "date-time" so malformed timestamps do not enter the ontology contract.

Also applies to: 76-78

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/healthPhoto.json` around lines 48 - 50, Update the
updatedAt and capturedAt schema properties to include the JSON Schema "format":
"date-time" constraint alongside their existing string type, ensuring both
timestamps reject malformed values.

Comment on lines +51 to +62
"mediaType": {
"type": "string",
"enum": [
"image/jpeg",
"image/png",
"image/webp"
]
},
"dataUri": {
"type": "string",
"description": "The image itself: data:<mediaType>;base64,…"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Constrain dataUri to the declared image format.

The schema accepts arbitrary strings, including non-data: URIs, malformed base64, and MIME types that disagree with mediaType. Add a data-URI/base64 pattern and ideally bind each allowed mediaType to its matching URI prefix.

Proposed fix
     "dataUri": {
       "type": "string",
+      "pattern": "^data:image/(jpeg|png|webp);base64,[A-Za-z0-9+/]+={0,2}$",
       "description": "The image itself: data:<mediaType>;base64,…"
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"mediaType": {
"type": "string",
"enum": [
"image/jpeg",
"image/png",
"image/webp"
]
},
"dataUri": {
"type": "string",
"description": "The image itself: data:<mediaType>;base64,…"
},
"mediaType": {
"type": "string",
"enum": [
"image/jpeg",
"image/png",
"image/webp"
]
},
"dataUri": {
"type": "string",
"pattern": "^data:image/(jpeg|png|webp);base64,[A-Za-z0-9+/]+={0,2}$",
"description": "The image itself: data:<mediaType>;base64,…"
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/healthPhoto.json` around lines 51 - 62, Constrain
the dataUri property in the health photo schema to a valid data URI containing
base64-encoded image data, and ensure its MIME prefix matches the declared
mediaType enum value. Use schema pattern/conditional validation tied to
mediaType, preserving only the supported JPEG, PNG, and WebP formats.

Comment on lines +63 to +71
"byteSize": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reject non-positive image metadata.

byteSize, width, and height currently accept negative and zero values, allowing invalid image metadata into the vault. Add minimum: 1 to each field.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/healthPhoto.json` around lines 63 - 71, Update the
byteSize, width, and height properties in the health photo schema to require
positive integers by adding a minimum value of 1 to each field, while preserving
their existing integer types.

"$schema": "http://json-schema.org/draft-07/schema#",
"schemaId": "879df524-f062-44eb-9a05-52dc62884e6c",
"title": "Meal",
"description": "One meal. The photo is NOT embedded here: `photo.ref` points at the HealthPhoto envelope that holds the bytes (canonical + reference, never a copy). nutritionEstimate is STRUCTURALLY an estimate (AI vision output, `derivedFrom` names the photo it was read from) — readers must present it as an estimate, never as a measured fact.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'services/ontology/schemas/meal.json' || true

echo "== schema header relevant sections =="
if [ -f services/ontology/schemas/meal.json ]; then
  wc -l services/ontology/schemas/meal.json
  sed -n '1,130p' services/ontology/schemas/meal.json
fi

echo "== search for photo schemas / additionalProperties in meal.json =="
python3 - <<'PY'
import json
from pathlib import Path
p=Path('services/ontology/schemas/meal.json')
data=json.loads(p.read_text())
def walk(path, obj):
    if isinstance(obj, dict):
        print(path, {k: obj.get(k) for k in ['type','additionalProperties','required'] if k in obj})
        for k,v in obj.items():
            walk(f'{path}.{k}', v)
    elif isinstance(obj, list):
        for i,v in enumerate(obj):
            walk(f'{path}[{i}]', v)
walk('root', data)
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 6817


Reject unexpected photo payloads.

photo documents that bytes are referenced, not embedded, but the schema still permits undeclared fields in Draft-07. Add additionalProperties: false so payloads cannot slip private image data beside photo.ref.

Proposed fix
       "required": [
         "ref"
-      ]
+      ],
+      "additionalProperties": false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"description": "One meal. The photo is NOT embedded here: `photo.ref` points at the HealthPhoto envelope that holds the bytes (canonical + reference, never a copy). nutritionEstimate is STRUCTURALLY an estimate (AI vision output, `derivedFrom` names the photo it was read from) — readers must present it as an estimate, never as a measured fact.",
"required": [
"ref"
],
"additionalProperties": false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/meal.json` at line 5, Update the schema object for
the meal definition in meal.json to set additionalProperties to false, rejecting
undeclared fields such as embedded photo data while preserving the existing
declared properties.

Comment on lines +67 to +74
"mealTypeSource": {
"type": "string",
"enum": [
"user",
"inferred"
],
"description": "user = stated by the person; inferred = guessed from local time of day + dish. An inferred type must not be presented as stated."
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make meal-type provenance explicit.

A record can contain mealType without mealTypeSource, so consumers cannot determine whether it was user-stated or inferred. Require the source whenever mealType is present, or add an explicit unknown value and define that fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/meal.json` around lines 67 - 74, Update the meal
schema’s mealType/mealTypeSource definition so every record containing mealType
must also provide mealTypeSource, preserving the existing user and inferred enum
values and their provenance semantics. Use the schema’s conditional
required-property mechanism rather than changing unrelated fields.

Comment on lines +110 to +114
"enum": [
"ai-vision",
"food-log"
],
"description": "ai-vision = AI photo analysis; food-log = user-entered food-app values"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Candidate file and relevant snippets =="
sed -n '1,220p' services/ontology/schemas/meal.json | nl -ba | sed -n '90,165p'

echo
echo "== Schema metadata / references to ai-vision/model/derivedFrom =="
rg -n '"ai-vision"|derivedFrom|model|method|Draft-07|if|required|allOf' services/ontology/schemas/meal.json

echo
echo "== Other schema files with conditional validation examples =="
fd -t f . services/ontology/schemas -x sh -c 'echo "--- $1"; rg -n "if|then|else|required|allOf|item" "$1" | head -80' sh {}

Repository: MetaState-Prototype-Project/prototype

Length of output: 258


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Candidate file and relevant snippets =="
awk '{printf "%6d  %s\n", NR, $0}' services/ontology/schemas/meal.json | sed -n '90,165p'

echo
echo "== Schema references =="
rg -n '"ai-vision"|derivedFrom|model|method|Draft-07|if|required|allOf|anyOf|oneOf' services/ontology/schemas/meal.json || true

echo
echo "== Validity / structural probe using Python json =="
python3 - <<'PY'
import json
from pathlib import Path
p = Path('services/ontology/schemas/meal.json')
data = json.loads(p.read_text())
# Locate aiVision-related entries without assuming exact keys.
def walk(node, path=()):
    if isinstance(node, dict):
        if node.get('aiVision') is not None:
            print('path:', ' -> '.join(str(k) for k in path))
            print(json.dumps(node, indent=2))
        for k, v in node.items():
            walk(v, path+(k,))
    elif isinstance(node, list):
        for i, v in enumerate(node):
            walk(v, path+(str(i),))
walk(data)
print('schemaId=', data.get('$schema'))
print('properties:', list(data.get('properties', {}).keys()))
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 3886


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== nutritionEstimate required block and top-level required =="
awk '{printf "%6d  %s\n", NR, $0}' services/ontology/schemas/meal.json | sed -n '162,185p'

echo
echo "== Full schema size and validation keywords =="
wc -l services/ontology/schemas/meal.json
python3 - <<'PY'
import json
p='services/ontology/schemas/meal.json'
data=json.load(open(p))
def collect(node,key):
    found=[]
    if isinstance(node,dict):
        if key in node:
            found.append((node[key],node.get('required')))
        for v in node.values():
            found.extend(collect(v,key))
    elif isinstance(node,list):
        for item in node:
            found.extend(collect(item,key))
    return found
for key in ["if","then","else","allOf","anyOf","oneOf","const"]:
    print(key, col:=collect(data,key))
    print("  len", len(col))
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 988


Require provenance for AI-vision estimates.

nutritionEstimate.method: "ai-vision" is currently allowed without model, derivedFrom, or total calorie/estimator metadata. Add Draft-07 conditional validation for AI estimates, or make nutritionEstimate required when photo exists; if the meal photo is the source, require that relationship explicitly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/meal.json` around lines 110 - 114, Update the
nutritionEstimate schema around the method enum to conditionally require
provenance metadata for “ai-vision” estimates: require model, derivedFrom
linking the estimate to the meal photo when applicable, and the total
calorie/estimator metadata. Preserve existing validation for “food-log”
estimates and use Draft-07-compatible conditional rules.

Comment on lines +151 to +153
"totalKcal": {
"type": "number"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reject negative calorie totals.

type: "number" accepts negative totalKcal values. Add "minimum": 0 to prevent invalid nutrition estimates.

Proposed fix
         "totalKcal": {
-          "type": "number"
+          "type": "number",
+          "minimum": 0
         },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"totalKcal": {
"type": "number"
},
"totalKcal": {
"type": "number",
"minimum": 0
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/meal.json` around lines 151 - 153, Add a minimum
constraint of 0 to the totalKcal property in the meal schema, while preserving
its existing number type, so negative calorie totals are rejected.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (11)
services/ontology/schemas/leanBodyMassObservation.json (2)

55-57: 🗄️ Data Integrity & Integration | 🟠 Major

Reject impossible negative health measurements.

The numeric observation schemas accept negative values. Add "minimum": 0 to each applicable field.

  • services/ontology/schemas/leanBodyMassObservation.json#L55-L57: add "minimum": 0 to value.
  • services/ontology/schemas/bloodGlucoseObservation.json#L55-L57: add "minimum": 0 to value.
  • services/ontology/schemas/bloodPressureObservation.json#L55-L60: add "minimum": 0 to both systolic and diastolic.
  • services/ontology/schemas/bodyMassObservation.json#L55-L57: add "minimum": 0 to value.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/leanBodyMassObservation.json` around lines 55 - 57,
Reject negative numeric health measurements by adding a minimum constraint of 0
to value in services/ontology/schemas/leanBodyMassObservation.json (lines
55-57), bloodGlucoseObservation.json (lines 55-57), and bodyMassObservation.json
(lines 55-57), and to both systolic and diastolic in
services/ontology/schemas/bloodPressureObservation.json (lines 55-60).

62-64: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Enforce the documented timestamp contract.

These measuredAt fields are documented as ISO 8601 timestamps with offsets, but the schemas only validate them as arbitrary strings. Add explicit format: date-time or an offset-capable pattern constraint for measuredAt in the affected ontology observation schemas.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/leanBodyMassObservation.json` around lines 62 - 64,
Add explicit ISO 8601 date-time validation with offset support to the measuredAt
property in services/ontology/schemas/leanBodyMassObservation.json (62-64),
services/ontology/schemas/bloodGlucoseObservation.json (62-64),
services/ontology/schemas/bloodPressureObservation.json (65-67), and
services/ontology/schemas/bodyMassObservation.json (62-64), using format
date-time or an equivalent offset-capable pattern while preserving the existing
string type and descriptions.
services/ontology/schemas/environmentalAudioSeries.json (5)

99-105: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Constrain derived counts to non-negative values.

  • services/ontology/schemas/environmentalAudioSeries.json#L99-L105: add minimum: 0 to stats.count.
  • services/ontology/schemas/exerciseMinutesSeries.json#L99-L105: add minimum: 0 to stats.count.
  • services/ontology/schemas/fatIntakeSeries.json#L99-L105: add minimum: 0 to stats.count.
  • services/ontology/schemas/headphoneAudioSeries.json#L99-L105: add minimum: 0 to stats.count.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/environmentalAudioSeries.json` around lines 99 -
105, Constrain the stats.count integer schema to non-negative values by adding
minimum: 0 in services/ontology/schemas/environmentalAudioSeries.json (99-105),
services/ontology/schemas/exerciseMinutesSeries.json (99-105),
services/ontology/schemas/fatIntakeSeries.json (99-105), and
services/ontology/schemas/headphoneAudioSeries.json (99-105).

48-50: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Replace MD5 wherever contentHash represents integrity. Use SHA-256 with a versioned migration, or explicitly restrict MD5 to non-security deduplication.

  • services/ontology/schemas/environmentalAudioSeries.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/exerciseMinutesSeries.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/fatIntakeSeries.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/headphoneAudioSeries.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/bodyTemperatureObservation.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/heightObservation.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/restingHeartRateObservation.json#L48-L50: replace or narrow the MD5 contract.
  • services/ontology/schemas/skinTypeFact.json#L48-L50: replace or narrow the MD5 contract.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/environmentalAudioSeries.json` around lines 48 -
50, Replace the MD5 integrity contract for contentHash in
services/ontology/schemas/environmentalAudioSeries.json (48-50),
services/ontology/schemas/exerciseMinutesSeries.json (48-50),
services/ontology/schemas/fatIntakeSeries.json (48-50),
services/ontology/schemas/headphoneAudioSeries.json (48-50),
services/ontology/schemas/bodyTemperatureObservation.json (48-50),
services/ontology/schemas/heightObservation.json (48-50),
services/ontology/schemas/restingHeartRateObservation.json (48-50), and
services/ontology/schemas/skinTypeFact.json (48-50) with a versioned SHA-256
contract, or explicitly document and constrain contentHash to non-security
deduplication rather than integrity validation.

55-62: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate chunk-key dates and UTC offsets, not just their shape. date: ^\d{4}-\d{2}-\d{2}$ accepts impossible values like 2024-13-32, and utcOffset accepts values outside IETF IANA timezone offset range such as +25:30, before sample epoch validation runs. Add actual calendar/date range and offset bounds, preferably via $dynamicRef "$date"/date-time plus a numeric or offset-moment constraint.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/environmentalAudioSeries.json` around lines 55 -
62, Strengthen the date and utcOffset validation in the date/utcOffset
properties of services/ontology/schemas/environmentalAudioSeries.json (lines
55-62), exerciseMinutesSeries.json (lines 55-62), fatIntakeSeries.json (lines
55-62), and headphoneAudioSeries.json (lines 55-62): replace shape-only regex
validation with the shared date/date-time constraint or equivalent calendar
validation, and enforce valid IETF offset bounds so impossible dates and offsets
such as +25:30 are rejected before sample epoch validation.

72-81: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Define sample tuple positions explicitly. In Draft-07, items: { ... } treats sample arrays as homogeneous numeric arrays, so a malformed triple won’t fail because one position has the wrong numeric semantics. Use positional schemas and additionalItems: false for point samples [epochSeconds, value] and interval samples [startEpochSeconds, endEpochSeconds, value].

  • services/ontology/schemas/environmentalAudioSeries.json
  • services/ontology/schemas/exerciseMinutesSeries.json
  • services/ontology/schemas/fatIntakeSeries.json
  • services/ontology/schemas/headphoneAudioSeries.json
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/environmentalAudioSeries.json` around lines 72 -
81, Update the samples item schema in
services/ontology/schemas/environmentalAudioSeries.json,
services/ontology/schemas/exerciseMinutesSeries.json,
services/ontology/schemas/fatIntakeSeries.json, and
services/ontology/schemas/headphoneAudioSeries.json to use positional Draft-07
tuple schemas: point samples must define [epochSeconds, value], interval samples
must define [startEpochSeconds, endEpochSeconds, value], and each must set
additionalItems to false while preserving the existing length constraints.

26-42: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Enforce the platform provenance contract consistently. The field is documented as a @-prefixed w3id, but these schemas only assert type: "string" and keep source as the required provenance field, so arbitrary platform values and missing platform entries are accepted. Add the canonical @^...$ assertion and require platform in the affected schemas' provenance.required arrays, or explicitly document that legacy/optional imports may omit it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/environmentalAudioSeries.json` around lines 26 -
42, Enforce the platform provenance contract in the provenance definitions for
services/ontology/schemas/environmentalAudioSeries.json lines 26-42,
services/ontology/schemas/exerciseMinutesSeries.json lines 26-42,
services/ontology/schemas/fatIntakeSeries.json lines 26-42,
services/ontology/schemas/flightsClimbedSeries.json lines 26-42,
services/ontology/schemas/headphoneAudioSeries.json lines 26-42,
services/ontology/schemas/bodyTemperatureObservation.json lines 26-42,
services/ontology/schemas/heightObservation.json lines 26-42,
services/ontology/schemas/restingHeartRateObservation.json lines 26-42, and
services/ontology/schemas/skinTypeFact.json lines 26-42: constrain platform to
the canonical `@-prefixed` w3id pattern and replace the provenance requirement of
source with a required platform entry in each schema’s provenance.required
array.
services/ontology/schemas/bodyTemperatureObservation.json (1)

62-64: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Enforce timestamp formats in the ontology schemas.
These fields are only type: "string" with no format, pattern, or custom assertion, so { "measuredAt": "not-a-timestamp" } or { "recordedAt": "abc" } passes validation. Add the appropriate constraint for ISO-8601-with-offset values in bodyTemperatureObservation, heightObservation, and restingHeartRateObservation, plus a concrete timestamp format for skinTypeFact.recordedAt.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/bodyTemperatureObservation.json` around lines 62 -
64, The ontology schemas do not validate timestamp values. In
services/ontology/schemas/bodyTemperatureObservation.json (62-64),
heightObservation.json (62-64), and restingHeartRateObservation.json (62-64),
add the appropriate ISO-8601-with-offset constraint to the measuredAt or
recordedAt string fields; in skinTypeFact.json (61-63), add a concrete timestamp
format to recordedAt. Preserve the existing field descriptions and schema
structure.
services/ontology/schemas/heartRateSeries.json (2)

72-81: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Add domain bounds to point-series measurement values.

  • services/ontology/schemas/heartRateSeries.json#L72-L81: require heart-rate values to be non-negative.
  • services/ontology/schemas/heartRateVariabilitySeries.json#L72-L81: require HRV values to be non-negative.
  • services/ontology/schemas/respiratoryRateSeries.json#L72-L81: require respiratory-rate values to be non-negative.
  • services/ontology/schemas/oxygenSaturationSeries.json#L72-L81: require saturation values to be between 0 and 100.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/heartRateSeries.json` around lines 72 - 81, Update
the nested numeric item schemas in
services/ontology/schemas/heartRateSeries.json (72-81),
services/ontology/schemas/heartRateVariabilitySeries.json (72-81), and
services/ontology/schemas/respiratoryRateSeries.json (72-81) to require values
of at least 0. In services/ontology/schemas/oxygenSaturationSeries.json (72-81),
require values to be within the inclusive range 0–100; preserve the existing
array cardinality constraints.

55-63: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use range-aware temporal validation. Shape-only regexes admit impossible dates and offsets, which can create invalid chunk keys or session dates.

  • services/ontology/schemas/heartRateSeries.json#L55-L63: validate the calendar date and UTC-offset range.
  • services/ontology/schemas/heartRateVariabilitySeries.json#L55-L63: validate the calendar date and UTC-offset range.
  • services/ontology/schemas/respiratoryRateSeries.json#L55-L63: validate the calendar date and UTC-offset range.
  • services/ontology/schemas/oxygenSaturationSeries.json#L55-L63: validate the calendar date and UTC-offset range.
  • services/ontology/schemas/standMinutesSeries.json#L55-L63: validate the calendar date and UTC-offset range.
  • services/ontology/schemas/sleepSession.json#L55-L57: validate the calendar date.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/heartRateSeries.json` around lines 55 - 63, Replace
the shape-only temporal regex validation in
services/ontology/schemas/heartRateSeries.json lines 55-63,
services/ontology/schemas/heartRateVariabilitySeries.json lines 55-63,
services/ontology/schemas/respiratoryRateSeries.json lines 55-63,
services/ontology/schemas/oxygenSaturationSeries.json lines 55-63, and
services/ontology/schemas/standMinutesSeries.json lines 55-63 with range-aware
validation for real calendar dates and valid UTC offsets. Apply calendar-date
validation only to the date field in services/ontology/schemas/sleepSession.json
lines 55-57, preserving the existing schema structure and field formats.
services/ontology/schemas/sleepSession.json (1)

52-64: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Validate sleep timestamps as date-time values.

updatedAt, startDate, and endDate in SleepSession, plus each stage’s start and end, are typed only as strings. Add format: "date-time" or an equivalent ISO 8601 timestamp schema for these instant values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/sleepSession.json` around lines 52 - 64, Update the
SleepSession schema’s updatedAt, startDate, and endDate properties to validate
ISO 8601 date-time values using the schema’s date-time format, and apply the
same validation to each sleep stage’s start and end properties. Leave the
date-only date property unchanged.
♻️ Duplicate comments (3)
services/ontology/schemas/biologicalSexFact.json (1)

55-60: 🎯 Functional Correctness | 🟡 Minor

Reject boolean biological-sex values.

true and false have no interoperable biological-sex meaning. Remove boolean and constrain the string branch to the ontology’s agreed controlled vocabulary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/biologicalSexFact.json` around lines 55 - 60,
Update the value schema for biological-sex facts to remove the boolean type and
retain only strings. Constrain the string branch to the ontology’s agreed
controlled vocabulary using the schema’s enum or equivalent vocabulary
mechanism.
services/ontology/schemas/activeEnergySeries.json (2)

72-81: 🗄️ Data Integrity & Integration | 🟠 Major

Enforce three-value interval samples.

Each schema fixes sampleType to interval but accepts two- or three-number arrays. Require positional [start, end, value] tuples and reject trailing items with "additionalItems": false.

  • services/ontology/schemas/activeEnergySeries.json#L72-L81: replace the homogeneous nested items schema with three positional schemas.
  • services/ontology/schemas/basalEnergySeries.json#L72-L81: replace the homogeneous nested items schema with three positional schemas.
  • services/ontology/schemas/cyclingDistanceSeries.json#L72-L81: replace the homogeneous nested items schema with three positional schemas.
  • services/ontology/schemas/energyIntakeSeries.json#L72-L81: replace the homogeneous nested items schema with three positional schemas.
  • services/ontology/schemas/proteinIntakeSeries.json#L72-L81: replace the homogeneous nested items schema with three positional schemas.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/activeEnergySeries.json` around lines 72 - 81,
Update the samples schemas in services/ontology/schemas/activeEnergySeries.json
lines 72-81, services/ontology/schemas/basalEnergySeries.json lines 72-81,
services/ontology/schemas/cyclingDistanceSeries.json lines 72-81,
services/ontology/schemas/energyIntakeSeries.json lines 72-81, and
services/ontology/schemas/proteinIntakeSeries.json lines 72-81 to require
exactly three positional numeric values representing start, end, and value.
Replace the homogeneous nested items definition with three positional schemas
and set additionalItems to false so two-value tuples and trailing items are
rejected.

12-18: 🗄️ Data Integrity & Integration | 🟠 Major

Require device in every series envelope.

All five schemas describe null as the explicit unknown-device value but still allow omission, creating ambiguous device partitions.

  • services/ontology/schemas/activeEnergySeries.json#L12-L18: add "device" to the root required list.
  • services/ontology/schemas/basalEnergySeries.json#L12-L18: add "device" to the root required list.
  • services/ontology/schemas/cyclingDistanceSeries.json#L12-L18: add "device" to the root required list.
  • services/ontology/schemas/energyIntakeSeries.json#L12-L18: add "device" to the root required list.
  • services/ontology/schemas/proteinIntakeSeries.json#L12-L18: add "device" to the root required list.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/activeEnergySeries.json` around lines 12 - 18, Add
“device” to the root required list in
services/ontology/schemas/activeEnergySeries.json (12-18),
services/ontology/schemas/basalEnergySeries.json (12-18),
services/ontology/schemas/cyclingDistanceSeries.json (12-18),
services/ontology/schemas/energyIntakeSeries.json (12-18), and
services/ontology/schemas/proteinIntakeSeries.json (12-18), while preserving
each schema’s existing nullable device definition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/ontology/schemas/dailyActivitySummary.json`:
- Around line 26-29: Constrain the provenance.platform string using the existing
canonical w3id/@eName identifier pattern in
services/ontology/schemas/dailyActivitySummary.json (26-29),
services/ontology/schemas/healthPhoto.json (26-29),
services/ontology/schemas/meal.json (26-29), and
services/ontology/schemas/workout.json (26-29). Apply the same pattern
consistently to each platform property while preserving its current type and
description.

In `@services/ontology/schemas/device.json`:
- Around line 51-53: Add registeredBy to the required arrays in
services/ontology/schemas/device.json (lines 51-53) and
services/ontology/schemas/deviceLink.json (lines 21-23), ensuring both device
schemas require platform provenance while preserving their existing property
definitions.

In `@services/ontology/schemas/stepLengthSeries.json`:
- Around line 26-28: The provenance.platform property in
services/ontology/schemas/stepLengthSeries.json, stepSeries.json,
walkingAsymmetrySeries.json, walkingDoubleSupportSeries.json,
walkingRunningDistanceSeries.json, walkingSpeedSeries.json,
waterIntakeSeries.json, wristTemperatureSeries.json, and
carbohydrateIntakeSeries.json must use the repository’s canonical eName
constraint instead of an unconstrained string; add platform to
provenance.required wherever the provenance contract requires it.

In `@services/ontology/schemas/vo2MaxObservation.json`:
- Around line 55-64: Update the value property in vo2MaxObservation to require a
non-negative number using the appropriate minimum constraint, and update
measuredAt to enforce an ISO 8601 date-time format with offset while preserving
its string type and description.

---

Outside diff comments:
In `@services/ontology/schemas/bodyTemperatureObservation.json`:
- Around line 62-64: The ontology schemas do not validate timestamp values. In
services/ontology/schemas/bodyTemperatureObservation.json (62-64),
heightObservation.json (62-64), and restingHeartRateObservation.json (62-64),
add the appropriate ISO-8601-with-offset constraint to the measuredAt or
recordedAt string fields; in skinTypeFact.json (61-63), add a concrete timestamp
format to recordedAt. Preserve the existing field descriptions and schema
structure.

In `@services/ontology/schemas/environmentalAudioSeries.json`:
- Around line 99-105: Constrain the stats.count integer schema to non-negative
values by adding minimum: 0 in
services/ontology/schemas/environmentalAudioSeries.json (99-105),
services/ontology/schemas/exerciseMinutesSeries.json (99-105),
services/ontology/schemas/fatIntakeSeries.json (99-105), and
services/ontology/schemas/headphoneAudioSeries.json (99-105).
- Around line 48-50: Replace the MD5 integrity contract for contentHash in
services/ontology/schemas/environmentalAudioSeries.json (48-50),
services/ontology/schemas/exerciseMinutesSeries.json (48-50),
services/ontology/schemas/fatIntakeSeries.json (48-50),
services/ontology/schemas/headphoneAudioSeries.json (48-50),
services/ontology/schemas/bodyTemperatureObservation.json (48-50),
services/ontology/schemas/heightObservation.json (48-50),
services/ontology/schemas/restingHeartRateObservation.json (48-50), and
services/ontology/schemas/skinTypeFact.json (48-50) with a versioned SHA-256
contract, or explicitly document and constrain contentHash to non-security
deduplication rather than integrity validation.
- Around line 55-62: Strengthen the date and utcOffset validation in the
date/utcOffset properties of
services/ontology/schemas/environmentalAudioSeries.json (lines 55-62),
exerciseMinutesSeries.json (lines 55-62), fatIntakeSeries.json (lines 55-62),
and headphoneAudioSeries.json (lines 55-62): replace shape-only regex validation
with the shared date/date-time constraint or equivalent calendar validation, and
enforce valid IETF offset bounds so impossible dates and offsets such as +25:30
are rejected before sample epoch validation.
- Around line 72-81: Update the samples item schema in
services/ontology/schemas/environmentalAudioSeries.json,
services/ontology/schemas/exerciseMinutesSeries.json,
services/ontology/schemas/fatIntakeSeries.json, and
services/ontology/schemas/headphoneAudioSeries.json to use positional Draft-07
tuple schemas: point samples must define [epochSeconds, value], interval samples
must define [startEpochSeconds, endEpochSeconds, value], and each must set
additionalItems to false while preserving the existing length constraints.
- Around line 26-42: Enforce the platform provenance contract in the provenance
definitions for services/ontology/schemas/environmentalAudioSeries.json lines
26-42, services/ontology/schemas/exerciseMinutesSeries.json lines 26-42,
services/ontology/schemas/fatIntakeSeries.json lines 26-42,
services/ontology/schemas/flightsClimbedSeries.json lines 26-42,
services/ontology/schemas/headphoneAudioSeries.json lines 26-42,
services/ontology/schemas/bodyTemperatureObservation.json lines 26-42,
services/ontology/schemas/heightObservation.json lines 26-42,
services/ontology/schemas/restingHeartRateObservation.json lines 26-42, and
services/ontology/schemas/skinTypeFact.json lines 26-42: constrain platform to
the canonical `@-prefixed` w3id pattern and replace the provenance requirement of
source with a required platform entry in each schema’s provenance.required
array.

In `@services/ontology/schemas/heartRateSeries.json`:
- Around line 72-81: Update the nested numeric item schemas in
services/ontology/schemas/heartRateSeries.json (72-81),
services/ontology/schemas/heartRateVariabilitySeries.json (72-81), and
services/ontology/schemas/respiratoryRateSeries.json (72-81) to require values
of at least 0. In services/ontology/schemas/oxygenSaturationSeries.json (72-81),
require values to be within the inclusive range 0–100; preserve the existing
array cardinality constraints.
- Around line 55-63: Replace the shape-only temporal regex validation in
services/ontology/schemas/heartRateSeries.json lines 55-63,
services/ontology/schemas/heartRateVariabilitySeries.json lines 55-63,
services/ontology/schemas/respiratoryRateSeries.json lines 55-63,
services/ontology/schemas/oxygenSaturationSeries.json lines 55-63, and
services/ontology/schemas/standMinutesSeries.json lines 55-63 with range-aware
validation for real calendar dates and valid UTC offsets. Apply calendar-date
validation only to the date field in services/ontology/schemas/sleepSession.json
lines 55-57, preserving the existing schema structure and field formats.

In `@services/ontology/schemas/leanBodyMassObservation.json`:
- Around line 55-57: Reject negative numeric health measurements by adding a
minimum constraint of 0 to value in
services/ontology/schemas/leanBodyMassObservation.json (lines 55-57),
bloodGlucoseObservation.json (lines 55-57), and bodyMassObservation.json (lines
55-57), and to both systolic and diastolic in
services/ontology/schemas/bloodPressureObservation.json (lines 55-60).
- Around line 62-64: Add explicit ISO 8601 date-time validation with offset
support to the measuredAt property in
services/ontology/schemas/leanBodyMassObservation.json (62-64),
services/ontology/schemas/bloodGlucoseObservation.json (62-64),
services/ontology/schemas/bloodPressureObservation.json (65-67), and
services/ontology/schemas/bodyMassObservation.json (62-64), using format
date-time or an equivalent offset-capable pattern while preserving the existing
string type and descriptions.

In `@services/ontology/schemas/sleepSession.json`:
- Around line 52-64: Update the SleepSession schema’s updatedAt, startDate, and
endDate properties to validate ISO 8601 date-time values using the schema’s
date-time format, and apply the same validation to each sleep stage’s start and
end properties. Leave the date-only date property unchanged.

---

Duplicate comments:
In `@services/ontology/schemas/activeEnergySeries.json`:
- Around line 72-81: Update the samples schemas in
services/ontology/schemas/activeEnergySeries.json lines 72-81,
services/ontology/schemas/basalEnergySeries.json lines 72-81,
services/ontology/schemas/cyclingDistanceSeries.json lines 72-81,
services/ontology/schemas/energyIntakeSeries.json lines 72-81, and
services/ontology/schemas/proteinIntakeSeries.json lines 72-81 to require
exactly three positional numeric values representing start, end, and value.
Replace the homogeneous nested items definition with three positional schemas
and set additionalItems to false so two-value tuples and trailing items are
rejected.
- Around line 12-18: Add “device” to the root required list in
services/ontology/schemas/activeEnergySeries.json (12-18),
services/ontology/schemas/basalEnergySeries.json (12-18),
services/ontology/schemas/cyclingDistanceSeries.json (12-18),
services/ontology/schemas/energyIntakeSeries.json (12-18), and
services/ontology/schemas/proteinIntakeSeries.json (12-18), while preserving
each schema’s existing nullable device definition.

In `@services/ontology/schemas/biologicalSexFact.json`:
- Around line 55-60: Update the value schema for biological-sex facts to remove
the boolean type and retain only strings. Constrain the string branch to the
ontology’s agreed controlled vocabulary using the schema’s enum or equivalent
vocabulary mechanism.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6fdcd61f-44db-4f07-a780-598ca4f3ba88

📥 Commits

Reviewing files that changed from the base of the PR and between c826c81 and af98b4f.

📒 Files selected for processing (45)
  • services/ontology/schemas/activeEnergySeries.json
  • services/ontology/schemas/basalEnergySeries.json
  • services/ontology/schemas/biologicalSexFact.json
  • services/ontology/schemas/bloodGlucoseObservation.json
  • services/ontology/schemas/bloodPressureObservation.json
  • services/ontology/schemas/bloodTypeFact.json
  • services/ontology/schemas/bodyFatPercentageObservation.json
  • services/ontology/schemas/bodyMassObservation.json
  • services/ontology/schemas/bodyTemperatureObservation.json
  • services/ontology/schemas/carbohydrateIntakeSeries.json
  • services/ontology/schemas/cyclingDistanceSeries.json
  • services/ontology/schemas/dailyActivitySummary.json
  • services/ontology/schemas/device.json
  • services/ontology/schemas/deviceLink.json
  • services/ontology/schemas/energyIntakeSeries.json
  • services/ontology/schemas/environmentalAudioSeries.json
  • services/ontology/schemas/exerciseMinutesSeries.json
  • services/ontology/schemas/fatIntakeSeries.json
  • services/ontology/schemas/flightsClimbedSeries.json
  • services/ontology/schemas/headphoneAudioSeries.json
  • services/ontology/schemas/healthPhoto.json
  • services/ontology/schemas/heartRateSeries.json
  • services/ontology/schemas/heartRateVariabilitySeries.json
  • services/ontology/schemas/heightObservation.json
  • services/ontology/schemas/leanBodyMassObservation.json
  • services/ontology/schemas/meal.json
  • services/ontology/schemas/oxygenSaturationSeries.json
  • services/ontology/schemas/proteinIntakeSeries.json
  • services/ontology/schemas/respiratoryRateSeries.json
  • services/ontology/schemas/restingHeartRateObservation.json
  • services/ontology/schemas/skinTypeFact.json
  • services/ontology/schemas/sleepSession.json
  • services/ontology/schemas/standMinutesSeries.json
  • services/ontology/schemas/stepLengthSeries.json
  • services/ontology/schemas/stepSeries.json
  • services/ontology/schemas/vo2MaxObservation.json
  • services/ontology/schemas/walkingAsymmetrySeries.json
  • services/ontology/schemas/walkingDoubleSupportSeries.json
  • services/ontology/schemas/walkingHeartRateObservation.json
  • services/ontology/schemas/walkingRunningDistanceSeries.json
  • services/ontology/schemas/walkingSpeedSeries.json
  • services/ontology/schemas/waterIntakeSeries.json
  • services/ontology/schemas/wheelchairUseFact.json
  • services/ontology/schemas/workout.json
  • services/ontology/schemas/wristTemperatureSeries.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • services/ontology/schemas/bodyFatPercentageObservation.json
  • services/ontology/schemas/bloodTypeFact.json

Comment on lines +26 to +29
"platform": {
"type": "string",
"description": "w3id (@eName) of the platform that wrote this envelope — machine-readable authorship; resolve it to read that platform's self-description"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
fd -a '.*\.json$' services/ontology/schemas | sort | sed 's#^\./##' | rg 'dailyActivitySummary|healthPhoto|meal|workout' || true

echo "== target snippets =="
for f in services/ontology/schemas/dailyActivitySummary.json services/ontology/schemas/healthPhoto.json services/ontology/schemas/meal.json services/ontology/schemas/workout.json; do
  echo "--- $f"
  sed -n '1,80p' "$f" | cat -n
done

echo "== identifier constraints in ontology schemas =="
rg -n 'pattern|`@eName`|w3id|format|uri|url|schema|envelope|platform|origin|provenance' services/ontology/schemas -C 2 || true

echo "== repository identifier validation references =="
rg -n '`@eName`|w3id|platform|provenance|format' . -g '!node_modules' -g '!dist' -g '!build' -C 1 | head -200 || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 50394


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
fd -a '.*\.json$' services/ontology/schemas | sort | sed 's#^\./##' | rg 'dailyActivitySummary|healthPhoto|meal|workout' || true

echo "== target snippets =="
for f in services/ontology/schemas/dailyActivitySummary.json services/ontology/schemas/healthPhoto.json services/ontology/schemas/meal.json services/ontology/schemas/workout.json; do
  echo "--- $f"
  sed -n '1,80p' "$f" | cat -n
done

echo "== identifier constraints in ontology schemas =="
rg -n 'pattern|`@eName`|w3id|format|uri|url|schema|envelope|platform|origin|provenance' services/ontology/schemas -C 2 || true

echo "== repository identifier validation references =="
rg -n '(`@eName`|w3id|platform|provenance)' . -g '!node_modules' -g '!dist' -g '!build' -C 1 | head -200 || true

Repository: MetaState-Prototype-Project/prototype

Length of output: 50394


Constrain provenance.platform to a canonical identifier.

These schemas describe platform as a resolvable w3id/@ename, but the field only accepts any string. Add the same identifier-pattern constraint to each instance:

  • services/ontology/schemas/dailyActivitySummary.json
  • services/ontology/schemas/healthPhoto.json
  • services/ontology/schemas/meal.json
  • services/ontology/schemas/workout.json
📍 Affects 4 files
  • services/ontology/schemas/dailyActivitySummary.json#L26-L29 (this comment)
  • services/ontology/schemas/healthPhoto.json#L26-L29
  • services/ontology/schemas/meal.json#L26-L29
  • services/ontology/schemas/workout.json#L26-L29
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/dailyActivitySummary.json` around lines 26 - 29,
Constrain the provenance.platform string using the existing canonical
w3id/@eName identifier pattern in
services/ontology/schemas/dailyActivitySummary.json (26-29),
services/ontology/schemas/healthPhoto.json (26-29),
services/ontology/schemas/meal.json (26-29), and
services/ontology/schemas/workout.json (26-29). Apply the same pattern
consistently to each platform property while preserving its current type and
description.

Comment on lines +51 to +53
"registeredBy": {
"type": "string",
"description": "w3id of the platform that provisioned this device vault"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Enforce platform provenance consistently across both device schemas.

Both schemas accept records without registeredBy, despite the PR objective requiring machine-readable platform provenance.

  • services/ontology/schemas/device.json#L51-L53: add registeredBy to the schema’s required array.
  • services/ontology/schemas/deviceLink.json#L21-L23: add registeredBy to the schema’s required array.
📍 Affects 2 files
  • services/ontology/schemas/device.json#L51-L53 (this comment)
  • services/ontology/schemas/deviceLink.json#L21-L23
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/device.json` around lines 51 - 53, Add registeredBy
to the required arrays in services/ontology/schemas/device.json (lines 51-53)
and services/ontology/schemas/deviceLink.json (lines 21-23), ensuring both
device schemas require platform provenance while preserving their existing
property definitions.

Comment on lines +26 to +28
"platform": {
"type": "string",
"description": "w3id (@eName) of the platform that wrote this envelope — machine-readable authorship; resolve it to read that platform's self-description"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "Target files:"
for f in \
  services/ontology/schemas/stepLengthSeries.json \
  services/ontology/schemas/stepSeries.json \
  services/ontology/schemas/walkingAsymmetrySeries.json \
  services/ontology/schemas/walkingDoubleSupportSeries.json \
  services/ontology/schemas/walkingRunningDistanceSeries.json \
  services/ontology/schemas/walkingSpeedSeries.json \
  services/ontology/schemas/waterIntakeSeries.json \
  services/ontology/schemas/wristTemperatureSeries.json \
  services/ontology/schemas/carbohydrateIntakeSeries.json
do
  echo "--- $f"
  wc -l "$f"
  sed -n '1,80p' "$f" | cat -n
done

echo
echo "Search for provenance/eName/platform schema patterns:"
rg -n '"provenance"|"platform"|"eName"|"required"' services/ontology/schemas services -g '*.json' | sed -n '1,240p'

echo
echo "List all schema provenance blocks with platforms:"
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('services/ontology/schemas').glob('*.json'):
    try:
        data=json.loads(p.read_text())
    except Exception as e:
        print(f"{p}: INVALID JSON: {e}")
        continue
    props=data.get('properties',{})
    prov=props.get('provenance',{})
    if 'platform' in prov:
        print(f"{p}")
        print(json.dumps({
          "required": prov.get("required"),
          "platform": prov.get("properties",{}).get("platform")
        }, indent=2))
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 48156


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "eName-like validation patterns:"
rg -n '"pattern":|`@-`|eName|@' services/ontology/schemas services -g '*.json' | sed -n '1,320p'

echo
echo "JSON Schema validators/definition files:"
git ls-files | rg -i 'validator|schema|schema-validation|json-schema|required|envelope|schema' | sed -n '1,240p'

echo
echo "Read-only Python JSON Schema invariant check for target 'platform' properties:"
python3 - <<'PY'
import json, pathlib, re, math
for path in sorted(pathlib.Path('services/ontology/schemas').glob('*.json')):
    try:
        with path.open() as f: data=json.load(f)
    except Exception as e:
        print(f"{path}: INVALID JSON: {e}")
        continue
    prov=data.get("properties",{}).get("provenance")
    if not prov or not isinstance(prov, dict): continue
    prop=prov.get("properties",{}).get("platform")
    if prop is None or not isinstance(prop, dict): continue
    ok=False
    why=[]
    try:
        p=prop.get("pattern")
        if p:
            re.compile(p)
            ok=True
        if isinstance(prop.get("const"), str):
            ok=True
        if isinstance(prop.get("enum"), list) and any(isinstance(v, str) for v in prop["enum"]):
            ok=True
        if len(prop.get("type", [])) == 1 and isinstance(prop["type"], str) and prop["type"] == "string" and not prop.get("minLength", 0):
            why.append("bare string")
    except Exception as e:
        ok=False
        why.append(f"bad pattern: {e}")
    print(f"{path}: platform ok={ok}; why={prop}; unresolved_constraints={why}")
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 50393


Constrain provenance.platform to the documented eName contract.

platform is described as a resolvable w3id (@ename), but its schema property is only type: string with no minLength, pattern, or enum. Add the repository canonical eName constraint to each schema and add platform to provenance.required if the provenance contract requires it.

📍 Affects 9 files
  • services/ontology/schemas/stepLengthSeries.json#L26-L28 (this comment)
  • services/ontology/schemas/stepSeries.json#L26-L28
  • services/ontology/schemas/walkingAsymmetrySeries.json#L26-L28
  • services/ontology/schemas/walkingDoubleSupportSeries.json#L26-L28
  • services/ontology/schemas/walkingRunningDistanceSeries.json#L26-L28
  • services/ontology/schemas/walkingSpeedSeries.json#L26-L28
  • services/ontology/schemas/waterIntakeSeries.json#L26-L28
  • services/ontology/schemas/wristTemperatureSeries.json#L26-L28
  • services/ontology/schemas/carbohydrateIntakeSeries.json#L26-L28
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/stepLengthSeries.json` around lines 26 - 28, The
provenance.platform property in services/ontology/schemas/stepLengthSeries.json,
stepSeries.json, walkingAsymmetrySeries.json, walkingDoubleSupportSeries.json,
walkingRunningDistanceSeries.json, walkingSpeedSeries.json,
waterIntakeSeries.json, wristTemperatureSeries.json, and
carbohydrateIntakeSeries.json must use the repository’s canonical eName
constraint instead of an unconstrained string; add platform to
provenance.required wherever the provenance contract requires it.

Comment on lines +55 to +64
"value": {
"type": "number"
},
"unit": {
"type": "string",
"const": "mL/kg/min"
},
"measuredAt": {
"type": "string",
"description": "ISO 8601 with offset"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
git ls-files | rg 'services/ontology/schemas/vo2MaxObservation\.json|vo2MaxObservation\.json$' || true

echo "== schema excerpt =="
if [ -f services/ontology/schemas/vo2MaxObservation.json ]; then
  cat -n services/ontology/schemas/vo2MaxObservation.json
fi

echo "== references =="
rg -n "vo2MaxObservation|VO2Max|VO₂|maxObservation|measuredAt|v2 max" services/ontology -S || true

echo "== schema files with constraints =="
python3 - <<'PY'
import json, pathlib
p=pathlib.Path('services/ontology/schemas/vo2MaxObservation.json')
if p.exists():
    data=json.loads(p.read_text())
    props=data.get('properties',{})
    for k,v in props.items():
        print(f'{k}: {v}')
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 6120


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== available JSON validators =="
for cmd in ajv jsonSchema jsonlint; do
  if command -v "$cmd" >/dev/null 2>&1; then
    echo "$cmd: $(command -v "$cmd")"
  else
    echo "$cmd: not found"
  fi
done

python3 - <<'PY'
import json, pathlib
schema=json.loads(pathlib.Path("services/ontology/schemas/vo2MaxObservation.json").read_text())
for name in ("value", "measuredAt"):
    prop=schema["properties"].get(name, {})
    print(f"{name}: type={prop.get('type')}, keys={sorted(prop.keys())}")
PY

# Read-only behavioral probe: validate sample payloads against the schema using any installed JSON Schema CLI/API.
python3 - <<'PY'
import json, pathlib, json, subprocess, sys, tempfile, os
from pathlib import Path

schema_path = Path("services/ontology/schemas/vo2MaxObservation.json")
samples = [
    {"value": -1, "measuredAt": "arbitrary"},
    {"value": 0, "measuredAt": "2024-01-01Z"},
    {"value": 45, "measuredAt": "2024-01-01"},
    {"value": 50, "measuredAt": "2024-01-01T12:00:00+02:00"},
]
# Check common validators without installing repo dependencies.
for spec in [
    ("ajv_cli", ["ajv", "validate", "-s"]),
    ("json-validator-js", ["json-validator-js", "validate"]),
    ("node-ajv-cli", ["ajv-cli", "validate", "-s"]),
]:
    cmd = spec[0]
    args = spec[1]
    try:
        out = subprocess.run(["type", "-p", cmd], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
        print(f"FOUND {cmd}={out.stdout.strip()}")
        break
    except subprocess.CalledProcessError:
        continue
else:
    print("NO_CLI: no common JSON Schema CLI available")
    # Minimal semantic observation from the schema text: properties exist without numerical/string constraints.
PY

Repository: MetaState-Prototype-Project/prototype

Length of output: 871


Constrain VO₂ max values and timestamps.

value is only typed as number, so negative VO₂ max values validate, and measuredAt is only typed as string despite being documented as ISO 8601 with offset. Add a non-negative numeric bound and an ISO date-time constraint for measuredAt.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/ontology/schemas/vo2MaxObservation.json` around lines 55 - 64,
Update the value property in vo2MaxObservation to require a non-negative number
using the appropriate minimum constraint, and update measuredAt to enforce an
ISO 8601 date-time format with offset while preserving its string type and
description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant