Contract Version: 1.0 Created: 2026-03-24 Owning Cores: CL (Clinical & EHR), FW (Forms & Workflow) Status: Draft ADR Reference: ADR-004: CL-FW Event PatternsDocumentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Purpose: Define the event contracts for CL clinical events consumed by FW-16 (Event-Based Workflow Triggers) for automated task creation, notifications, and escalation workflows.
Automated event publishers (system actor)
Cron jobs and other non-human publishers must setmetadata.user_id to a well-known platform system profile so audit trails stay consistent (no NULL actor, no arbitrary strings).
| Item | Value |
|---|---|
Reserved pf_profiles.id | 00000000-0000-0000-0000-000000000001 |
| Username | system (stored in pf_profiles.custom_fields.username and auth raw_user_meta_data) |
| Seeding | supabase/migrations/20260325141500_pf_system_automation_profile.sql — inserts matching auth.users + auth.identities (non-login password) and pf_profiles with email = system@encore.local, full_name = System Automation, first_name / last_name = System / Automation, custom_fields = {"platform_system_actor": true, "username": "system"}. |
| Consumers | Edge functions such as cl-assessment-expiry-checker, cl-moud-monitoring-checker, cl-care-gap-rules, care-gap closure (closed_by), pf_notifications and any publisher that sets metadata.user_id on domain events — all MUST use this UUID. |
metadata.user_id unless a spec explicitly documents a different service principal.
Event Catalog
Event 1: cl_assessment_expired
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (cron edge function: cl-assessment-expiry-checker) |
| Subscribers | FW (task creation) |
| Trigger | Assessment next_due_date has passed without a new assessment being completed |
| FW Action | Create reassessment reminder task assigned to treating clinician |
- Template:
reassessment_reminder - Task: “Complete overdue assessment”
- Assignee:
assigned_clinician_id - Priority:
highif days_overdue > 7,mediumotherwise - Due date: 3 business days from task creation
Event 2: cl_moud_monitoring_overdue
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (cron edge function: cl-moud-monitoring-checker) |
| Subscribers | FW (care team alert) |
| Trigger | MOUD monitoring checkpoint overdue (e.g., UDS not completed within monitoring window) |
| FW Action | Alert care team; create follow-up task |
- Template:
moud_care_team_alert - Alert: PF-10 notification to all
care_team_ids - Task: “Complete for MOUD patient” assigned to
assigned_clinician_id - Priority:
high - Escalation: If not resolved in 48 hours, escalate to supervisor (Event 3)
Event 3: cl_moud_adherence_risk
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (triggered by adherence scoring logic in CL-21) |
| Subscribers | FW (escalation workflow) |
| Trigger | Patient’s MOUD adherence score drops below threshold (e.g., 2+ missed UDS, missed appointments) |
| FW Action | Escalate to clinical supervisor; create urgent review task |
- Template:
moud_escalation - Alert: PF-10 critical notification to
supervisor_id - Task: “Urgent MOUD adherence review” assigned to
supervisor_id - Priority:
critical - Due date: Same business day
Event 4: cl_care_gap_identified
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (cron edge function: cl-care-gap-rules) |
| Subscribers | FW (task creation) |
| Trigger | Care gap rule identifies an open gap for a patient (e.g., missed HEDIS measure) |
| FW Action | Create task for care manager to close gap |
- Template:
care_gap_task - Task: “Close care gap: ” assigned to
care_manager_idor unassigned pool - Priority:
medium(elevated tohighif due_date < 30 days) - Due date: 14 business days or
due_date, whichever is earlier
Event 5: cl_crisis_episode_opened
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (CL-13: Crisis Intervention) |
| Subscribers | FW (supervisor notification), GR (incident awareness) |
| Trigger | New crisis episode created with risk_level = ‘high’ or ‘imminent’ |
| FW Action | Immediate notification to clinical supervisor and care team |
- Template:
crisis_supervisor_notification - Alert: PF-10 critical notification to
supervisor_idand site clinical lead - No task created (crisis is actively managed by assigned clinician)
- If
crisis_type = 'observation_23hr', also create 6 interval assessment tasks (4-hour cadence)
Event 6: cl_restraint_event_initiated
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (CL-13: Crisis Intervention — restraint/seclusion workflow) |
| Subscribers | GR (incident auto-create), FW (automation template restraint_incident_creation) |
| Trigger | Restraint or seclusion physically initiated (initiation_time recorded per 42 CFR 482.13) |
| FW Action | Create incident-tracking workflow + PF-10 supervisor alert (critical) |
| GR Action | Create or update GR-09 incident record; map payload entity_id to cl_restraint_seclusion_events.id |
restraint_incident_creation — drives GR incident stub + PF-10 supervisor notification per org rules.
GR / PF-10: GR-09 consumes the event for regulatory incident creation; PF-10 delivers the critical alert to supervisor_id (or site escalation path).
Canonical event name: cl_restraint_event_initiated (physical start / initiation_time). Do not alias to cl_restraint_event_documented without updating EVENT_CONTRACTS.md, GR-09, and CL-GR-CLINICAL-INCIDENT-INTEGRATION.md — those documents MUST stay aligned with this contract.
FW-16 consumer spec: restraint_incident_creation automation template
FW-16 MUST register a workflow template named restraint_incident_creation (referenced by fw_workflow_events.auto_task_template for cl_restraint_event_initiated). Implementation MUST satisfy GR-09 incident auto-create and compliance testing.
| Area | Requirement |
|---|---|
| Payload validation | Validate required fields: entity_id, entity_type === 'restraint_seclusion_event', chart_id, initiation_time (ISO 8601), organization_id from metadata. Reject or DLQ events missing any required field; do not create tasks on invalid payloads. |
| PHI / PII stripping | Follow ADR-004: payloads use UUID identifiers only for patients/charts; no free-text clinical content in FW task titles or notification bodies beyond org-approved templates. Strip or hash any unexpected string fields before persisting to FW tables or PF-10. |
| Audit logging (42 CFR 482.13) | Log every automation execution to PF-04 pf_audit_logs (or append-only clinical audit per org policy) with: organization_id, user_id = reserved system profile UUID, action = e.g. fw.restraint_incident_automation.executed, timestamp, new_values JSONB containing event_id, correlation_id, entity_id, template = restraint_incident_creation, and outcome (created_task_ids, gr_incident_id if returned). Retention MUST meet restraint/seclusion record requirements. |
| GR-09 integration | Template nodes SHALL create or idempotently update the GR-09 regulatory incident record linked to cl_restraint_seclusion_events.id = entity_id, then route PF-10 critical notification to supervisor_id or org escalation path. |
restraint_incident_creation MUST be defined in the workflow templates seed (or equivalent FW-16 registry) with nodes implementing the table above: (1) validate payload, (2) call GR-09 incident upsert, (3) enqueue PF-10 supervisor alert. Until the template exists in seed, deployments SHOULD treat auto_task_template as a documentation contract and implement the template before enabling production automation for this event.
Event 7: cl_restraint_event_terminated
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (CL-13) |
| Subscribers | GR (GR-09 auto-close / escalation), FW (FW-16 debriefing task — e.g. template keyed to post-restraint debrief) |
| Trigger | Restraint/seclusion ended (termination_time recorded) |
| FW Action | Optional debriefing task trigger (FW-16); link to cl_restraint_seclusion_events |
| GR Action | GR-09 may auto-close draft incident or escalate if duration_exceeded or regulatory flags set |
Event 8: cl_care_gap_closed
| Field | Value |
|---|---|
| Channel | cl_events |
| Publisher | CL (CL-35 Population Health — auto-close cron or manual closure) |
| Subscribers | FW (optional follow-up tasks), analytics |
| Trigger | Care gap transitions to closed (closed_at set) |
| FW Action | Optional workflow (e.g. close related tasks, notify care manager) |
Event Registration Seed Data
All CL→FW events must be registered infw_workflow_events for FW-16 to consume them:
Drift Prevention
To ensure event contracts don’t diverge between CL publishers and FW consumers:CI Check (Recommended)
Add to CI pipeline: validate that everypg_notify('cl_events', ...) call in CL code matches a registered event in fw_workflow_events seed data.
Manual Audit (Current)
- When adding a new CL event, update this contract and the seed SQL
- Update
EVENT_CONTRACTS.mdwith the new event entry - PR template includes checklist item: “Event contract updated if new events added”
Idempotency & DLQ
Summary aligns with ADR-004. Canonical handler pattern (copy-paste for FW/edge consumers):- On failure, row in
fw_domain_eventsusesstatus = 'failed', incrementretry_countper retry attempt, populateerror_message. - Cron retries with exponential backoff (e.g. 1s, 2s, 4s) up to 3 additional attempts; after max retries:
retry_count = 3,processed_atremainsNULL, PF-10 notifies system admin. - No retry on 4xx except 429 (rate limit).
Related Documents
- EVENT_CONTRACTS.md — Canonical event schema and channel registry
- ADR-004: CL-FW Event Patterns — Channel routing and payload conventions
- CL-PM-EVENT-WIRING-INTEGRATION.md — CL-PM event contracts (companion)
- FW-16 Event-Based Workflow Triggers — FW automation infrastructure
- CL-13 Crisis Intervention — Crisis events source
- CL-21 MOUD Tracking — MOUD events source
- CL-35 Population Health — Care gap events source
- constitution.md §1.3 — No direct core-to-core imports