> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross-Core Integration, Events, Automator & Workflow — Deep Dive & Recommendations

> Version: 1.0 Last Updated: 2026-03-11 Status: Analysis and recommendations

# Cross-Core Integration, Events, Automator & Workflow — Deep Dive & Recommendations

**Version:** 1.0\
**Last Updated:** 2026-03-11\
**Status:** Analysis and recommendations

This document provides a deep dive into cross-core integration strategy, event consumer/pub-sub, the automation engine, and workflow execution — with identified gaps and a consistent approach for improvement.

***

## 1. Cross-Core Integration Strategy

### 1.1 Current State

The platform uses three integration patterns (constitution §1.3, [PLATFORM\_INTEGRATION\_LAYERS.md](./integrations/PLATFORM_INTEGRATION_LAYERS.md), [CROSS\_CORE\_INTEGRATIONS.md](./integrations/CROSS_CORE_INTEGRATIONS.md)):

| Pattern                           | Use Case                                 | Implementation                                                                                                                  |
| --------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **1. Platform Integration Layer** | Shared capability used by multiple cores | `@/platform/*` (forms, notifications, workforce, workflow canvas, realtime, events, etc.)                                       |
| **2. Event-Based Integration**    | Loose coupling, async, audit trail       | Domain events via `publishEvent()` → `fw_domain_events`; HTTP `event-consumer`; DB triggers → `pg_notify` (documented channels) |
| **3. API Contracts**              | Synchronous request-response             | Documented in [API\_CONTRACTS.md](./integrations/API_CONTRACTS.md); many planned, few implemented as formal REST                |

**Strengths:**

* Clear decision tree in `.cursor/rules/integration-patterns.md` and constitution.
* Platform layers are well-documented (Forms, Notifications, Workforce, Realtime, Events).
* Event channels and naming are defined in [EVENT\_CONTRACTS.md](./integrations/EVENT_CONTRACTS.md) with canonical channels (`domain_events`, `automation_trigger`, `fa_events`, `cl_pm_events`, etc.).
* Cross-core FK is scoped (ADR-002: CL may reference `pm_encounters.id` only).
* Dependency graph in CROSS\_CORE\_INTEGRATIONS.md is up to date.

### 1.2 Gaps & Inconsistencies

| Gap                                 | Description                                                                                                                                                                                                                                                                                                                           |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Event delivery vs documentation** | EVENT\_CONTRACTS and DATA\_FLOW describe `pg_notify` → “Edge Function Listener.” Edge functions are HTTP-invoked; there is no in-repo **pg\_notify → HTTP** bridge (e.g. Supabase Database Webhooks or a worker). So “listener” is either external or unimplemented.                                                                  |
| **Dual event paths**                | Two distinct mechanisms: (A) **Table-driven:** `publishEvent()` → `fw_domain_events` → trigger `fw_process_domain_event()` → inserts `fw_workflow_executions` (queued). (B) **HTTP-driven:** Client or service invokes `event-consumer` with `event_type` + `payload`. They are not unified; which to use when is not always obvious. |
| **API contracts**                   | API\_CONTRACTS lists many planned contracts (e.g. FA → RH episode balance, HR → RH employee lookup). Implementation status is mixed; no single “contract registry” with implementation status and version.                                                                                                                            |
| **Platform layer index**            | PLATFORM\_INTEGRATION\_LAYERS has a good table; some entries are “Planned” or “In Progress.” A single “integration health” view (events, API, platform layers) would help.                                                                                                                                                            |

***

## 2. Event Consumer & Pub/Sub

### 2.1 Current Mechanisms

**Path A — Domain events table (FW automation / workflow):**

1. Cores call `publishEvent({ event_name, organization_id, payload })` from `@/platform/events`.
2. Event is inserted into `fw_domain_events`.
3. DB trigger `fw_process_domain_event()` runs on INSERT:
   * Matches `fw_automation_rules` with `trigger_type = 'event'` (or `pm_event`) and `event_config`/`trigger_config`.
   * For each match, inserts a row into `fw_workflow_executions` with `status = 'queued'` and `trigger_payload`.

**Path B — HTTP event-consumer:**

1. Caller (client or edge function) invokes `supabase.functions.invoke('event-consumer', { body: { event_type, payload } })`.
2. `event-consumer` edge function:
   * Validates auth and body.
   * Runs **Teams notifications** (if `pf_teams_notification_config` has a rule for `event_type`).
   * Runs **domain handlers** (e.g. `referral_accepted` → CL transition + discharge checklist; other event types can be added in code).
