Skip to main content
This page is synced from /constitution.md at the repository root. Edit the source file — this published copy is regenerated by npm run docs:sync-canonical. See the governance index for related documents.

Encore OS Platform – Engineering & Product Constitution

Version: 1.18.0
Last Updated: 2026-06-15
This constitution defines the non‑negotiable guardrails for designing, building, and operating the Encore OS platform and its modules. It applies to everyone: engineers, product, data, and any AI assistants. When documents conflict, this constitution wins. Full document hierarchy: constitution.mdAI_GUIDE.mdAGENTS.md.cursor/rules/

Table of Contents


1. Architecture & Module Boundaries

The platform is structured as a Platform Foundation plus domain cores. Boundaries are hard rules, not suggestions.

1.1 Platform & Cores

  • Platform Foundation (PF)
    Identity, tenancy, access control, navigation, audit, shared UX, cross‑cutting services, PWA infrastructure, jurisdiction/compliance configuration (PF-96), and integration glue. PF owns the jurisdiction profile system that provides state-specific Medicaid compliance rules as structured, versioned configuration data consumed by CL and PM.
  • Domain Cores
    • RH – Recovery Housing & Operations
    • FA – Finance & Revenue
    • HR – Workforce & HRIS
    • GR – Governance, Compliance & Learning
    • FW – Forms & Workflow
    • FM – Facilities, Inventory & Vendors
    • LO – Leadership Operating System
    • CE – Community Engagement
    • IT – IT & Security
    • CL – Clinical & EHR (never a base dependency)
    • PM – Practice Management (healthcare revenue cycle; distinct from FA general accounting)

1.2 Rules

  • All code, tables, APIs, and UI features MUST declare an owning core/module (e.g., RH-01, FA-01).
  • Platform Foundation is the only shared base layer. Cores may depend on PF, but not on each other, except via explicit, documented integration contracts.
  • CL (Clinical) is architecturally downstream:
    • No other core may depend on CL.
    • No “hidden clinical” logic in RH/FA/HR.
  • PM (Practice Management) and CL (Clinical) are tightly integrated operationally but architecturally independent:
    • Both depend only on PF, never on each other.
    • Integration via Platform Integration Layer (@/platform/clinical, @/platform/scheduling), events, and shared type definitions in PF.
    • The encounter (pm_encounters, owned by PM) is the canonical entity linking scheduling, clinical documentation, and billing. CL reads encounter context via @/platform/scheduling.
    • PM handles healthcare revenue cycle (claims, eligibility, ERA); FA handles general accounting (GL, AP, AR).
    • Encounter-to-billing pipeline: CL note finalization triggers PM charge capture via events.
  • Cross-core database references:
    • By default, cross-core table references use UUID columns validated at the application layer (no database FK constraints).
    • Exception (CL-PM only): The encounter entity (pm_encounters) is the canonical joint between clinical documentation and revenue cycle. CL tables MAY reference pm_encounters.id via a database FK with ON DELETE RESTRICT to preserve referential integrity. This exception is scoped to the encounter entity and documented in ADR-002. No other cross-core FK is permitted without an ADR.
  • Cross‑core integrations MUST be:
    • Defined as explicit contracts (events, APIs, or data feeds).
    • Documented in architecture diagrams and specs.
Rationale: Clear domain boundaries avoid monolith creep, enable parallel delivery, and keep clinical complexity from contaminating operational systems.

1.3 Integration Patterns

When one core needs to interact with another (e.g., RH needing forms from FW), the integration MUST follow these patterns:

Integration Pattern Decision Tree

See: docs/architecture/integrations/index.md for complete integration documentation. Pattern 1: Platform Integration Layer
  • For cross-cutting capabilities used by multiple cores (like Forms & Workflow), create an integration layer within Platform Foundation.
  • Example: /src/platform/forms/ provides simple hooks and components that wrap FW functionality.
  • Other cores interact with this integration layer, NOT directly with /src/cores/fw/.
Pattern 2: Event-Based Integration
  • Cores publish domain events (e.g., “resident admitted”, “form submitted”).
  • Subscribing cores listen and react without direct coupling.
  • Events MUST be documented in a central registry.
Pattern 2b: Event Registry Pattern (FW-16)
  • For workflow triggers based on domain events, cores register events in fw_workflow_events table.
  • Event registry stores: event_name, display_name, description, owning_core, category, payload_schema.
  • Workflow designers browse available events by core (HR, RH, FA, etc.) in the trigger configuration UI.
  • Cores publish events via Platform Integration Layer: import { publishEvent } from '@/platform/events';
  • FW Automation Engine subscribes to events and triggers matching workflows.
  • Constitutional compliance: Events remain within Pattern 2 (event-based integration).
Pattern 2c: Database Trigger → Edge Function
  • For automated processing triggered by database changes (INSERT, UPDATE, DELETE).
  • Database trigger calls pg_net to invoke edge function asynchronously.
  • Edge function performs complex processing (AI, external API calls, multi-step workflows).
  • Constitutional compliance: Async processing without blocking database transactions.
Pattern 3: API Contracts
  • Well-defined, versioned APIs with clear request/response schemas.
  • Documented in OpenAPI specs or equivalent.
  • Breaking changes require version bumps and migration paths.
When to Use Which:
  • Use Platform Integration Layer for shared utilities that multiple cores need (forms, notifications, file uploads).
  • Use Event-Based for asynchronous workflows and loose coupling.
  • Use API Contracts for synchronous, request-response interactions.
Example Integrations:
  • Form Submission → Entity Creation: FW map_to_entity action uses process-entity-mapping Edge Function to create/update records in FA, HR, RH tables from form submissions. Configuration maps form fields to entity columns + custom_fields JSONB.
  • Picklist Integration: FW Form Builder can use PF-15 picklists as data source for select fields, managed centrally in Platform Settings.
Prohibited:
  • Direct imports from one core into another (e.g., import { something } from '@/cores/fa/...' inside RH code).
  • Shared database tables between cores without explicit ownership.
Architecture Decision Records (ADRs):
  • Any exception to the above integration patterns MUST be documented as an ADR in docs/architecture/decisions/.
  • ADR format: Use specs/_templates/ADR_TEMPLATE.md.
  • ADRs are permanent records; they may be superseded but never deleted.
Rationale: Clear integration patterns prevent hidden dependencies and make the system easier to test, deploy, and evolve independently.

1.4 Form Ownership Pattern

The platform’s Forms & Workflow (FW) core provides form infrastructure used across all domain cores. To maintain clear ownership and enable module-specific views: Database:
  • All forms MUST have an owning_core column (type core_code enum)
  • Values: 'pf', 'rh', 'fa', 'hr', 'gr', 'fw', 'fm', 'ce', 'cl', 'pm'
  • Default: 'pf' (Platform Foundation / shared forms)
Module-Specific Views:
  • Each core SHOULD have a dedicated forms page at /{core}/forms
  • Example: /hr/forms shows only forms where owning_core = 'hr'
  • Platform admins can access all forms via /fw/forms
Form Creation:
  • Forms created within a core’s context default to that core’s owning_core
  • Example: Creating a form from /hr/forms/new defaults to owning_core = 'hr'
Platform Integration Layer:
  • useFormList accepts owningCore filter
  • FormSelector accepts owningCore prop
  • ModuleFormsPage provides reusable filtered list
Rationale: Explicit form ownership enables module-specific administration, improves user experience by showing only relevant forms, and maintains architectural clarity without violating core boundaries.

2. Specification‑First Delivery

No meaningful feature is built without a written specification.

2.1 Requirements

Every feature with non‑trivial impact MUST have a spec that:
  • Uses the spec template: specs/_templates/SPEC_TEMPLATE.md (see Section 2.3)
  • Names the core and module (e.g., RH-01: Census & Beds).
  • Articulates:
    • Business context and problem statement.
    • In‑scope / out‑of‑scope.
    • User stories and acceptance criteria.
    • Functional and non‑functional requirements.
    • Performance requirements (p50, p95, p99 targets).
    • Security considerations (PHI/PII, RLS, permissions).
    • Testing strategy (unit, integration, RLS, E2E).
    • Rollback strategy (for breaking changes).
    • Known limitations (deferred features, technical debt).
  • Defines:
    • Data model changes (entities, relationships).
    • Integration points and dependencies (documented in /docs/architecture/integrations/).
    • Success metrics (how we know it worked).

2.2 Process

  • Spec → Implementation Plan → Tasks → Delivery → Completion Report.
  • Any deviation from architecture or this constitution MUST be called out in the spec with rationale.
Rationale: Spec‑first delivery reduces rework, aligns stakeholders, and creates institutional memory.

2.3 Spec Template

All new specifications MUST use the template at specs/_templates/SPEC_TEMPLATE.md, which includes:
  • Required Sections: Business Context, Objectives, Scope, User Stories, Functional Requirements, Data Model, Integration Points, Performance Requirements, Security Considerations, Testing Strategy, Rollback Strategy, Known Limitations, Success Metrics, Implementation Plan.
  • Integration Documentation: All cross-core integrations must be documented in /docs/architecture/integrations/ with event schemas or API contracts. See docs/architecture/integrations/index.md for overview.
  • Constitutional Compliance: Each spec includes a checklist ensuring compliance with architecture, database, security, testing, and documentation requirements.
  • Implementation Plans: For complex features requiring multi-phase implementation, data migrations, breaking changes, or cross-module coordination, create a separate implementation plan using specs/_templates/PLAN_TEMPLATE.md. The spec template includes guidance on when a separate plan is needed.

3. Testing & Quality Discipline

Testing is a first‑class deliverable, not an afterthought.

3.1 Principles

  • Every business rule MUST be covered by automated tests.
  • Critical flows (auth, tenancy, billing, clinical, data movement) MUST have integration or end‑to‑end coverage.
  • No feature is “done” if tests are missing or flaky.
  • “Done” means reachable capability, not artifact‑existence. A spec is not complete because its files, tasks, or acceptance criteria exist on disk — it is complete when the terminal user action actually works. Dogfood it: stand the stack up and exercise the real path before claiming completion.
  • A skipped test is unproven, not passing. Treat green‑by‑skip (tests that skipIf a missing stack/seed/capability) as zero coverage for that claim, never as a pass. Prefer an honest failing result over a misleadingly green artifact, and state which path you actually ran.

