Skip to main content

PF-111 — Unified AI Gateway Integration

Spec: PF-111 Unified AI Gateway Consolidation Status: Planned (stub — completed during Phase 1 implementation) Owner: Platform Foundation (PF) Last Updated: 2026-05-29
Integration with an external system (Vercel AI Gateway), not a cross-core integration. Listed here for the external-integration catalog; not added to CROSS_CORE_INTEGRATIONS.md (no core-to-core surface).

External System

Consumers (16 edge functions)

All AI-calling edge functions import only supabase/functions/_shared/ai and call the AIProvider interface: ai-assistant, ai-skill-execute, ai-document-analyze, ai-generate-template, ai-categorize-transactions, ai-match-transactions, ai-match-benefits-employees, generate-report-narrative, generate-embeddings, chatbot-message, ce-extract-document-data, extract-document-text, hr-ai-import-assist, messaging-summarize-conversation, messaging-translate-message, org-data-sync-consumer.

Contract (to be finalized in Phase 1)

  • Request: OpenAI-compatible chat-completions body (model, messages, optional tools, tool_choice, temperature, max_tokens, stream).
  • Response (non-stream): normalized to { content, toolCalls?, usage?, modelUsed }.
  • Response (stream): SSE passthrough, OpenAI-compatible frames (consumed by src/platform/ai/utils/encoreOpenAiSseChatTransport.ts).
  • Errors: { error: { code, message } }, sanitized; 429 retried with backoff; 402/401 non-retryable; ≥500 retryable.
  • PHI lane: lane: 'phi' resolves to BAA-covered models for modules with a PHI-lane configuration, and throws PhiLaneNotConfiguredError for any module that does not. As of 2026-05-29, the clinical (cl) and practice management (pm) modules are enabled on the PHI lane with anthropic/claude-sonnet-4.6 (primary) and openai/gpt-4o (fallback) — both BAA-covered through the Vercel AI Gateway. All other modules continue to fail closed on lane: 'phi'.

PHI lane routing

The PHI lane is fail-closed by default. Any module that calls resolveModels(module, 'phi') without an explicit BAA-confirmed entry raises PhiLaneNotConfiguredError. As of 2026-05-29, with Vercel AI Gateway BAA + ZDR confirmed, the following modules are enabled on the PHI lane: All other modules (for example gr, hr, fa, ce) continue to throw PhiLaneNotConfiguredError on the PHI lane and must use the standard lane until a per-module entry is added to PHI_MODELS. To enable a new module, add it to supabase/functions/_shared/ai/models.ts with a BAA-covered primary plus fallback.

Trace store (Langfuse)

All AI calls routed through the gateway are instrumented with Langfuse tracing at the single _shared/ai seam (tracing.ts, withTracing decorator, wired into createAIProvider). Retention caveat: Langfuse Cloud SaaS has no configurable server-side retention cap (EE-gated; Encore does not have a Langfuse EE license). This is acceptable only while no PHI content is ever sent to Langfuse. Residency recommendation (ops, no code change): Rotate LANGFUSE_BASE_URL Edge Function Secret to https://us.cloud.langfuse.com to align production trace storage with the US region and eliminate the mismatch with the MCP dev tool. Command: supabase secrets set LANGFUSE_BASE_URL=https://us.cloud.langfuse.com --project-ref <ref>. Gate before enabling content capture: If input/output are ever attached to Langfuse observations (any lane), the following must happen first — in order — before deployment:
  1. Execute a Langfuse BAA.
  2. Rotate LANGFUSE_BASE_URL to https://hipaa.cloud.langfuse.com (or a self-hosted instance).
  3. Update AI_SUBPROCESSOR_BAA_POSTURE.md and the REGULATORY_COMPLIANCE_TRACKER row.
Full posture documentation: AI_SUBPROCESSOR_BAA_POSTURE.md.

Open items

  • Confirm "provider/model" ids (incl. an embedding model for generate-embeddings) against the live catalog.
  • Finalize request/response examples once the gateway is wired (Phase 1).

PF-111-EN-01 — AI Usage/Audit Ledger + Cost Governance

Spec: PF-111-EN-01 Status: Partially implemented — ledger table + agent dimensions + PHI-access audit shipped; spend-cap pre-dispatch wiring, pricing table, and per-org rollup view are planned. ADR: ADR-029 (platform-wide AI governance posture) Last Updated: 2026-06-28

Producer / Consumer Matrix

Event Contract

PF-111-EN-01 does not define typed domain events in the pub/sub sense. The anomaly surface emits PF-10 notifications via direct createNotification() invocation. No entries in EVENT_CONTRACTS.md are required. PF-10 notification shape emitted by pf-check-ai-usage-anomalies (runs hourly via pg_cron): Deduplication is keyed on (alert_config_id, organization_id) via pf_ai_usage_alert_history cooldown check.

API / RPC Surface

