Skip to content

4. Demographics — Assertion Stream Model

Demographics are matching evidence as much as they are display data. Overwriting them (LWW storage) destroys evidence (maiden names, old phone numbers, prior transliterations). Therefore:

4.1 Demographic assertions

Each change is an immutable assertion event: source S asserts at HLC t that field F of patient P has value V, with provenance class C. Displayed demographics are a projection. Sync is set union, conflict-free.

Provenance ladder: fact-proven (laboratory/scientifically-established truth — a karyotype, a confirmed assay — that can override what an official document merely attests) > document-verified > patient-stated > third-party-stated > clinician-observed > imported/unknown > inferred. Capturing provenance must cost the registrar one tap. The ladder is value-open: an unrecognized provenance term ranks lowest, so it can never displace a known-provenance value (principle 4).

Comparator-profile tag (matcher interpretation provenance). An assertion also carries an optional comparator-profile — the naming/date/address convention under which the value should be interpreted by the matcher (namespace@content-hash, content-addressed so it is globally meaningful with no central registry). It is additive provenance (no day-one reserve; absence = unknown → the matcher degrades to human review), defaults silently from the registering node's locale with a registrar-visible override (the relocation and visitor cases — a tourist injured in the Top End must not be silently tagged with the local Indigenous convention, nor vice-versa), and is per-assertion (one patient may carry differently-tagged names). This is what lets the right comparator travel with the data while the comparator code travels the distribution plane — see identity §5.13, ADR-0014.

4.2 Per-field projection policy

Field Nature Projection rule Conflict across linked records means
Names Multi-valued set (legal, maiden, alias, transliteration) All retained; display = most-recent legal name (recency-first; provenance and origin break ties), falling back to the most-recent name of any use when no legal name exists (ADR-0036) Weak evidence
DOB Stable, precision-aware: (value, precision, basis) Provenance beats recency; verified value locks vs. lower provenance Strong evidence against link
Sex / gender Three fields: sex-at-birth, administrative sex, gender identity Sex-at-birth provenance-locked; administrative sex provenance-first (document-anchored marker; recency wins among equal provenance) (ADR-0037); gender identity patient-stated authoritative, recency wins Sex-at-birth conflict: strong evidence against link
Identifiers (national ID, insurance, program IDs) Multi-valued set keyed by issuing system; representation per §4.4 Set union, never LWW Same-system different-value = very strong evidence against link (a hard veto; keys on the §4.4 normalized form, degrades honestly)
Phone Volatile Recency (HLC) wins; history retained Nearly meaningless
Address Multi-valued, volatile, use-scoped (§4.3) Per use: displayed current = most-recent assertion within the use (recency-first — addresses are volatile; provenance/origin break ties; ADR-0038); full history retained; supersession is an explicit assertion, never an overwrite Weak evidence (culture-aware via the profile comparator; tight geo or exact structured match is mild positive evidence, weighted by accuracy_m)
Deceased status Safety-asymmetric Sets easily, never auto-clears; reversal = explicit human event Strong evidence against link
Photo Optional; powerful in low-ID settings Append-only gallery, newest displayed Human-reviewable evidence

Notes: - DOB precision is first-class ("age about 40, recorded 2026-06"). Default 01-01 birthdays are down-weighted by the matcher (overrepresented in low-resource registries). - Conflicting "corrections" at equal provenance during a partition are not auto-resolved: project prior stable value, flag for human review. Rule: recency resolves volatile fields; humans resolve identity-bearing fields. - Names are recency-first (not provenance-locked like DOB): names legitimately change (marriage, transition), so the current name the patient goes by displays; the old name is retained as evidence. A verified document does not pin a stale name or a deadname (ADR-0036). - Sex-at-birth is the sex assigned/observed at birth; a karyotype (chromosomal sex) is a distinct fact with its own field, never asserted as a sex-at-birth value (the AIS/Swyer case records two facts, not one overwriting the other) (ADR-0037).

4.3 Address: the three-facet value

