φ(ai) PHI AI
DocumentationDocs
Repository
On this page — 25 sections

Detailed system documentation

The complete reference for PHI AI — the AI-native platform for protected health data — in one place: what it is, every profile and permission, every screen, every record type in the Data Store, how the assistant works, how the audit trail works, the full architecture with its data flows, the animated flow diagrams, and every programmatic surface. Written to be read by anyone who works in or around the platform, not only engineers. Sections follow the role signed in: parts a role cannot use are not shown.

On this page
Part I — The system: purpose · design principles · identity, roles & permissions · purpose of use · screen-by-screen reference · the Data Store · the assistant in depth · the audit trail · security model · extensibility & model integration · configuration
Part II — Full architecture with data flows: the animated picture · component reference · trust boundaries · cloud architecture · failure modes
Part III — Data flow diagrams: the six journeys, animated and walked through step by step
Part IV — API details: shared conventions · retrieval tools · the model API · route surface · ingestion · export · vendor authentication · error model

1. Purpose and positioning

PHI AI is an AI-native platform for protected health data — designed from first principles for AI as a first-class, governed consumer of the clinical, financial and behavioral-health record. It is not an AI feature bolted onto a records system: the architecture exists because AI reads this data. The role-scoped retrieval tools, the sensitivity segmentation, the purpose-of-use tagging, the hash-chained audit of every model interaction, the invariants and the signature gates are not add-ons around a database — they are the platform, built for the moment a model touches a protected record. EMRs connect to it as data planes: sources records arrive from, targets signed work delivers to.

It does three jobs:

  1. It ingests. Clinical, financial and behavioral-health records arrive from source EMRs — in bulk (whole patient populations over the FHIR Bulk Data API) and in real time (admissions, discharges, lab results and payment remittance on streaming feeds) — and are encrypted, classified for sensitivity, and indexed into the Data Store, where they become AI-ready: every record carries the classification and provenance the gates need before a model may read it.
  2. It answers and drafts. A retrieval-tuned AI assistant (PHI RAG) answers questions from the Data Store with citations, drafts clinical documentation, triages inboxes, abstracts quality measures, and screens cohorts — always inside the asker's role, always on the record.
  3. It governs. Consent gates, sensitivity segmentation, purpose-of-use tracking, signature requirements, export controls and an append-only audit trail make every use of the data visible and every refusal a recorded event — governance designed for AI use of PHI, not retrofitted to it.

Equally important is what the platform is not:

  • It is not a bolt-on. Nothing here was retrofitted onto an existing product: the data model, the gates and the audit chain were designed together, for AI use of protected data, from the first line. Signed clinical documentation still delivers to the EMR, which remains the chart of legal record — a legal reality, not an architectural dependency.
  • It is not autonomous. No generated text enters a chart, and no record leaves the organization, without a human decision. Drafts wait in the signature queue; exports pass consent gates.
  • It is not a medical device. It issues no diagnostic or treatment directive; every answer's basis is independently reviewable through its citations (see Compliance & responsibility).

2. Design principles

Two principles sit above everything else; five more run through every screen and every API in their service.

  1. AI for PHI. The platform exists to put AI at the center of protected health data — not beside it, not bolted on after. Every design decision below is downstream of this one: the AI is a first-class, governed consumer of the record, reaching data through the same gates as people, citing what it reads, and drafting rather than deciding.
  2. Compliance first. Compliance is the core design principle, not a policy layer: the rules live in the shape of the system. Population tools return counts and cannot enumerate; unsigned drafts have no write path; psychotherapy content has no export path; recording waits for the jurisdiction's consent. Where a rule can be structural, it is.
  3. Minimum necessary. Every profile holds an enumerated list of permissions. A screen, record or tool outside that list does not exist for that profile — the navigation does not show it, the route refuses it, and the assistant does not hold the tool. Nothing is reachable "because the database has it."
  4. Nothing silent. Every question asked of the AI, every record it reads, every export, every configuration change, every override and every refusal is appended to a hash-chained audit trail that cannot be quietly edited. When records are withheld from an answer or an export, the withholding is counted and stated, never invisible.
  5. Fail closed, refuse loudly. A gate that cannot decide denies. A run that cannot finish is marked failed, never partially-complete. And a refusal is presented as a first-class outcome — in run histories, on screens, in the audit trail — because a gate that fails closed is the product, not an error condition.
  6. A human signs. AI-drafted documentation is a draft until a licensed person signs it (the signature rule). Population queries return counts, never named lists, on the de-identified plane (the counts-never-lists rule).
  7. Calm surfaces. The interface is designed for people who live in an EMR all day: one identity card, collapsible detail, no autoplaying anything, and a design language where color always means something — orange marks state that demands attention, green marks records arriving, navy marks reading.

3. Identity: profiles, roles and permissions

Access control is two-layered: a profile (a person) holds one or more roles, and each role grants an enumerated set of permissions. Screens and actions check permissions, never roles, so a new role can be composed without touching a single screen.

3.0 Where roles come from — and where they do not

This system is not the source of truth for users or roles, and is not intended to be. It is designed to be governed by your organization's identity source of truth — your identity provider and directory (Entra ID / Okta / LDAP or equivalent), where accounts are created, roles are assigned, access is reviewed, and departures are processed. The platform's job is enforcement, not authority:

  • Identity arrives established. In the recommended deployment the platform trusts an identity your reverse proxy / SSO has already authenticated, or one a SMART-on-FHIR launch carries from the EMR. The platform authenticates nobody in that mode and stores no credential.
  • Role assignments originate upstream. The roles an identity carries are asserted by your identity layer; the platform maps them to its enumerated permissions and enforces them on every route, tool and option set. Change a person's role in your directory and the platform's enforcement follows — there is no separate role store to drift out of sync.
  • Local accounts are a fallback, not the design. The optional local-accounts mode exists for organizations with no identity provider at all; it is off by default, and it is the only configuration in which this platform holds a credential. If you have an IdP, use it.
  • The Control panel's matrix is an enforcement view, not a user directory. It shows what each role can reach so reviews and audits have a live artifact — it is not where people are provisioned, and deliberately has no "create user" button in IdP-governed deployments.
  • Reviews and deprovisioning belong to your source of truth. Access recertification, joiner/mover/leaver processing and emergency revocation all happen in your identity system; the platform reflects the result on the next request. (See Compliance & responsibility — access governance is an organizational duty this software cannot discharge.)

3.1 Profile archetypes

Profiles are composed from roles; the identities behind them come from your identity provider (§3.0). The archetypes below are the working realities the role set is designed around — this demonstration site's persona switcher signs you in as one archetype at a time. It also offers a second group that holds one role each, so every role can be inspected on its own: a composite can never show you a boundary, because its other roles keep filling the gap. Signing in as the auditor alone is how you see that an auditor is not a clinician with extras.The demonstration cast itself is documented with the rest of the synthetic environment in Emulators & non-PHI setup.

ArchetypeRolesWorking reality this models
Treating clinicianClinician Charts in context, the assistant, drafting and signing. No claims detail, no audit access, no psychotherapy notes — treatment does not need them.
Records professionalHealth Information Management, Auditor Release of information, claims, integration monitors, and read access to the audit trail. The person a privacy officer calls first.
AnalystAnalyst Population health and research: cohorts, risk models, quality measures — on the de-identified plane, where no record-level identifier ever renders.
ResearcherResearcher Record-level work across many charts under an IRB or privacy-board approval, with the research purpose stamped on every read. Distinct from the analyst, who counts a population and cannot open a chart, and from the clinician, who opens the chart of the patient in front of them.
Behavioral-health clinicianClinician, Psychotherapy Ordinary chart access plus the psychotherapy store. The only archetype that can open a psychotherapy note.
Operations administratorAdministrator, Auditor, Disposition EMR connections, import/export managers, configuration, retention decisions, audit review. Cannot open a chart — operations does not need one.
System administratorSystem Administrator (wildcard) Every permission, plus the Control panel no other archetype sees. Full control is not exemption: every switch is audited under the operator's name.

3.2 The permission matrix