pf_record_agent_phi_access(...) — SECURITY DEFINER, fail-closed PHI-access writer (FR-10/FR-11/FR-12)
Grants: authenticated, service_role. A write without governance_approval_id raises check_violation. If the insert fails the caller (TypeScript recordAgentPhiAccess()) throws PhiAccessLogError and MUST block the PHI operation — the audit is a precondition, not fire-and-forget. pf_agent_usage_rollup(p_organization_id, p_since) — SECURITY DEFINER, read-only fleet rollup (FR-13)
Gated on pf.audit.phi_access.view permission. Joins pf_ai_usage_logs (agent rows) + pf_agent_phi_access_log (PHI touches) via FULL OUTER JOIN on (agent_principal_id, session_id). Content-free. PF-130 is the exclusive read consumer. pf_ai_usage_rollup(...) — per-org billing rollup view + RPC (FR-4) — planned
Not yet materialized. Depends on pf_ai_model_pricing (also planned). To be defined in spec PF-111-EN-01 FR-4. TypeScript helpers (Deno edge runtime, _shared/ai/agent-usage.ts):
  • checkAgentBudget(input: AgentBudgetInput, projectedCost: number): AgentBudgetVerdict — pure, synchronous budget-decision function. Evaluates task → agent → org hard caps independently; returns { throttled: true, dimension, limit, used } on a hard breach and { throttled: false, warn: true } on an org soft-limit breach. Not yet wired into the gateway dispatch path.
  • recordAgentPhiAccess(rpc: UsageRpcClient, input: PhiAccessInput): Promise<{ recorded: true; id: string }> — calls pf_record_agent_phi_access via RPC; throws PhiAccessLogError on failure; caller MUST re-throw to block the PHI operation.
  • buildUsageRecord(module, result): AIUsageRecord (in _shared/ai/usage.ts) — builds a PHI-safe token record; persistence to pf_ai_usage_logs is planned (FR-2) but not yet wired.
Gateway pre-dispatch spend-cap — planned (FR-5 / FR-9) When wired into _shared/ai/usage.ts, the gateway will evaluate checkAgentBudget() plus the per-org PF-43 entitlement before every provider call. A hard breach throws AiBudgetExceededError (error class planned; not yet declared in codebase) and records a status='throttled' ledger row without dispatching to the provider. A soft-limit breach warns and proceeds.

Data / FK Contract

pf_ai_usage_logs — live, shipped The last four columns were added by migration 20260630000008_pf111_en01_agent_phi_access_audit.sql (additive, nullable; existing rows stay NULL). Indexes on (organization_id, agent_principal_id, created_at) (filtered, agent rows only) and (organization_id, session_id) (filtered). No cross-core FK on any column. pf_agent_phi_access_log — new, shipped via migration 20260630000008 No PHI value columns by construction. resource_table + resource_ref are soft (text + UUID) references — not FKs — so any-core records can be named without violating the no-cross-core-FK rule (constitution §1). Append-only: UPDATE revoked from authenticated; no UPDATE/DELETE RLS policy. pf_ai_model_pricing — planned (not yet materialized) To be defined in spec PF-111-EN-01 FR-3. Drives deterministic estimated_cost_usd computation; unknown model logs at zero cost (never blocks the call). pf_ai_usage_alert_configs / pf_ai_usage_alert_history — live, shipped Config-driven anomaly detection consumed by the pf-check-ai-usage-anomalies scheduled function. Metric types: daily_cost_usd, hourly_call_count, failure_rate_pct, per_org_daily_cost_usd, per_model_daily_cost_usd. Cooldown deduplication keyed on (alert_config_id, organization_id).

PHI / RLS / Tenant-Scoping Notes

  • pf_ai_usage_logs — RLS on organization_id; org-member reads; gateway / service-role writes. No content columns: prompt_tokens, completion_tokens, total_tokens are integer counts only. The table has no column capable of holding prompt or response text (NFR-1 enforced by schema, not policy).
  • pf_agent_phi_access_log — deny-by-default RLS. SELECT requires both pf_has_org_access and the pf.audit.phi_access.view permission (compliance / admin readers only). INSERT is exclusively via the pf_record_agent_phi_access SECURITY DEFINER RPC. UPDATE is revoked from authenticated; no DELETE policy. Append-only audit by construction.
  • pf_agent_usage_rollup — SECURITY DEFINER function; pf.audit.phi_access.view gated; returns only aggregated counts and costs — no content, no per-row PHI exposure.
  • SUD category handling — PHI touches on 42 CFR Part 2 records set phi_category='sud_part2'; the access event is recorded here, but the protected SUD content itself is governed by CL / PF-27-EN-01. This table records the access event identifier, not the content.
  • No cross-core FKsresource_table / resource_ref are soft (text + UUID) references, enabling PHI-touch audit of any-core records without a DB-level FK. agent_principal_id / session_id / parent_task_id are loose UUID references to PF-30-EN-01 and PF-125 entities (same-platform, no FK declared).
  • Compliance gatespecs/pf/reviews/PF-111-EN-01-COMPLIANCE-SIGNOFF.md must exist before pipeline_status may advance to compliance_reviewed (governed spec; regulated PHI-adjacent audit trail).

Open Items

PF-111-EN-02 — AI Eval / Observability Quality Gate

Spec: PF-111-EN-02 AI Eval / Observability Quality Gate PF-111-EN-02 formalises ownership and run-mode governance for the three-layer eval harness (L1 JSONL deterministic / L2 self-hosted Langfuse observability / L3 Promptfoo LLM-judge) that rides the AI gateway established by PF-111. This enhancement introduces no new cross-core contracts or external integration surfaces — it operates entirely within the existing Vercel AI Gateway surface, the supabase/functions/_shared/ai consumer interface, and the metadata-only Langfuse trace pipeline already documented in this file. PHI guardrails remain unchanged: Langfuse traces stay metadata-only pending a signed BAA and US-residency confirmation, and real-trace eval-candidate capture remains deferred per the same PHI policy inherited from the parent spec.