Demographic shape varies by nation, legislation, and culture; the infrastructure must carry any address representation while the UI localises presentation (ADR-0032, principle 12). An address is a §4.1 assertion whose value has three facets, only the first mandatory:

  • display (mandatory) — the complete human-readable address, the value-core of the §4.5 demographic legibility twin for an address (principle 11); always sufficient alone. It is derived from the structured parts by the profile's formatter when they are present (so it cannot drift), authored verbatim when they are absent, and materialised into the signed event at authoring time so a node lacking the profile still has correct display text (re-derivation/verification needs the profile).
  • geo (optional) — a first-class geolocation (lat, lon, accuracy_m, basis), precision-aware (principle 4 in space): accuracy_m is the honest uncertainty radius (GPS ±10 m, village centroid ±2 km), basis its provenance (device_gps / map_pin / geocoded_from_text / region_centroid / declared). The culture-neutral universal locator, frequently the only viable address in informal-settlement, refugee, disaster, and remote contexts. Geocoding is advisory and off the wire — turning text into a point is a new geocoded_from_text assertion, never a mutation.
  • structured (optional) — an open ordered bag of named parts plus a content-addressed locale profile (namespace@hash). The profile defines the parts, their order, the formatter, advisory validators, and the §5.13 matcher comparator — one locale bundle carries all of these. The profile reference rides the assertion as data; the profile code travels the §7.6 distribution plane.

No canonical part names; values opaque to the core. parts keys are interpreted by the profile, never by Cairn core; country is a part, not a privileged column (stateless / disputed-territory / cross-border cases). Validation is advisory — per-profile validators flag for human review, never reject (principle 4); the in-DB floor enforces only the culture-neutral structural invariants (display non-empty; structuredprofile present; parts are text) and never holds a profile (principle 12).

Multi-valued, use-scoped. A patient holds a set of addresses; each assertion carries an optional use from a recommended-but-open vocabulary (residential, postal, temporary, work, …) — recommended so the common case interoperates, open so it cannot become capture. Multiple scripts/transliterations are multiple assertions, each with its own profile+display.

Honest degradation. A node lacking a record's profile still shows display and uses geo; parts render as opaque labelled strings (never reinterpreted under a substitute profile); matching degrades to human review. Cross-facet consistency (display == formatter(parts)) is an advisory verification by profile-holding nodes, not a floor gate — keeping the floor culture-neutral (ADR-0032). Confidentiality (refuge addresses, geo especially) is ADR-0006 key-custody + safety-projection; a clinic that requires structured entry enforces it as soft UI policy (ADR-0021), never on the wire.

