ADR-0035 — Entities, relationships, and the provider-number relational model¶
Context¶
ADR-0033 / §4.4 settled patient-identifier representation and drew the patient-vs-professional boundary, but deferred one piece it named: a billing/provider number is not a per-person fact. In the systems the maintainer has worked in (AU Medicare the sharpest case) a provider number is issued per (practitioner × practice-location) — one clinician carries a different number at each site they bill from, a third at the hospital. Neither §4.4 (subject = the patient) nor §7.5 (subject = the clinician-as-actor, a per-person identity) has a home for an identifier that is an attribute of an edge between two parties.
Billing is unsystematic within a single country, let alone across them: some payers scope a number to a physical location, some to a billing organisation, some to a contract. Hard-coding "location" or "org" as the relational anchor would repeat the cultural-capture mistake §4.3/§4.4 avoided for addresses and identifiers. The entity/edge shape is a can't-retrofit, day-one decision (as with ADR-0013/ADR-0032), so it is fixed now.
Decision¶
Demographics gains a generalised identifier subject: the §4.4 identifier-set machinery (value/system/normalized/profile/use·type, set-union, append-only, provenance ladder, hard-veto matching) is lifted from subject = patient to subject = any entity, plus a reified relationship subject. Homed as §4.6.
-
Entity — a first-class append-only entity, canonical-identified (ADR-0031) like a patient/actor, asserted through §4.1. It carries an open
kind(person,organization,location, …), a 0:many §4.4 identifier set, the mandatory §4.5 legibility twin, and an optional §4.3 address facet. A person-entity who also signs carries an optional one-wayactor_refto its §7.5 actor-UUID — pointing entity→actor only, conferring no signing authority, absent for orgs/locations/suppliers. -
Relationship — a reified, directional, typed edge between two entities with its own canonical identity, asserted append-only:
from/to(entity-UUIDs) + an opentype(practices-at,bills-under,employed-by,supplies, …) + its own 0:many §4.4 identifier set. This is where the AU Medicare provider number lives — amedicare-provideridentifier on the (personpractices-atlocation) edge; a payer that scopes per-billing-entity uses person×organisation, supply uses org×org. Validity is asserted/superseded/ended through the §5.7/§7.5 append-only algebra shape (assert/supersede/revoke/end), never overwritten; because the edge is reified, ending one affiliation never touches another, and the §7.7 revocation cascade scopes to exactly that edge. -
Subject-kind partitioning — structural non-conflation. Every identifier set is tagged
(subject_kind, subject_uuid),subject_kind ∈ {patient, entity, relationship}. Matching only ever compares identifiers within one partition: the identity §5.2 patient-match pipeline pullspatientand can never see a billing number; the §4.4 hard veto applies within a partition only. A billing/entity identifier never authorizes signing (only §7.5 actor keys sign;actor_refis one-way). So ADR-0033's stated non-conflation becomes enforced — a billing number cannot become a patient match key (wrong partition) nor a signing credential (only actors sign), by construction. -
Position, not value. The invariant 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 and as a §4.6 billing identifier (a WorkCover case requiring the treating clinician's AHPRA cited on the claim). That 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 must allow. Who signs stays distinct from who/how billed, even when the number is identical.
Matching, validation, floor — reuse §4.4 within a partition. Hard veto = same system/different normalized, forces a human decision, honest degradation when the normalizer profile is absent, system: unknown never vetoes; validators flag-not-reject (principle 4). The culture-neutral in-DB floor adds only: an entity has a text kind + non-empty twin; a relationship names two existing entity-UUIDs + a type + non-empty twin; the subject_kind tag is present and immutable (cross-partition comparison structurally impossible). The floor never holds a profile, runs a checksum, validates a billing format, or branches on an unknown kind/type (principle 12).
Safety class (§9): the entity/relationship data is fit-for-purpose (a wrong provider number → a rejected claim, caught immediately — it does not corrupt the record, mis-merge a patient, or leak). The subject_kind partition, the one-way actor_ref, and the append-only floor invariants are safety-critical (in-DB/Rust) — they are what prevent conflation.
Consequences¶
- Easier: any billing-number scoping (person×location, person×org, org×org supply) is expressible with no schema migration (kind + type + system are data); the same entity registry serves suppliers/contracts; per-edge revocation is exact; signing and billing are structurally separate.
- Harder / the bet: a reified-relationship + entity registry is more moving parts than a flat per-person field, and (as in ADR-0014) we bet content-addressed profiles distribute reliably off the clinical plane so cross-node matching of provider/location identifiers degrades honestly rather than mis-firing.
- How we'd know the bet fails: a billing/entity identifier is observed reaching the patient-match pipeline, or an
actor_refis observed granting signing authority (either is a partition-leak correctness bug — the structural guarantee was violated); or relationship-identifier matching produces same-system holds at a rate that swamps human review where profiles have not propagated. - No new founding principle — an application of principles 1/2/4/11/12 reusing ADR-0014's profile machinery and the §5.7/§7.5 algebra; the new
subject_kindtag makes an existing invariant enforced, not a new architectural axis.