Twelve permissions exist. The wildcard * (System Administrator only) grants all of them.

PermissionGrantsClinicianHIMAuditorAnalystPsychotherapyAdministratorDisposition
patient:searchFind patients by name or MRN
patient:readOpen charts, labs, documents
assistant:useAsk the AI assistant
claims:readClaims, remittance, prior auth
roi:manageRelease-of-information queue
analytics:queryCohorts & population screens
psychotherapy:readThe psychotherapy store
audit:readRead the audit trail
integration:viewImport/export managers
admin:configEMR configuration, run kickoffs
retention:readRetention & disposition
system:adminThe Control panel
sensitivity:viewSensitive-categories operations screen
report:readData Store inventory & integrity checks
integration:exportExport managers, EMR-connection docs
ingest:writeImport an individual patient from the source EMR
ambient:captureConsent-gated ambient documentation capture

Three deliberate asymmetries are worth noticing, because they carry the security model:

  • Psychotherapy is not a superset. Holding psychotherapy:read grants nothing else. The behavioral-health clinician profile holds Clinician and Psychotherapy; a hypothetical account holding only Psychotherapy could open a psychotherapy note and nothing besides.
  • Auditor is read-only and narrow. The Auditor role holds exactly audit:read. Audit review does not require chart access, so it does not include it.
  • The Administrator cannot open a chart. Operations work — connections, imports, configuration — never requires reading a patient's record, so the Administrator role does not include patient:read. When an Administrator hits a chart URL, the refusal lands in the audit trail like any other.

3.3 Refusal behavior

A request outside the profile's permissions returns HTTP 403 with a page that names the missing permission, and writes an access.denied event carrying the actor and the permission that was missing. Refusals are not exceptions to the audit trail — they are among its most useful entries, because a pattern of denials is how a privacy officer discovers someone probing beyond their role.

4. Purpose of use

Every action that touches a record carries a purpose of use, integrated into the workflow where the action happens. The five purposes mirror HIPAA's permitted-use structure:

PurposeMeaningTypical actor
TreatmentCare of the individual patientClinician, psychotherapist
PaymentBilling, claims, remittance, prior authorizationHIM, revenue cycle
Health care operationsQuality, training, administration, integrationAdministrator, analyst
Patient requestThe patient asked — access, amendment, ROIHIM
LegalSubpoena, court order, counsel reviewHIM, compliance