Display-winner: per-use recency-first. A patient holds one current address per use (residential, postal, work are independently current). Within a use the newest assertion wins (recency-first — addresses are volatile; a fresh patient-stated move must displace a stale document-verified address, the same reasoning names follow and the inverse of DOB's provenance-lock), with provenance then origin as deterministic tiebreaks. All addresses are retained as matching evidence; the UI surfaces past/other-use addresses from the retained set (ADR-0038).

4.4 Identifiers: representation

Demographics §4.2 settles the projection policy for patient identifiers (set union, never LWW; same-system different-value is a hard veto). This section settles their representation — and it diverges from the §4.3 address model in one load-bearing way: address matching is advisory; identifier matching carries a hard veto, so "same system" must be determinable independently of validator version, and the veto must never mis-fire on a node that lacks a validator (ADR-0033, principle 12).

Note

The patient's external identifier here is distinct from the system's own canonical identifier (UUIDv7 + multihash, ADR-0031). This section says "normalized form" for the matching key, never "canonical".

An identifier is a §4.1 assertion whose value has these facets, only the first two mandatory:

  • value (mandatory) — the as-entered identifier string; the evidence facet and the value-core of the §4.5 demographic legibility twin for an identifier (principle 1), always sufficient alone, never destroyed or rewritten (maiden insurance numbers, old transcriptions stay as matching evidence).
  • system (mandatory) — the stable content-addressed namespace the hard veto keys on (nhs-number, medicare-au), globally meaningful with no central registry. May be an explicit unknown sentinel (a number copied off an unrecognised card — principle 4: still recordable, weak evidence only, never a veto).
  • normalized (optional, materialised at authoring when the profile is present) — the profile's normalized form of value (separators stripped, case/grouping canonicalised): the matching key. Materialising it into the signed event is the identifier analogue of §4.3 materialising display — a node lacking the profile code can still veto-match correctly on it instead of mis-firing on formatting noise.
  • profile (optional)namespace@hash, the versioned validator bundle (format + checksum + normalizer + matching comparator), riding the §7.6 distribution plane. Needed to re-derive/verify normalized and to run advisory validation; evolves independently of system — the split that lets the veto key on stable identity while validators version freely. Reuses the ADR-0014 profile-bundle machinery.
  • use/type (optional) — a recommended-but-open vocabulary (national-id, insurance, program, mrn): recommended so the common case interoperates, open so it cannot become capture.

Matching & honest degradation (safety-critical). Per identity §5.2, same system, different value is a hard veto that forces a human decision, never an auto-link and never an auto-reject. "Different value" means different normalized forms, not different value strings — 9434765919 and 943 476 5919 are the same identifier and raise no veto. A node decides "same vs different value" only on a basis it can trust:

  • both assertions carry a materialised normalized form → it compares those (works without the profile code; the normal path, and the reason we materialise);
  • a normalized form is absent and this node also lacks the profile to derive one → it may treat string-equal as a positive signal, but must not declare a same-system mismatch from string inequality (the difference may be pure formatting) — it holds for human review rather than firing the veto or demoting an existing link.

This is the identifier analogue of §4.3's "never reinterpret parts under a substitute profile": a node never fires a hard veto on a basis it cannot trust. system: unknown never participates in the veto.

Advisory validation; culture-neutral floor. Per-profile validators (checksum, length, format) flag for human review, never reject (principle 4) — a Medicare number off a faded card with a bad check digit, a malformed-but-real legacy ID, a number a dying patient half-recalls must all be recordable. The in-DB floor enforces only the culture-neutral structural invariants (value non-empty text; system present; normalized is text when present; normalized materialised ⇒ profile named) and never holds a profile, never runs a checksum, never rejects on validation (principle 12). Cross-facet verification (normalized == normalizer(value)) is an advisory check by profile-holding nodes, never a floor gate.

Patient vs professional identifiers (the boundary). This section is patient identifiers (subject = the patient). Professional licensure/registration identifiers — AHPRA/GMC/NPI — answer "who is licensed / who may sign?" (subject = the clinician as an actor) and live in the §7.5 actor registry, never conflated with patient identifiers: a person who is both carries patient IDs here and registration numbers there — conflating them would let a patient ID act as a signing credential, or a registration number act as a patient match key. Billing/relational provider numbers (e.g. AU Medicare provider numbers) answer "who/how billed?", are an attribute of an edge (not a per-person fact), and live in §4.6 on the entity/relationship — a provider number is relational (different per practice/location → scoped to person×org). The same licensure value may validly recur in §4.6 as a billing identifier — position, not value, decides the role (ADR-0035).

4.5 The demographic legibility twin

A demographic assertion (§4.1) is an event, so it already carries the mandatory §3.13 signed, mechanically-derived plaintext legibility twin (principle 11, ADR-0034). This section binds demographics to that invariant and adds the two demographic-specific requirements the §4.3 address case discovered, uniformly across every field.

  • The twin renders this demographic fact as profile-independent plaintext — field + human-readable value + use/provenance context. "Address (residential), document-verified: 12 Smith St, Darwin NT 0800, Australia"; "NHS number, document-verified: 943 476 5919"; "Name (legal): 田中 太郎"; "Date of birth (patient-stated): about 1980 (year only)" — imprecise facts (principle 4) render legibly too.
  • Materialised at authoring, profile-independent. The twin never requires the field's profile/schema to render and is carried in the signed event, so a node lacking that profile — or generations of schema behind — still reads the fact. This generalizes §4.3's "materialise display into the signed event at authoring" from one field to all of §4.
  • No exceptions; display/value are named instances. The twin is mandatory on every demographic assertion. §4.3 display and §4.4 value are the value-core the twin wraps for those fields — one twin per assertion, never a second that can drift (§3.15). For a self-legible scalar (a name string, a DOB) the value-core is the value's own plaintext rendering. The uniformity, not the redundancy, is the point: it is what stops a future field shape from silently regressing principle 11.

Forward guarantee. Any future jurisdiction-defined demographic field shape inherits this rule by construction — it cannot be introduced in a form a profile-less node renders as opaque structured noise. This is the demographic analogue of ADR-0012's additive-only schema evolution.

Culture-neutral floor; advisory verification (principle 12). The in-DB floor enforces only the structural invariant — every demographic assertion carries a non-empty plaintext twin — and never validates the twin's content, never holds a profile, never runs a formatter. A profile-holding node may re-derive the twin from the structured value and flag drift (twin == render(value / parts)), advisory only, never a floor gate — the same treatment §4.3 gives display == formatter(parts) and §4.4 gives normalized == normalizer(value).

Legibility is not matching. The twin is for reading, never a matching shortcut. A profile-less node reads the twin but still degrades matching to human review per ADR-0032/ADR-0033 and identity §5.2; the matching keys (normalized, geo, structured parts) stay separate from the twin. Twin readability never upgrades or downgrades a link decision (ADR-0034).

4.6 Entities, relationships, and provider identifiers

§4.4 settled patient-identifier representation and noted that a provider number is relational — different per practice/location — and deferred that model. This section closes it, and in doing so generalises the §4.4 identifier machinery from subject = patient to subject = any entity, plus a reified relationship subject (ADR-0035, principle 12). The provider-number person×location/org case is the worked example; the same shape serves orgs, locations, suppliers, and contracts.

The entity. A first-class append-only entity — canonical-identified (UUIDv7 + multihash, ADR-0031) like a patient or actor, asserted through §4.1. It carries:

  • kind — a recommended-but-open vocabulary (person, organization, location, …); the core never branches on an unknown kind beyond partitioning.
  • a 0:many identifier set — the §4.4 facets verbatim (value / system / normalized / profile / use·type), set-union, append-only, provenance ladder. A person-entity carries provider IDs; a location facility/site IDs; an organisation ABN/registration IDs.
  • the mandatory §4.5 legibility twin; an optional §4.3 address facet (esp. for location/organisation entities).
  • for a person-entity who also signs clinical events, an optional one-way actor_ref to its §7.5 actor-UUID — entity→actor only, conferring no signing authority, absent for suppliers/orgs/locations. A wrong actor_ref is repaired by an append-only overlay (principle 2), never erased.

The relationship (where billing numbers live). A relationship is a reified, directional, typed edge between two entities with its own canonical identity, asserted append-only: from/to (entity-UUIDs) + a recommended-but-open type (practices-at, bills-under, employed-by, supplies, …) + its own 0:many §4.4 identifier set. The AU Medicare provider number is a medicare-provider identifier on the (person practices-at location) edge; a payer that scopes per-billing-entity uses person×organisation, supply uses org×org — the billing mess is absorbed because the edge terminates at any entity. Validity is asserted/superseded/ended through the §5.7/§7.5 append-only algebra shape (assert/supersede/revoke/end), never overwritten: a locum leaving Clinic A ends that relationship, Clinic B untouched, and the §7.7 revocation cascade scopes to exactly that edge.

Subject-kind partitioning (the non-conflation guarantee). Every identifier set is tagged (subject_kind, subject_uuid) with subject_kind ∈ {patient, entity, relationship} (patient = the §4.4 sets). Matching only ever compares identifiers within one partition — the identity §5.2 patient-match pipeline pulls patient and can never see a billing number; provider de-duplication pulls entity, kind=person; the §4.4 hard veto applies within a partition only. A billing/entity identifier never authorizes signing (only §7.5 actor keys sign; actor_ref is one-way). So ADR-0033's non-conflation becomes structural: a billing number cannot act as a patient match key (wrong partition) nor a signing credential (only actors sign), by construction rather than convention.

Position, not value. The partition keys on where an identifier sits, never on its value. The same AHPRA registration string may validly appear at once as a licensure/authority credential on the §7.5 actor (the who-may-sign facet) and as a §4.6 billing identifier — a WorkCover insurance case that requires the treating clinician's AHPRA cited on the claim. This is not conflation: one partition slot serving two roles would be; the same value across two partitions for two purposes is exactly what the model allows. Who signs (actor credential) stays distinct from who/how billed (entity·relationship identifier), even when the number is identical.

Matching, validation, floor — reuse §4.4 within a partition. Identifier matching reuses §4.4 verbatim (hard veto = same system/different normalized, forces a human decision, honest degradation when the profile is absent, system: unknown never vetoes); validators flag-not-reject. Every entity/relationship assertion carries the mandatory §4.5 twin — "Organization: Top End Medical Clinic; ABN 12 345 678 901", "Relationship (practices-at): Dr Smith → Top End Medical Clinic; Medicare provider 2426789A, from 2024-03." The culture-neutral in-DB floor enforces only structural invariants — an entity carries a text kind + non-empty twin; an identifier element obeys the §4.4 rules; a relationship names two existing entity-UUIDs + a type + a non-empty twin; the subject_kind tag is present and immutable (cross-partition comparison structurally impossible) — and never holds a profile, runs a checksum, validates a billing format, branches on an unknown kind/type, or rejects on validation (principle 12). The entity/relationship data is fit-for-purpose; the partition tag, one-way actor_ref, and floor invariants are safety-critical (§9) — they are what prevent conflation.