---
title: "Data provenance and device accuracy"
description: "Who measured a value, with what instrument, by what method and when, and the strict limit on what an interface may assert about a number it cannot vouch for."
url: "https://opsinjs.pensievelabs.org/health/data-provenance-and-device-accuracy"
source: "https://opsinjs.pensievelabs.org/health/data-provenance-and-device-accuracy.md"
section: "Health"
kind: "health"
evidence: "opinion"
reviewed: "2026-09-02"
reviewer: "design"
aliases: ["provenance", "device accuracy", "who measured", "wearable", "source of data", "self-reported"]
implements: ["source-citation", "disclaimer-note", "relative-time", "value", "result-card", "metric-tile"]
---

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> Nothing is missing from this page. The data simply does not live in
> the prose.

<PageTemplate kind="health" />

## What this means [#what-this-means]

A typical health dashboard gives values of different provenance identical visual
authority. Four tiles showing blood pressure, heart rate, sleep and weight share
a card, a typeface and a place in the layout, while the numbers on them were
produced in four different ways.

The four numbers are four different kinds of object. The blood pressure came
from a validated upper-arm cuff. The heart rate is a wrist optical estimate,
which is far more reliable at rest than it is during movement. The sleep figure
is a model's inference from movement and heart rate rather than a measurement of
sleep at all. The weight was typed in by the reader, from memory, last Thursday.

Four values of different provenance classes, rendered with identical visual
authority, leave the reader no way to tell a measurement from a guess made by an
algorithm about a process it cannot observe. Identical presentation transfers the
credibility of the highest class onto the lowest, so the weight recalled from
memory is read with the standing of the validated cuff.

Provenance determines the weight a reader may place on a value and bounds what
the interface may assert about it, which makes it part of the value rather than
metadata attached to it. The four classes below set that bound, and rule 3 turns
it into a constraint on which values may carry a status.

## The rule [#the-rule]

**Every health value carries its provenance, and what the interface may assert
about a value is bounded by that provenance.**

### The four provenance classes [#the-four-provenance-classes]

The system recognises four classes, listed here in descending order of what the
interface may claim for a value in that class.

| Class                   | Example                                                        | The interface may                                                                                           |
| ----------------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Clinically measured** | Laboratory result, clinic-measured blood pressure              | Compare against an attributed reference range; carry a status                                               |
| **Device measured**     | Validated home cuff, glucose meter, scale                      | Compare against a range where the device's method supports it; carry a status where a clinical rule says so |
| **Device estimated**    | Optical heart rate in motion, sleep stages, energy expenditure | Show as an estimate, show trends; **never** carry a clinical status on its own                              |
| **Self-reported**       | Typed weight, symptom rating, remembered dose                  | Record and display as reported; never present as measured                                                   |

### The ten rules [#the-ten-rules]

No component enforces any of these rules today. The *Enforced by* column names
the catalogue's candidate carrier for the obligation together with its build
state, and is empty where the catalogue holds no candidate.

