Feature ID: CL-36Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Status: π Specification
Spec Reference: CL-36-ai-assisted-clinical-documentation.md
Last Updated: 2026-03-31
Last Verified: β
Table of Contents
- Overview
- Quick Reference
- Integration Points
- Data Contracts
- Event Contracts
- Edge Function Contracts
- Security and RLS
- External Vendor Integration (Phase 3)
- Common Mistakes
- Related Docs
Overview
CL-36 provides platform-level AI documentation capability across note types (CL-04 progress notes, CL-14 group notes, CL-24 telehealth notes). It creates AI session audit records (cl_ai_documentation_sessions) and per-note attribution records (cl_ai_note_attributions). AI vendor calls are made exclusively from edge functions β no PHI flows client-side to AI vendors. Org-level opt-in is required; 42 CFR Part 2 consent gate (CL-11) is enforced before any AI vendor call.
Quick Reference
| Item | Value |
|---|---|
| Core tables | cl_ai_documentation_sessions, cl_ai_note_attributions |
| Settings columns | cl_ai_documentation_enabled, cl_ai_ambient_vendor, cl_ai_data_residency, cl_ai_policy940_enforcement on cl_module_settings |
| Permission keys | cl.ai_documentation.use, cl.ai_documentation.admin |
| 42 CFR Part 2 gate | cl_check_sud_consent(chart_id, 'ai_documentation', auth.uid()) from CL-11 (three-argument signature; edge: use p_requesting_user from JWT) |
| AI platform layer | @/platform/ai (PF-27) when available; edge function adapter otherwise |
| Session lifecycle | initiated β draft_generated β attested (or cancelled) |
Integration Points
| From | To | Pattern | Notes |
|---|---|---|---|
| CL-36 | CL-04 | Data write (adds cl_ai_note_attributions linked to progress note) | Phase 1 |
| CL-36 | CL-14 | Data write (same attribution pattern for group notes) | Phase 3 |
| CL-36 | CL-24 | Data write (same attribution pattern for telehealth notes) | Phase 3 |
| CL-36 | CL-11 | Function call (cl_check_sud_consent) | Before every AI vendor call |
| CL-36 | PF-27 (Platform AI) | Platform Layer | If/when PF-27 available; interim: direct edge function |
| CL-36 | PF-02 / PF-30 | Platform Layer (auth, RBAC, audit) | Permission gate on cl.ai_documentation.use |
| CL-36 | pm_encounters | FK / Data Lookup | cl_ai_documentation_sessions.encounter_id β pm_encounters.id (ADR-002) |
| CL-36 | External AI Vendors | API (edge function only; Phase 3 for ambient) | BAA required; API keys in Supabase Vault |
Data Contracts
cl_ai_documentation_sessions (audit log β immutable)
| Column | Type | Description |
|---|---|---|
id | uuid PK | |
organization_id | uuid | Tenant anchor (RLS) |
user_id | uuid β pf_profiles | Clinician who initiated |
chart_id | uuid β cl_charts | Patient chart |
encounter_id | uuid β pm_encounters | Linked encounter |
note_id | uuid | Polymorphic; see note_type |
note_type | text CHECK | 'progress_note' | 'group_note' | 'telehealth_note' |
status | text CHECK | 'initiated' | 'draft_generated' | 'cancelled' | 'attested' |
draft_source | text CHECK | 'structured_data' | 'ambient_voice' |
ai_vendor | text | Vendor slug (ambient only); null for structured-data |
session_started_at | timestamptz | |
session_ended_at | timestamptz | null if cancelled |
attestation_at | timestamptz | Populated on attestation |
attestation_by | uuid β pf_profiles | |
custom_fields | JSONB | |
created_at, updated_at, created_by, updated_by | audit |
cl_ai_note_attributions
| Column | Type | Description |
|---|---|---|
id | uuid PK | |
organization_id | uuid | Tenant anchor (RLS) |
note_id | uuid | Matches cl_ai_documentation_sessions.note_id |
note_type | text CHECK | Same values as sessions |
ai_session_id | uuid β cl_ai_documentation_sessions | |
ai_assisted | boolean | |
attribution_label | text | 'Drafted with AI assistance' (default) |
ai_attestation_at | timestamptz | Updated on attestation |
ai_attestation_by | uuid β pf_profiles | |
custom_fields | JSONB | |
created_at, updated_at, created_by, updated_by | audit |
Canonical AI Draft Interfaces (Clarification #13)
The edge function uses canonical request/response interfaces for testability and minimum-necessary PHI enforcement. Vendor adapters map these to vendor-specific payloads.PHI Inclusion/Exclusion Lists (Clarification #19)
Included (minimum necessary): diagnosis codes (ICD-10), assessment instrument scores (numeric only), treatment plan goal summaries, prior note summary (AI-generated, not full text), service type, encounter date. Excluded (never sent): patient name, DOB, SSN, address, phone, email, insurance IDs, financial data, photo/biometric data, SUD-specific identifiers beyond CL-11 consent gate. Edge function enforces both lists.API Key Model (Clarification #11)
Hybrid β platform-level default key with per-tenant override. Edge function checksAI_VENDOR_{TENANT_ID}_API_KEY first (where TENANT_ID is derived from verifiedOrgId), falls back to AI_VENDOR_DEFAULT_API_KEY. Tenant resolution uses verifiedOrgId from the verified JWT/user profile only. Any organization_id, organizationId, or similar field in the request body is ignored server-side to prevent tenant spoofing; clients must not rely on body org for tenancy or key selection.
Concurrency Control (Clarification #16)
One active session per note at a time; multiple notes can generate concurrently. Edge function checks for existing session with(note_id, note_type) where status = 'initiated' within the timeout window; rejects with user-friendly message if in-flight.
Session Update Scope (Clarification #14)
Only lifecycle fields may be updated after INSERT:status, attestation_at, attestation_by, session_ended_at, updated_at, updated_by. All other columns are immutable. Phase 1: application logic; Phase 2: trigger-based guard.
Data Residency (Clarification #20)
Phase 1 (US only): contractual via BAA. Phase 3 (when EU added): edge function selects vendorβs region-specific API endpoint based oncl_ai_data_residency. Adapter pattern supports per-vendor endpoint mapping.
Event Contracts
CL-36 does not publish events in Phase 1 or 2. Phase 3 consideration: if AI draft generation failure needs to notify the clinician asynchronously, acl_ai_draft_failed event may be added. No contract defined yet.
Edge Function Contracts
cl-ai-generate-draft (Phase 2)
Generates a note draft from structured encounter data. Called from the browser via authenticated Supabase client; does not send raw PHI to the AI vendor without first invoking cl_check_sud_consent.
Request (from browser β edge function):
JSON body includes note context only. Do not send organization_id for tenancy β the edge function derives org from the authenticated session (verifiedOrgId).
403 SUD_CONSENT_NOT_CLEAREDβ 42 CFR Part 2 gate triggered403 AI_DOCUMENTATION_DISABLEDβ org opt-in not enabled503 AI_VENDOR_UNAVAILABLEβ graceful degradation; app continues without draft
Deno.serve()onlygetCorsHeaders(req.headers.get('origin'))from_shared/cors.tscreateLoggerfrom_shared/logger.ts; no PHI in log messages- JWT verified on every request; use verifiedOrgId from JWT/profile for RLS, session rows, and
AI_VENDOR_{TENANT_ID}_API_KEYresolution β ignore any org id in the request body
Security and RLS
- Both tables have RLS enabled via
cl_check_ai_session_access(session_org_id)SECURITY DEFINER function - No DELETE policy on either table (immutable audit records)
- AI vendor API keys stored in Supabase Vault; accessed only from edge functions
- No PHI stored in
cl_ai_documentation_sessionsbeyond FKs; note text is never persisted to the audit log cl_check_sud_consent()from CL-11 must be invoked before every AI vendor call
External Vendor Integration (Phase 3)
Ambient voice vendors (Nabla, Nuance DAX, Abridge, Suki) integrated via a common adapter pattern in a single edge function (cl-ai-ambient-draft). The vendor is determined by cl_ai_ambient_vendor on cl_module_settings. Each vendor implements the adapter interface:
healthCheck(): Each adapter must implementhealthCheck()returningtruewhen the vendor API is reachable,falseotherwise. Used to fail fast before sending PHI.- Edge function behavior: Before calling
generateDraft(context), the edge function must calladapter.healthCheck()(adapter selected fromcl_ai_ambient_vendorvia factory). IfhealthCheck()returnsfalse, respond with503 AI_VENDOR_UNAVAILABLEinstead of relying solely on exception handling; do not callgenerateDraftin that case.generateDraftimplementations remain unchanged. - Adapter factory: Any factory or selection code that returns adapters must ensure returned adapters implement the full interface including
healthCheck.
Common Mistakes
| Mistake | Mitigation |
|---|---|
| Sending PHI to AI vendor from browser | All vendor calls must be in edge functions only |
Not invoking cl_check_sud_consent before AI call | Required; hard block on failure |
| Skipping BAA with AI vendor | BAA must be in place before any PHI flows to vendor |
Using note_type as an unvalidated string | Always use CHECK constraint values |
| Allowing note finalize without attestation | cl_ai_note_attributions.ai_attestation_at must be non-null before finalize |