3. No subscription to PostgreSQL NOTIFY; invocation is push-by-caller only.

**Path C — Realtime (Supabase):**

* **Postgres Changes:** Client subscribes to table changes (e.g. `fw_workflow_executions`, `pf_notifications`) via `@/platform/realtime` hooks. Used for live UI updates, not for “event routing” to server-side handlers.
* **Broadcast:** Ephemeral, non-persisted; used for typing, presence, or in-app signals. Not used as the primary event bus for cross-core domain events.

**Path D — pg\_notify (documented, server-side consumer unclear):**

* EVENT\_CONTRACTS and DATA\_FLOW describe channels (`domain_events`, `automation_trigger`, `fa_events`, etc.) and say “Subscribers consume via edge functions that listen to pg\_notify.”
* In the repo there is no edge function that “listens” to pg\_notify (edge functions are HTTP-triggered). So either:
  * A Supabase Database Webhook (or similar) maps NOTIFY to HTTP and calls an edge function, or
  * The intended “listener” was never implemented and form/DB-triggered flows rely on something else (e.g. client invoking automation-executor after form submit).

### 2.2 Gaps

| Gap                                 | Description                                                                                                                                                                                                                                                                                                                        |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **No single “event bus” doc**       | Table-driven (fw\_domain\_events) vs HTTP (event-consumer) vs pg\_notify are described in different places. One “Event delivery options” section with “when to use which” would reduce confusion.                                                                                                                                  |
| **event-consumer handler registry** | Handlers are hardcoded in `event-consumer/index.ts`. Adding a new event type requires code change and deploy. A small registry (e.g. event\_type → handler name or config) could make it easier to extend.                                                                                                                         |
| **Queued workflow executions**      | `fw_process_domain_event()` queues executions; no in-repo **worker or cron** that picks `status = 'queued'` and runs them (e.g. by calling automation-executor or a dedicated execution runner). So event-triggered rules may never run unless something else processes the queue.                                                 |
| **Form submission → automation**    | DATA\_FLOW describes: form INSERT → trigger → pg\_notify('automation\_trigger') → automation-executor. No migration defines `trigger_automation_on_submission`; automation-executor is invoked only via HTTP (e.g. dry-run). So either form-triggered automation is implemented elsewhere (e.g. client or webhook) or it is a gap. |

***

## 3. Automator (FW-03)

### 3.1 Current State

* **Rules:** `fw_automation_rules` with `trigger_type`, `trigger_config`, `event_config`, `date_relative_config`, `conditions`, `status`. Actions in `fw_automation_actions`.
* **Trigger types:** `form_submitted`, `form_updated`, `field_changed`, `schedule`, `webhook`, `manual`, `pm_event`, `event`, `date_relative`.
* **Executor:** Edge function `automation-executor`:
  * Invoked via **HTTP** with body `{ trigger_data, dry_run? }`.
  * Validates JWT and org access (V2 pattern with `pf_user_role_assignments`).
  * For form triggers, expects `trigger_data` with `trigger_type`, `submission_id`, `form_id`, `organization_id`, `submission_data`, etc.
  * Fetches matching rules, evaluates conditions, executes actions (send\_email, send\_notification, update\_record, create\_record, call\_webhook, run\_function), supports visual workflow graph (FW-06 Phase 2) and variables (FW-18).
* **Event-triggered rules:** When an event is inserted into `fw_domain_events`, `fw_process_domain_event()` only **queues** executions (inserts into `fw_workflow_executions`). The automation-executor is not invoked for those queued rows in the codebase (no cron or worker that reads `fw_workflow_executions` and calls the executor).

### 3.2 Gaps & Inconsistencies

| Gap                                       | Description                                                                                                                                                                                                                                                                        |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger config shape**                  | Different trigger types use different columns: `event_config`, `date_relative_config`, `trigger_config` (for pm\_event, form\_submitted). Documented in FW AGENTS.md; edge function and UI must handle all consistently.                                                           |
| **Who invokes executor for form submit?** | If there is no DB trigger → pg\_net → automation-executor, then either the client must call automation-executor after form submit (with trigger\_data), or a separate mechanism (e.g. cron polling `fw_form_submissions`) must exist. Not clearly documented.                      |
| **Queued executions not processed**       | Event and pm\_event triggers only create `fw_workflow_executions` with status `queued`. A **workflow execution processor** (cron or DB-triggered HTTP) that picks queued rows and runs them (via automation-executor or an internal runner) is missing or lives outside this repo. |
| **PM-19 vs event registry**               | PM-19 uses `trigger_config` with `PMEventTriggerConfig`; these events are not in `fw_workflow_events`. Documented as intentional; keep a single place that lists “event-triggered” vs “PM-internal” so automation UX stays consistent.                                             |