3.2 Expectations

  • Unit tests: Core logic, utilities, hooks, isolated components.
  • Integration tests: Cross‑component flows, API contracts, RLS behavior, key DB workflows.
  • E2E tests: Priority journeys (e.g., admit resident → assign bed → bill → reconcile).
Suggested targets (to be tuned as we mature):
  • New modules: ~80%+ coverage for core logic.
  • Platform and cross‑cutting utilities: ~80%+.
  • Overall baseline: a sustainable bar agreed by engineering leadership.
Rationale: High‑risk domains (housing, finance, clinical, compliance) demand a strong testing posture to avoid regressions and production risk.

3.3 Test File Naming Conventions

Consistent test file naming enables automatic discovery and clear organization. File Naming Standards: Directory Structure:

3.4 Public API Documentation Coverage

Public function-like exports are part of product quality and maintainability and MUST be documented.
  • In-scope exported declarations (function declarations, classes, and function-valued exported constants) MUST include TSDoc/JSDoc comments.
  • Changed-file no-regression MUST be enforced before merge using npm run docs:comments:audit:changed.
  • Repository baseline coverage for in-scope declarations MUST be maintained at 100% unless an approved exception is documented in a spec/errata with owner and expiry.
  • Documentation comments MUST be meaningful (describe behavior and intent), not placeholder boilerplate.
Rationale: API-level documentation reduces onboarding friction, review ambiguity, and regression risk when ownership changes or cross-core integration evolves. Required Test Coverage by Feature Type: Test Templates: Use templates from specs/_templates/tests/ for consistent structure:
  • RLS_TEST_TEMPLATE.ts - Row-Level Security tests
  • UNIT_TEST_TEMPLATE.ts - Unit tests for hooks/utilities
  • INTEGRATION_TEST_TEMPLATE.ts - Workflow integration tests
  • E2E_TEST_TEMPLATE.ts - Playwright end-to-end tests
See Also: tests/README.md for comprehensive testing documentation.

4. Data, Security & Privacy

We operate as though under full HIPAA and payer audit from day one.

4.1 Security

  • Principle of least privilege for all users, services, and APIs.
  • All configuration secrets (keys, credentials, tokens) MUST be stored in secure environment management (not in code, migrations, or docs).
  • No backdoor “superuser” flows without explicit design, audit, and logging.

4.2 PHI / PII Handling

  • Use synthetic, de‑identified data in tests and examples.
  • Do NOT log free‑text PHI or full identifiers; prefer stable IDs and minimal necessary data.
  • Any export, report, or integration involving PHI MUST:
    • Be explicitly scoped in a spec.
    • Have a defined retention and access pattern.
  • Regulatory compliance tracking: Clinical and billing regulatory deadlines (e.g. 42 CFR Part 2, USCDI v3, CMS-0057-F, PDMP) MUST be tracked in docs/compliance/REGULATORY_COMPLIANCE_TRACKER.md. When a deadline is missed or at risk, interim procedures MUST be documented and followed until the responsible spec is implemented.
Rationale: Security and privacy violations are existential risks for the organization and the communities we serve.

4.3 AI Integration Security

The platform integrates AI capabilities via the Vercel AI Gateway (PF-111). All AI features MUST follow these security guidelines.

4.3.1 Architecture

  • AI features MUST use the Platform AI Integration Layer (@/platform/ai)
  • All AI calls MUST go through edge functions, NEVER direct client-side calls
  • Cores MUST NOT implement their own AI edge functions; use ai-assistant with module context
  • AI responses are stateless; conversation history is managed client-side

4.3.2 PHI Protection (CRITICAL)

  • NEVER send PHI/PII to external AI services
  • Sanitize all user input before including in AI prompts
  • Use anonymized identifiers (e.g., “Resident R-001” not “John Doe”)
  • Module context provides audit trail of AI usage per organization
  • AI features SHOULD require user consent (settings toggle)

4.3.3 API Key Security

  • AI_GATEWAY_API_KEY is an Edge Function Secret (PM-15-P2); read it via requireEnv('AI_GATEWAY_API_KEY') in _shared/ai/vercel-gateway.ts
  • NEVER expose the API key to client code

4.3.4 Model Selection

  • Models are routed per module, not a single global default — see STANDARD_MODELS / PHI_MODELS in supabase/functions/_shared/ai/models.ts (each entry is a [primary, fallback] pair). E.g. gr/hr/cl/pmanthropic/claude-sonnet-4.6; faopenai/gpt-4o; pf/rh/ce/fwgoogle/gemini-2.5-flash; lo/fmgoogle/gemini-2.5-flash-lite. Update routing there, not inline.

4.3.5 Error Handling

  • 429 (Rate Limited): Show “Please wait and try again”
  • 402 (Payment Required): Show “AI credits depleted” with link to settings
  • 500 (Gateway Error): Show “AI temporarily unavailable”
  • Network errors: Graceful degradation, non-AI fallback when possible

4.3.6 Integration Pattern

Pattern: Edge Function → Vercel AI Gateway → Response Stream

4.3.7 Module Context

All AI requests MUST include module context for audit and specialization:
  • module: Core code (pf, rh, fa, hr, gr, fw, fm, lo, it, ce, cl, pm)
  • feature: Specific feature within module
  • contextData: Additional metadata for prompt customization
  • jurisdictionProfileId: (optional) When the AI feature operates in a jurisdiction-sensitive context (CL, PM, GR), include the organization’s jurisdiction profile ID so AI responses can be tailored to the correct state’s regulations and compliance rules. AI prompts MUST NOT include PHI/PII regardless of jurisdiction context.
Rationale: Centralized AI integration ensures consistent security, audit trails, and cost management across all modules. Jurisdiction context enables state-aware AI advice without duplicating compliance logic.

4.4 Permissions System Architecture (PF-30)

The platform implements a three-tier permission system for granular access control: Tier 1: Module Permissions (PF-30)
  • Format: {module}.{entity}.{action}
  • Examples: hr.employees.view, fa.bills.approve, rh.residents.create
  • Categories: view, create, edit, delete, approve, admin
  • Defined in pf_module_permissions table (1,600+ permissions; baseline seed + ~19 *_permissions_sync_* migrations)
  • See docs/pf/module-permissions-matrix.md for complete catalog
Tier 2: Object Permissions (PF-26)
  • Entity-level access with actions (view, create, edit, delete) per role
  • Defined per record or record type
Tier 3: Field-Level Permissions (PF-26)
  • Field visibility rules per role
  • Controls which fields users can see/edit
Permission Check Hierarchy:
If any tier fails, access is denied. Custom Roles:
  • Organizations can create custom roles with specific permission sets
  • Custom roles can optionally inherit from system roles (staff, readonly, site_admin)
  • Custom roles CANNOT inherit from org_admin or platform_admin (security constraint)
  • See pf_custom_roles and pf_role_permissions tables
Role Assignment:
  • Users assigned via pf_user_role_assignments table
  • Supports site-scoped assignments (site_ids column)
  • Supports time-limited access (expires_at column)
  • Users can have multiple roles
System Status:
  • V2 is the only active permission system
  • All organizations use granular permissions exclusively
  • Legacy pf_user_roles table is read-only (retained for audit/rollback purposes)
Rules:
  1. All UPDATE RLS policies for permission tables MUST include WITH CHECK clause
  2. Permission checks MUST use pf_has_permission() SECURITY DEFINER function
  3. Navigation filtering MUST use permission-based access control
  4. Permission checks are cached for 5 minutes (React Query staleTime)
  5. Custom roles scoped to organization (multi-tenant isolation)
Rationale: Granular permissions enable organizations to customize access control beyond fixed roles while maintaining security through explicit allow-listing.

5. Database, Naming & Environment Guardrails

The database is a core part of the platform, not an implementation detail. We treat it as product.

5.1 Multi‑Tenant Data Model

  • All business data tables MUST include tenant context (for example organization_id, and site_id where applicable).
  • Application-layer filter: Filtering by organization_id (and site_id where applicable) is REQUIRED on all mutations (INSERT, UPDATE, DELETE) as defense-in-depth. It is RECOMMENDED on SELECT queries as defense-in-depth alongside RLS; RLS remains the primary enforcement for reads.
  • Row‑Level Security (RLS) (or equivalent mechanism) MUST be enabled and enforced on all business tables.
  • RLS policies MUST guarantee:
    • No cross‑organization data leakage.
    • Restricted cross‑site visibility according to defined roles.
  • Any change to RLS MUST be accompanied by test coverage validating the tenant‑isolation behavior.
  • Jurisdiction-aware configuration: Organization-level and site-level business rules that vary by state Medicaid program (e.g., clinical assessment requirements, billing thresholds, filing deadlines, documentation timeliness) SHOULD be read from the jurisdiction profile system (PF-96) when available. Until PF-96 is implemented, state-specific configuration MAY use module-level settings with documented migration paths and TODO(PF-96) markers. New features in CL and PM MUST NOT introduce state-specific constants without a TODO(PF-96) marker; they SHOULD consume values from pf_jurisdiction_profiles, pf_org_jurisdiction_config, or pf_site_jurisdiction_config once available. See specs/pf/specs/PF-96-medicaid-state-compliance-configuration.md.

5.2 Database Naming Conventions

Schemas
  • Prefer a single primary application schema (e.g., public) unless a compelling separation exists.
  • If multiple schemas are used, each schema MUST have a documented ownership and purpose.
Tables
  • All table names use snake_case and should be plural (e.g., rh_residents, fa_transactions).
  • Tables owned by a core MUST be prefixed with that core:
    • pf_ – Platform Foundation (e.g., pf_users, pf_organizations, pf_sites).
    • rh_ – Recovery Housing (e.g., rh_residents, rh_beds, rh_phases).
    • fa_ – Finance (e.g., fa_transactions, fa_ledgers).
    • hr_ – Workforce & HR (e.g., hr_employees, hr_credentials).
    • gr_ – Governance & Learning (e.g., gr_policies, gr_training_events).
    • fw_ – Forms & Workflow (e.g., fw_forms, fw_workflow_runs).
    • fm_ – Facilities & Maintenance (e.g., fm_work_orders).
    • cl_ – Clinical & EHR (e.g., cl_patient_charts, cl_progress_notes, cl_prescriptions).
    • pm_ – Practice Management (e.g., pm_patients, pm_claims, pm_appointments).
  • Junction tables use both entities with an underscore, ordered alphabetically (e.g., rh_resident_phases, fa_transaction_tags).
