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.
5.1 Linkage layer — never merge, always link¶
- 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¶
Registration is an act, recorded by one event type — identity.registration.asserted — carrying the
class below as a discriminant, so the §5.8
precedence rule (the first event carrying a new patient UUID must be a registration) needs no carve-out
for any class. Only Standard carries a search attestation; for the other two a search attestation would
be a claim about an act nobody performed, so it is structurally absent, not empty
(ADR-0061).
| Class | Use | Properties |
|---|---|---|
| Standard | Normal registration | Search-before-create funnel; the act carries the search that preceded it |
| Unidentified | Unconscious/unknown patient ("John Doe") | §5.4; no search — search-after-create by necessity |
| Pseudonymous (sanctioned) | Legally permitted anonymous/protective care | §5.6 |
A non-standard registration states its basis (the value-open reason the class applies); a standard one does not, because there the class is the explanation and a mandatory free-text box would be a required field satisfiable only by fabrication (principle 4).
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 — and, since ADR-0061, the same erasure must reach the registration attestations that name that patient as a displayed candidate, which are demographic-plane and therefore written in the clear (not born-sealed); mechanism concern, recorded here — the sentence a rung-2 implementer actually reads — so the rung-2 implementation cannot honestly miss either surface.)
(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)¶
- Search-before-create funnel: "new patient" unreachable until local-scope matching has run; candidates shown with photo/age/locale/last visit; the create act names the near-matches that were displayed — not merely how many, because six months later the only question that matters is whether this duplicate was on the screen, and "yes" (fix the UI) and "no" (fix the comparator) have opposite fixes a count cannot distinguish (ADR-0061). Finding candidates is advisory — it never blocks, vetoes or auto-decides (a miss is a false split, §5.2's safe direction, backstopped by the hub sweep, ADR-0014); what is safety-critical is that the act carries a well-formed attestation, which is checkable in the database.
Important
The precedence rule is enforced at the LOCAL door only, and that asymmetry is deliberate. The first event carrying a new patient UUID must be a registration is refused unbypassably at submit_event (issue #345, which also retired the legacy unfloored patient.created, so the rule needs no carve-out for any type). The remote apply door never applies it: set-union sync has no ordering, so a peer's clinical event legitimately precedes the registration licensing it, and a fail-closed remote door would wedge replication on honest traffic (ADR-0061 decision 3 — strict-submit / lenient-apply). The rule is self-satisfying afterwards, so a chart seeded by an out-of-order peer event is never refused a later local write; it stays fully readable and findable while its registration is in flight, and a chart with no registration act on file is a queryable, flaggable state (#354), never a hidden one. The lenient remote door does not reopen the bypass, because a client role cannot reach it: the runtime role holds EXECUTE on the local door alone and no INSERT on the event log, so the validated submit surface is the only way a client writes at all (principle 12) — the remote door belongs to the sync daemon, carrying events another node has already accepted.
- Partition-aware duplicate expectation (see §5.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.
- 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 projection's concrete shape (ADR-0063, first built 2026-08-14 as a trailing
EventBody.safetyfield beside a sealedpayload.safetysibling):- The seal boundary IS the coarsening boundary — two tiers, not one. The precise
{class, severity}is computed pre-seal, on the node that had a coding authority in hand, and travels inside the sealed payload under the same DEK as the body it describes; a rung chosen from the then-effective grade travels in the clear on the signed envelope. Every degradation then falls out of the seal rather than needing machinery: a reader with custody but no coding authority has the precise class available under the seal (the class is carried, never re-derived — ADR-0059 decision 4; the shipped read surfaces serve the clear rung, so recovering it is a future reader's query rather than one that exists today), a reader without custody gets the rung, and a crypto-shredded event keeps its rung permanently. Emitting the precise class in the clear was rejected as a leak: for the cases this section exists for, the class is the disclosure. - Three rungs:
{"rung":"precise","class":…,"severity":…}→{"rung":"kind","severity":…}→{"rung":"existence"}, chosen by a monotone non-decreasing map from the ADR-0062 sensitivity rank (routine→precise;sensitive→kind;restricted/sequestered/unrecognised →existence). Keying on rank rather than on the grade string inherits the open vocabulary and the unknown-ranks-MAX rule for free. The middle rung carries nokindfield becauseevent_log.event_typealready publishes the word medication in the clear. The coarsest rung still emits a row — coarseness varies, existence never disappears. - Coarsening binds at emission and is re-applied at read; both are load-bearing, for different reasons. Emission is the only coarsening that binds a peer's raw-SQL client, because it decides what goes on the wire at all. Read is the only answer to a peer that emitted a finer rung than this node's grade licenses — which is legitimate, not hostile, because the grade is node-relative (ADR-0062 decision 9). The effective rung is the coarser of emitted and locally licensed. Neither alone suffices: emission cannot control a peer's bytes, and read cannot un-publish a byte already sent. Consequently a grade raised after authoring cannot claw back an already-replicated rung (ADR-0005's best-effort and declared).
- The floor is at the LOCAL authoring door only, and the read model is total. The structural-vs-ceremony rule would put a shape check at both doors; here the deciding argument is blast radius. A sensitivity assertion is an event, so refusing a malformed one drops one assertion — but the safety signal is a field on a clinical event, so refusing it at the apply door would drop the medication assertion it rides on. A de-identified advisory field must never destroy clinical content (ADR-0060: the system may fail to record an order; it may never cancel one). So the remote door admits verbatim and the read model is total instead: an unrecognised rung reads as
existence, aclassbeside a coarser rung is never surfaced, and an unrecognised severity ranks MAX. The same rule binds one layer up — a half-formed class claim emits no clear signal rather than a malformed one, since a signal the local door would refuse aborts the whole submit. - The class lookup ships empty.
safety_class_map, keyed on the(system, code)pair, ships and stays empty exactly as the sensitivity category blacklist does: Cairn ships the lookup mechanism and never the drug knowledge (principle 9). It is the seam a coding authority populates. - An uncoded medication — and a coding absent from the map — emit nothing at all, not an
existencemarker. There is no class on any node for an uncoded drug, so an existence marker would manufacture a signal from an absence of knowledge and paint a warning across most of most charts on day one — §5.12's alert fatigue, reproduced deliberately. A coding with a class on asequesteredchart does emit{"rung":"existence"}: there the signal exists and is being blurred.
- The seal boundary IS the coarsening boundary — two tiers, not one. The precise
- 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 stream's concrete shape (ADR-0062, first built 2026-08-10 as
sensitivity.grade.asserted/sensitivity.grade-withdrawal.asserted):- An assertion names one subject — an
event, athread, or apatient(the whole chart) — and an event's effective grade is the MAX by rank over standing assertions on all three. Standing = asserted minus withdrawn. Ties break on the assertion'scontent_addressand decide only which assertion is named as the reason. The grade converges under set-union sync with no ordering rule, and inheritance is computed at read, so grading a thread covers events authored before and after the grading, with no backfill. An assertion that cannot be matched to a subject on this chart — an unrecognisedsubject_kind, or apatient/eventsubject naming something not on this chart, including a target event that has not replicated yet — coarsens chart-wide, bounded by the querying event's envelope patient; the not-yet-replicated case is transient and self-resolves when the target lands. - The ladder is
routine(0) →sensitive(10) →restricted(20) →sequestered(30), open-vocabulary, and an UNRECOGNISED grade ranks MAX — deliberately inverting the §3.17 clock-confidence rank's unknown-ranks-0. Absence still ranks 0: no assertion at all isroutine; only an unparseable or unrecognised grade value coarsens. - Declassification is withdraw-by-reference. A withdrawal names the withdrawn assertion's
content_address; that assertion stays in the log, readable and re-assertable. Standing is a set difference evaluated at read, so a withdrawal may arrive before the assertion it withdraws and still take effect when it lands. - Sensitivity assertions are plaintext by necessity (ADR-0052 §2's list): a node must read the grade in order to coarsen, and coarsening is what a node holding no custody must still do. The matched blacklist category never travels on the wire — an assertion carries subject, grade and provenance (
human|advisory) only. - Raising is frictionless; lowering is a ceremony. The ceremony is enforced at the LOCAL authoring door only, and it is three rules: a chart-wide raise must name the chart it is authored on and must carry a rationale, and a withdrawal requires a bound human author (ADR-0053). The remote apply door admits all three ceremony refusals; the withdrawal's non-empty rationale is a separate structural floor, enforced at both doors. The chart-wide naming rule exists because a mis-typed subject fails in two directions at once: the chart it was authored on coarsens (visible), while the chart the author meant to seal silently keeps reading
routine(invisible, and undetectable at read — nothing on that chart ever mentions the assertion). Dismissing an advisory-authored protective tag is a lowering and routes through the same ceremony — ADR-0043's dismissable-by-anyone rule does not reach it. - A protection-REMOVING act takes effect only if an accountable human stands behind it — admit the claim, withhold the power (ADR-0064). A withdrawal is not owner-gated (it is cross-author by design) and the ceremony is local-only, so the apply door admits any structurally well-formed withdrawal — but admission is not effect. A withdrawal counts in the asserted-minus-withdrawn set difference only when it carries authority: either a vouched attestation whose attester resolves to exactly one enrolled human actor, or self-withdrawal by the human who made the assertion (both
actor_ids known, and human — which is what stops an advisory actor stripping its own protective auto-tag, enforcing ADR-0062 decision 6 structurally; that decision is the carve-out from ADR-0043, whose own rule is dismissable-by-anyone). Everything else isunverifiedand moves nothing. Three properties make this safe rather than merely strict: nothing is refused at either door, so the event lands, converges, is readable and is re-assertable and no set forks; only lowering is gated, so a protective act is never impeded; and the verdict is computed at read, so a withdrawal that is inert today because its target has not replicated yet self-heals the moment the target lands. It does not deadlock, because the local door already demands a bound human author for a withdrawal — a locally-authored withdrawal already carries what the attested route asks for, so no new gesture is added, and the remedy for a cross-node one is to attest it, not to re-assert the grade. Authority is consulted at exactly one site per dial — inside the single definition of what still applies — so display coarsening, safety-rung emission, the CLI read path and any future custody dial inherit it structurally rather than by anyone remembering. The bar is a fixed floor, not a deployment threshold: principle 9 governs what is confidential, never whether removing protection must be accountable. Computing the verdict at read cuts both ways, and the second edge is declared rather than hidden: because both routes resolve the actor through the live registry, revoking an actor re-raises every grade they lawfully declassified — safe in direction (protection restored, never removed) but a state change with no author, and whether it is right is an open question, not a settled rule. - This buys accountability, not authorization — the record is the control and the gate is only the forcing function. Authority is "a human this node can hold responsible", never "someone with standing on this chart": that fact fails the locum, the night-cover registrar and the receiving ED, and is replication-relative besides. It is paper's own posture — anyone who can reach the file can open the sealed envelope, and what paper provides is not a lock but an unmistakable record that it was opened. So the residual is made visible by two surfaces, which take the two halves of one rule — flag what cannot self-heal; view what can:
- a withdrawal worklist (a view, always accurate and self-clearing, because authority is computed at read precisely because the answer improves) carrying two rows:
inert— the gate stopped it, and it clears when the target replicates or when any accountable route achieves the same effect; andstranger-attested— the gate let it through, an accountable human lowered a grade on a chart they had no prior presence on at the moment of the strip. The time bound is the decision: without it the flagged actor clears their own row simply by continuing to work on the chart. Chart presence, not node of origin, is the question — a local clinician who is a stranger to the chart is exactly as unaccountable as a remote one, and a self-assertednode_originis not a fact a control may rest on. - a safety-overclaim ledger (a flag, because its condition is a published byte that can never improve) recording an emitted rung finer than the chart's grade licenses. At the local authoring door only, deliberately breaking the clock-grade precedent it copies: locally the node's own grade is authoritative for its own authoring, so a finer rung means the emission path was bypassed; remotely the identical bytes arrive routinely and honestly from an older or differently-custodial peer, so flagging there would accuse honest peers and reproduce §5.12's alert fatigue in the one ledger that must stay trustworthy. A detector must reproduce the emitter's inputs exactly: coarsening is the safe direction when it withholds a disclosure, and the opposite when it coarsens the licensed rung in an overclaim test — there it manufactures false accusations against the system's own correct output, and a ledger of false rows is worse than no ledger.
- a withdrawal worklist (a view, always accurate and self-clearing, because authority is computed at read precisely because the answer improves) carrying two rows:
- Chart-wide grading is expressible, deliberately effortful, and never automatic. It is the only subject that covers threads nobody has opened yet. Three controls and no cap: the rationale requirement; the automatic category lookup cannot express a chart-wide candidate at all; and the read surface always names which subject won.
- The effective grade is node-relative, not a global fact. Thread membership is knowable only with custody, so an unresolvable thread takes a conservative bound — the max over that chart's thread-scoped assertions, when it has any — and gaining custody can therefore lower a displayed grade. The bound is what keeps coarsen-but-survive true after a crypto-shred. It is scoped to
clinical.*and to unrecognised/future event types; types positively known to be thread-free (notes, demographics, identity, registration) contribute nothing.
- An assertion names one subject — an
- Custody narrowing (dial 2) is a ladder, and narrowing changes the cost and the noise of reading — never whether the content can be reached at a node that holds the key or can reach one (ADR-0065, §5.9 part C). Three rungs, with audited break-glass beside every one — it is not a fourth rung: custody follows admission (the default); narrowed to named nodes (the serve door withholds the DEK from a non-holder peer); narrowed to named actors (the in-DB floor gates quiet unseal at a holder node). Withhold the key, never the bytes is unchanged — a non-holder still receives ciphertext and the safety projection. The bound on the invariant is load-bearing: rung 2's glass is local, but a rung-1 break-glass is a network act, so a partitioned non-holder falls to the honest-disclosure branch below and genuinely cannot reach the content — the one place this ladder loses to the paper envelope, which travels inside the file (#498; carried-with-patient custody is the candidate close).
- Node custody is the norm and per-clinician custody the exception, because a blanket per-clinician policy makes ordinary work inside a location impossible — in an emergency department the team reads the chart. This is also what keeps break-glass rare enough to mean anything: at a holder node, reading sensitive content is ordinary work with no ceremony, and the glass breaks only off-ladder. Making break-glass the route for the normal case would be §5.11's confirmation-dialog disease and §5.12's alert fatigue in one gesture.
- The node's own DEK is the keyring and the floor is the glass — no new key material and no escrow tier. A rung-2 break-glass is the in-DB floor admitting an actor and writing its audit row in the same transaction; a rung-1 break-glass is the ADR-0004 acquisition trichotomy already named below. The keyring is local, never a remote provider: one reached over the network fails at 3am under partition, which is an availability failure on the safety path. Consequently custody narrowing and break-glass are not separable — the glass must exist before anything is sealed behind it.
- Custody is an additive field on the sensitivity assertion, not a second event type, so one gesture sets both dials. Two independently-settable dials would be independently forgettable — protection real in the projection and absent at the wire — and would cost two acts against paper's one (principle 3). It also inherits ADR-0064's authority floor for free: widening custody is protection-removing and is expressed as withdraw-by-reference, so it already passes the one site every dial keys on. Custody sets across standing assertions compose by intersection — forced, not chosen, because that free inheritance holds only if adding an assertion can never widen — and an intersection can empty: two honest chart-wide narrowings by clinicians who never met collapse the holder set to nobody, making every read on that chart a break-glass read and destroying the rarity the ladder rests on (#499 — chart-wide narrowing is not buildable until it is decided).
- Custody narrows on an
eventor apatient, never on athread. Thread membership is knowable only with custody, so a custody-less node cannot tell which events a thread-scoped narrowing covers; serving them is a silent leak, and applying the conservative bound instead would make break-glass routine on precisely the nodes that see the patient least. The bound is right for disclosure and wrong for custody — the same asymmetry ADR-0064 found for the overclaim detector, so "conservative" is a property of a direction, not of a value: before reusing a bound, ask what it now drives. Refused at the local authoring door, admitted at the remote one, surfaced on the worklist. - An unparseable
custodyobject holds nobody, and the grade still stands. Failing closed on custody is affordable only because the keyring guarantees reachability — the cost is a loud read, not a lost record — and that guarantee is itself bounded at rung 1 offline (#498), which is exactly where fail-closed stops being cheap. But the assertion is never refused for it at the remote door, becausecustodyis a field on an assertion and refusing it there would destroy the grade with a malformed protection field; locally it is refused, like any malformed body this node's own client mints (ADR-0063's constrained where MINTED, permissive where it ARRIVES). That door split — and the opposite-looking one a bullet above, where a thread-scoped narrowing is refused locally and admitted remotely — turns on retryability, not defectiveness: the author is present to correct a local refusal and absent for a remote one. This is the general rule these doors have implemented four times: refuse at a door only what that door can drop whole — a malformed assertion drops one assertion, a malformed field on a clinical event drops the event carrying it. The question is never how defective the bytes are; it is what else dies with them. - An unrecognised custody shape ranks MAX, as in the sensitivity and safety ladders — but for a different reason, and the difference is load-bearing: there MAX withholds protection, here it withholds only quiet access. The three ladders agree; their arguments do not, and carrying this one's justification into a site where reachability is not guaranteed turns fail-closed into a destroyer of access.
- Per-clinician custody is enforced by the floor, not by cryptography. Per-actor wrapping is available — a clinician's signing key is a passphrase-sealed artifact the node never holds — but against node-level database access it buys noise rather than protection, since that access can break glass regardless, while creating a silent, unrecoverable loss mode: no escrow exists for actor keys (ADR-0026: the signing key is never backed up), so a departed clinician and a dead laptop render content permanently unreadable with no erasure record to say so. An EHR may lose a record deliberately, audibly and by ceremony; never by a forgotten passphrase. Deferred with its threat named, and blocked meanwhile on a reader identity (§5.11), since today's authorship surfaces attribute writes only.
- Declared, not implied: narrowing is forward-looking — nothing un-knows a DEK already fetched, so a rendered holder list would be a precise untruth in the reassuring direction (principle 4) and the list is an enforcement input, never the safety story a clinician is told; and enforcement is schema-generation-local — a node that does not understand the field serves the DEK, which is ADR-0012's two-plane model working as designed. This buys a default and a record, not a lock — the ADR-0064 posture one dial over, and paper's own: the sealed envelope opens for anyone holding the file, and what paper provides is not a lock but an unmistakable record that it was opened.
- 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 onpatient_uuidand 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. Breaking the glass is loud in three directions with different jobs (ADR-0065): location — immediate and in-chart, the torn envelope colleagues see, and the only one that actually restrains, since what deters is not a notification read months later but a trace visible now to the people you work beside — then custodian and patient, both §5.12 discharging obligations rather than fire-and-forget. The notification is itself a disclosure and must be coarsened and patient-channelled accordingly: “sealed content on your record was opened at Clinic A” delivered to a household phone reaches the person the record was sequestered against, with a pointer.
- 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.
-
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).
-
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).
-
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.
-
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.userandevent.authorare 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-asrescues 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 selects — proximity 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 whethersign-asis 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-aware — no-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 anangloand acapeyorkname, 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/016reserves 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).