***

## 4. Workflow

### 4.1 Current State

* **Visual workflow (FW-06):** Workflow builder (React Flow), definitions stored in DB; execution is driven by automation-executor when invoked with appropriate trigger\_data (e.g. form\_submitted or workflow\_execution payload). Executions stored in `fw_workflow_executions`; realtime subscription used for monitoring.
* **XState machine (FW-18):** `createWorkflowMachine` / `useWorkflowMachine` in `@/cores/fw/machines` — client-side step machine (form, approval, action, condition, notification, wait). **Not wired** to the server-side workflow definition or automation-executor; no production callers outside the machines module. FW AGENTS.md and FORMS\_WIZARDS\_WORKFLOWS\_AUTOMATIONS\_RECOMMENDATIONS.md mark it as experimental / reserved for future use.
* **Workflow vs automation:** Workflow builder = graph of nodes (trigger, actions, conditions, approvals). Automation rules = single trigger + conditions + actions. Overlap in concept; different UX and data model.

### 4.2 Gaps

| Gap                                        | Description                                                                                                                                                                                                                                   |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Two execution models**                   | Server-side: definition → automation-executor → fw\_workflow\_executions. Client-side: XState step machine. They are not connected; avoid spreading a second execution model until there is a concrete product need (e.g. approval chain UI). |
| **Single “Create automation” entry**       | Recommendation in FORMS\_WIZARDS\_WORKFLOWS\_AUTOMATIONS\_RECOMMENDATIONS: one entry point (“Simple rule” vs “Workflow”) to reduce confusion.                                                                                                 |
| **Platform workflow = visualization only** | `@/platform/workflow` (WorkflowCanvas, swim lane) is for visualization only; execution stays in FW. Document this so new features don’t add execution logic to platform.                                                                      |

***

## 5. Recommendations — Improvement, Gaps, Consistency

### 5.1 Cross-Core Integration

| Rec    | Priority | Action                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **R1** | High     | **Unify event delivery documentation.** Add a single “Event delivery” section (e.g. in EVENT\_CONTRACTS or a new `docs/architecture/EVENT_DELIVERY.md`) that describes: (1) **Table-driven:** `publishEvent()` → `fw_domain_events` → trigger → queued workflow executions — use for FW automation/workflow triggers. (2) **HTTP event-consumer:** `invoke('event-consumer', { event_type, payload })` — use for cross-core side effects (Teams, CL transitions, etc.) that need a single place to add handlers. (3) **Realtime:** Postgres Changes / Broadcast for UI only, not for server-side event routing. (4) **pg\_notify:** Document current state: channels and DB triggers exist; server-side “listener” is either via Supabase webhooks/external worker or not yet implemented; clarify and document. |
| **R2** | Medium   | **Integration health view.** Add a short “Integration status” page or table: Platform layers (with status), API contracts (planned vs implemented), event channels (table vs HTTP vs pg\_notify). Link from CROSS\_CORE\_INTEGRATIONS and PLATFORM\_INTEGRATION\_LAYERS.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **R3** | Low      | **API contract registry.** In API\_CONTRACTS or a companion file, add a table: contract name, provider, consumer, status (planned / in progress / implemented), version. Keeps API strategy and implementation status in one place.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

### 5.2 Event Consumer & Pub/Sub

| Rec    | Priority | Action                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **R4** | High     | **Implement or document queued execution processing.** Either: (A) Add a **cron-driven edge function** (or worker) that polls `fw_workflow_executions` for `status = 'queued'`, then invokes automation-executor (or a dedicated “run-workflow-execution” function) with the execution id and trigger\_payload; or (B) Use Supabase Database Webhooks to call an edge function on INSERT to `fw_workflow_executions` where status = 'queued'. Document the chosen approach in EVENT\_CONTRACTS and in automation-executor README. |
| **R5** | High     | **Form submission → automation.** Confirm intended flow: (1) Client invokes automation-executor after form submit with trigger\_data, or (2) DB trigger on `fw_form_submissions` + pg\_net (or webhook) to call automation-executor. If (2), add the trigger and webhook; if (1), document it in FW-03 and DATA\_FLOW so implementers don’t assume a DB listener.                                                                                                                                                                 |
| **R6** | Medium   | **event-consumer handler registry.** Option A: Keep code-registered handlers but list them in a small table in EVENT\_CONTRACTS (event\_type → handler name, one-line description). Option B: Add a DB or config table (event\_type → handler key) so new event types can be wired without code change. Prefer A for simplicity unless you need non-deploy configuration.                                                                                                                                                         |
| **R7** | Medium   | **Idempotency and retries.** For event-consumer and any new execution processor, document idempotency (e.g. event\_id or execution\_id idempotency key) and retry/backoff so handlers are safe when invoked more than once. *Rationale: Prevents duplicate side effects and data corruption when events are retried or delivered multiple times.*                                                                                                                                                                                 |