Columns
  • All column names use snake_case.
  • Primary keys:
    • Prefer id as the primary key column, with type uuid or integer as documented in the DB architecture.
    • If a natural key is used, it MUST be documented in the spec.
  • Foreign keys:
    • Use <entity>_id corresponding to the referenced table (e.g., resident_id, organization_id, site_id).
  • Standard audit columns:
    • created_at (UTC timestamp).
    • updated_at (UTC timestamp).
    • created_by (user ID, where applicable).
    • updated_by (user ID, where applicable).
  • Soft‑delete pattern (where used):
    • deleted_at (nullable UTC timestamp).
    • Records with deleted_at not null are considered logically deleted.

5.2.1 Custom Fields & Extensibility

Purpose: Enable organizations to extend business entities with domain-specific metadata without schema changes. When to Use custom_fields: All business entity tables MUST include custom_fields JSONB DEFAULT '{}' NOT NULL unless:
  • The table is purely a junction/mapping table (e.g., hr_team_members, rh_resident_phases).
  • The table is an audit/log table (e.g., pf_audit_logs, fw_automation_logs).
  • The table is a system/configuration table managed exclusively by the platform.
Examples of business entities requiring custom_fields:
  • Core entities: pf_profiles, hr_employees, rh_residents, fa_transactions
  • Workflow entities: fw_form_submissions, fw_automation_rules, hr_onboarding_instances
  • Document entities: pf_documents, hr_employee_credentials
Custom Fields vs. Settings vs. Preferences: Design rules (summary):
  • Include custom_fields in migrations with COMMENT ON COLUMN and 3–5 realistic examples (not generic placeholders).
  • Query with ?, ->>, @> as needed; add a GIN index on custom_fields when queried heavily.
  • custom_fields inherits the table’s RLS; do not store secrets (SSN, passwords) in JSONB.
Playbook: Migration snippets, table template, and patterns: docs/development/DATABASE_DEVELOPMENT_GUIDE.md § Creating Tables with RLS and Custom Fields. New Table Checklist: When creating a new business entity table, developers/AI MUST:
  • ✅ Include organization_id (multi-tenant context)
  • ✅ Include custom_fields JSONB DEFAULT '{}' (extensibility)
  • ✅ Include created_at, updated_at (audit trail)
  • ✅ Add COMMENT ON COLUMN with 3-5 example use cases
  • ✅ Enable RLS policies
  • ✅ All UPDATE policies include WITH CHECK clause (see §5.2.9)
  • ✅ Document in spec and IMPLEMENTATION_LOG.md

5.2.2 Organizational Data Structure

Purpose: Standardize organizational data entities across all modules for consistent policy assignment, access control, and reporting. Platform Foundation Organizational Entities:
  • Sites (pf_sites): Physical work locations with tax jurisdiction and address
  • Departments (pf_departments): Unified organizational units (operational + cost centers)
  • Levels (pf_levels): Employee classification with numerical ranking
  • Positions (pf_positions): Job title library for consistency
  • Teams (pf_teams): Cross-functional groups
Design Rules:
  1. Unified Departments: Use pf_departments for both HR and FA (not separate tables)
    • department_type field: ‘operational’ | ‘cost_center’ | ‘both’
    • Single source of truth eliminates duplication
  2. Work Location: Use primary_site_id (NOT work_location TEXT) for employee location
    • pf_sites includes tax_jurisdiction, address fields, timezone for structured operations
  3. Level Assignment: All employees should have level_id for policy assignment
    • Levels enable level-based policies (spend policies, access control)
    • level_rank (1-10) for ordering and formula fields
  4. Site Usage: Include site_id (nullable) when entity is location-specific
    • Required for: residences, work orders, assets, site-specific policies/forms
    • Optional for: organization-wide entities (strategic goals, vision)
  5. Programs: rh_programs (operational) and fa_programs (financial) serve different purposes
    • rh_programs: Resident program structure, phase management
    • fa_programs: Medicaid cost reporting, grant tracking
    • Optional relationship: fa_programs.rh_program_id for financial tracking
Module-Specific Organizational Entities:
  • RH: rh_programs (operational/resident programs)
  • FA: fa_programs (financial/cost reporting programs), fa_funds
  • HR: hr_employees, hr_employee_sites
Jurisdiction Profile Assignment:
  • Organizations MUST have a jurisdiction_profile_id FK to pf_jurisdiction_profiles (PF-96)
  • Sites MAY override the organization’s jurisdiction profile via pf_site_jurisdiction_config for multi-state operations (e.g., telehealth providers operating across state lines)
  • The jurisdiction profile provides state-specific clinical, billing, and compliance configuration consumed by CL, PM, and GR features
  • Profile resolution order: site override → organization profile → federal baseline defaults
Integration:
  • All modules reference pf_departments, pf_sites, pf_levels, pf_teams
  • CL and PM modules reference pf_jurisdiction_profiles for state-specific rules
  • No cross-core dependencies (all via Platform Foundation)
  • Organizational data managed through Platform Foundation, consumed by domain cores
Rationale: Unified organizational data structure enables consistent policy assignment, access control, and reporting across all modules while maintaining clear architectural boundaries. Jurisdiction profiles extend this to state-specific compliance configuration.

5.2.3 Module Settings Pattern

Purpose: Enable organization-level configuration of module behavior without code changes or environment-specific configuration. When to Use Module Settings: Every domain core (HR, FW, RH, FA, etc.) SHOULD have a module settings table and admin page unless the module has no configuration requirements. Required Components:
  1. Settings Table: {core}_module_settings
    • One row per organization (1:1 relationship)
    • Contains configuration columns specific to the module
    • Includes standard audit columns (created_at, updated_at, created_by, updated_by)
    • RLS policies: View (org users), Insert/Update (org_admin only)
  2. Admin Page: src/cores/{core}/pages/{Core}Settings.tsx
    • Route: /{core}/settings
    • Access: org_admin only (enforced in navigation and route)
    • Tabbed interface organizing related settings
    • Auto-creates settings record if not exists
  3. Hook: src/cores/{core}/hooks/use{Core}ModuleSettings.ts
    • Query hook: Fetch organization’s settings
    • Mutation hooks: Create/update settings
    • Handles loading states, errors, cache invalidation
  4. Form Component: src/cores/{core}/components/{Core}SettingsForm.tsx
    • Tabbed form matching logical groupings
    • Form validation with Zod schemas
    • Save/reset actions with confirmation
DDL template: docs/development/DATABASE_DEVELOPMENT_GUIDE.md § Constitution playbook: PF DDL templates — Module settings table. UI pattern: docs/development/settings-pattern-guide.md — shared settings layout, skeletons, and form structure. When to use settings vs elsewhere (decision rule):
  • Settings when organizations differ in requirements/preferences — time-based values, business-rule thresholds, UI/UX defaults, performance tuning, feature behavior.
  • Jurisdiction profile (pf_jurisdiction_profiles, PF-96) when the value varies by state Medicaid program (filing deadlines, timed-code thresholds, assessment / documentation-timeliness rules). Module settings override profile defaults only when an org explicitly customizes beyond its jurisdiction baseline.
  • Hard-code only system constants (enum values, system-wide limits).
When writing a spec, identify hard-coded values and document them in the spec’s “Settings Considerations” section. Admin-page requirements, the per-core status matrix, the new-core implementation checklist, and examples are the extended reference — see settings-pattern-guide.md; do not duplicate them here.

5.2.4 Centralized Picklist System

Purpose: Enable organizations to define and manage custom picklist values without code changes or database migrations, providing flexibility for domain-specific workflows. When to Use Picklists vs Enums: Playbook: Table DDL, indexes, and example RLS: docs/development/DATABASE_DEVELOPMENT_GUIDE.md § Constitution playbook — Picklists. Application hooks and UI: specs/pf/PF-15-picklist-system.md. Custom field definitions may reference picklist_id on pf_custom_field_definitions (same guide § Custom field definitions). Spec-Authoring Checklist (Picklist Evaluation): When a spec introduces new status fields, categories, types, reasons, or any dropdown/select option list:
  • Evaluate each value list against the Picklists vs Enums table above
  • Document the decision in the spec’s Enums and Source Types section: Picklist: Yes (org-customizable) | No (system constant, reason: ___)
  • If picklist: add a task to seed default picklist values via migration (INSERT INTO pf_picklists / pf_picklist_items)
  • If picklist: reference in forms via usePicklistItems(picklistId) instead of hardcoded <option> elements or CHECK constraints
  • If enum: use CHECK (column IN (...)) only for true system constants; document why the values are not org-customizable
Rationale: Organizations have diverse terminology and workflow requirements that can’t be predicted upfront. Picklists provide flexibility while maintaining data integrity and multi-tenant isolation.

5.2.5 Custom Field Definitions (PF-16)

Status: Implemented — see specs/pf/PF-16-custom-field-definitions.md for hooks, components, admin UI, and supported entities. Purpose: Enable organizations to define schema-like metadata for custom fields, providing structure and validation for the JSONB custom_fields column. When to Use Custom Field Definitions: Custom field definitions are appropriate when:
  • Organizations need to document what custom fields they use
  • Validation rules are required for custom field values
  • UI needs to dynamically render custom field inputs
  • Reporting needs to know custom field schemas
Playbook: DDL, example RLS, and validation_rules JSON samples: docs/development/DATABASE_DEVELOPMENT_GUIDE.md § Constitution playbook — Custom field definitions. Relationship to custom_fields JSONB:
  • custom_fields column: Stores actual data values (flexible, unstructured)
  • pf_custom_field_definitions: Stores metadata about what fields exist (structured, documented)
  • Custom field definitions are OPTIONAL — organizations can use custom_fields without defining schemas
  • When definitions exist, UI can provide better forms, validation, and reporting
Hooks, admin UI, components, and the build checklist live in specs/pf/PF-16-custom-field-definitions.md.

5.2.6 Entity Field Configuration (PF-17) ✅

Purpose: Enable organizations to control field layouts, visibility, and permissions for entity forms without code changes. Design principles (guardrails):
  • Configuration applies to UI only, NOT database schema — DB constraints (e.g. NOT NULL columns) remain unchanged.
  • Per-entity-type (e.g. hr_employees, rh_residents); org admins manage via UI, no code changes.
  • Mobile responsive: column_span: 2 becomes full width on mobile.
