Skip to content

5. Identity Subsystem

Important

Never merge — always link; never erase — always overlay. Patient UUIDs are immortal; identity is an append-only stream of link/unlink/reattribute/identify/repudiate/dispute events (§5.7). Every identity error — accidental or deliberate — must be repairable by an auditable event with no data loss.

  • Patient UUIDs are immortal and immutable; clinical events reference their original UUID forever (sole exception: reattribution overlay, §5.5).
  • Identity is an append-only stream of link / unlink assertions with provenance, HLC, confidence.
  • The "person" (golden identity) is a projection: the connected component of the link graph. The unified chart unions the event streams of all member UUIDs.
  • Consequences: merges sync trivially (events union); redundant links are idempotent; unmerge is always possible and clean (split the component; nothing was rewritten).

5.2 Matching pipeline (safety-asymmetric: false merge ≫ worse than false split)

  • Deterministic tier: exact match on a strong identifier → auto-link with provenance.
  • Probabilistic tier: Fellegi–Sunter-style scoring; conservative auto-link threshold; wide middle band raises a "possible duplicate" banner on both charts (surfacing safety content — allergies, active meds — without co-mingling) and queues human reconciliation.
  • Locale-pluggable comparators: phonetic encodings, name structures, nickname/transliteration lexicons, DOB precision handling, address semantics are deployment configuration, not hardcoded — the full extension point (the comparator API, weight configuration, the evaluation harness, and the comparator-profile that travels with the data) is §5.13.
  • Where matching runs follows topology: at registration within local scope (search-before-create); cross-facility at the lowest tier that sees both registrations (typically the hub); link events flow down through normal sync.
  • First-contact discovery (no common ancestor below the nation): a patient new to a region has no tier that has seen both registrations. Cairn does not answer this with a national Master Patient Index (the capture surface principle 7 forbids); instead the replicated essential-state tier puts each person's essential safety snapshot + a blocking-key summary on every federated node, so discovery is a local matcher query — offline, partition-proof, no broadcast of who is being sought. A hit feeds this same pipeline (middle band → human → link), then the full record is acquired lazily (§6.4); no match degrades honestly to "no history available" (§5.4). See ADR-0016.
  • A national/memorable identifier is a deterministic accelerator, never a dependency. Where one exists (e.g. a personnummer), it is a strong deterministic-tier key and the best blocking key in the summary → instant high-confidence links; where it does not (children, dementia, non-residents, the uncommunicative), the fuzzy tiers still work. Cairn uses such an ID but never mandates one, and never depends on the patient carrying or recalling anything.
  • Coherence check (feedback loop): the unified-chart projection continuously validates linked components against the §4.2 conflict column. Contradictions (same-system identifier mismatch, verified-DOB clash, sex-at-birth clash) demote the link to human review and render the chart in under-review trust mode. Every new demographic assertion cheaply re-triggers local matching. The same-system identifier mismatch keys on the §4.4 normalized form and degrades honestly — a node lacking the issuing-system profile holds for human review rather than declaring a mismatch from formatting noise. Matching is subject-kind-partitioned (§4.6): this pipeline compares only patient-subject identifiers, so a provider/billing number (an entity- or relationship-subject identifier) can never act as a patient match key.

Note

The matcher is advisory — it proposes link candidates (Python; see technology.md). Applying the closed event algebra and maintaining its projections is authoritative, in-database logic. The seam between them is the database boundary (language-substrate §9.3–§9.4).

5.3 Registration classes

Class Use Properties
Standard Normal registration Search-before-create enforced funnel
Unidentified Unconscious/unknown patient ("John Doe") §5.4
Pseudonymous (sanctioned) Legally permitted anonymous/protective care §5.6

Registrations created during a partition are tagged and go to the head of the upstream matching queue on reconnect — post-partition reconciliation is a scheduled pipeline stage, not an error state.

5.4 Unidentified registration (John Doe) — baked into the root

  • UUID minted immediately; care proceeds without delay.
  • System-generated callsign (e.g. Unknown-ED-<site>-<date>-A), never plausible fake names; matcher excludes placeholder names from its feature space.
  • Identity evidence captured as clinician-observed assertions: estimated age with basis, observed sex, photo, distinguishing marks, belongings, EMS pickup context — honest data, full matcher features.
  • Identity-pending is an active workflow state: chart renders in unconfirmed trust mode ("no history available; allergies unknown"); matcher re-runs on every new evidence assertion.
  • Resolution = identification event (who, method) + ordinary link assertion if a prior chart exists. On link during an active encounter, the system pushes an alert: "prior history now available — N allergies, M active medications — review now."
  • Partition-safe by construction: registration and care are local; identification may occur at hub tier; the link event syncs down normally.

5.5 Reattribution — one primitive, tiered workflows

