Inbound (request)
- Prompt arrives at the Node core.
- PHI Rail decides: is the destination on the BAA allowlist?
- Yes → pass through unchanged (BAA mode).
- No → call PHI Gateway → scrub identifiers, get back a payload of typed aliases (PERSON_xxxx, EMAIL_xxxx, …) + a hydration map.
- The scrubbed payload + a SCRUB_MODE_GUARDRAIL system message ("never invent identifiers") goes to the LLM.
Outbound (response)
- LLM returns response containing aliases.
- PHI Rail calls phi_rehydrate with the response + the original hydration map.
- Real identifiers are spliced back in.
- Response flows to the caller.
Layered detection
The PHI Gateway runs a chain: known contacts (vault membership) → regex patterns → Presidio NER → insurance-specific dictionary. The first hit wins. Each stage has a confidence score that gates whether to alias.
Audit
Every scrub event is logged (timestamp, source, identifier counts — never the actual values). Queryable via phi_audit_query.