Key features, components, admin UI, and the implementation reference live in specs/pf/PF-17-entity-field-configuration.md.

5.2.7 PWA & Mobile Considerations

Offline Data:
  • Tables that support offline functionality MUST be designed with sync capabilities
  • Consider sync_status or last_synced_at columns for offline-first features
  • Background sync queues SHOULD use dedicated tables (e.g., fw_offline_queue)
Mobile Performance:
  • Indexes MUST be optimized for mobile query patterns
  • Avoid N+1 queries that impact mobile performance
  • Consider materialized views for dashboard aggregations
Indexes & Constraints
  • Every foreign key column used in joins MUST have an index.
  • Unique constraints MUST be named explicitly and reflect purpose (e.g., rh_residents_organization_id_external_id_key).
Storage Buckets
  • Storage bucket names MUST follow the pattern: {core_prefix}-{purpose}
    • Examples: pf-avatars, pf-documents, fw-submission-attachments
  • Public vs private buckets MUST be explicitly documented in specs
  • Bucket RLS policies MUST enforce tenant isolation
Database Functions
  • Function names MUST follow the pattern: {core_prefix}_{action}_{entity}()
    • Examples: pf_has_role(), fw_execute_automation_rule(), rh_calculate_occupancy()
  • All functions that support RLS policies MUST be SECURITY DEFINER
  • Function ownership and purpose MUST be documented in migration comments

5.2.8 Cross-Core Database References

When a table in one core needs to reference an entity owned by another core:
  • Default pattern: UUID column with no FK constraint. Validation at the application layer. Column comment MUST document the target table and owning core.
  • Scoped exception (requires ADR): For tightly coupled domains where referential integrity is critical (e.g., CL-PM encounter references), a database FK MAY be used with ON DELETE RESTRICT. An ADR in docs/architecture/decisions/ MUST document the exception, its scope, and its rationale.
  • Column naming: Use {target_entity}_id (e.g., encounter_id for pm_encounters).
  • Indexes: Cross-core reference columns MUST be indexed.

5.2.9 RLS UPDATE Policy Requirements

Critical Rule: All RLS UPDATE policies MUST include both USING and WITH CHECK clauses. Why This Matters:
  • USING controls which rows can be selected for update
  • WITH CHECK controls what values the row can be updated to
  • Without WITH CHECK, a user can change organization_id to move data between tenants
Standard UPDATE Pattern:
Creator-Only UPDATE with Tenant Protection:
Failure Mode: Without WITH CHECK, a user who can update a row can change its organization_id, effectively moving data between tenants and breaking multi-tenant isolation. Playbook: Full patterns and examples live in docs/development/DATABASE_DEVELOPMENT_GUIDE.md § RLS Policy Patterns.

5.3 Migrations & Change Management

  • All schema changes MUST be implemented as migrations in version control.
  • Migrations MUST be:
    • Monotonic and ordered via timestamp or sequence.
    • Re‑runnable in lower environments from a clean database.
  • Migration file naming:
    • Manual migrations: YYYYMMDDHHMMSS_core_short_description.sql (14-digit timestamp, seconds included — matches every file under supabase/migrations/)
      Example: 20260522143000_rh_add_resident_phases.sql.
    • Lovable-generated migrations: Auto-generated names are acceptable (e.g., 20241124123456_remote_schema.sql)
    • The important requirement is monotonic ordering and clear purpose in comments, not the exact filename format.
  • Direct schema changes in shared environments are prohibited except emergency hotfixes; those require:
    • Documentation of the hotfix.
    • Follow‑up migration to codify the change.
  • Destructive changes (dropping tables/columns, changing primary keys, altering tenant keys) MUST:
    • Be explicitly marked as breaking in the spec.
    • Include a data‑migration strategy and rollback considerations.

5.4 Environment Separation

  • Local, dev, staging, and prod environments MUST each have:
    • Separate databases and credentials.
    • Clear, documented data refresh patterns.
  • Pre‑merge validation MUST:
    • Run migrations against a non‑prod database.
    • Run the test suite relevant to the changes (unit, integration, RLS, etc.).

5.5 Production Deployment & Rollback

Deployments to production require discipline and a clear rollback strategy. Deployment Requirements:
  • All production deployments MUST:
    • Pass the full test suite in a staging environment.
    • Have a documented rollback plan.
    • Be tagged with semantic version numbers.
    • Include a deployment checklist (migrations, config changes, feature flags).
  • Database migrations in production MUST be:
    • Backward-compatible whenever possible.
    • Applied before code deployment (to support rollback).
    • Tested against a production-like dataset.
Rollback Strategy:
  • Code rollback: Previous version available via version control tags.
  • Database rollback: Documented down-migrations for each schema change.
  • Feature flags: Use flags to disable new features without redeployment.
  • Monitoring: Alert on error rate spikes, latency increases, or failed health checks.
Emergency Hotfixes:
  • Require explicit approval from technical owner.
  • Must be followed by a proper migration and test coverage.
  • Documented in IMPLEMENTATION_LOG.md within 24 hours.

5.6 Performance & Monitoring Standards

The platform MUST be observable and performant. Performance Targets:
  • API response time: p95 < 500ms for read operations, p95 < 2s for writes.
  • Page load time: p95 < 3s for initial load, p95 < 1s for navigation.
  • Database queries: Index all foreign keys; no full table scans in production.
Monitoring Requirements:
  • All production deployments MUST have:
    • Health check endpoints (/health, /readiness).
    • Error tracking (e.g., Sentry, Rollbar).
    • Structured logging with correlation IDs.
    • Database query performance monitoring.
  • Critical flows (auth, billing, clinical) MUST have:
    • Synthetic monitoring (uptime checks).
    • Alerting on error rates > 1% or latency p95 > SLA.
Logging Standards:
  • Use structured JSON logs with standard fields: timestamp, level, module, action, user_id, org_id, correlation_id.
  • Do NOT log PHI, PII, or secrets.
  • Log retention: 30 days for info, 90 days for errors, 1 year for audit logs.
Rationale: Tenancy mistakes, naming chaos, and poor DB hygiene are the fastest ways to break trust, slow delivery, and lose control of the platform.

5.7 RLS Anti-Patterns & Security Definer Functions

Critical: Avoiding Infinite Recursion RLS policies MUST NOT query the same table they are protecting. This causes infinite recursion errors. ❌ WRONG - Recursive RLS Policy:
✅ CORRECT - Security Definer Function:
When to Use SECURITY DEFINER Functions:
  • When RLS policies need to query other tables to make authorization decisions
  • When checking role-based access that requires joining tables
  • When implementing reusable authorization logic across multiple policies
Security Definer Function Requirements:
  • MUST be explicitly marked as SECURITY DEFINER with SET search_path = public
  • MUST have clear, descriptive names indicating their purpose
  • MUST be tested thoroughly to prevent privilege escalation
  • MUST be documented in specs and migration comments
Rationale: SECURITY DEFINER functions execute with the privileges of the function owner (usually postgres), bypassing RLS. This breaks recursion and provides a safe, reusable way to implement complex authorization logic.

5.8 Edge Function Patterns

Edge functions extend backend capabilities for complex processing, external integrations, and async workflows.

5.8.1 Shared Code Pattern

When multiple edge functions need common logic: Location: supabase/functions/_shared/ Structure:
Usage:
Requirements:
  • All shared code MUST be Deno-compatible (no Node.js-specific APIs)
  • Shared utilities MUST be stateless and side-effect-free
  • Types MUST be exported for consumer functions
  • NEVER import from src/ - shared code lives in _shared/
  • Edge functions MUST use verifyOrgAccess() or verifyOrgRole() from _shared/auth.ts for organization membership checks. Inline pf_user_role_assignments queries are prohibited — they are prone to PGRST116 errors and bypass centralized .limit(1) safeguards.

5.8.2 Database Trigger → Edge Function Pattern

For async processing triggered by database changes: When to Use:
  • AI-assisted processing (summarization, extraction)
  • External API calls (webhooks, integrations)
  • Multi-step workflows
  • Long-running operations that shouldn’t block the transaction
Implementation:
Best Practices:
  • Use AFTER triggers (not BEFORE) to avoid blocking transactions
  • Include organization_id for tenant context
  • Handle edge function errors gracefully (don’t fail the trigger)
  • Log trigger invocations for debugging

5.9 Scheduled Task Pattern

For recurring background jobs using pg_cron and pg_net. When to Use:
  • Daily/weekly reports and summaries
  • Data cleanup and archival
  • Scheduled syncs with external systems
  • Recurring notifications (e.g., “credentials expiring this week”)
  • Aggregation and metric calculations
Implementation:
Cron Expression Reference: Job Management:
Best Practices:
  • Use descriptive job names with core prefix
  • Document schedule and purpose in code comments
  • Edge function MUST handle idempotency (safe to run multiple times)
  • Include triggered_at in payload for debugging
  • Set up alerts for failed job runs
  • Consider timezone implications (pg_cron runs in UTC)
Rationale: Scheduled tasks enable automation of recurring operations without external infrastructure, maintaining the platform’s serverless architecture.

5.10 Bulk Import & Data Migration Standards

Bulk import means parsing CSV (or similar) and writing records to the database. All such flows MUST follow these standards. Shared CSV Parsing:
  • MUST use shared CSV parsing from Platform (@/platform/csv or the documented shared location). No duplicate parseCsvLine/parseCsv implementations in cores or platform components.
Edge Function vs Client-Side:
  • Use an edge function when the import involves multi-entity creation, auth/invites, or transaction ordering that must be server-side (e.g., employee roster with sites, departments, profiles, and optional user accounts).
  • Use client-side chunked insert for simple insert-only to one or a few tables (e.g., contacts, credentials, custom object records). Batch size MUST be 50 unless justified otherwise.
Progress & UX:
  • For client-side bulk insert, show determinate progress when the operation can exceed a few seconds (e.g., percentage per batch).
  • For edge-function-based import, indeterminate progress is acceptable unless the function supports progress reporting.
Post-Import:
  • After successful import, invalidate every query key affected by the import (e.g., list and detail queries for the imported entity and any related entities).
References:
  • docs/development/BULK_IMPORT_MIGRATION_RECOMMENDATIONS.md
  • docs/guides/use-cases/bulk-import-migration.md

6. PWA & Mobile-First Requirements