| #  | Requirement                                                                                                                                                                                                 | Where it must appear                                               | Who keeps it today                             | Enforced by                                                                                             |
| -- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| 1  | Provenance is recorded at capture and travels with the value. It cannot be reconstructed later and it cannot be defaulted.                                                                                  | In the record, from the moment of capture onwards.                 | The caller's data layer.                       |                                                                                                         |
| 2  | Provenance is visible to the reader in plain words: "from your cuff", "estimated by your watch", "you entered this".                                                                                        | At the value, in the same view and in the value's accessible name. | The caller's view code.                        | `SourceCitation` (renders the words beside the value; does not put them in the value's accessible name) |
| 3  | A value's status is bounded by its class. An estimated value may not escalate on its own, and may instead prompt a measurement: "Your watch noticed something unusual. Take a reading with your cuff."      | Wherever a status is assigned to the value.                        | The caller, at the point the status is chosen. |                                                                                                         |
| 4  | Classes are never combined in one figure without saying so. A weekly average combining two measured and five self-reported readings is a different object from an average of seven measurements.            | Beside every aggregate, average or total.                          | The caller's aggregation code.                 |                                                                                                         |
| 5  | The provenance string names the device rather than the brand's marketing. "Your Model X cuff" qualifies; "clinically validated technology" does not.                                                        | In the provenance string itself.                                   | The product's content owner.                   |                                                                                                         |
| 6  | A manufacturer's accuracy claim is never restated as the product's own. A cited claim is attributed and linked. It is never paraphrased into a stronger claim, and a figure is never invented in its place. | Wherever an accuracy figure appears.                               | The product's content owner.                   | `SourceCitation` (renders whatever citation text it is handed; does not check it against the source)    |
| 7  | The interface states what the device does not do. A wrist sensor does not measure blood pressure, and a movement-based sleep model does not measure sleep stages.                                           | Once, at the number the limitation bears on.                       | The product's content owner.                   | `DisclaimerNote` (renders the sentence but checks nothing)                                              |
| 8  | A model output is labelled as a model output, with what it takes as input. See [Risk and statistics](./risk-and-statistics.mdx).                                                                            | At the model's output, wherever it is rendered.                    | The caller's view code.                        |                                                                                                         |
| 9  | Self-reported data is never silently corrected. An implausible entry is queried with the reader rather than overwritten.                                                                                    | At the entry being questioned.                                     | The caller's data layer.                       |                                                                                                         |
| 10 | Exports carry provenance, because a clinician receiving a summary needs to know which numbers are measurements. See [Sharing with a clinician](../patterns/sharing-with-a-clinician.mdx).                   | In the exported document.                                          | The caller's export code.                      |                                                                                                         |

<SafetyCallout severity="attention" evidence="opinion">
  The most common serious provenance failure in consumer health products is an
  estimated value driving an alert: a wrist sensor's reading during exercise
  raising a cardiac alarm, or a movement-based sleep model triggering advice. The
  reading itself is not in error; the estimate is being asked a question it cannot
  answer. Rule 3 bounds a value's status by its class so that an estimate cannot
  escalate on its own.
</SafetyCallout>

## Why (evidence) [#why-evidence]

<ResearchNote evidence="opinion" date="2026-09-02">
  **Opinion.** This page publishes no device accuracy figures, for two reasons.
  Accuracy is method-specific and condition-specific: a sensor that performs well
  at rest on one skin tone and one wrist position may perform materially worse
  under other conditions, and a single headline figure hides exactly the variation
  that matters. Published figures also date quickly, and a stale number copied
  from a design system into a product is a provenance failure of our own. Any
  accuracy claim in your product should come from the manufacturer's current
  documentation or from a study you have read, attributed in place.

  The four-class model is ours, and it is coarse on purpose: a finer taxonomy
  would be more accurate and would not survive contact with a product team. Four
  classes can be assigned correctly by someone who is not an expert, which is the
  property we optimised for.

  The equity dimension is real and is stated here without a figure and without a
  citation: optical sensing depends on light interacting with skin, and
  performance differences across skin tones have been discussed extensively in
  both the research literature and the regulatory conversation. A product team
  relying on optical measurement should put that question to its supplier
  explicitly, and it is a reason to apply rule 7, which requires the interface to
  say what the device does not do.

  What would change our mind: no observation we can presently name would revise
  the structure of the model, and evidence from product teams that
  clinician-entered-but-not-measured values fit none of the four classes would add
  a fifth class to the table above.
</ResearchNote>

## Applying it [#applying-it]

<DoDont>
  <DoDont.Do>
    "128/82 mmHg. From your cuff, this morning at 07:40." The string carries the
    device and the time of capture alongside the value, which places the reading
    in the device-measured class at the moment it is read.
  </DoDont.Do>

  <DoDont.Dont>
    "128/82 mmHg" with the source visible only by tapping through to a detail
    screen. Provenance held behind a tap is absent from the glance and from the
    value's accessible name, which are the two places a reviewer checks for it.
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    "Your watch estimated 7 hours of sleep. It works this out from movement and
    heart rate, so treat it as an estimate rather than an exact measure." The
    string names the estimating device, the inputs the model uses, and the class
    of the figure.
  </DoDont.Do>

  <DoDont.Dont>
    "You had 1 h 12 m of deep sleep." The figure is given to the minute, in the
    words of a measurement, for a sleep stage the device infers from movement and
    heart rate rather than observes.
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    "Your watch noticed a high reading during exercise. Optical readings are less
    reliable when you are moving. Take a reading at rest to check." The message
    names the condition that limits the reading and asks for a measurement in a
    class that may carry a status.
  </DoDont.Do>

  <DoDont.Dont>
    Raise an `urgent` cardiac alert from a wrist optical reading taken mid-run. An
    optical reading taken in motion is device-estimated, and rule 3 places that
    class outside the set that may carry a clinical status on its own.
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    "You entered this on 3 March." The string names the reader as the source and
    the date of entry, and makes no claim that the figure was measured.
  </DoDont.Do>

  <DoDont.Dont>
    Style a typed weight identically to a scale reading. A typed value styled
    identically to a measured one carries no class signal at the point of reading,
    so the self-reported figure is read with the standing of the scale.
  </DoDont.Dont>
</DoDont>

## Components that implement this [#components-that-implement-this]

{/* Generated from `implements`. Do not restate the list by hand. */}

`source-citation` ships for exactly this job: an attributed, dated, linkable
statement of where a number or a claim came from, usable next to a value and
inside a longer explanation. It has not been reviewed, and the four-field
provenance model below is a specification it does not yet enforce.

Of the ids on this page that are built, only `ResultCard` can carry provenance at
all, and it carries it as a free-text footnote rather than as one of the four
classes above, so nothing in the system can act on the class or check that rule 3
was kept. `Value` has no provenance prop, and `MetricTile` fixes
`event="measured"`, which means a device-estimated or self-reported figure routed
through it is announced in the words of a measurement.
[MetricTile](../components/metric-tile.mdx) records that gap on its own page and
in its own file. `RelativeTime`'s five events name the moment a number belongs
to, not where it came from, and `DisclaimerNote` renders a sentence the product
wrote. Rules 1 and 2 are therefore the caller's to keep in its own data layer
today, and the interface will not stop a screen that skips them.

## What this does not cover [#what-this-does-not-cover]

* **Device accuracy figures.** None are published here, for the reasons set out
  under "Why (evidence)" above.
* **Device selection, procurement or regulatory clearance.** These are product
  decisions well outside a design system.
* **Data provenance in the technical sense.** That means lineage, audit trails
  and reproducibility. This page is about what the reader is told.
* **Interoperability standards.** Mapping to a clinical data standard belongs to
  the caller's data layer; the four classes above are a presentation model rather
  than a schema.
* **Freshness and staleness.** These are covered by
  [Uncertainty, staleness and missing data](./uncertainty-and-staleness.mdx).

<Todo>
  Specify the four provenance classes as a shared type, and the prop that
  carries one, across every component that renders a health value, so that rule 3
  can be enforced rather than reviewed, and a figure whose class forbids a status
  cannot be given one by accident.
</Todo>

## Updates to this page [#updates-to-this-page]

<Reviewed />