The purpose is not decorative, and it is deliberately not a session mode — there is no ambient purpose selector, because a purpose of use is an assertion about a specific action, not a state a session sits in. It is asserted where data actually moves: the assistant collects it per question, an ROI request records its purpose at creation and every resolution of that request carries it, signature commits are treatment by definition, operations actions are operations — and where no explicit choice is called for, the default derives from the role doing the work (a clinician's reads assert treatment; records and operations roles assert operations). Every audit event stores the result, which is what lets the organization answer the two questions HIPAA's accounting and minimum-necessary rules keep asking: who touched this record, and under what claimed justification. In the deployable platform the purpose additionally travels as an IAM session tag, so even the cloud permission layer knows why a read is happening.

5. Screen-by-screen reference

5.0 Sticky patient context — the one-patient-per-screen contract

Wrong-chart errors happen when a screen shows one patient while the clinician believes they are working on another. The platform prevents this with a contract enforced by screen class, not by convention:

  • Single-patient screens (chart, claim, imaging study, draft review, release review, prior authorization) synchronize the patient-context strip to the patient they render — the strip can never name a different person than the page below it. Each context move is an audited session.context event.
  • Patient-linked worklists (signature queue, inbox, imaging worklist, claims queues, release requests) show only the in-context patient's items, behind one shared scope banner. Widening to all patients takes an explicit action and is recorded on the audit trail as session.scope_widened.
  • Documents file to their own patient. An ambient visit note attaches to the visit's patient — never to whoever happens to be in context, and never to a stand-in. If that patient cannot be resolved, the platform refuses to draft rather than file to the wrong chart. The ambient encounter list itself is scoped like every other worklist, and opening an encounter moves the context to the visit's patient before anything renders.

Every screen is classified against this contract at build time, a runtime tripwire records any worklist that renders outside it, and the regression suite derives its coverage from the same classification — so a new screen cannot ship unclassified.

5.1 Clinical workspace

ScreenRequiresWhat it does
PHI AI assistantassistant:use The platform's front door: the PHI RAG prompt interface with the running thread, prompt history and saved prompts. Every question is audited; answers carry citations and withholding counts.
Patients & chartspatient:search Search by name or MRN across the population; paginated roster with demographics and payer.
Patient chartpatient:read The storyboard: demographics banner, problems, medications, allergies, encounters, labs with abnormal flags, documents, imaging, claims summary — with a callout stating how many sensitive records were withheld from this view and why. The psychotherapy section renders only for the Psychotherapy role.
Summarizationpatient:read Chart-in-context summarization: what the assistant produces, what it cites, what it refuses to infer.
Inbox triagepatient:read Results and messages ranked by clinical urgency, each ranking traceable to the record that caused it.
Ambient documentationpatient:read The functional ambient pipeline: consent gate (jurisdiction- and modality-aware) → self-hosted ambient listener (registry slot ambient) → speaker-labeled transcript → SOAP draft into the signature queue. Synthetic encounters on this site; no live microphone by design.
Patient instructionspatient:read Discharge and after-visit instructions drafted at a patient-appropriate reading level, from the visit's actual records.
Signature queuepatient:read the signature rule's home: AI drafts wait here for a licensed reviewer to edit and sign. Signing writes signature.committed; nothing advances by default or timeout.

5.2 Revenue & records

ScreenRequiresWhat it does
Claims & billingclaims:read The financial plane: claims with line items, payers, adjudication status, denials and totals across the population.
Claim detailclaims:read A single claim: service lines, CPT codes, billed/allowed/paid amounts, adjudication history.
Prior auth & appealsclaims:read Payer criteria checked against real chart evidence. Each criterion shows the record that satisfies it — or shows the gap. Nothing is inferred to fill a gap.
Documentation gapsclaims:read Coding-support review: where documentation does not support the coded level, shown as evidence, drafted queries awaiting human sign-off.
Release of informationroi:manage The ROI queue: requests with requester, scope and legal basis. Fulfilling or denying writes roi.fulfilled / roi.denied. Requests touching Part 2 content without Part 2 consent cannot be fulfilled.
Sensitive categories The segmentation explainer: which categories exist, how records are classified, what each category's handling rule is. Readable by everyone, because the rules are not secrets.

5.3 Population

ScreenRequiresWhat it does
Cohort builderanalytics:query Condition-based cohort counts on the de-identified plane. Returns numbers, never lists (the counts-never-lists rule); each query writes analytics.query.
No-show riskanalytics:query Appointment no-show modeling: features, calibration, and the fairness constraints the model must satisfy before use.
Scheduling optimizationanalytics:query Template and capacity optimization under fairness constraints — overbooking burdens must not concentrate on protected groups.
Trial pre-screeninganalytics:query Protocol criteria matched against de-identified records; candidate counts go to study staff, identities do not.
Quality measuresclaims:read eCQM abstraction: numerators and denominators computed from the record, each element traceable to its source.
Ingest & mapping QA Terminology mapping quality: unmapped codes, mapping confidence, and the review queue for low-confidence matches.
Imaging worklist & AI readpatient:read Imaging studies with modality, body site and report status; the study viewer's AI imaging read is a genuine vision inference over the frames — the registry's imaging-slot model describes what is visible, measures discrete findings from the acquisition scale, and drafts a structured report into the signature queue. On this site the frames are synthetic phantoms and the read says so.
Data Store The live holdings audit: every table with row counts and date ranges, plus six integrity checks run on load (see §6.4).

5.4 Integration

ScreenRequiresWhat it does
Source & target EMRsadmin:config Connection configuration for the source EMR (records arrive from) and target EMR (records deliver to), with each of the six supported vendors' real seams: auth method, bulk capability, write surface.
Bulk import managerintegration:view FHIR Bulk Data runs: history with per-run status and record counts, the watermark rule, and a live kickoff honoring the vendor's 24-hour window — a second kickoff inside the window is refused and recorded.
Streaming dataintegration:view Inbound feeds (ADT, ORU labs, 835 remittance) with per-partition checkpoints. A gap between checkpoint and latest offset is surfaced loudly, never interpolated.
Bulk export managerintegration:view Outbound bulk: deliveries to the target EMR, HIE contributions, registry submissions, ROI productions. Sensitive-category exclusions counted; Part 2 redisclosure refused without consent; partial exports marked failed.
Streaming exportintegration:view Outbound feeds under acknowledgment discipline: acknowledged vs produced sequence per feed; held means queued and accounted; paused means a governance decision that accumulates rather than leaks.

5.5 System

ScreenRequiresWhat it does
Control panelsystem:admin The System Administrator's seat: the model registry (every model of every kind — LLM, predictive, classifier, optimization, mapper — with bring-your-own registration by provider/model ID or HTTPS endpoint, and an audited registered → enabled → activated lifecycle per capability slot), per-model management panels for the assistant models, live controls (retrieval switch, model kill switch, bulk-hold release, feed pause/resume), a live audit-chain verification, the full user-and-permission matrix, the full editable platform configuration, and the recent administrative-action log.

5.6 Governance

ScreenRequiresWhat it does
Registry & preflight Every AI capability is registered before use; preflight verdicts check a capability's declared scope against what it is about to do.
Fairness screen Subgroup performance for the predictive models: where a model underperforms for a group, the screen shows it rather than averaging it away.
Ambient consent gate Deny-by-default recording consent, keyed on jurisdiction and modality, with visit-level attestation. Every evaluation writes consent.evaluated.
Source attributes Provenance: which source system, which run and which mapping produced each record class.
EMR conformance Per-vendor conformance posture: what each EMR's API actually supports, verified rather than assumed.
Retentionretention:read Retention schedules by record class and the disposition queue — what is due, what holds apply, who decides.
Auditaudit:read The trail itself: filterable events with actor, action, object reference, purpose, and chain position.

6. The Data Store

6.1 Record types

On this demonstration site the Data Store holds a fully synthetic population — no real person's data appears anywhere — with full longitudinal records. Every record class the platform can house is populated:

Record classContentsNotes
PatientsName, MRN, birth date, gender, address, phone, payer, deceased flagNames are cleaned human names, not identifiers — the roster reads like a real one.
EncountersType, period, reason, provider, facilityUp to 25 most recent per patient.
ConditionsDiagnosis, onset/abatement, status, sensitivity classSocial-history noise (employment status, "medication review due") is filtered at ingestion.
MedicationsDrug, status, authored date, sensitivity classDeduplicated to the latest order per drug.
Allergies & immunizationsSubstance/vaccine, dates, status
ProceduresProcedure, date, encounter linkage
ObservationsLabs and vitals on a curated LOINC panel (A1c, lipids, renal function, CBC, blood pressure, BMI…) with abnormal flagsReference-range logic marks abnormals (A1c ≥ 6.5, SBP ≥ 140, …).
DocumentsClinical notes with body text and sensitivity classNotes classified sensitive are withheld from ordinary retrieval with the withholding stated.
Imaging studiesModality, body site, report status
Claims & claim linesPayer, billed/allowed/paid, adjudication status, CPT-coded service linesThe financial plane — in scope by design, queryable by the assistant for claims:read holders.
Psychotherapy notesSession notes, kept in a physically separate tableSee §6.3. Never exported, never in ordinary retrieval.
ROI requestsRequester, scope, legal basis, status
Signature draftsAI drafts awaiting signature
PromptsEvery question asked of the assistant, per user, with saved flagsQuestions are stored; answers are not — an answer is regenerated from records, not cached as a shadow chart.
Integration stateBulk runs, stream partitions, bulk exports, stream feeds, configurationThe operational record the integration screens render.
Audit logThe hash chain (see §8)Append-only.

6.2 Sensitivity classification

At ingestion, every condition, medication and document is classified into one of five sensitive categories — or none. Classification is first-match-wins against curated terminology:

CategoryCodeCoversHandling rule
Substance use disordersud_part2 SUD diagnoses and treatment: opioid/alcohol dependence, MAT medications (buprenorphine, methadone, naltrexone), overdose events 42 CFR Part 2: withheld from ordinary retrieval; redisclosure in any export refused without Part 2-specific consent.
Mental healthmental_health Psychiatric diagnoses (depression, anxiety, PTSD, bipolar) and psychotropic medications (SSRIs, benzodiazepines…) Withheld from ordinary retrieval with counts stated; visible to treating roles where permitted.
Reproductive healthreproductive Pregnancy, contraception, fertility care Withheld from ordinary retrieval; state shield laws may impose stricter export rules.
HIVhivHIV status and antiretroviral therapy Withheld; many states require specific consent for disclosure.
GeneticgeneticGenetic tests and screening results Withheld; GINA constrains downstream use.

Two honest limits of the demonstration classifier, stated because a production deployment must do better: it is keyword-driven (a production system uses curated value sets — SNOMED, RxNorm, LOINC — maintained clinically), and first-match-wins means a record in two categories carries its first. The handling pipeline — withhold, count, state, refuse redisclosure — is the part the demonstration reproduces faithfully.

6.3 The psychotherapy store

Psychotherapy notes are not a sensitivity class — they are a separate store. This mirrors HIPAA's own structure, which defines psychotherapy notes as notes "separated from the rest of the individual's medical record" (45 CFR §164.501). Concretely:

  • They live in their own table, never joined into chart queries.
  • Only psychotherapy:read can list or open them, and the assistant requires an explicit minimum-necessary confirmation before disclosing session content even to that role.
  • Every listing writes psychotherapy.list; every read writes psychotherapy.disclosure.
  • No export path includes them. Not bulk, not streaming, not ROI. The export managers count them among the withheld.

6.4 The Data Store audit page

The Data Store screen renders, live on every load: per-table row counts, earliest and latest record dates per class, and six integrity checks — orphaned-reference sweeps, encounter linkage, sensitivity-classification coverage, duplicate detection, the psychotherapy separation invariant, and a full audit-chain verification. A failing check renders as a failure; the page does not average problems away.

7. The assistant (PHI RAG) in depth

7.1 The retrieval contract

PHI RAG is a retrieval-tuned system: the language model never answers about records from memory. The contract, enforced by the system prompt and the tool design together:

  • Answer only from retrieved records. Every factual claim about a patient cites its source in the form [MRN-###### · chart].
  • Never assert absence. The model may not claim a record does not exist or a document does not say something unless it retrieved and read that document. "Not found in what I retrieved" is the honest formulation, and the required one.
  • Confirm before sweeps. A question requiring a population-wide read triggers a minimum-necessary confirmation: the assistant states what it would have to read and asks before reading.
  • State the withholding. When the gate withholds sensitive records from retrieval, the answer says how many and under which rule — the reader knows the answer is incomplete and why.
  • Counts, never lists. On the population plane, the assistant returns cohort sizes, not names (the counts-never-lists rule). A request to enumerate patients with a condition is refused with the invariant named.

7.2 Threads, history and saved prompts

The assistant keeps a per-session thread (the last 12 turns render; the model sees the last 6). Every question is stored per-user in prompt history — questions only, never answers, so history is a workflow convenience rather than a shadow copy of PHI. Any question can be saved for reuse; clicking a history or saved item prefills the ask box and runs nothing until the user presses Ask.

7.3 Degradation ladder

The assistant degrades in defined steps, never silently: live model with retrieval → retrieval disabled (System Administrator switch: the assistant refuses to discuss records at all and says why) → live calls off or key absent (the deterministic scripted fallback answers, labeled as such) → model call failure (the error is stated; the question was already audited; nothing was read). At no rung does it guess.

8. The audit trail

8.1 Event anatomy

Every event is one appended row: at · actor · action · resource_ref · purpose · prev_hash · event_hash. The event_hash is the SHA-256 of the event's content plus the previous event's hash, which chains the log: editing or deleting any historical row changes every hash after it, and the Control panel's verification (which re-derives the entire chain on every load) turns from intact to BROKEN with the first bad row identified.

Object references, never content: the log records that a psychotherapy note was disclosed to its treating clinician for treatment — it does not copy the note. The audit trail must be reviewable by auditors without itself becoming a PHI disclosure surface.

8.2 Event catalog

EventWritten when
ai.queryAny question is asked of the assistant (before any retrieval happens).
phi.searchA patient search runs (screen or assistant tool).
phi.disclosureA chart, lab set, document or claims record is read — by a person or by the assistant on a person's behalf.
psychotherapy.list / psychotherapy.disclosurePsychotherapy sessions are listed / a session note is read.
analytics.queryA population count runs on the de-identified plane.
access.deniedAny refusal: missing permission, missing consent, missing role.
consent.evaluatedThe ambient consent gate renders a verdict.
consent.attestedA visit-level verbal attestation is captured, unlocking all-party-state recording.
ambient.capture_openedAn ambient capture session opens (with a model.inference event naming the listener).
ambient.transcribedA capture's transcript is committed to its recording (with a model.inference event naming the engine that produced it).
signature.committedA human signs a draft (the signature rule's event).
roi.fulfilled / roi.deniedA release-of-information request is resolved.
bulk.completed / bulk.refusedA bulk import run finishes / is refused by the rate-limit window.
export.completed / export.refusedA bulk export delivers / is refused by the consent gate or write surface.
config.changedEMR connection configuration is saved.
system.*Control panel actions: system.rag_on/off, system.assistant_on/off, system.feed_paused/resumed, system.hold_released.

8.3 What the trail is for

Three consumers, three uses: the privacy officer answers a patient's accounting-of-disclosures request from phi.disclosure and roi.* events; the security team reads access.denied patterns and system.* overrides as its detection surface; and the auditor verifies the chain and samples events against source screens. In the deployable platform, concurrent writers can legitimately fork the chain (two processes appending at once); forks are recorded and merge verification handles them — a fork is not tampering, and verification knows the difference.

9. Configuration reference

Runtime configuration lives in the platform configuration store, editable only through audited screens:

KeyMeaningSet from
source_vendor / source_base_url / source_client_id / source_group_id The source EMR connection: vendor, FHIR base, OAuth client, bulk-export groupSource & target EMRs
target_vendor / target_base_url / target_client_id The delivery target for write-back and bulk exportSource & target EMRs
rag_enabledPHI RAG retrieval switch — off means the assistant refuses to read the Data Store and says soControl panel · PHI RAG
assistant_liveLive model calls — off means the scripted fallback answers, labeled as suchControl panel · the active assistant model

10. Security model — the consolidated view

Each control above appears where it operates; this section is the one place they are stated together, layer by layer.

  • At rest. Every stored object is envelope-encrypted before it lands: a per-object data key, wrapped by a organization-managed KMS key that never leaves the key service. Key use is logged by the cloud, so a decryption that bypassed the application would still leave evidence. The psychotherapy store is physically separate with its own access policy.
  • In transit. TLS 1.2+ end to end — EMR↔platform, platform↔storage, platform↔KMS, platform↔model provider — and the storage buckets carry policies that refuse non-TLS requests rather than merely preferring encrypted ones.
  • Identity & session. The application binds localhost and trusts only a reverse-proxy-established identity (your SSO), or SMART launch from the EMR, or — as the fallback — local accounts. Sessions are signed; every mutation requires the session's CSRF token; roles mirror cloud IAM roles so the application layer and the infrastructure layer cannot disagree about who may do what. The platform is not the source of truth for users and roles — your organization's identity system is.
  • AI-specific controls. The model receives excerpts, never a database connection. Tool schemas are generated per role, so an unpermitted capability is absent rather than refused. Temperature 0, bounded output, a six-turn context tail — the model never accumulates unbounded PHI context. Model traffic runs inside your BAA'd cloud account (Bedrock, Vertex AI, Azure AI Foundry) or under a dedicated agreement with whichever vendor's API you call directly. None of these controls depend on which model answers — they are properties of the platform, so changing model vendors changes the answer's author and nothing about what it is allowed to see. Psychotherapy access for the assistant is a separate, default-off switch.
  • Structural refusals. The controls above are not policies asking models or people to behave: population tools return counts and cannot enumerate; unsigned drafts have no write path; psychotherapy content has no export path. The refusal is in the shape of the API, not in a prompt.
  • Monitoring. The hash-chained audit trail is re-verified on every Control panel load; model analytics watch drift and fire alerts that never auto-close; access.denied patterns surface probing. What the platform cannot see — your risk analysis, your BAAs, your workforce training — is enumerated in Compliance & responsibility.

11. Extensibility — frontier models, your models, your features

PHI AI is a highly configurable platform, not a fixed product. Three extension surfaces are part of the core design, and all three are managed — registered, enabled, activated, monitored and audited — through the same Control panel, never through code changes.

11.1 Every major frontier model integrates

The assistant's foundation-model slot is provider-pluggable. Out of the box it speaks three provider surfaces — the Anthropic API, AWS Bedrock and GCP Vertex AI — which between them serve the major frontier families: Claude, Gemini, Llama, Mistral and the rest of each catalog. Beyond the built-in providers, the model registry accepts any model behind an HTTPS endpoint, so Azure AI Foundry in your own tenant, a frontier model reached through your own gateway, an open-weights model you host, or a fine-tune you trained all join the same way — and a model registered that way is not a second-class citizen: it lands in the same slot, under the same audited lifecycle, with the same permissions. Which model is live is a Control panel decision: register it, enable it, activate it into the slot — every step audited — and deactivating falls back to the built-in default rather than to silence. The demo on this site happens to run Claude Sonnet 5; a deployment runs whatever you choose, under your own BAA with your AI provider.

11.2 Bring, build and extend your own models

The registry is not only for language models. Nine model kinds are first-class — foundation, retrieval, deterministic, predictive, classifier, imaging, optimization, mapper, custom — and fifteen capability slots wire them into the product: assistant, claims, prior-auth, coding, ROI, no-show, segmentation, ambient (the self-hosted speech listener), triage, scheduling, ingest, imaging, trials, measures, and other. Activate your own denial-risk model into the claims slot and the Claims & billing screen scores with your model; the built-in core steps aside but stays registered, one click from reinstatement. Every model in a slot automatically inherits the platform's management surface: lifecycle audit events, live performance metrics, drift recognition against the population it serves, and alerting that never closes itself.

11.3 Step by step: bringing your own model — with audit and tracking on

The lifecycle below is the only path a model takes into production, and it is the same for a frontier LLM behind a gateway, a vendor's risk model, and a classifier your own team trained. Following it is what enables PHI AI's required audit and tracking — a model that skips a step simply never serves a slot, so there is no untracked way in.

  1. Prepare the endpoint. Expose the model behind HTTPS (the registry rejects non-TLS endpoints at registration). Decide its capability slot up front — the slot determines which feature it powers and which metrics will watch it. Your endpoint must be stateless with respect to PHI: it receives the request, returns the inference, and retains nothing — the same posture your BAA with the model's provider must cover.
  2. Register it (Control panel → Model registry → Register): name, kind (foundation · retrieval · deterministic · predictive · classifier · imaging · optimization · mapper · custom), slot, provider, model ID, version, endpoint URL, and its stated purpose. Registration writes system.model_registered to the audit trail naming the model — tracking begins before the model serves anything.
  3. Enable it (system.model_enabled). Enabled means eligible, not live: the slot still runs its current model. This is the state for validation against your own data.
  4. Activate it into its slot (system.model_activated, recording the slot). The feature screen switches to your model immediately, and its AI-core banner says so: "activated from the registry." The built-in core steps aside but stays registered — deactivating falls back to it, never to silence. The assistant slot additionally requires kind foundation and a model ID, because that slot is live-wired to the provider API.
  5. Verify the tracking took hold. Open the feature's screen, then the audit trail: every invocation of the slot now writes model.inference naming your model and version (e.g. claims/pending-queue n=25 model=YourRiskModel v2.1). Assistant questions carry model= on their ai.query events the same way. This is not optional instrumentation you add — the platform writes it at every slot invocation, whichever model is active.
  6. Confirm monitoring attached. Model analytics & monitoring computes the slot's performance metrics and population-stability drift for whatever model serves it — your model inherits the watch the moment it activates. Alerts fire on the same thresholds, are acknowledged under a name (model.alert_acknowledged), and never close themselves.
  7. Operate it like everything else. Disable (system.model_disabled) degrades the feature honestly with the switch named on its screen; delete (system.model_removed) requires the model be non-builtin and falls the slot back first. Every state change is an audited event under the operator's name — the model's whole life on the platform is reconstructible from the trail.

What PHI AI requires of you, summarized: a TLS endpoint, a truthful registration (kind, version, purpose), your own BAA with the model's provider for any PHI-reading slot, and validation before activation. What PHI AI guarantees in return: lifecycle audit, per-invocation model.inference attribution, live metrics, drift recognition, and alerting — for every model, built-in or brought, with no additional integration work.

11.4 Extend the features themselves

Features are built against slots and permissions, not against models or roles — which is what makes them extensible. A new feature declares the capability slot it draws from and the permission that gates its screen; the registry, monitoring, refusal and audit machinery attach to it for free. The same pattern governs what already ships: when a System Administrator disables a slot's model, that feature degrades honestly on its own screen with the switch named, and everything else keeps working. Roles compose the same way — screens check permissions, never role names, so your organization's identity system can define new roles without a code change anywhere.

11.5 The configuration surface, in one place

Everything below is live-configurable from the Control panel and the Source & target EMRs screen, and every change writes config.changed (or its own system.* event) under the operator's name:

  • Models: the active model per capability slot, the assistant's live-call and retrieval switches, the answer-length bound, and the full registry lifecycle.
  • Integrations: source and target EMR vendor, base URLs, client IDs, the bulk group, and each outbound feed's paused/healthy state — with independent SSO per side.
  • Deployment shape: the small/large storage profile, retention periods with per-resource-type overrides, and the per-cloud infrastructure variables (all set at deploy time, all documented in Setup & deployment).
  • Identity: proxy SSO, SMART launch, or local accounts — with roles asserted by your identity source of truth.

The regulatory frame for all of the above: Compliance & responsibility. Deployment sizing and infrastructure: Setup & deployment.

Full architecture with data flows

The whole platform on one page — an AI-native architecture, designed from first principles for AI use of protected data: the animated map first, then a component-by-component reference, the trust boundaries, the deployable platform's cloud architecture, and the failure-mode table. Watch the dots: each moving dot is data traveling — green flows are records arriving, navy flows are people and the AI reading under the platform's rules, orange flows are records leaving, and every faint gray thread reports to the audit trail. Hover over any box for a plain-English explanation.

PHI AI — end-to-end architecture (animated)

Records flow from the source EMRs through ingestion into the encrypted Data Store, where sensitive categories are fenced off. People and the AI assistant read through role gates; drafts return to the EMR only with a human signature; exports pass consent gates before anything leaves. Every box reports to the audit trail at the bottom — including the gates' refusals.

1. How to read the picture

  • Nothing skips the gates. There is no path from the Data Store to a person, the AI, or another organization that does not pass a role, consent or signature gate. If you trace any navy or orange arrow backward from its destination, you pass through a gate before you reach the data.
  • The AI is inside the walls. PHI RAG reaches the Data Store only through the same audited, role-scoped tools people use — the model never holds a database connection, and the foundation model (the LLM you bring — Claude Sonnet 5 in this demo) receives only the excerpts the gates released for the current question.
  • The audit trail sees everything. Every arrow that moves data — and every arrow a gate refuses — lands on the hash chain. The trail records references, never content.
  • Green in, orange out. Arrival and departure are different disciplines: arrival is about completeness (watermarks, checkpoints, surfaced gaps), departure is about permission (consent gates, exclusion counts, refusals).

2. Component reference

2.1 Source EMRs

  • Role: data planes into the AI-native platform — Epic, Oracle Health, athenahealth, eClinicalWorks, MEDITECH, NextGen. Records arrive from them; signed documentation delivers back to them (the chart of legal record, as the law requires — the intelligence, governance and AI-ready data model live in this platform).
  • Inputs: signed write-back and configured deliveries.
  • Outputs: bulk extracts and streaming events.
  • Failure mode: vendor unavailability stalls ingestion — runs fail visibly, watermarks hold, and nothing downstream silently ages.

2.2 Bulk import

  • Role: population-scale arrival over the FHIR Bulk Data API.
  • Honors: each vendor's real seams — Epic's one-run-per-24h group export with no incremental mode, NextGen's absence of bulk entirely.
  • Emits: bulk.completed / bulk.refused.
  • Key property: the watermark — the timestamp of the last known-complete extract — advances only on a clean run, so a half-arrived population can never masquerade as the current state.

2.3 Streaming intake

  • Role: real-time arrival — ADT admissions and discharges, ORU lab results, X12 835 remittance — on partitioned feeds.
  • Key property: per-partition acknowledged checkpoints; a gap between checkpoint and latest offset is displayed with its exact range on the Streaming data screen.
  • Deliberate non-feature: gap interpolation. A pipeline that guesses what it missed is a data-integrity incident that has not been discovered yet.

2.4 Encrypt · store · index

Role: the only doorway into the Data Store. Every record — bulk or streamed — is (1) encrypted, (2) classified for sensitivity (sud_part2, mental_health, reproductive, hiv, genetic, or none; psychotherapy content routed to its separate store), (3) normalized (reference resolution, terminology mapping), and (4) indexed for retrieval. Key property: classification happens at the door, not at read time — a record's sensitivity is a stored fact, uniform for every downstream gate.

2.5 The Data Store

  • Role: the encrypted holdings — clinical, financial and behavioral-health record classes (the full inventory with live counts is on the Data Store screen).
  • Key properties: no direct read path exists; every consumer goes through the gates; the psychotherapy store is physically separate; six integrity checks run live on the Data Store screen, including full audit-chain verification.
  • Role: the enforcement point every read crosses. Evaluates: the profile's permissions (enumerated, no wildcards except the System Administrator's audited *), the record's sensitivity class against the reader's role and the applicable consent, and the session's purpose of use.
  • Outputs: released records, plus a withholding count for whatever was held back.
  • Emits: phi.disclosure-family events on release, access.denied on refusal. Key property: the gate cannot be bypassed by the AI — the assistant's tools call the same gate code the screens do.

2.7 PHI RAG (retrieval-tuned LLM)

  • Role: the assistant. Plans retrieval, calls role-scoped tools, assembles gate-released excerpts, and produces cited answers.
  • Contract: answer only from retrieved records; cite as [MRN-xxx · chart]; never assert absence from unretrieved documents; confirm before population sweeps; state withholdings; counts, never lists, on the population plane.
  • Controls: the Control panel's retrieval switch (off = the assistant refuses to read the Data Store at all and says so).
  • Emits: ai.query per question, plus the tools' own events.

2.8 The foundation model — yours

  • Role: the foundation language model PHI RAG runs on, called over the model API at temperature 0 with bounded output.
  • Bring your own: this demonstration runs Claude Sonnet 5, but the slot is provider-pluggable — a deployment activates the LLM the organization chooses, under its own BAA with its AI provider.
  • Receives: the system contract, the last six turns, the role's tool schemas, and gate-released excerpts — never a database connection, never bulk data.
  • Controls: the live-calls switch; off degrades to the scripted fallback.
  • Data terms: excerpts are used to answer the question, not to train models, under the organization's agreement with the provider.

2.9 People & screens

  • Role: six profiles across the role model, each seeing exactly the screens its permissions allow (the full matrix is in the system documentation).
  • Key property: screens check permissions, not roles — role composition changes without touching screens.

2.10 Human signature

  • Role: the signature rule's enforcement point. AI drafts queue; a licensed reviewer edits and signs; only the signed artifact acquires a write path to the EMR.
  • Emits: signature.committed. Deliberate non-feature: auto-commit, batch signing, or timeout-advance. A draft's only exits are a signature or a return.

2.11 Export managers

  • Role: the only doorways out — bulk delivery and outbound feeds. Apply the consent & redisclosure gate, record exclusion counts, honor the destination's write surface, and track acknowledgment.
  • Emits: export.completed / export.refused.
  • Key property: the three outcomes (complete / failed / refused) are all first-class and all visible in run history.

2.12 The audit trail

Role: the append-only, hash-chained memory of everything above. Every component writes to it; nothing edits it; the Control panel re-derives the full chain on every load and reports intact or the first broken row. In the deployable platform, concurrent writers may fork the chain legitimately; verification understands forks and distinguishes them from tampering.

3. Trust boundaries

Five boundaries, and what is allowed to cross each:

BoundaryCrosses itNever crosses it
Vendor EMR ↔ platform Authenticated bulk extracts, streaming events, signed write-back, configured deliveries Unsigned generated content; credentials in either direction beyond the OAuth flows
Ingestion ↔ Data Store Encrypted, classified, indexed records Unclassified records; unencrypted records
Data Store ↔ readers (people or AI) Gate-released records with withholding counts Direct queries; sensitive records for excluded roles; psychotherapy content for anyone but the Psychotherapy role
Platform ↔ model provider The contract, the question, gate-released excerpts for this question Bulk data; a database connection; credentials; records the gate withheld
Platform ↔ external recipients Consent-gated packages with recorded exclusions; acknowledged feed events Psychotherapy notes (ever); Part 2 content without Part 2 consent; partial exports presented as complete

4. The deployable platform's cloud architecture

The platform ships this architecture hardened:

  • Envelope encryption. Every stored object is encrypted with its own data key; data keys are wrapped by a KMS master key that never leaves the key service. Compromising storage yields ciphertext; key use is itself logged.
  • Isolated stores. Record objects, audit events, and psychotherapy content live in separate stores with separate access policies — the psychotherapy separation is infrastructure, not a WHERE clause.
  • Relational index + OMOP. A relational index serves the screens; an OMOP common-data-model layer serves research-grade analytics on the de-identified plane.
  • IAM enforcement in depth. Roles are enforced in the application and as cloud IAM policy, with the purpose of use carried as an IAM session tag — the storage layer itself can refuse a read whose purpose tag is absent.
  • A no-script web tier. The product interface runs under a Content-Security-Policy of script-src 'none': the screens execute no JavaScript, eliminating the XSS class outright. (This documentation's animated diagrams are the one scripted surface, and they render no PHI.)
  • Credential hygiene. Model-provider and vendor credentials live server-side in restricted stores, never in pages, never in the repository.

5. Failure modes

What breaks, what happens, and what is designed to never happen:

FailureWhat happensWhat never happens
Bulk download interruptedRun marked failed; watermark holds; retry is a fresh runA partial population presented as current
Stream broker restartGap surfaced with exact offsets; processing resumes from checkpointInterpolated events; silently skipped offsets
Model API downError stated; scripted fallback answers, labeled; questions still auditedUnlabeled degraded answers; lost audit events
Export destination rejectingBulk: run failed. Streaming: held with retry, backlog countedDropped deliveries; regenerated-and-duplicated deliveries
Gate cannot evaluate (missing consent state)Deny, with the rule named; access.deniedFail-open release
Audit chain brokenVerification reports the first bad row on the Control panel and Data Store screensQuiet acceptance of a tampered log
Session identity no longer existsFalls back to the default (least-privileged clinician) profileA role-less or elevated ghost session

The individual journeys — question to answer, records arriving, records leaving, draft to signature — are animated step-by-step in Data flow diagrams.

Data flow diagrams

The six journeys data makes through the AI-native platform, animated and then walked through step by step — with the audit event written at every step and the failure branches spelled out. Notice that the AI sits inside every flow, never outside the gates: this is what a platform designed for AI use of protected data looks like in motion. Dots are data on the move; a red branch is a refusal, and the refusal is always recorded, never silent. Hover over any box for a plain-English explanation.

1 · A question becomes a cited answer (PHI RAG)

A user asks a question. The assistant checks their role and purpose, retrieves only the records their permissions allow (the withholding gate counts what it holds back), sends those excerpts to the model, and returns an answer with citations.

Walkthrough

#StepWhat happensAudit event
1The questionA signed-in profile asks. Their identity, roles and ambient purpose of use travel with the question. The question is stored in prompt history (questions only — answers are never stored).ai.query
2Retrieval planningPHI RAG selects among the tools its role's schema contains. A tool the role lacks is absent, not forbidden — the model cannot even attempt it.
3The gateEach tool call passes the same role/consent/purpose gate a screen does. Sensitive-category records the reader may not see are withheld and counted.phi.search / phi.disclosure / analytics.query
4RetrievalGate-released excerpts come back as tool results. Population tools return counts, never lists (the counts-never-lists rule).
5DraftingThe foundation model (yours — this demo runs Claude Sonnet 5) writes the answer from the excerpts, at temperature 0, citing each source as [MRN-xxx · chart]. It may not characterize documents it did not retrieve.
6The answerThe cited answer renders, including the withholding statement ("3 mental-health records were withheld from this view"). The reader knows what the answer could not see.

Failure branches: a population-wide question pauses for a minimum-necessary confirmation before step 3; a request to enumerate a cohort is refused with the counts-never-lists rule named; retrieval disabled (Control panel) refuses at step 2 with the switch named; a model failure at step 5 reports the error — steps 1–4's audit events are already on the chain, so the trail shows exactly what was read even for a failed turn.

2 · Records arrive (bulk import)

A bulk run asks the source EMR for its patient group, polls until ready, downloads the record files, and encrypts, stores and indexes every record.

Walkthrough

#StepWhat happensAudit event
1KickoffGroup/[id]/$export against the source EMR, asynchronous. On Epic the group is a provisioned Group FHIR ID and the window is one run per 24 hours per client.
1aRate-limit branchA kickoff inside the window is refused by the platform, before the vendor sees it, and the refusal is itself a recorded run in the manager's history.bulk.refused
2Status pollThe status URL returns progress until the manifest is ready. Bulk export has no incremental mode on Epic — every run is a full re-extract.
3DownloadNDJSON files, one resource type per file. An interruption at any file marks the whole run failed.
4Encrypt · store · indexReference normalization, sensitivity classification at the door, encryption, indexing. Only now, and only for a clean run, does the watermark advance.bulk.completed

The watermark rule, precisely: the watermark is the timestamp of the last run that completed every file. A failed run leaves it untouched, so every downstream consumer — screens, the assistant, analytics — can state exactly how fresh its world is, and a half-arrived extract can never impersonate the current population. The System Administrator can release the 24-hour hold from the Control panel; the override writes system.hold_released, because an override that leaves no trace is a vulnerability, not a feature.

3 · Records leave (export & delivery)

An export names its scope and destination, then passes the consent gate. What passes is delivered and acknowledged; what is refused is a recorded refusal, not a quiet omission.

Walkthrough

#StepWhat happensAudit event
1The requestScope (full population / cohort / one patient), destination (target EMR, HIE, registry, payer, ROI requester), format (FHIR NDJSON or C-CDA).
2The consent & redisclosure gatePsychotherapy notes are never in scope. Part 2 content without Part 2-specific consent refuses the export. Other sensitive categories are excluded per the data-sharing agreement — excluded, and counted.
2aRefusal branchThe gate's no is a first-class outcome: the run appears in history as refused with its reason, exactly where an auditor will look.export.refused
3PackagingThe allowed set is packaged with its exclusion counts recorded — the withheld records are numbers in the run history, never a silent gap the recipient cannot see.
4DeliveryOn the destination's write surface. A destination with no bulk write path (NextGen) refuses at this step rather than degrading into thousands of unrequested individual writes.export.completed
5AcknowledgmentStreaming deliveries track acknowledged vs produced sequence. Held = queued and accounted, retried without regenerating. Paused = a governance decision that accumulates and does not leak.
4 · A draft becomes part of the record (signature & write-back)

The one path by which generated content reaches the legal record — and the human decision standing in the middle of it.

Walkthrough

#StepWhat happensAudit event
1The materialA visit happens; ambient documentation or a summarization request produces the raw material.ai.query + phi.disclosure
2The draftPHI RAG drafts the note from retrieved records, labeled as a draft, carrying its citations.
3The queueThe draft waits in the signature queue. It has no write path from here — that is the signature rule, structurally.
4The humanA licensed reviewer reads the draft against its citations, edits it, and decides. On signing, the content becomes the signer's — clinically and legally.signature.committed
4aReturn branchA draft not accepted is returned or discarded. Drafts never advance by timeout, default, or batch approval.
5Write-backOnly the signed note is delivered to the EMR (on Epic, a DocumentReference create), attributed to the signer. The EMR remains the legal record.
5 · An imaging series becomes a draft report (AI read)

A genuine vision inference over the frames: the registry's imaging-slot model describes what it can actually see, measures from the acquisition scale, and its draft waits for a licensed reader like every other draft.

Walkthrough

#StepWhat happensAudit event
1The studyA reader opens a study in the viewer; the open is a recorded disclosure, and the context strip follows the study's patient.phi.disclosure
2The framesRepresentative frames of the series are rendered and sent to the imaging-slot model — pixels, the acquisition scale, and the problem list; never an answer key.ai.query
3The readThe vision model describes only what is visible, measures discrete findings in mm, names the frame each appears on, and drafts TECHNIQUE / FINDINGS / IMPRESSION.model.inference
4The cacheOne read per study, ever: the result is cached against the study and generator version, so every later viewer reads the same draft at no model cost.
5The draftFiling the read creates an unsigned draft report on the study's patient — into the signature queue, never past it.ai.draft_created
6 · A visit recording becomes a signed note (ambient)

The consent gate decides before one word is captured; the self-hosted listener transcribes inside the deployment; the note files to the visit's own patient and waits for a signature.

Walkthrough

#StepWhat happensAudit event
1The gateBefore capture: is recording this visit lawful in this jurisdiction, for this modality, with this consent? An all-party state holds capture until the visit-level attestation exists.consent.evaluated / consent.attested
2The captureRecord / pause / stop. Audio stays inside the deployment — the listener is self-hosted, so no ASR vendor ever touches a voice and no vendor BAA exists because none is needed.ambient.capture_opened
3The transcriptThe listener's genuine output, speaker-labeled, imperfections included — the drafting model flags garbled terms for the signer rather than guessing.model.inference
4The noteA SOAP draft from the transcript, filed to the visit's own patient — never to whoever is in context, never to a stand-in. Unresolvable patient → loud refusal, no draft.ai.draft_created
5The signatureThe draft waits in the signature queue; on signing it becomes the clinician's note and only then acquires a write path.signature.committed

What never happens, on any of these flows

  • Data released without a gate evaluating the reader, the record and the purpose — and writing the event.
  • A withholding, exclusion or refusal that is invisible to the person looking at the result.
  • A partial arrival or partial delivery presented as complete.
  • Generated content entering the legal record without signature.committed above it in the chain.
  • Psychotherapy content in any export, to any destination, under any scope.

The components these flows run across are documented in Architecture & data flows; the exact API calls are in API details.

API details

Every programmatic surface of the AI-native platform, in depth: the conventions all of them share, the retrieval tools the AI assistant calls (with request and response shapes), the model API behind it, the application's own route surface, the EMR-facing integration APIs records arrive and leave through, and how the platform authenticates to each vendor. These APIs were designed for AI as the consumer — audit-before-data, role-scoped tool schemas, structured refusals — not adapted to it afterward.

1. Conventions shared by every surface

  • Audit before data. Every surface writes its audit event before returning data. A crashed request leaves its intent on the trail; there is no window in which data moved but no record says so.
  • Permission checks name their permission. A refusal states the missing permission (integration:view, system:admin, …) and writes access.denied with that permission as the object reference.
  • Refusals are data, not errors. A consent refusal, a rate-limit refusal or a write-surface refusal returns a structured outcome (status: refused, with the reason) — it is a legitimate result the caller is expected to display, not an exception to swallow.
  • State-changing calls are POST + CSRF. Every mutating route requires the session's CSRF token; GETs never mutate.
  • Purpose travels. The session's ambient purpose of use is recorded with every event a surface writes.

2. The assistant's retrieval tool API

PHI RAG reaches the Data Store only through eight narrow tools. The tool schemas are generated per role: a profile lacking a permission does not get a degraded tool — the tool is absent from the schema entirely, so the model cannot even attempt the call. Every tool audits before returning.

2.1 search_patients

Requires patient:search · audits phi.search

Token-wise AND match over names and MRNs — every word in the query must match, in any order. Demographics only; no clinical content.A worked example against this site's synthetic dataset is in Emulators & non-PHI setup.

{"name": "search_patients", "input": {"query": "jane sample"}}
→ [{"id": 0, "mrn": "MRN-######", "name": "Jane Q. Sample",
    "birth_date": "YYYY-MM-DD", "gender": "female", "payer": "…"}]

2.2 get_patient_chart

Requires patient:read · audits phi.disclosure

The storyboard in structured form: demographics, active problems, medications, allergies, recent encounters. Sensitive-category rows are withheld and counted — the response carries a withheld_from_retrieval block naming each category and its count, which the assistant is required to state in its answer.

{"name": "get_patient_chart", "input": {"patient_id": 214}}
→ {"patient": {...}, "conditions": [...], "medications": [...],
   "encounters": [...],
   "withheld_from_retrieval": {"mental_health": 3, "sud_part2": 1}}

2.3 get_labs

Requires patient:read · audits phi.disclosure

Lab and vital series from the curated LOINC panel, optionally filtered to one analyte, with abnormal flags computed from reference-range logic (A1c ≥ 6.5%, systolic ≥ 140 mmHg, LDL ≥ 160 mg/dL, BMI ≥ 30, …).

2.4 read_document

Requires patient:read · audits phi.disclosure

One clinical note's full text. A document classified into a sensitive category is refused for roles the rule excludes; the refusal is returned as a structured withholding (category named, content absent) and audited. This is the tool behind the never-assert-absence rule: the model may only characterize documents this tool has actually returned.

2.5 get_claims

Requires claims:read · audits phi.disclosure

The financial plane for one patient: claims with payer, billed / allowed / paid amounts, adjudication status, and CPT-coded service lines. Absent for profiles without claims:read — a clinician's assistant genuinely does not have this tool.

2.6 count_cohort

Requires analytics:query · audits analytics.query

Condition-matched population counts. Returns a number, never a list — the tool is structurally incapable of enumerating patients, which is how the counts-never-lists rule is enforced at the API layer rather than by asking the model nicely.

{"name": "count_cohort", "input": {"condition": "diabetes"}}
→ {"condition": "diabetes", "patient_count": 541}

2.7 list_psychotherapy_notes / 2.8 read_psychotherapy_note

Require psychotherapy:read · audit psychotherapy.list / psychotherapy.disclosure

Present only in the Psychotherapy role's tool schema. Listing returns session metadata; reading returns one session's content — and the assistant is instructed to obtain an explicit minimum-necessary confirmation from the user before reading session content even for this role. Both events name the specific note in the audit trail, which is what an accounting of disclosures for psychotherapy content requires.

3. The model API

3.1 Request anatomy

PHI RAG calls the Anthropic Messages API. Each turn sends: the system prompt (the retrieval contract, the citation format, the refusal rules, the role's identity and purpose), the last six conversation turns, the role's tool schemas, and the user's question:

POST https://api.anthropic.com/v1/messages
x-api-key: [server-side credential — never in a page]
anthropic-version: 2023-06-01

{"model": "claude-sonnet-5",
 "max_tokens": 1500,
 "temperature": 0,
 "system": "You are the PHI AI assistant... [contract]",
 "tools": [ ...role-scoped tool schemas only... ],
 "messages": [ ...last 6 turns..., {"role": "user", "content": "..."} ]}

3.2 The tool loop

  1. The model responds with either final text or a tool_use block naming a tool and its input.
  2. The platform validates the tool exists for this role, executes it server-side (audit first, then query, then withholding), and returns a tool_result block.
  3. The loop repeats — typically one to four tool calls — until the model emits final text. The loop is bounded; a runaway loop terminates with the turn's partial work discarded and the query already audited.
  4. The final text is rendered with its citations. Answers are not stored; only the question enters prompt history.

3.3 Model parameters and failure behavior

  • temperature 0 — deterministic drafting; clinical answers should not vary with the weather.
  • Bounded output and a six-turn context tail — the model never accumulates an unbounded PHI context.
  • Failure ladder: retrieval disabled → structured refusal; live calls off / no key → deterministic scripted fallback, labeled; API error → the error is stated, the question was already audited, nothing was read.

4. The application's route surface

The application's own HTTP surface, useful as a map of what exists. Every route is /?p=<page>; every mutation is a POST with action and CSRF token.

Route / actionMethodRequiresWrites events
p=assistantGETassistant:use
action=askPOSTassistant:useai.query + per-tool events
action=prompt (save/unsave/delete)POSTassistant:use
p=patients / p=patientGETpatient:search / patient:readphi.search / phi.disclosure
p=document / p=psych_noteGETpatient:read / psychotherapy:readphi.disclosure / psychotherapy.disclosure
p=claims / p=claim / p=priorauthGETclaims:read
p=cohortGETanalytics:queryanalytics.query
action=signPOSTpatient:readsignature.committed
action=roiPOSTroi:manageroi.fulfilled / roi.denied
p=auditGETaudit:read
p=bulkimport / p=streaming / p=bulkexport / p=streamexportGETintegration:view
action=run_bulkPOSTadmin:configbulk.completed / bulk.refused
action=run_exportPOSTadmin:configexport.completed / export.refused
p=emrconfig / action=save_configGET / POSTadmin:configconfig.changed
p=controlpanelGETsystem:admin
action=sys_rag / sys_assistant / sys_feed / sys_release_holdPOSTsystem:adminsystem.*
p=docs / p=datastore / p=segmentation / p=consent / p=spec…GETnoneconsent.evaluated (consent page)

5. Ingestion APIs — records arriving

5.1 FHIR Bulk Data Export (population import)

The only sanctioned way to ingest an entire population. The flow against the source EMR:

  1. Kickoff. GET [base]/Group/[group-id]/$export?_type=Patient,Encounter,Condition,… with Prefer: respond-async and Accept: application/fhir+json. The server answers 202 Accepted with a Content-Location status URL. On Epic, the group is a Group FHIR ID provisioned with the app registration, and a group is limited to one export per 24 hours per client — a second kickoff is refused by the platform before it ever reaches the vendor, and the refusal is a recorded run.
  2. Status polling. GET [status-url] returns 202 with an X-Progress header while running, then 200 with a manifest:
{"transactionTime": "2026-08-27T01:00:05Z",
 "request": ".../Group/eGrp-7ac2/$export",
 "requiresAccessToken": true,
 "output": [
   {"type": "Patient",   "url": ".../file-01.ndjson"},
   {"type": "Encounter", "url": ".../file-02.ndjson"},
   {"type": "Condition", "url": ".../file-03.ndjson"}, ...]}
  1. Download. Each file is newline-delimited JSON, one FHIR resource per line, fetched with the access token. urn:uuid:-style references are normalized to resource-relative references during ingestion so the record graph links correctly.
  2. Encrypt · store · index. Every resource is encrypted, classified for sensitivity (§6.2 of the system documentation), and indexed. Only a run that completes every file advances the watermark — the marker of the last known-complete extract. A dirty run is marked failed and the watermark holds, so nothing downstream ever believes a partial extract was the world.

5.2 Streaming intake

Three inbound feeds, each partitioned with acknowledged checkpoints:

  • ADT — admissions, discharges, transfers. Near-real-time census and the trigger for downstream notifications.
  • ORU — lab results as they finalize.
  • X12 835 — payment remittance, feeding the claims plane.

The checkpoint protocol: each partition tracks checkpoint_offset (last event fully processed) and latest_offset (newest event seen). Processing advances the checkpoint only after the event is durably stored. A gap — offsets seen but unacknowledged, as after a broker restart — is surfaced on the Streaming data screen with the exact offset range, and is never interpolated: an interpolated gap is a silent data-integrity failure wearing a healthy pipeline's clothes.

6. Export APIs — records leaving

6.1 Bulk delivery

A bulk export names a scope (full population, cohort, or one patient), a destination (target EMR, HIE, registry, payer, or an ROI requester) and a format (FHIR NDJSON or C-CDA). The pipeline: assemble the scope → consent & redisclosure gate (psychotherapy notes never included; Part 2 content refuses without Part 2-specific consent; other sensitive categories excluded per the data-sharing agreement, with counts) → package with exclusion counts recorded → deliver on the destination's write surface → mark complete only if everything delivered. Outcomes are three, all recorded: complete (with records-delivered and records-withheld counts), failed (destination rejected or transfer interrupted — never presented as partially complete), and refused (the gate said no; the refusal carries its reason).

6.2 Write-back (signed documentation)

The one path by which generated content reaches the EMR: a draft signed in the signature queue (signature.committed) is delivered as a vendor-appropriate write — on Epic, a DocumentReference create carrying the signed note, attributed to the signer. Unsigned content has no write path; there is no API to force it.

6.3 Outbound feeds

Streaming exports track delivered_seq (acknowledged by the destination) against latest_seq (produced locally). The difference is the held backlog: held retries against the destination without regenerating or skipping; paused is a governance decision (from the Control panel) that accumulates sequence and leaks nothing; resuming delivers from the checkpoint. The de-identified research feed carries no identifiers by construction.

7. Vendor authentication

Per-vendor detail with inline citations to each vendor's published documentation lives in EMR connections.

7.1 SMART Backend Services (Epic)

  1. The platform registers as a backend service and holds a private key; the EMR holds the public key.
  2. Per token request, the platform signs a JWT (RS384) with claims iss = sub = client ID, aud = the token endpoint, exp ≤ 5 minutes, single-use jti.
  3. POST [token-endpoint] with grant_type=client_credentials, client_assertion_type=…jwt-bearer, the signed assertion, and scope=system/*.read (plus write scopes only where write-back is configured).
  4. The short-lived access token authorizes the bulk and FHIR calls; tokens are never persisted beyond their life.

7.2 The other vendors — flows per their own documentation

Oracle Health: two documented modes — client credentials (secret in a Basic header) or a signed JWT assertion, with the JWT mode the documented path for bulk; every resource scope must be requested explicitly (wildcards unsupported), so a missing scope fails at the resource and conformance is verified per-resource. eClinicalWorks: the same asymmetric private-key JWT assertion as Epic — no client secret. athenahealth: OAuth2 client credentials with a client secret — the one profiled vendor whose documented flow is a secret. MEDITECH / NextGen: SMART Backend Services recorded as the ONC g(10) certification baseline and flagged for portal confirmation; NextGen exposes no documented bulk export and no bulk write surface — population ingestion falls back to per-patient reads, and a bulk export aimed at it is refused with the seam named. Full citations per vendor: EMR connections.

8. Error model

ConditionBehaviorOn the audit trail
Missing permission403; the page names the permissionaccess.denied
Consent absent (Part 2, psychotherapy, recording)Structured refusal with the rule namedaccess.denied / export.refused / consent.evaluated
Vendor rate limitRun refused before reaching the vendorbulk.refused
Destination without a write surfaceExport refused, seam namedexport.refused
Transfer interruptedRun marked failed; watermark holdsbulk.completed (status failed)
Model API failureError stated; nothing read; fallback offeredai.query (already written)
Stale session identityFalls back to the default profile

The architecture behind these surfaces is drawn in Architecture & data flows; the journeys are animated step-by-step in Data flow diagrams.