Encore OS is a Progressive Web App (PWA) with mobile-first responsive design. All features MUST be designed and implemented with mobile devices as the primary target, with desktop as an enhancement.

6.1 PWA Requirements

Installability:
  • All builds MUST include proper PWA manifest with real app icons (not placeholders)
  • Icons MUST be provided in required sizes: 192x192, 512x512, with maskable support
  • Manifest MUST include app name, short name, theme color, background color
  • Install prompt MUST be implemented for discoverability
Offline Functionality:
  • Forms and submissions MUST work offline with background sync
  • Critical user flows MUST degrade gracefully when offline
  • Offline detection UI MUST be provided
  • Service worker MUST be properly configured and tested
Performance:
  • Lighthouse PWA score MUST be 90+ in production
  • First Contentful Paint: <2s
  • Time to Interactive: <3.5s on 3G
  • All assets MUST be cached appropriately
Testing:
  • PWA install flow MUST be tested on iOS, Android, and desktop
  • Offline functionality MUST be tested
  • Service worker updates MUST be tested
  • Lighthouse audit MUST be run before production deployment

6.2 Mobile-First Design Principles

Responsive Breakpoints:
  • Mobile: < 768px (primary target)
  • Tablet: 768px - 1024px
  • Desktop: > 1024px
  • All layouts MUST work on mobile first, then enhance for larger screens
Touch Targets:
  • All interactive elements MUST have minimum 44x44px touch targets
  • Spacing between touch targets MUST be at least 8px
  • Buttons, links, and form controls MUST meet accessibility standards
Safe Area Insets:
  • All fixed navigation elements (top header, bottom nav) MUST account for safe area insets
  • Use env(safe-area-inset-top) and env(safe-area-inset-bottom) in CSS
  • Test on devices with notches and home indicators (iPhone X+, modern Android)
Orientation:
  • Primary orientation: Portrait
  • Landscape orientation MUST be supported but may have simplified layouts
  • Critical features MUST work in both orientations
Performance:
  • Mobile pages MUST load in <3s on 3G
  • Images MUST be optimized and lazy-loaded
  • Code splitting MUST be used for route-based components
  • Heavy components MUST be lazy-loaded

6.3 Navigation Requirements

Navigation Documentation:
  • All modules MUST have a navigation worksheet at specs/{core}/navigation/NAVIGATION_WORKSHEET.md
  • Navigation worksheets MUST use the template from specs/_templates/NAVIGATION_WORKSHEET_TEMPLATE.md
  • Navigation worksheets MUST document all navItems, navGroups, routes, permissions, and breadcrumb configuration
  • Navigation worksheets MUST be updated when adding or restructuring navigation
Navigation Structure:
  • Modules MUST have 4-8 navGroups (recommended)
  • Each navGroup MUST have 3-7 items (recommended)
  • Single-item groups MUST be merged into related groups
  • Groups with 8+ items SHOULD be split into logical subgroups
Icon Consistency:
  • Each distinct feature MUST have a unique icon within the same navigation context
  • Icons MUST be imported from lucide-react exclusively
  • Icons MUST be semantically meaningful and visually distinct
  • Duplicate icons for different features are prohibited
Mobile Navigation:
  • Bottom tab bar MUST be used for primary navigation (< 768px)
  • Bottom nav MUST include safe area insets
  • Mobile menu sheet MUST provide access to all modules and nested navigation
  • Navigation state MUST be preserved across page refreshes where applicable
  • Mobile header SHOULD display current location context (breadcrumb or page title)
Desktop Navigation:
  • Desktop primary navigation (>= 768px) MUST offer at least Sidebar mode; MAY offer Dock and Taskbar as user-selectable alternatives.
  • When Sidebar mode is selected, sidebar open and collapse state MUST be persisted (e.g. in localStorage).
  • Breadcrumbs MUST be provided for deep navigation (3+ levels)
  • Active state indicators MUST be clear and accessible
Accessibility:
  • All navigation MUST be keyboard accessible
  • Focus indicators MUST be visible
  • ARIA labels MUST be provided for screen readers
  • Navigation depth MUST be reasonable (max 4 levels recommended)
See: docs/architecture/standards/NAVIGATION_STANDARD.md for complete navigation standards and docs/architecture/standards/PERMISSION_KEY_STANDARD.md for permission key patterns.

6.3.1 Breadcrumb Standards

Breadcrumbs provide hierarchical navigation context and MUST be implemented consistently across the platform. Architecture:
  • Base Primitives: Use @/shared/ui/breadcrumb components (Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator)
  • Auto-Generated: Desktop header uses @/platform/navigation/Breadcrumbs.tsx for automatic route-based breadcrumbs
  • Route Labels: Centralized in @/platform/navigation/route-labels.ts (~150 routes across all modules)
  • Mobile Support: Mobile navigation MUST include MobileBreadcrumbs component (max 2 segments, horizontally scrollable)
When to Show Breadcrumbs:
  • ✅ Detail pages (viewing/editing a specific entity)
  • ✅ Nested settings pages (3+ levels deep)
  • ✅ Multi-step workflows
  • ❌ Module overview/dashboard pages (ModuleSwitcher provides context)
  • ❌ Top-level list pages (e.g., /hr/employees)
  • For tabbed hub routes (?tab=), the active tab is included as the final breadcrumb segment (see NAVIGATION_STANDARD §2a and hub-tab-labels).
Implementation patterns (in priority order): (1) rely on auto-generated header breadcrumbs (default — most pages need nothing); (2) PageContainer breadcrumbs={[…]} showBreadcrumbs for dynamic entity names / non-route segments; (3) manual @/shared/ui/breadcrumb primitives (rare). Full code + step-by-step: breadcrumb-implementation-guide.md. Route Label Maintenance:
  • All route labels are centralized in src/platform/navigation/route-labels.ts; Breadcrumbs use this for segment labels
  • Tab context for hub routes (?tab=) comes from hub-tab-labels (or the central hub-tab config in @/platform/navigation/hub-tab-labels.ts); implementers should maintain both route-labels and hub-tab-labels when adding tabbed hubs
  • When adding new features, add corresponding labels to ROUTE_LABELS map
  • Naming conventions:
    • Use sentence case: “Work orders” not “Work Orders”
    • Be concise: “Employees” not “Employee Management”
    • Match UI terminology consistently
  • Fallback: Path segments are auto-capitalized (e.g., work-orders → “Work Orders”)
Mobile Requirements (CRITICAL):
  • Mobile header MUST include MobileBreadcrumbs component
  • Maximum 2 visible segments on mobile (truncate earlier segments)
  • Use horizontal scroll for overflow content
  • Touch targets MUST be 44x44px minimum
  • Breadcrumbs MUST respect safe area insets
Prohibited Patterns:
  • ❌ Manual inline breadcrumbs without using components (e.g., raw <div> with ChevronRight)
  • ❌ Breadcrumbs that don’t match actual navigation hierarchy
  • ❌ Non-clickable intermediate breadcrumb segments (except current page)
  • ❌ Skipping ROUTE_LABELS when adding new routes
  • ❌ Creating module-specific route label files (use centralized file only)

6.4 Dashboard Standards

Layout Patterns:
  • Dashboards MUST use consistent widget-based layouts
  • Grid system MUST be responsive (1 column mobile, 2-3 columns desktop)
  • Widgets MUST be self-contained and reusable
  • Loading states MUST be standardized (use skeleton loaders)
User Customization (REQUIRED):
  • Module dashboards MUST support user widget customization
  • Widget visibility is two-tier: org admins enable/disable widgets platform-wide via pf_module_settings.enabled_widgets (JSONB boolean map, default-ON — absent key = enabled), checked with useWidgetEnablement() from @/platform/dashboard/hooks/useWidgetEnablement; per-user show/hide preferences MUST be stored in pf_user_dashboard_preferences and apply only to widgets the org has enabled.
  • Widget ID naming convention: {core}-{feature} (e.g., fa-budget-alerts, hr-time-clock)
  • Users MUST be able to show/hide widgets via settings dialog
  • Widget reordering SHOULD be supported via drag-and-drop
Widget Implementation Standards:
  • All dashboard widgets MUST use DashboardWidget wrapper from @/platform/dashboard/components/DashboardWidget
  • Widgets MUST be lazy-loaded using React.lazy() for performance
  • Widgets MUST handle loading, error, and empty states gracefully
  • Widgets MUST be registered in @/platform/dashboard/widget-registry.ts for platform-wide availability
  • Widget components location: src/cores/{core}/components/dashboard/
  • Widget file naming: {Feature}Widget.tsx (e.g., BudgetAlertsWidget.tsx, TimeClockWidget.tsx)
Data Fetching:
  • Dashboards MUST fetch real-time data (NO hardcoded values)
  • Each module SHOULD have a consolidated use{Core}DashboardStats.ts hook
  • Use React Query with appropriate staleTime (5 minutes for dashboard data)
  • Implement optimistic updates where applicable
Content Requirements:
  • Main dashboard MUST include personalized content (not just module launcher)
  • Dashboards MUST show recent activity where applicable
  • Empty states MUST be provided with helpful CTAs
  • Quick actions MUST be prominently displayed
Performance:
  • Dashboards MUST implement progressive loading (above-the-fold first)
  • Heavy widgets MUST be lazy-loaded
  • Real-time updates MUST use Supabase realtime subscriptions
  • Dashboard load time MUST be <2s on desktop, <3s on mobile
Consistency:
  • All module dashboards MUST follow shared dashboard patterns
  • Widget components MUST be reusable across modules
  • Dashboard customization is REQUIRED for all module dashboards
Rationale: Mobile-first design ensures the platform is accessible to field staff using mobile devices, while PWA capabilities enable offline work and native app-like experience. Consistent navigation and dashboard patterns reduce cognitive load and improve user efficiency.

6.5 Frontend Performance Patterns

Frontend performance is critical for PWA and mobile-first experience. These patterns are MANDATORY for all new code. Playbook: Copy-paste examples and the pattern index: AGENTS.md (Quick Reference), .cursor/rules/quick-reference.mdc, .cursor/rules/performance-patterns.md. Route-Level Code Splitting (REQUIRED):
  • ALL route components MUST use React.lazy() for code splitting; direct route component imports are PROHIBITED.
Suspense Boundaries (REQUIRED):
  • Route-level Suspense MUST wrap lazy-loaded routes; use RouteLoadingSkeleton / AppLoadingSkeleton as documented in platform navigation components.