### 5.3 Automator

| Rec     | Priority | Action                                                                                                                                                                                                                                                                                                                                                           |
| ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **R8**  | High     | **Trigger config reference in one place.** Keep and maintain the “Automation trigger config reference” (trigger\_type → config location and shape) in FW AGENTS.md; ensure automation-executor and UI both reference it and handle all trigger types. Add a short “Trigger config” section in EVENT\_CONTRACTS or FW-03 spec for event/date\_relative/pm\_event. |
| **R9**  | Medium   | **Single “Create automation” entry.** From the Automations dashboard, offer “Simple rule” (AutomationRuleBuilder) and “Workflow” (visual builder). Reduces confusion between rules and workflows (already recommended in FORMS\_WIZARDS\_WORKFLOWS\_AUTOMATIONS\_RECOMMENDATIONS).                                                                               |
| **R10** | Low      | **PM-19 and fw\_workflow\_events.** Explicitly document that PM-19 event types are “PM internal” and not registered in `fw_workflow_events`; list them in a small table so event-driven automation behavior is predictable.                                                                                                                                      |

### 5.4 Workflow

| Rec     | Priority | Action                                                                                                                                                                                                                                                                                                                                        |
| ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **R11** | Medium   | **XState role.** Keep XState workflow machine as “experimental / reserved for future” unless a concrete feature (e.g. approval chain UI, submission wizard) adopts it. Document in FW AGENTS.md and form-libraries-advanced-extensions: “Do not use in new features without a product requirement.” Avoid a second, parallel execution model. |
| **R12** | Low      | **Workflow vs automation in docs.** In FW AGENTS.md or a short “Workflow and automation” doc, state: “Visual workflows = multi-step automation with graph/approvals; Automation rules = single trigger → one or more actions. Use workflows for branching/approvals; use rules for simple when-X-then-Y.”                                     |
| **R13** | Low      | **Platform workflow = visualization only.** In PLATFORM\_INTEGRATION\_LAYERS and platform workflow README, state that WorkflowCanvas / swim lane are for visualization only; execution lives in FW (automation-executor, fw\_workflow\_executions).                                                                                           |

### 5.5 Consistency Approach (Summary)

1. **One event narrative:** Document the two main paths (table-driven for FW automation, HTTP event-consumer for cross-core handlers) and when to use each; clarify pg\_notify and Realtime roles.
2. **Close the execution loop:** Ensure “queued” workflow executions are processed (cron or webhook) and form submission triggers automation in a documented, consistent way.
3. **Single reference for triggers:** One maintained “trigger config” and “event vs PM-internal” reference for automation and workflow.
4. **Unified automation UX:** One entry point for creating automations (simple rule vs workflow) and clear guidance on workflow vs rule.
5. **No duplicate execution model:** Keep XState experimental until a concrete feature uses it; execution remains server-side (automation-executor + fw\_workflow\_executions).

***

## 6. References

* [CROSS\_CORE\_INTEGRATIONS.md](./integrations/CROSS_CORE_INTEGRATIONS.md) — Integration matrix and dependency graph
* [EVENT\_CONTRACTS.md](./integrations/EVENT_CONTRACTS.md) — Event channels and payloads
* [PLATFORM\_INTEGRATION\_LAYERS.md](./integrations/PLATFORM_INTEGRATION_LAYERS.md) — Platform layer index
* [API\_CONTRACTS.md](./integrations/API_CONTRACTS.md) — Synchronous API contracts
* [DATA\_FLOW.md](./patterns/DATA_FLOW.md) — Request lifecycle and automation flow
* [FORMS\_WIZARDS\_WORKFLOWS\_AUTOMATIONS\_RECOMMENDATIONS.md](../archive/development/FORMS_WIZARDS_WORKFLOWS_AUTOMATIONS_RECOMMENDATIONS.md) — Forms, wizards, workflows, automations (archived)
* Constitution §1.3 — Integration patterns
* `.cursor/rules/integration-patterns.md` — Pattern decision tree
* `src/platform/events/README.md` — Platform events API
* `src/cores/fw/AGENTS.md` — FW automation and workflow patterns