The reattribution event — "event set E belongs to UUID-B, not UUID-A" — is an immutable overlay all projections respect (digital strike-through: originals stay in place, excluded from the source chart's projection, visible in its chart-history view). It is event-granular (a single note, observation set, or order can move). Granularity lives in the primitive; risk control lives in the workflow tier:

Tier Use case Conditions (enforced automatically) Adjudication
1 — Self-correction Misfiled documentation: clinician with multiple charts open saves into the wrong one (high-frequency, often ≥ weekly per clinician) Author moves own event(s); within time window (same shift / 24 h, policy-config); destination patient in author's active care context (open/recent encounters) None — one-click "move to correct patient," picker pre-filled with author's open charts. Full audit automatic. Friction target: < 10 seconds, or it competes with copy-paste-and-lose-provenance or with not fixing it at all
2 — Supervised Not the author, window expired, or destination outside care relationship Any Tier-1 condition unmet One second sign-off (records officer / senior clinician)
3 — Forensic Identity theft, disputes (§5.5), adversarial cases Two-person rule; adjudication queue; affected events render under-review on both charts until resolved

Auto-escalation: any event with executed real-world effects (administered medication, performed procedure, transfused product) is barred from Tier 1 and escalates with an incident-workflow flag. Reattribution records documentation truth; it must never paper over a clinical incident.

Contamination cascade (mandatory on reattribution arrival, local or via sync): - Recompute decision support / alerts on both source and destination charts. - Notify every user who viewed or acted on the misfiled content during the exposure window ("a note you read on patient B at 14:32 has been moved to patient A"). Generated locally on each node as the event lands → partition-safe by construction. - Disclosure-scope query as a named feature: exposure window + viewer list is a single query over the append-only audit log (GDPR/HIPAA breach-scoping in seconds, not weeks).

(a) Fabricated persona (deliberate false identity): confession → link assertion to real chart + repudiation events marking false assertions. Repudiated values leave the displayed projection but enter a known-alias pool retained by the matcher (aliases are reused). The fact of presentation under a false name is preserved (medico-legally required). (Erasure note: the alias pool is discoverable matcher state derived from the repudiated assertions — an ADR-0005 rung-2 "deniable" erasure of those assertions must therefore reach the pool's projection too, or the denied name remains findable by anyone who can query the matcher; mechanism concern, recorded here so the rung-2 implementation cannot honestly miss it.)

(b) Identity theft (events on victim's chart): Tier-3 reattribution of the affected encounter(s). Dispute event as the patient/victim-initiated front door ("I was never there in March"), feeding the review queue.

5.6 Pseudonymous (sanctioned) care

  • Covers legally permitted anonymous STI testing, protective aliases (domestic violence), staff treated at their own facility.
  • Deliberately unlinked; flagged internally; later linking is patient-initiated and consent-gated.
  • Link assertions may carry a visibility scope; linking must never silently broaden access. A sequestered episode joins the person's connected component (enabling e.g. interaction checking) without its contents flooding every chart view. Identity linkage and consent scoping intersect at the link event — this is an architectural invariant, not an edge case. The mechanism that makes "interaction checking without flooding the chart" concrete — the safety projection, the graded sensitivity stream, and break-glass — is §5.9.

5.7 Identity event algebra (closed set; all append-only, syncable, auditable)

Event Resolves Adjudication
assert Registration & demographic updates Automatic
link / unlink Duplicates, John Doe identification, confessions Auto above threshold, else human
identify Identity-pending → confirmed Human; method recorded
repudiate Known-false assertions → alias pool Human
reattribute Misfiled documentation; wrong-chart contamination; identity theft Tiered: self-service (author, windowed) / one sign-off / two-person rule (§5.5)
dispute Patient-initiated review Triage to queue

Chart trust states (projection-side contract): confirmed / unconfirmed (identity-pending) / under-review (coherence failure, open dispute, pending reattribution). The chart always tells the clinician how much to trust the identity behind it. Responsibility-state composes into this contract: an event whose authorship is un-vouched (a non-human author with no responsibility-bearing human) renders with an explicit unattested marker — a form of acknowledged uncertainty (principle 4), distinct from wrong (§5.10).

Biometrics: excluded from core (vendor/AGPL minefield; poor offline performance on constrained hardware). Accommodated as one more identifier system in the multi-valued set via a pluggable module. The core must work with names, dates, photos, and human judgment alone.

5.8 Registration & documentation workflow (normative)

  1. Search-before-create enforced funnel: "new patient" unreachable until local-scope matching has run; candidates shown with photo/age/locale/last visit; the create button records that N near-matches were displayed.
  2. Partition-aware duplicate expectation (see §5.3).
  3. Wrong-chart protection at point of care (read side): demographic banner always shows photo + age + provenance-flagged identifiers; cheap "confirm patient" affordances emit verification assertions, raising provenance as a side effect of normal care.
  4. Wrong-chart protection at point of documentation (write side): every input surface carries persistent patient identity (photo, name, age, per-patient color coding consistent across all open windows). Documentation is bound to an explicit armed write-context designed on possession semantics (paper precedent: you physically held one chart; the misfile is a disease of windowing, which abstracted possession away). One chart is "in hand" for writing at a time; picking it up is a single natural gesture; which chart is held is as unmissable as the color of a folder. Cross-window paste of patient-bound content is flagged at paste time. The concrete possession model, its fusion with fast authentication, and the work-salvage primitive are §5.11.

Warning

Confirmation dialogs are explicitly NOT the wrong-chart safety mechanism — they fail the paper-parity test (vision §1.2). Restore the physical affordance (possession: one chart in one hand) instead.

5.9 Sensitivity grade, the safety projection, and break-glass (visibility scope)

Resolves former open question §11.8 — see ADR-0006. Also answers the rung-1 follow-on left open by ADR-0005.

"Scope" had been carrying three independent decisions; a sensitive episode is their collision point. Pulling them apart gives four dials, of which only the last two carry confidentiality:

Dial For a safety-relevant sensitive episode Owned by
1. Replication always on (mandatory; set-union) sync (§6.4, ADR-0004)
2. Decryptability gated; break-glass acquires the key key custody (§3.8, ADR-0005)
3. Body visibility sealed until break-glass visibility scope (§5.6)
4. Safety signal always on, abstracted the safety projection, below
  • Replication is never the confidentiality boundary. A sensitive episode that carries any safety relevance replicates unconditionally; confidentiality lives entirely in dials 2–4, never in withholding the row. You cannot break glass on, nor warn about, content that never arrived — and a maximally-sealed episode still owes a future clinician a signal (a sealed pregnancy termination still implies Rhesus-sensitization the next antenatal clinician must act on). This confirms ADR-0004: sync scope was never permitted to be an access control.
  • The safety projection is a separate, de-identified signal emitted beside a sealed body: coarse safety classes (interaction/allergy class, Rh-sensitizing event, contraindication flags), a severity grade, and a pointer to the sealed event — never the agent, diagnosis, or sensitive scope keys. The classes are a mechanical projection of the body's coded fields (a coded drug's interaction class is a property of the code, not a confidentiality judgment), so it is a normal pre-seal projection step. It replicates in the clear like an allergy — it is the safety floor — and local decision-support fires a warning that names nothing: "⚠ Grade X interaction with confidential content — break glass to view / discuss with the patient / document the decision." This makes the §5.6 promise concrete and is partition-safe (the warning is local, no key needed). Its granularity is a policy-configured disclosure-coarsening ladder (precise class → "confidential medication, severity X""confidential content, break glass") mirroring the §7.1 erasure ladder. Safety-floor invariant: the sensitivity grade controls the projection's coarseness, never its existence — secrecy blurs the safety signal, never extinguishes it.
  • The safety projection outlives the body it protects. When the sealed body is crypto-shredded (rung 3, §3.8 / ADR-0005), the de-identified safety projection coarsens but survives — the Rh-after-termination signal must reach a future antenatal clinician even after the episode itself is erased. It is shreddable only at rung 4 (best-effort oblivion), and its survival is named in the honest-erasure ceiling's declaration (ADR-0005 §5). Coarsen-but-survive is the same safety-floor invariant one axis over: erasure, like secrecy, blurs the signal — extinguishing it takes an explicit rung-4 oblivion, never a side effect (ADR-0052).
  • Sensitivity is a graded, multi-source, append-only assertion stream; the effective grade is a projection (never merge, always overlay, the same shape as the link graph §5.1 and the per-field demographic projection §4.2). Because what is confidential is cultural/regional/personal, Cairn ships only three infrastructure pieces — a deployment-populated category blacklist (coded-category → default grade; whitelisting is impossibly wide), the confidentiality grading system itself, and human editability of tag/grade (patient request: divorce, family dispute; clinician judgment: domestic violence, mental health). How they combine is policy (principle 9): whether a blacklist auto-tag applies silently, requires clinician acceptance, or whether a deployment is manual-only, is a UI-layer policy decision Cairn makes expressible but never enforces. The grade drives the seal rung (dial 2) and the projection coarseness (dial 4). Effective grade is the highest standing assertion; declassification is an authorized overlay, never an erasure (mirroring the §5.5 tiers).
  • The envelope is not automatically safe. Plaintext scope keys (department = sexual-health) can be the whole disclosure, so the semantic scope key is abstractable to an opaque "confidential-episode" routing token (§3.5). This is self-reinforcing: opacifying the key means the sync prefetch predicate can no longer select on it, so replication degrades to "everything for this patient" — exactly the mandatory replication above. Identity/sync still bind on patient_uuid and HLC; only the human-meaningful label is generalized.
  • Break-glass is audited key-use (distinct from key-destruction/erasure), the mirror of the ADR-0004 acquisition trichotomy: key-holder present → local unseal; carried-with-patient (the patient is a key-holder, paper-parity-exact); from sibling/parent on reconnect; or, none reachable → honest disclosure "sealed content exists here; the key is not present on this node" (the warning already fired; only the specifics are unavailable — honest-assembly-state, §6.2). It is an append-only audited access event (§7). The architecture always provides break-glass; whether the UI offers it and what authorization it demands is policy.
  • The essential-safety flag reuses this mechanism, and the confidential-essential case composes with it (ADR-0016). Which items are "essential" (replicated on the §6.7 essential-state tier) cannot be a fixed schema list — the canonical case is a privacy-sensitive, sporadically-taken drug with a lethal interaction the patient will not disclose. "Essential" is therefore the same graded, multi-source, append-only stream as sensitivity (policy default pre-label pack + any accountable contributor may tag; by principle 4, when unsure, err toward essential). An item that is both essential and confidential splits exactly along dials 2–4 above: the de-identified safety projection (interaction class + severity, naming nothing) replicates broadly and is itself the actionable fact, while the identified body stays sealed behind audited break-glass — keeping the patient safe without outing them and without depending on point-of-care disclosure.
  • The safety projection generalizes to version skew, not just confidentiality (ADR-0012, data-model §3.13). A node that cannot parse an event's newer format is in the same position as one that cannot decrypt a sealed body: it owes the clinician the most it safely can. The two collapse into one rendering bounded on two axes — min(what this node can parse, what it is cleared to see) — degrading down a single ladder (rich → generic-descriptor → plaintext twin → this safety projection → partition-honest floor). The safety-floor invariant above (coarseness varies, existence never disappears) is the shared rule; the seal-time projection seam is the same seam as the write-time legibility-twin derivation.

5.10 Authorship and responsibility-state (the consumer side)

Note

Authorship the clinician cannot see is useless. Responsibility-state is surfaced in three layers, the same shape as the sensitivity / safety-projection design (§5.9). The model itself is data-model §3.9 / ADR-0007.

  1. Informational floor (always). The record honestly shows provenance and responsibility-state — "AI-drafted, unattested" vs "attested by Dr X". It never gates, blocks, or forces anything; surfacing it is the job (principle 3 — confirmation dialogs are explicitly not a safety mechanism).

  2. Projected trust signal. Responsibility-state feeds the existing chart/event trust projection (confirmed / unconfirmed / under-review, the projection-side contract above). Un-vouched AI content can render visually distinct, or be held out of certain auto-derived projections until vouched — still never a hard block. "No human vouches for this yet" is acknowledged uncertainty (principle 4): distinct from wrong, from not-yet-reviewed, and from refused. The same projection carries a recall marker when an event's authoring agent was later superseded or revoked ("authored by a model version since found defective", security §7.5) — overlaid, never erased. The same projection carries the registry-dispute state (ADR-0054): an event signed by a key implicated in an unresolved actor-registry conflict attributes to the honest candidate set ("one of Dr X / Dr Y — registry dispute pending") — acknowledged uncertainty, distinct from unknown — and re-derives to the exact author when the dispute is adjudicated; while disputed, registry-granted permissions are withheld but content keeps flowing (sync §6.9).

  3. Expressible policy rung. "Un-vouched suppressing AI output must be attested before it takes effect" is an available policy, never mandatory — tied to the additive-vs-suppressing distinction (data-model §3.9). Cairn ships the rung; the deployment decides (principle 9). How such a rung is expressed — an append-only, authority-gated policy-assertion stream with an effective-policy projection — is security §7.9.

  4. Automation-complacency (the consumer-side blind spot) (ADR-0010). The structural classifier sees an output's direct effect, not its second-order effect on human behaviour: a formally-additive alert (it only raises a flag, hides nothing, is always overridable) can still atrophy the independent human process it was meant to backstop, so its false-negative becomes total — worse than paper, where everyone screened by hand. Two responses, both within existing primitives: a responsible human may ratchet a formally-additive output toward "treat as suppressing" (so reliance pulls it into the accountability regime, data-model §3.9); and Cairn detects the atrophy — when independent human review of a class has collapsed to near-zero (humans now only acknowledge the automated assessment, never assess first, measurable from the §5.12 acknowledgment and §7 audit streams) — and surfaces it as an additive, governance-tier meta-warning ("independent review of X has fallen to near-zero; the automated layer is now a single point of failure"). Being additive, it is safe un-owned and self-consistent; being statistical, it is a population/governance signal (mostly-pull), most honest at a tier with volume — a single workstation cannot tell complacency from a quiet shift.

5.11 Point-of-care identity: possession, fast authentication, and salvage

Resolves former open questions §11.9 (armed write-context) and §11.12 (authentication vs. paper-parity) — see ADR-0008.

§11.9 and §11.12 are one problem: the point-of-care binding of which patient and which clinician to a write. Paper bound both in a single physical situation — you, present, holding one folder, pen in hand — and both bindings were continuously, ambiently visible. Windowing broke the subject binding (the wrong-chart misfile); shared login broke the author binding. Restoring them is one act.

The tension is illusory. "Fast/proximity sessions vs. security posture" is a false trade-off, the same shape ADR-0006 found in "scope" and ADR-0007 in "signature": one word, authentication, carries two jobs at different frequencies — gatekeeping (may this person touch the system? coarse, rare, can be heavy) and attribution (who authored this event? fine, per-write, must be paper-cheap). Deployed EHRs fuse them, dragging gatekeeping cost onto every write; clinicians defeat that with shared logins — so the audit-trail collapse is caused by the parity violation, not traded against it. Make per-write attribution sub-second and the incentive to share evaporates: the security win comes from the parity win.

  • Possession binds (clinician, patient) in one ambient gesture. Exactly one chart is in hand for writing (reading many is free). The write surface carries the patient's colour + persistent photo + name/age as the visual environment — ambient, peripheral, zero cognitive cost, the opposite of a confirmation dialog (a dialog demands a discrete act of attention and habituates to click-through; ambient display is passively absorbed). The arming gesture is cheap in time but high in distinctiveness — the antidote to reflexive click-through: a deliberate, spatially-specific motor act tied to this patient (a band-tap at the bedside, the patient's own token, paper-exact; or a drag into the single in-hand slot at a workstation). It must cost the same cold or warm — re-arming a patient from this morning's batch is as cheap as the patient in front of you.
  • Authentication exists; its three pains are removed. Authentication is infrastructure and must be provided — the point is not to abolish the gate but to strip the three things clinicians actually hate, each a corollary of an existing founding principle, not a new axiom:
  • Never make the user wait if engineering can avoid it (latency limb of paper-parity, principle 3; vision §1.2) — MRU-defaulted selector, type-a-few-chars-and-enter, no spinner, heavy work in the background while the clinician already writes, cache-and-hide not cache-and-clear. Instant re-auth is the precondition that makes presence-driven auto-de-arm parity-legal (auto-lock is only not a regression because the re-arm after it is free).
  • Always a fallback — no dead-ends, no IT dependency (availability + paper-parity, principles 5 + 3) — a resilience ladder badge → password → self-recovery (security-Q / SMS / recovery codes) → audited break-glass, every rung self-service, bottoming out in the existing partition-honest break-glass primitive (§5.9). Recovery is break-glass for the auth layer. (The §7.1 severity-ladder motif recurring a third time.)
  • Never make the user redo work already done (work-preservation — append-only, principle 1, extended to the pre-commit side of the commit boundary; and identity-repair, principle 2, applied to the author) — see salvage, below.
  • Stranded work is salvaged by identity-repair, not a wall. Because session.user and event.author are independently bindable (data-model §3.10) — the load-bearing invariant, and exactly what deployed EHRs lack — a clinician whose draft is stranded in the wrong session resolves it with a trichotomy: sign-as (attribute this note to me, authenticate me as author, session untouched — the default, because forcing a switch makes two people redo work), switch (explicit), or stay. sign-as rescues your own stranded work, requires authenticating as the claimed author (strictly more honest than today's silent-session-author save), and is logged append-only as drafted-in-session-of-A, signed-by-B-via-sign-as. It is the §5 repair philosophy — prevention cannot be complete, therefore repair is first-class, cheap, fast, forensically clean — applied to the authoring act; the backstop for the inevitable imperfection of presence-driven locking. It replaces the three bad real-world hacks (free-text [Dr X:], wrong-author save, lost work).
  • Authorship is note-level. A note is one event with a note-level contributor set (§3.9, ADR-0007 unchanged); authorship of spans within one note is not modelled — it would complicate every note for a rare edge (one author types part, a second finishes and signs). In the dominant salvage case the whole note is the signer's work, so note-level is correct; the rare cross-author case keeps the cheap free-text escape hatch, and where structural truth matters there, authorship (who typed) and attestation (who vouches) already separate (security §7.2).
  • Authorship-confidence is a grade, not a gate (acknowledged uncertainty, principle 4). Where author identity cannot be cheaply established (badge forgotten, two in range, emergency), the system never blocks — it records attested / asserted / unattributed (authored-at-station-X, identity unknown — never a guess) and refines by overlay, composing into the existing chart/event trust projection (§5.7 / §5.10) — no new stream. Passive proximity only narrows candidates; the explicit arming gesture selectsproximity is a hint, not an authority (ADR-0004).
  • Make contention cheap (the software's answer to the workstation shortage, where 2–5 clinicians routinely fight for one station): collapse the per-switch tax to ~0 so a shared station approximates N private ones, restoring the paper desk where several clinicians each held their own folder at once. A station may hold multiple warm, resident, hidden (clinician, patient, draft) contexts, each kept alive by its owner's token and surfaced one-at-a-time by proximity. Bought by the same invariant (the context store is keyed by (author, patient), not by the session); resource-bound, hence policy/hardware-gated.
  • Rhythm-agnostic (live / after-each-patient / batch-much-later / AI-scribed / forced-retrospective are all first-class): bitemporal time absorbs them (§3.6) and the cold = warm arming cost means a late batch is not a degraded mode.
  • The write surface this context arms — how events are authored inside it (the rx!/tx! type-through model, the thin encounter grouping the context's committed events share, and the delete-vs-erase distinction) — is data-model §3.15 / ADR-0020.
  • Mechanism not policy (principle 9), resource-proportional (principle 4). Cairn ships the possession primitive, proximity/token session model, ambient identity display, authorship-confidence grade, patient-bound clipboard payloads, and the session ≠ author + durable-draft invariants. Deployment selects token tech (NFC / BLE / phone / pluggable biometric / plain local credential), which ladder rungs exist, whether unattributed writes are permitted, the de-arm threshold, and whether sign-as is offered. The primitive degrades to no special hardware — a Pi clinic with no badges still gets the on-screen in-hand slot, a local credential, ambient display, singular arming, and no network gate; token hardware enhances possession, never a requirement.

Warning

The (clinician, patient) binding and the authorship stamp are safety-critical (a defect mis-binds the subject or mis-attributes the author) → Rust/in-database trusted surface, alongside the identity algebra (§9); proximity/UI (badge/BLE reading) is fit-for-purpose (a defect shows the wrong name ambiently, caught instantly). The seam — UI proximity event → authoritative authorship stamp — is the one safety-critical path, structurally like the §5.9 seal-time projection seam.

5.12 The notification economy: salience, responsibility-routing, and the acknowledgment floor

Resolves former open question §11.10 — see ADR-0009. Minimal invariants: data-model §3.11.

Several places in this spec already emit notifications — history-arrival (§5.4), the contamination cascade (§5.5), the safety-projection warning (§5.9), responsibility-state (§5.10), and freshness/honest-assembly (§6.2). They are all instances of one model, not bespoke features. The danger is the economy: these signals are safety-critical but additive, and additive signals are what drown when a system pushes everything — the deployed-EHR alert-fatigue catastrophe, which is the same disease as the confirmation-dialog click-through §5.11 designed against: a discrete demand for attention, repeated until reflexively dismissed unread.

  • "Priority" is one word hiding orthogonal dials (the recurring motif: scope ADR-0006, signature ADR-0007, authentication ADR-0008). A notification is salience (intrinsic importance) × acknowledgment requirement (none / soft-seen / hard closed-loop) × addressing (who owns acting on it) × modality (interruptive / ambient / pull-digest) × escalation. The load-bearing split is salience ≠ interruptiveness: a high-salience standing fact (a penicillin allergy) is rendered ambient and always-visible, never re-popped — re-popping it manufactures click-through; a high-urgency transition (a critical result just landed) is interruptive once, then becomes ambient and acknowledged. This generalises the §5.11 finding (ambient/peripheral display is the opposite of a confirmation dialog) from the arming gesture to all surfaced information. The mechanism of alert fatigue is exactly the collapse of these dials into one scale defaulted to interruptive popup.
  • A notification is a projection, not a mailbox. It is a delta — the event stream evaluated against this clinician's own audit-log record of what they have already viewed/acted on (the contamination cascade is the pure case, "a note you read moved"; history-arrival is a delta against the previously-empty state). The audit log already records view/act (it powers the §5.5 disclosure-scope query). So the inbox is a derived projection + an append-only acknowledgment event, never a mutable unread-flag — the same never merge, always overlay shape as the link graph (§5.1), the sensitivity grade, and the trust state. Acknowledgment rides the existing audit stream (§7); no new stream.
  • Noise reduction is suppression, and suppression is accountable (§3.9 / ADR-0007). To cut noise you must hide signal, and hiding is the suppressing act. Demotion / coalescing / digest is additive (the signal still reaches the human, only quieter, batched, or merged — free, safe-by-construction); filtering-out / auto-acknowledge / below-threshold-hiding is suppressing (owned, audited, policy-gated). The line: demotion changes how/when a signal reaches you; suppression decides it never does (or decides on your behalf). A machine-authored notification may only ever raise signal, never lower it; auto-acknowledging a hard-ack class is the silent-falsification line paper-parity excludes (it claims a human closed the loop who did not). Every suppressing rung is an explicit, owned, audited configuration act (principle 9).
  • Salience is set by a triage extension point — mechanism, not policy (ADR-0010). The flood of objectively-normal results is tamed by demotion (priority-lowering — additive: the result still reaches whoever opens the chart), never by hiding. What sets the priority is a pluggable trend-aware classifier: a deterministic rule reads the time series (eGFR 90→70→30 = ALERT; 30→35→38 = TREND IMPROVING — the same latest value, opposite salience), and optional AI oversight adds interpretive context (medication, past history, recent consults). Its output is an authored, additive event with a contributor set — {rule-classifier | AI, graded | triaged} (data-model §3.9 contributory roles) — safe un-owned because additive (it only sets the salience dial; it never hides). Cairn ships the seam and the demotion-can-never-silently-become-a-hide floor; the rules and the model are deployment policy.
  • Responsibility-to-follow-up is a graded, multi-source, append-only overlay; the effective responsible set is a projection. The co-equal inbox is the infrastructure; policy does the prioritisation (a workforce that is largely locum routinely has the ordering doctor gone before the result lands; many sites have no follow-up policy at all; resource-poor remote sites run informally — whoever has time works the queue). A result bears a responsibility tag: the orderer is an intrinsic tag, always prioritised for the telephone callback; policy adds fallback tags and more than one clinician may hold one at once — a critical-results default fallback, the covering doctor for an orderer who has left or is temporarily absent, and a timeout reassignment when the responsible present doctor has not addressed it inside a policy window (they may be busy with something more urgent). The effective responsible set is the highest-standing projection over this overlay — the same shape as the §5.9 sensitivity stream and the §5.1 link graph.
  • Follow-up responsibility is never a visibility gate — the safety floor. A new result is always visible to whoever has just opened the patient; the architecture never withholds. The "orderer must review/release before anyone else sees it" preference — repeatedly observed to cause missed critical results — is expressible only as ambient state ("not yet reviewed by the requesting doctor"); the architecture refuses to enforce withholding from a present clinician. This is the consumer-side mirror of ADR-0006's "replication is never the confidentiality boundary": routing decides who owns acting on and acknowledging a result, never who may see it.
  • Acknowledgment is a single explicit human confirm, recorded as an append-only audit event ({who, when, action-taken?}); never auto-satisfied for the hard-ack class. Closed-loop read-back (repeat-the-value) is a UI/policy layer on top of the confirm. Whose acknowledgment discharges the obligation versus merely records a view is policy.
  • Escalation ladder, never a dead-end (the severity-ladder motif a fourth time — erasure → disclosure-coarsening → auth-resilience → escalation). A hard-ack notification unacknowledged inside its policy window re-routes down the responsible-set projection (orderer → covering → on-call → the patient's current care-context holder, §5.11) and bottoms out in a determinate, reachable human — never a silent drop.
  • Safety floor: filtering changes a notification's modality, never extinguishes a mandatory-ack one — the direct mirror of §5.9's "secrecy blurs the safety signal, never extinguishes it."
  • Partition-honest inbox. The projection is over locally-available events; a trigger may still be on another node, so "all caught up / inbox zero" is never claimed across a partition — acknowledged uncertainty (principle 4) and §6.2 honest-assembly-state for the inbox. The honest ceiling mirrors the erasure ceiling: "to this node's knowledge, you have seen everything relevant."
  • Mostly-pull, selectively-push — the paper-parity-derived default. Paper was almost entirely pull (seen on picking up the chart) plus a few pushes (the critical-value phone call, the allergy sticker); deployed EHRs invert this to everything-push, and paper-parity prescribes the inversion back (vision §1.2).
  • Mechanism not policy (principle 9). Cairn ships the dials, a default class→dial blacklist (which classes are hard-ack / never-filterable — the §5.9 sensitivity-blacklist shape), the responsibility-tag overlay, the timeout-reassignment and escalation primitives, acknowledgment-as-audit-event, and the inbox projection. Policy assigns classes, escalation windows, the fallback tags, whose-ack-discharges, and what is filterable — and may express, but the architecture will never enforce as withholding, an orderer-release gate.

Warning

Floor enforcement is safety-critical — that a hard-ack class cannot be filtered to nonexistence, that a present clinician is never denied sight of a result, and that escalation fires on non-acknowledgment → in-database/Rust trusted surface (§9). Advisory salience-ranking of routine noise and the digest UI are fit-for-purpose. The seam — automated filter → the floor that guarantees a hard-ack notification still escalates — is the one safety-critical path, structurally like the §5.9 seal-time and §5.11 proximity→stamp seams.

5.13 Locale-pluggable comparators (the matcher extension point)

Resolves former open question §11.7 — see ADR-0014. The matcher is advisory (§5.2); these are its plugins, not safety-critical logic.

Hardcoding one culture's name/date/address model is cultural capture — a matcher that assumes given+family order, Soundex, and a reliable Gregorian DOB fails the Top End clinic, the refugee camp, and the Indonesian mononym. Pluggable, locally-evaluable comparators are paper-parity for the registrar in any culture (principle 7 / principle 9). §11.7 is structurally low-stakes — the matcher only proposes (its outputs become ordinary assert/link events through the algebra §5.7), so there is no envelope reserve and no new event stream, and the blast radius is doubly contained: a comparator is only additive advisory evidence into a conservative human-backstopped decision, and "unmerge is always clean" (§5.1) makes even a wrong auto-link reversible.

  • The comparator API contract. A comparator is a pure, field-typed function returning a graded agreement level (exact / nickname- or transliteration-equivalent / phonetic / edit-distance / none — Fellegi–Sunter weighs each differently), not a boolean. Three properties are principle-bearing: uncertainty-awareno-data is never disagreement (§3.7; a missing field contributes zero, never a penalty; precision-tagged values yield partial agreement); provenance-aware — agreement/disagreement weight scales with §4.2 provenance; and it operates over the multi-valued name history set, not the display value — maiden/married switching, changed family names, and aliases match because the append-only set retained them (match if any historical name agrees), comparing role-tagged tokens order-tolerantly (given-name order, given/family swaps, hyphenated-surname order).
  • Comparator identity travels with the data; code travels the distribution plane; a missing comparator degrades to human. A comparator-profile tag rides each demographic assertion as declarative, non-executable provenance (§4.1) — namespace@content-hash, content-addressed so it is globally meaningful with no central registry (the ADR-0013 payoff). It defaults silently from the registering node's locale, with a registrar-visible override (a one-tap convention selector) for relocation and visitor cases (a tourist injured in Cape York must not be silently tagged with the local Indigenous convention, nor vice-versa); it is per-assertion (one patient may carry an anglo and a capeyork name, each tagged). The code/weights travel the security §7.6 distribution plane, never the clinical mesh. When a node lacks a record's tagged comparator — or matches across two profiles — it never forces its local comparator; it surfaces the pair to a human (the §3.13 honest-degradation pattern applied to matching). Safety-preserving by construction: uncertainty about which comparator applies can only withhold an auto-link, never manufacture one — it sits on the safe side of the false-merge ≫ false-split asymmetry automatically.
  • Weight configuration is the locale parameter set; the matcher is a registered actor. The m/u probabilities per field per agreement-level are the deployment's tuning; a comparator+weight bundle is the matcher's version-pinned standing configuration (ADR-0011), so "which links did config v3 propose?" is recall-traceable and a bad rollout is recalled via the §5.5 contamination cascade. The same content-addressed locale bundle also carries the address grammar, formatter, and advisory validators (§4.3, ADR-0032) — a culture is defined once, not as separate comparator and address systems.
  • The evaluation harness and the duplicate-sweep miss-detector. Human-adjudication outcomes (confirmed/rejected links, disputes) are free labeled data; the harness scores precision/recall with the false-merge rate as its own safety-asymmetric metric. The confident-reject blind spot — true matches the live matcher rejected and never surfaced — is closed by a periodic, low-priority, aggressive background re-match sweep at the hub tier that never auto-acts, emits a ranked possible-duplicate worklist, and runs preemptibly, never starving clinical work (the ADR-0013 byte-tier discipline); its yield is the miss-rate/drift metric (the ADR-0010 atrophy-signal pattern). Two existing legs complete it: opportunistic re-match on every new assertion (§5.2/§5.4 — a reject flips as a shared phone/ID/refined-DOB lands; monotonic refinement), and a cheap point-of-care "this might be a duplicate — search & link" affordance (paper-parity gain: the patient who says "I have another file here" is evidence the matcher never had).
  • The safety floor pluggability may not relax. Regardless of plugged comparators: auto-link needs a conservative threshold, the wide middle band goes to humans, and the §5.2 coherence check still demotes contradictions. A small closed set of hard vetoes (same-system identifier mismatch; verified DOB clash; verified sex-at-birth clash; deceased-status conflict — §4.2) forces a human decision — never an auto-link, and never an auto-reject (an auto-reject is itself a silent false split). Err on caution; prompt the user. (Implementation honesty: of the four vetoes, deceased-status is still a stub in the shipped floor — db/016 reserves the slot but evaluates nothing, so today it vetoes nothing. The closed set is spec-final; its fourth member is not yet live.)
  • Federated distribution — GitHub doubles as the registry. Cairn-official vetted signed packs plus community packs, signed and content-addressed so trust is in the signature/hash, not the host; git is mirrorable and sneakernet-cloneable, so GitHub is convenience, never a dependency (no point of capture).

Note

Blast radius: every comparator, the weight-learning, the harness, and the duplicate sweep are fit-for-purpose (Python, advisory — a defect is a bad proposal a human reviews). The conservative threshold, the hard-veto set, the coherence check, and the proposal → identity-algebra apply seam are safety-critical (in-database) — the recurring seam motif (§9).