Loading States (REQUIRED):
  • NEVER use return null during loading; use skeleton loaders from @/platform/navigation/components/ to avoid CLS.
QueryClient Configuration (REQUIRED):
  • Default query options SHOULD include staleTime 5 minutes, gcTime 10 minutes, retry: 1, refetchOnWindowFocus: false (see global app setup).
Font Optimization (REQUIRED):
  • Maximum 2–3 font families; font-display: swap; preconnect for font CDNs; no duplicate font imports.
Preconnect Hints (REQUIRED):
  • Preconnect to critical origins (e.g. Google Fonts, Supabase project host) in app HTML/template per platform setup.
Performance Targets:
  • Lighthouse Performance Score: 85+
  • First Contentful Paint: <2s
  • Largest Contentful Paint: <2.5s
  • Cumulative Layout Shift: <0.1
  • Time to Interactive: <3.5s on 3G
Rationale: These patterns reduce initial bundle size by 60-80%, prevent layout shift, and enable fast page transitions essential for PWA experience.

6.6 Authentication State Management

Critical Rules:
  • ALWAYS use useCurrentUser hook from @/platform/auth (not scattered supabase.auth.getUser() calls)
  • ALWAYS use static Supabase imports at file top (never dynamic imports in useState or elsewhere)
  • ALWAYS use useEffect for auth side effects (NEVER useState for side effects)
  • NEVER call supabase.auth.getUser() directly in components or hooks
Benefits:
  • Performance: Single API call instead of 162+ (99% reduction)
  • Consistency: All components see same auth state simultaneously
  • Reliability: Automatic cache invalidation on auth state changes
  • Build Quality: No mixed import warnings or React anti-patterns
Playbook: Complete hook implementation, usage examples, and common mistakes: .cursor/rules/react-patterns.md § Common Mistake → Correct Pattern. Quick reference: AGENTS.md § Authentication Patterns. Implementation Checklist:
  • Use useCurrentUser hook from @/platform/auth
  • Use static Supabase imports (at file top, never dynamic)
  • Use useEffect for side effects (NEVER useState)
  • Export useCurrentUser from src/platform/auth/index.ts
  • Test auth state changes (login, logout, refresh)
Prohibited Patterns:
  • ❌ Direct supabase.auth.getUser() calls in components
  • ❌ Dynamic Supabase imports (import('@/integrations/supabase/client'))
  • ❌ Using useState for side effects or async operations
  • ❌ Multiple auth state management approaches in same codebase
Rationale: Centralized authentication state eliminates redundant API calls, prevents race conditions, and establishes a single source of truth for user identity. This pattern is essential for scalable, maintainable authentication in React applications.

6.7 UI/UX Guardrails

Reference: See docs/development/UI_UX_STANDARDS.md for complete UI/UX patterns and standards.
Color Utilities: See docs/development/SEMANTIC_COLORS.md for semantic color mapping utilities and semanticColorClasses from @/shared/lib/semantic-colors. Run scripts/utils/audit-hardcoded-colors.sh to detect hardcoded color classes.
Design System (MUST):
  • Token-Based Styling: All colors, spacing, and typography MUST use semantic tokens from src/index.css, never hardcoded Tailwind color classes (e.g., text-green-500, bg-red-100).
  • Semantic Colors: Use semantic color tokens (success, warning, destructive, primary, etc.) for status indicators and UI feedback. Use semanticColorClasses utility from @/shared/lib/semantic-colors for consistent color mapping.
  • Component Variants: Use standardized component variants (Badge, Button, Alert) instead of custom className overrides.
Page Templates (MUST):
  • Loading States: All loading states MUST use skeleton loaders (<Skeleton /> component), never return null.
  • Error States: All error states MUST show user-friendly messages with recovery actions.
  • Empty States: All list/detail pages MUST use the shared <EmptyState /> component with clear next steps.
Shared Primitives (SHOULD):
  • PageHeader: Use PageHeader component for consistent page titles, descriptions, and actions.
  • StatCard: Use StatCard component for dashboard metrics and overview statistics.
  • EmptyState: Use EmptyState component for all empty list/search states.
  • CardActionsMenu: Use CardActionsMenu for card action menus with proper touch targets.
Navigation & IA (MUST):
  • Route Taxonomy: Follow established route patterns (flat structure with nested sub-modules where appropriate).
  • Breadcrumbs: Show breadcrumbs on detail pages (3+ segments) and nested sub-module pages, not on overview/list pages.
  • Route Integrity: All navigation metadata (module registry, breadcrumb labels) MUST reference routes that exist in the router.
Mobile-First (MUST):
  • Touch Targets: All interactive elements MUST meet 44x44px minimum touch target size.
  • Safe Areas: Fixed elements (header, bottom nav) MUST respect safe area insets using .safe-area-top, .safe-area-bottom utilities.
  • Header Density: Mobile header chrome MUST minimize vertical space consumption (< 120px target on most pages).
  • Always-Visible Actions: Card actions MUST be visible without hover (no hover-only action patterns).
Dialog & Sheet Sizing (MUST):
  • Standard Size Tiers: All DialogContent MUST use one of 5 standard Tailwind size tiers: sm:max-w-md (small), sm:max-w-lg (medium), sm:max-w-2xl (large), sm:max-w-3xl (x-large), sm:max-w-4xl (full). See .cursor/rules/dialog-size-standards.md for decision guide.
  • Responsive Prefix: All dialog/sheet widths MUST include the sm: responsive prefix (e.g., sm:max-w-lg not max-w-lg).
  • No Arbitrary Pixels: NEVER use arbitrary pixel values for dialog/sheet widths (e.g., max-w-[425px], max-w-[500px]). Use Tailwind utility classes only.
  • No Redundant Overflow: NEVER add overflow-y-auto or max-h-* to DialogContent — the base dialog.tsx component already handles overflow and max-height.
  • Page Containers: All page-level content MUST use the <PageContainer> component from @/shared/components/PageContainer — never manual container mx-auto patterns.
Prohibited Patterns (MUST NOT):
  • Native Browser Dialogs: NEVER use window.prompt(), window.confirm(), or window.alert(). Use custom Dialog, AlertDialog, or toast components instead.
  • Hover-Only Actions: NEVER hide card/row actions behind :hover states. Actions must be accessible on touch devices.
  • Hardcoded Color Maps: NEVER create switch/if statements returning hardcoded Tailwind colors. Use semanticColorClasses utility instead.
  • Arbitrary Dialog Sizes: NEVER use arbitrary pixel widths (max-w-[425px]) on dialogs or sheets. Use standard Tailwind size tiers.
  • Manual Page Containers: NEVER use <div className="container mx-auto ..."> for page layout. Use <PageContainer> component.
Performance UX (MUST):
  • Route Code Splitting: All route components MUST use React.lazy() for code splitting.
  • Suspense Boundaries: All lazy routes MUST be wrapped in <Suspense> with skeleton fallbacks.
  • QueryClient Configuration: QueryClient MUST have default staleTime and gcTime configured (see docs/development/UI_UX_STANDARDS.md).
Accessibility (MUST):
  • Keyboard Navigation: All interactive elements MUST be keyboard accessible with logical tab order.
  • Focus Indicators: All interactive elements MUST have visible focus indicators (2px solid outline using --ring token).
  • Contrast: All text MUST meet WCAG AA contrast ratios (4.5:1 for normal text, 3:1 for large text).
Prohibited Patterns:
  • ❌ Hardcoded Tailwind color classes (text-green-500, bg-red-100)
  • return null for loading states (must use skeleton loaders)
  • ❌ Direct route imports (must use React.lazy())
  • ❌ Missing error/empty states
  • ❌ Touch targets smaller than 44x44px
  • ❌ Missing safe area handling on fixed elements
Rationale: Consistent UI/UX patterns ensure maintainable, accessible, and performant user interfaces. Token-based styling enables theme consistency and dark mode support. Standardized page templates reduce cognitive load and improve developer velocity.

6.8 Wizard & Help UX Requirements

Multi-step workflows and contextual help are critical for complex features. These patterns ensure consistent, user-friendly experiences. When to Use Wizards: Wizard Standards (REQUIRED):
  • Progress Indicator: Wizards MUST show step progress (numbered steps or progress bar)
  • Draft Persistence: Wizards with >3 steps MUST auto-save drafts
  • Per-Step Validation: Validation MUST occur before allowing next step
  • Back Navigation: Users MUST be able to go back without losing data
  • Review Step: Complex wizards SHOULD include a final review step
  • Exit Confirmation: Wizards with unsaved changes MUST prompt before exit
Contextual Help Standards (REQUIRED):
  • Domain Terminology: All industry-specific terms MUST have tooltips (use InfoTooltip or FormFieldWithHelp)
  • First-Time Guidance: New features SHOULD offer guided tours (use GuidedTour)
  • Step Guidance: Each wizard step SHOULD have a QuickTip explaining the purpose
  • Comprehensive Help: Complex features SHOULD include HelpPanel access
Help-component selection (InfoTooltip / FormFieldWithHelp / QuickTip / GuidedTour / HelpPanel), the wizard implementation checklist, and step-by-step build guidance are the extended reference — see WIZARD_UX_STANDARD.md + WIZARD_DEVELOPMENT_GUIDE.md (component API: src/platform/help/README.md). Prohibited Patterns:
  • ❌ Wizards without progress indication
  • ❌ Industry terms without explanations
  • ❌ Losing data on back navigation
  • ❌ Validation only on final submit
  • ❌ No way to save partial progress
Reference Implementation: src/cores/rh/components/wizards/ResidentAdmissionWizard.tsx See: src/platform/help/README.md for component API documentation. Rationale: Guided workflows reduce errors and improve completion rates. Contextual help reduces support burden and enables self-service learning.

6.8.1 Help Content Requirements

All features SHOULD include contextual help content: Tooltip Requirements:
  • All domain-specific terminology MUST have tooltips
  • All form fields with industry jargon MUST have explanations
  • Tooltips MUST be registered in src/platform/help/tooltip-content.ts
  • Use InfoTooltip for field labels, FormFieldWithHelp for form fields
Guided Tour Requirements:
  • Features with 4+ steps SHOULD have a guided tour
  • Tours MUST be skippable
  • Tour completion MUST be tracked
  • Tour steps MUST use stable DOM selectors (IDs preferred)
Help Panel Requirements:
  • Complex features SHOULD have a help panel
  • Help panels MUST include: Getting Started, Key Concepts, Common Tasks
  • Help panels SHOULD link to related guided tours
Documentation Templates:
  • Use specs/_templates/TOOLTIP_CONTENT_TEMPLATE.md for tooltip additions
  • Use specs/_templates/GUIDED_TOUR_TEMPLATE.md for tour definitions
  • Use specs/_templates/SPEC_TEMPLATE_LITE.md for content-only work
Content Gap Tracking:
  • See docs/production-readiness/CONTENT_GAPS_CHECKLIST.md for module-level tracking
  • All new features SHOULD contribute to closing content gaps
  • Run npx tsx scripts/audit-content-gaps.ts to identify gaps
  • Automated weekly audit via .github/workflows/content-gap-audit.yml
Document Templates (via PF-64):
  • Features that generate documents (letters, reports, certificates) SHOULD define templates
  • Use specs/_templates/SPEC_TEMPLATE_LITE.md for template definitions
  • Track in docs/production-readiness/CONTENT_GAPS_CHECKLIST.md with {MODULE}-DOC-## IDs
  • See src/platform/templates/README.md for PF-64 API
Form Submission PDF Export:
  • Form submissions (FW-02) can be exported as branded PDFs using PF-64 letterheads
  • Use useFormSubmissionPdf from @/platform/forms for submission-to-PDF conversion
  • Use useGenerateTemplatedPdf from @/platform/templates for templated PDF generation
  • Forms collect data; Document Templates format data for print — these are complementary, not competing features
  • See docs/guides/use-cases/template-selection.md for guidance on when to use each
Rationale: Consistent help content ensures users can self-serve, reduces support burden, and improves feature adoption rates. Automated auditing prevents content debt from accumulating.

7. Finance & Clinical Guardrails

Finance and clinical domains require stricter controls.

7.1 Finance (FA)

  • Subledger and accounting flows MUST be explicitly modeled and documented:
    • What events create charges, payments, adjustments, and write‑offs.
    • How and when postings roll into a general ledger or external system.
  • Financial transactions are append‑only:
    • Corrections use adjustments, not destructive updates.
  • All financial calculations (balances, aging, interest, accruals) MUST be covered by tests with edge cases.

7.2 Clinical (CL – Clinical & EHR)

  • Clinical capabilities (documentation, orders, outcomes) will only be built on top of a mature operational and financial backbone.
  • Any clinical feature must:
    • Be designed with auditability, versioning of records, and legal defensibility in mind.
    • Avoid being a dependency for non‑clinical cores.
Whole-Person Care Philosophy (behavioral health):
  • Clinical design MUST align with a recovery-oriented, trauma-informed, person-centered, and strengths-based model. Documentation and workflows MUST support the whole person, not only symptom or diagnosis.
  • Social Determinants of Health (SDOH) are first-class clinical data: screening, tracking, and referral to community resources MUST be supported where specified (e.g., CL-18). ICD-10-CM Z-codes (Z55–Z65) for SDOH MUST be available in the code library.
  • Peer support and lived experience services (peer specialists, recovery coaching) MUST be documented and billable per applicable specs (e.g., CL-19). Peer-delivered services are not optional add-ons but part of the care model.
  • Cultural responsiveness MUST be supported: language preference, interpreter use, and cultural factors in assessment and care planning. Documentation MUST support language services tracking and cultural adaptation where required by spec.
  • Jurisdiction-aware clinical requirements: Clinical documentation requirements (assessment elements, note content, timeliness rules, attestation language) vary by state Medicaid program. CL features SHOULD read these requirements from the organization’s jurisdiction profile (PF-96) when available. Until PF-96 is implemented, CL features MAY use AHCCCS defaults with TODO(PF-96) markers documenting the migration path. New CL features MUST NOT reference AHCCCS-specific policies (e.g., “AHCCCS Policy 940”, “AMPM 320-O”) as universal constants; they SHOULD use profile-driven configuration so that organizations in other states see their applicable requirements. Arizona remains the default profile for backward compatibility.
Rationale: Financial misstatements and clinical issues create outsized regulatory, legal, and reputational risk. Whole-person care alignment ensures the platform serves behavioral health and recovery outcomes, not only medical-model compliance. Jurisdiction-aware design enables multi-state expansion without code changes per state.

7.3 Medical Terminology Governance

  • Code library (PF-70): ICD-10-CM, CPT, HCPCS, LOINC, NDC, and related code sets MUST be managed through the platform medical terminology spec (PF-70). CL and PM MUST use the shared code library for diagnosis, procedure, and modifier selection; no hard-coded code lists in application code.
  • Updates: Code set updates (e.g., annual ICD-10-CM, CPT) MUST follow a documented, repeatable process with effective dating so that historical claims and documentation remain valid.
  • Validation: Code-modifier combinations and effective-date checks MUST be enforced at the point of use (e.g., charge capture, claim submission). Validation rules MAY be extended by organization or payer via PF-70 configuration.
Rationale: A single source of truth for codes ensures consistency across clinical documentation and billing and reduces errors from stale or divergent code lists.

8. Simplicity, Pragmatism & Decisions

We prefer simple, explainable solutions over clever but fragile ones.

8.1 Simplicity Rules

  • Don’t build features “just in case.” YAGNI is the default.
  • Avoid premature abstractions; duplication is acceptable until patterns are proven.
  • Lean on well‑understood frameworks and libraries instead of bespoke infrastructure.

8.2 Decision Discipline

  • Material decisions (architecture, data contracts, external dependencies) MUST:
    • Be captured in specs or lightweight ADRs (Architecture Decision Records).
    • Include trade‑offs and impact on other cores.

8.3 Code Review & Pull Request Standards

All code changes MUST go through review before merging. Pull Request Requirements:
  • PR title follows convention: [CORE-##] Short description (e.g., [RH-01] Add resident admission flow).
  • PR description includes:
    • Link to spec or issue.
    • What changed and why.
    • Testing approach and results.
    • Migration or deployment notes (if applicable).
  • PRs MUST be:
    • Small and focused (< 500 lines of code when possible).
    • Self-contained (one feature or fix per PR).
    • Accompanied by tests (unit, integration, or E2E as appropriate).
Review Checklist:
  • Does it follow constitution naming and structure conventions?
  • Are tenant isolation and RLS correctly applied?
  • Is there test coverage for new behavior?
  • Are migrations backward-compatible?
  • Is documentation updated?
  • Are there any security, privacy, or financial risks?
  • Are hard-coded values that should be settings identified and moved to module settings?
Review Turnaround:
  • PRs should be reviewed within 24 hours (business days).
  • Critical fixes: within 4 hours.
  • Reviewers should provide actionable feedback, not just “LGTM.”

8.4 Deprecation & Legacy Code Policy

Technical debt is managed, not ignored. Deprecation Process:
  • Code, APIs, or database columns marked for deprecation MUST:
    • Have a documented sunset date (at least 90 days out).
    • Log warnings when used.
    • Have a migration path documented.
  • Deprecated features MUST be removed within 180 days unless explicitly extended.
Legacy Code Management:
  • Legacy code that cannot be immediately refactored MUST:
    • Be clearly marked (e.g., // LEGACY: Do not extend. Migrate to XYZ by 2026-Q2).
    • Have a tracking issue for removal or refactor.
    • Not be a dependency for new features.
Cleanup Expectations:
  • Dead code (unused functions, components, imports) MUST be removed during PR review.
  • Commented-out code is not allowed; use version control history instead.
Rationale: Simple, well‑documented decisions scale better than cleverness, especially with multiple teams and AI contributors.

9. Documentation & Ownership

Documentation is part of the deliverable, not “nice to have.”

9.1 What Must Be Documented

For each core/module, the following must exist and be kept current:
  • Overview: What it does and what it owns.
  • Data model: Key entities, relationships, and IDs.
  • APIs/contracts: External and cross‑core interfaces.
  • Operational runbook: Monitoring, alerts, common failure modes, support paths.

9.2 Ownership

  • Every core/module has a clearly named business owner and technical owner.
  • Ownership includes:
    • Decision rights within that domain.
    • Responsibility for quality, documentation, and operational performance.

9.3 Implementation Log Requirements

The Implementation Log (specs/IMPLEMENTATION_LOG.md) is the system of record for completed work. When to Update:
  • After completing any feature spec (e.g., PF-01, RH-02).
  • After significant refactoring or infrastructure changes.
  • After fixing critical security or data integrity issues (especially RLS fixes).
  • After adding new components, hooks, or significant UI work.
  • After constitution or AI Guide updates.
  • AI Trigger: AI assistants MUST update the log as part of feature delivery, not as a separate task.
What to Document:
  • Feature ID and completion date.
  • Database changes (tables, functions, triggers, RLS policies).
  • Components and files created or significantly modified.
  • Integration points and dependencies.
  • Security considerations and testing status.
  • Known limitations or follow-up work.
Format:
  • Each feature gets its own section under the appropriate phase.
  • Use checkboxes (✅, 🔜, 🚨) to indicate status.
  • Link to relevant spec files.
  • Keep it concise but complete.
Responsibility:
  • The technical owner of a feature is responsible for updating the log.
  • AI assistants MUST propose log updates as part of feature delivery.
  • Updates should happen within 24 hours of feature completion.
Rationale: Clear ownership and written context enable velocity without chaos.

10. Governance, Versions & AI Alignment

This constitution itself is a living artifact.

10.1 Changes to the Constitution

  • Changes MUST be made via pull request and explicitly called out as “Constitution Update.”
  • Semantic versioning:
    • MAJOR: Breaking principle changes or removed principles.
    • MINOR: New principles or materially expanded guidance.
    • PATCH: Clarifications, wording, typos, non‑semantic fixes.
  • Any change MUST:
    • Include an updated version line and dates.
    • Note impacts on templates, tooling, or working agreements.

10.2 Relationship to AI Guidelines

  • This document defines what must be true for the platform.
  • AI_GUIDE.md (current: see docs/VERSIONS.md) defines how AI agents must behave to stay compliant with this constitution.
  • AGENTS.md (current: see docs/VERSIONS.md) provides a unified quick reference for all AI platforms.
  • In case of conflict, this constitution wins.
  • The canonical cross-platform “What AI Must NEVER Do” list is maintained in AGENTS.md; this constitution remains the normative source for underlying guardrails.
Quick Reference: For fast lookups, see AGENTS.md and .cursor/rules/constitution.mdc (section-scoped routing). Additional References:

10.3 Annual Constitution Review

The constitution is a living document. It must be reviewed annually to prune obsolete sections, incorporate lessons from the prior year, and align with regulatory or architectural changes. Cadence: Once per year, typically in Q1 (January–March). The review is triggered by a GitHub issue created via the issue template below. Review checklist:
  1. Check all §-level cross-references still point to existing files and correct sections
  2. Verify “What AI Must NEVER Do” in AGENTS.md is consistent with constitution guardrails
  3. Prune sections made obsolete by platform evolution (mark as [Deprecated §X.Y] with reason)
  4. Incorporate any ADRs from the past year that modified architectural rules
  5. Sync docs/VERSIONS.md with the new constitution version number
  6. Run npm run validate:governance and confirm all checks pass
GitHub issue template: Create an issue titled Annual Constitution Review — {YEAR} with label governance using this body:
Next scheduled review: 2027-Q1 (post-v1.0 launch)

11. Project Structure & Code‑Level Naming

Repository layout and naming are standardized to keep the system navigable.

11.1 Directory Structure

At the top level, the repository follows this structure:
  • /src
    • /platform – Platform Foundation (auth, tenancy, navigation, shared services).
    • /cores
      • /rh – Recovery Housing & Operations.
      • /fa – Finance & Revenue.
      • /hr – Workforce & HRIS.
      • /gr – Governance, Compliance & Learning.
      • /fw – Forms & Workflow.
      • /fm – Facilities, Inventory & Vendors.
      • /lo – Leadership Operating System.
      • /ce – Community Engagement.
      • /it – IT & Security.
      • /cl – Clinical & EHR.
      • /pm – Practice Management.
    • /shared – Reusable UI components, hooks, and utilities.
  • /supabase
    • /migrations – Database migration files (timestamped SQL).
    • /functions – Edge Functions (Deno-based).
    • /seeds – Seed data (non‑PHI, non‑prod only).
  • /specs
    • Per‑feature specs and plans organized by core (e.g., /specs/rh/specs/RH-01.md).
  • /docs
    • Architecture, development, deployment, migration, and testing documentation.
  • /tests
    • Unit, integration, E2E, RLS, and compliance test suites.
  • /scripts
    • Developer tooling, maintenance scripts, and data migration utilities.
For detailed directory structure, see CLAUDE.md § Directory Structure.

11.2 Code‑Level Naming

  • Source code directories under /src/cores MUST mirror the core naming (e.g., /src/cores/rh/residents, /src/cores/fa/billing).
  • File names use kebab-case or camelCase per language and framework norms, but MUST be consistent within a layer.
  • Domain models and services SHOULD carry explicit domain context (e.g., ResidentService, BillingLedger, AuditTrailLogger), not generic names like Manager or Helper.
Rationale: A clear, enforced project structure and naming scheme reduces onboarding time, accelerates reviews, and plays well with AI‑driven navigation.

12. Automation Governance

Automations that execute business logic must follow strict governance to prevent abuse, outages, and data integrity issues.

12.1 Approval for High-Risk Automations

  • Webhooks to external systems MUST be approved by org admin
  • Updates to critical tables (employees, documents, financials, residents) MUST be approved
  • Automations created by non-admin users SHOULD be reviewed before activation
  • Approval tracked: approved_by, approved_at, approval_notes

12.2 Circuit Breaker for Reliability

  • All automations MUST have circuit breaker enabled (default behavior)
  • Auto-pause after 5 consecutive failures
  • Notify creator immediately when circuit trips
  • Require manual reset with root cause analysis before re-enabling

12.3 Testing Requirements

  • All automations MUST be tested in dry-run mode before activation
  • Templates MUST include example trigger data for testing
  • Complex workflows (3+ actions) SHOULD have integration tests
  • Breaking changes to automation engine MUST have rollback plan

12.4 Audit & Monitoring

  • All executions MUST be logged to fw_automation_logs
  • Analytics dashboard SHOULD be reviewed weekly by automation owners
  • Failed automations (>10% failure rate) MUST be investigated within 24 hours
  • External webhooks MUST use HTTPS only (enforced by system)

12.5 Rate Limiting & Resource Protection

  • Email actions: Max 100 emails per hour per organization (to be implemented)
  • Webhook actions: 30 second timeout enforced
  • Record updates: RLS policies enforce tenant isolation
  • Scheduled automations: One execution per cron interval (no overlapping runs)
Rationale: Automations can trigger external APIs, modify data, and send communications. Governance prevents abuse, outages, and data integrity issues while enabling powerful workflow automation.

13. Definition of Done

Operational Definition of Done lives in docs/development/DEFINITION_OF_DONE.md — the source of truth for the completion sequence, AC/US/FR verification, and the machine-enforced gates (uiEvidenceGate, signoff markers, verify-acs). This section retains only the non-negotiable guardrails that must hold for every completed change, regardless of pipeline. “Done” means reachable capability, not artifact-existence (§3.1): a feature is complete only when the terminal user action actually works.

13.1 Security guardrails (non-negotiable)

  • RLS policies implemented for all new tables
  • RLS tests written and passing
  • All mutations include organization_id filter (defense-in-depth)
  • No PHI/PII in code, tests, logs, or error messages
  • SECURITY DEFINER functions used where needed
  • UPDATE policies include WITH CHECK clause
Rationale: A clear Definition of Done prevents incomplete features from being marked complete and ensures consistent quality. The operational checklist (typecheck/lint/build/test, the test-coverage matrix, docs, and review/deploy process) is maintained in the spine doc so it can evolve with tooling without a constitutional amendment; the security guardrails above remain constitutional because they protect multi-tenant isolation and PHI.
Version: 1.18.0 Ratified: 2025‑11‑24 Last Updated: 2026‑06‑15 Last Amended: 2026‑06‑15 Version History:
  • 1.18.0 (2026-06-15): §13 trimmed to non-negotiable security guardrails + a pointer to docs/development/DEFINITION_OF_DONE.md (now the operational DoD source of truth). Operational checklists (quality/tests/docs/process) moved to the spine so they evolve without a constitutional amendment. Resolves the prior triple-definition DoD drift.
  • 1.17.2 (2026-06-04): §6 trim pass (ADR-023 extraction): §6.3.1 breadcrumb code patterns → breadcrumb-implementation-guide.md; §6.8 wizard help-component table + checklist → WIZARD_UX_STANDARD.md + WIZARD_DEVELOPMENT_GUIDE.md. All guardrails (when-to-show, mobile-CRITICAL, prohibited patterns, REQUIRED wizard/help standards) kept.
  • 1.17.1 (2026-06-04): §5.2 trim pass (ADR-023 extraction): §5.2.3–§5.2.6 reduced to guardrail + target links (settings-pattern-guide.md, DATABASE_DEVELOPMENT_GUIDE.md, PF-15/16/17 specs); ~125 lines moved out, all guardrails kept.
  • 1.17.0 (2026-04-12): Added §12.3–§12.5 (Testing Requirements, Audit & Monitoring, Rate Limiting & Resource Protection) to Automation Governance section; TOC alignment.
  • 1.16.1 (2026-04-11): Documentation and governance alignment (AI tooling inventory references, spec workflow cross-links). No material change to technical guardrails in §1–§13.
  • 1.16.0 (2026-03-29): Added jurisdiction scope language for multi-state Medicaid compliance (PF-96). §1.1: PF owns jurisdiction profile system. §4.3.7: jurisdictionProfileId in AI module context. §5.1: jurisdiction-aware configuration rule (no hardcoded state-specific constants in CL/PM). §5.2.2: jurisdiction profile assignment and resolution order. §5.2.3: decision criteria for jurisdiction profile vs module settings. §7.2: jurisdiction-aware clinical requirements (profile-driven, not AHCCCS-hardcoded).
  • 1.15.0 (2026-03-19): Trimmed §6.6 Authentication State Management code blocks to bullets + playbook links (react-patterns.md, AGENTS.md); added DATABASE_DEVELOPMENT_GUIDE.md to CodeRabbit knowledge base.
  • 1.14.0 (2026-03-19): Consolidated §5.2 SQL-heavy playbooks into docs/development/DATABASE_DEVELOPMENT_GUIDE.md (Constitution playbook section); trimmed §6.5 code blocks in favor of AGENTS/quick-reference links; reordered §5.2.9 after §5.2.8.
  • 1.13.0 (2026-03-06): Public API documentation governance alignment. Added §3.4 Public API Documentation Coverage with 100% baseline requirement for in-scope exported function-like declarations.
  • 1.12.0 (2026-02-25): CL-PM architecture formalization. Added encounter entity to §1.2; cross-core database reference rules and CL-PM FK exception (ADR-002); §5.2.7 Cross-Core Database References; ADR requirement in §1.3.
  • 1.11.0 (2026-02-07): Added Bulk Import & Data Migration Standards (§5.10).
  • 1.7.0 (2026-01-25): Added Test File Naming Conventions (§3.3) with standardized patterns and templates. Added Definition of Done (§13) with comprehensive completion criteria checklist.
  • 1.6.1 (2025-12-03): Added LO core to the list of domain cores and updated module settings status table to reflect implemented cores (HR, FW, RH, FA, LO) and planned cores (GR, FM).
  • 1.6.0 (2025-01-27): Documented PF-15/16/17 customization infrastructure (picklists, custom fields, entity field configuration) and expanded PWA/mobile requirements and frontend performance patterns.
  • 1.3.0 (2025-11-25): Added Automation Governance section (11) covering approval workflows, circuit breakers, testing requirements, and monitoring standards for FW-03 automation engine.
  • 1.2.1 (2025-11-24): Added storage bucket naming (5.2), database function naming (5.2), RLS anti-patterns and SECURITY DEFINER guidance (5.7), clarified migration naming for Lovable-generated files (5.3), enhanced AI log update triggers (8.3).
  • 1.2.0 (2025-11-23): Added Integration Patterns (1.3), Production Deployment & Rollback (5.5), Performance & Monitoring (5.6), Code Review Standards (7.3), Deprecation Policy (7.4), and Implementation Log Requirements (8.3).
  • 1.1.0 (2025-11-23): Initial ratified version with core architecture, testing, security, and database guardrails.