Skip to main content

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.

Feature ID: GR-17
Spec: GR-17 Regulatory Change Management
Version: 1.0
Status: 📝 Planned
Last Updated: 2026-04-19
Owner: GR (Governance & Risk)

Overview

GR-17 detects changes in registered regulatory source documents (AHCCCS AMPM bulletins, DHCS Documentation Standards, federal CMS / SAMHSA notices, etc.), uses PF-27 Platform AI to classify the impact against the org’s existing gr_regulatory_requirements rows, and routes proposed actions through a human approval workflow that auto-creates gr_compliance_checks follow-ups, PF-10 notifications, and (optionally) re-ingests source documents into PF-61 so GR-06-EN-01’s RAG corpus stays current. Integration patterns used:
  • Platform Integration Layer: PF-10 (Notifications), PF-27 (Platform AI), PF-30 (Permissions), PF-46 (Data Retention), PF-60 (RAG), PF-61 (Knowledge Base), PF-96 (Jurisdiction Profiles)
  • Event Publisher: gr_regulatory_change_detected, gr_regulatory_change_approved
  • Cross-core (read-only): Reads gr_regulatory_requirements (GR-03) for impact classification; writes gr_compliance_checks (GR-03) on approval via GR-03’s existing mutation API (no duplicate insert logic)
  • External integrations: AHCCCS AMPM index (HTML/PDF, no auth), DHCS Documentation Standards (HTML, no auth); polling-based ingestion (webhook deferred)

Integration 1: GR-17 → GR-03 (Cross-core, intra-core helper)

Pattern: Direct DB read + GR-03’s gr_compliance_checks insert API
Status: 📝 Planned
Reads: gr_regulatory_requirements (id, title, topic tags, owner, jurisdiction_profile_id) — used as PF-27 prompt context for impact classification. RLS is org-scoped via gr_has_org_access(); classifier runs under the org’s service-role context with explicit organization_id filter. Writes: On approval of a gr_regulatory_change_impacts row with proposed_action ∈ {review, update, supersede}, GR-17 calls GR-03’s existing compliance-check insert API to create a gr_compliance_checks row referencing the affected requirement_id. GR-17 does NOT duplicate the GR-03 insert logic; it uses the platform helper. Tenant isolation: All reads/writes carry organization_id (defense-in-depth); RLS enforces. Failure mode: GR-03 insert failure rolls back the approval transaction (impact status flip + check insert + notification publish are one DB transaction; PF-61 enqueue is post-commit and may be retried independently).

Integration 2: GR-17 → GR-06-EN-01 (Event consumer, downstream)

Pattern: Event Consumer (subscribes to GR-17 events) + PF-61 corpus refresh
Status: 📝 Planned
GR-06-EN-01 (AI State Compliance Checking) consumes GR-17’s events and the refreshed PF-61 corpus to give compliance officers state-aware, citation-grounded answers reflecting the latest authoritative text.
  • Subscribes to gr_regulatory_change_detected to surface “rule change detected” notices in the advisor surface (without exposing classification details until human approval).
  • Consumes gr_regulatory_change_approved to know that a previously-stale citation now has a current document.
  • Reads from PF-61 corpus that GR-17 re-ingests on approval (no direct DB coupling between GR-17 and GR-06-EN-01).

Integration 3: GR-17 → PF-10 (Platform Layer — Notifications)

Pattern: Platform Integration Layer (PF-10)
Usage:
  • Approval-side: notify the affected gr_regulatory_requirements owner that a follow-up gr_compliance_checks row has been created; CC the org’s compliance officer role.
  • Source-health: notify org admins when a source has been errored for ≥ 24 hours or when PF-61 re-ingestion fails after approval.
Notification keys (registered in PF-10):
  • gr_regulatory_change_followup_assigned (per-approval; targets requirement owner; CC compliance officer role)
  • gr_regulatory_source_errored (rate-limited; one per 24 h per source; targets org admin)
  • gr_pf61_reingest_failed (after 5 failed retries per FR-5.4; targets org admin)
  • gr_regulatory_source_oversized_review (snapshot oversized = true per FR-2.5; targets source registrant + org admin)
  • gr_regulatory_source_phi_guard_triggered (PHI/PII heuristic match per FR-2.6; targets org admin)
Auth / tenant: Standard PF-10 helpers; payload is metadata-only (UUIDs + labels), never source body text.

Integration 4: GR-17 → PF-27 (Platform Layer — Platform AI)

Pattern: Platform Integration Layer (PF-27)
Usage: gr-classify-regulatory-change-impact edge function calls PF-27 to extract the changed sections, tag affected topics, propose an impact mapping to gr_regulatory_requirements, and assign a confidence score.
Prompt content (NO PHI):
  • Diff summary (regulatory text only — public)
  • Org’s relevant gr_regulatory_requirements.title + topic tags (no patient/employee identifiers)
  • Resolved jurisdiction profile context from pf_resolve_jurisdiction_profile() (PF-96): state, Medicaid program, regulatory body, retention rules
  • AI model version recorded on the resulting gr_regulatory_change_impacts.ai_model_version for audit
Refusal conditions:
  • Source body matches PHI/PII heuristics (SSN, MRN patterns) — abort, flag for manual review, do NOT call PF-27.
  • Source body exceeds regulatory_change_source_size_cap_mb — abort, flag for manual review.
Idempotency: Re-running classification on the same (change_event_id, requirement_id) updates the existing row; no duplicates.

Integration 5: GR-17 → PF-30 (Platform Layer — Permissions v2)

Pattern: Direct dependency
New permission keys (seeded via migration into pf_module_permissions and assigned to roles in pf_role_permissions; constants added to src/platform/permissions/constants.ts):
KeyPurposeDefault Roles
gr.compliance.regulatory_source.adminRegister / edit / soft-delete sources; manual “Poll now”gr.compliance.admin, org_admin
gr.compliance.regulatory_change.viewView change feed and impact detailsgr.compliance.admin, gr.compliance.viewer, org_admin
gr.compliance.regulatory_change.approveApprove / reject impact rows; triggers gr_compliance_checks insertgr.compliance.admin, org_admin
Audit gate: npm run audit:permissions (covered by validate:governance).

Integration 6: GR-17 → PF-46 (Platform Layer — Data Retention)

Pattern: Direct dependency
Usage: Snapshot, change-event, classification, and approval audit retention follows PF-46 retention rules. Default for compliance evidence: 7 years. Source rows support soft-delete (deleted_at); snapshots and change events are append-only and never logically deleted.
Retention policy keys (configured in PF-46):
  • gr_regulatory_source_snapshots — retain 7 years from fetched_at
  • gr_regulatory_change_events — retain 7 years from created_at
  • gr_regulatory_change_impacts — retain 7 years from approved_at / rejected_at (whichever applies)

Integration 7: GR-17 → PF-60 / PF-61 (Platform Layer — RAG / Knowledge Base)

Pattern: Platform Integration Layer (PF-61 ingestion API; PF-60 indexes the corpus)
Status: 📝 Planned
gr-pf61-refresh-source edge function is invoked post-approval when proposed_action ∈ {update, supersede} (and only when regulatory_change_pf61_auto_refresh_enabled = true for the org). It enqueues PF-61 ingestion of the affected source document; PF-60 re-indexes asynchronously.
  • Re-ingestion respects PF-61’s existing tenant scoping.
  • Re-ingestion failure does NOT roll back the approval; failure is logged and a gr_pf61_reingest_failed notification is sent to the org admin (Integration 3).
  • UI surfaces a pf_kb_refresh_status badge on the approved impact row (queued | running | done | failed).

Integration 8: GR-17 → PF-96 (Platform Layer — Jurisdiction Profiles)

Pattern: Direct dependency
Usage:
  • Each gr_regulatory_sources row binds to exactly one pf_jurisdiction_profiles.id.
  • Watcher reads jurisdiction context to scope per-source polling cadence overrides and known-source allowlists.
  • Classifier prompt includes resolved jurisdiction profile context (state, Medicaid program, regulatory body) so PF-27 can propose state-correct mappings.
  • AI auto-no_op confidence threshold honors PF-96 jurisdiction-scoped override (policy_overrides.gr_17.ai_auto_no_op_threshold) before falling back to the org’s gr_module_settings default and finally the platform default.
Resolution helper:
  • Frontend: useJurisdictionProfile(orgId?: string, siteId?: string) — wrapper around the PF-96 canonical contract pf_resolve_jurisdiction_profile(p_org_id, p_site_id)
  • Server: pf_resolve_jurisdiction_profile(p_org_id, p_site_id) — canonical RPC (SECURITY DEFINER)
  • Edge functions: getJurisdictionProfile(supabaseClient, orgId, siteId?) — canonical edge function helper

Event Contracts

Event: gr_regulatory_change_detected

Channel: gr_events
Publisher: GR-17 (gr-regulatory-change-watcher after creating a gr_regulatory_change_events row)
Subscribers: GR-06-EN-01 (advisor surface), org admin notifications via PF-10
Status: 📝 Planned
{
  event_type: 'gr_regulatory_change_detected';
  organization_id: uuid;
  timestamp: timestamptz;
  change_event_id: uuid;
  source_id: uuid;
  jurisdiction_profile_id: uuid;
  severity: 'info' | 'minor' | 'major' | 'critical';
  // No source body or diff text in payload — consumers read via DB lookup with their own RLS context.
}

Event: gr_regulatory_change_approved

Channel: gr_events
Publisher: GR-17 (gr_regulatory_change_impacts status → approved transition; transactional)
Subscribers: GR-03 (compliance check is already inserted in the same transaction; this event is informational), GR-06-EN-01 (corpus freshness signal), GR-08 (accreditation evidence linkage)
Status: 📝 Planned
{
  event_type: 'gr_regulatory_change_approved';
  organization_id: uuid;
  timestamp: timestamptz;
  change_event_id: uuid;
  impact_id: uuid;
  requirement_id: uuid | null;       // null when impact_status = 'unmatched' but approved as informational
  follow_up_check_id: uuid | null;    // null when proposed_action = 'no_op'
  proposed_action: 'review' | 'update' | 'supersede' | 'no_op';
  approved_by: uuid;
}

Events Consumed: None.


API Contracts

GR-03 Compliance Check Insert API (called synchronously by GR-17 on approval per FR-4.3):
  • Endpoint pattern: Server-side RPC or typed mutation helper (exact signature TBD; tracked in PENDING_CONTRACTS.md)
  • Logical request payload: { organization_id: UUID, requirement_id: UUID, regulatory_change_id?: UUID (optional GR-17 linkage), proposed_action: 'review' | 'update' | 'supersede' (NOT 'no_op'), actor_id: UUID, custom_fields?: JSONB }
  • Response: { check_id: UUID, status: 'pending' | 'inserted' }
  • Transactional semantics (NFR-3): This insert MUST occur within the same DB transaction as the GR-17 approval status flip and PF-10 notification publish. Rollback on any leg.
  • Authorization: Caller MUST have gr.compliance.regulatory_change.approve permission (enforced by GR-17 approval mutation; GR-03 insert API enforces org-scoped RLS).
  • Error codes: Standard RLS denial (403 / 42501); FK violation if requirement_id deleted (409 / 23503); sanitized via sanitizeErrorMessage().
  • Idempotency: Re-running the same (requirement_id, regulatory_change_id) pair MAY upsert or MAY error per GR-03 internal policy (GR-17 does not rely on duplicate-insert handling; approval is single-fire per impact row).
  • Constraint: Caller MUST NOT invoke this API when proposed_action = 'no_op' (GR-17 approval logic skips insert for no-op actions per FR-3.6 and FR-4.3).
See Integration 1 (GR-17 → GR-03) and Integration 5 (PF-30 permission key gr.compliance.regulatory_change.approve). Final signature tracked in PENDING_CONTRACTS.md until GR-17 Phase 3 implementation.

External Integrations

SourceURLAuthPollingOwnerStatus
AHCCCS AMPM index (Arizona)https://azahcccs.gov/shared/MedicalPolicyManual/None (public)Daily (default)Compliance officer (per-org registration)📝 Planned
DHCS Documentation Standards (California)https://www.dhcs.ca.gov/... (per profile)None (public)Daily (default)Compliance officer (per-org registration)📝 Planned
Additional state Medicaid sourcesper PF-96 profileNone (public, default)Daily (default)Compliance officer📝 Planned
Add to docs/architecture/integrations/EXTERNAL_INTEGRATIONS.md on Phase 1 implementation.

Security & Tenant Isolation

  • All four GR-17 tables include organization_id and are RLS-protected via gr_has_org_access() SECURITY DEFINER helper.
  • UPDATE policies include WITH CHECK (constitution §5.2.4).
  • Snapshots are append-only (no UPDATE/DELETE policies for non-superuser).
  • Source documents are public regulatory text only. Ingestion refuses content matching PHI/PII heuristics; abort + flag for manual review; never persist suspected PHI.
  • AI prompts contain only requirement titles + topic tags + diff text (no patient/employee identifiers).
  • URL validation: https:// required; reject private / loopback IPs at registration time.
  • Edge functions use _shared/auth.ts helpers (verifyOrgAccess() for user-initiated polls; service-role pattern for cron with explicit organization_id validation per call — never inline pf_user_role_assignments queries).
  • Sanitized error messages via sanitizeErrorMessage() for any user-facing error.

Scheduled Processing

CronCadenceFunction
Source poll15-minute tick; per-source skip if now() - last_polled_at < cadence_intervalgr-regulatory-change-watcher
Classification fallback retryEvery 15 min for events stuck in classifying ≥ 30 mingr-classify-regulatory-change-impact
Source-health alertsDailyinline in watcher; notifies via PF-10 when a source is errored ≥ 24 h
Cadence detail: Global cron tick every 15 minutes (*/15 * * * *); per-source skip if now() - last_polled_at < cadence_interval where cadence_interval is hourly = 60 min, daily = 24 h, weekly = 7 d per FR-2.1. Per-org soft cap of 50 sources processed per tick (FIFO by last_polled_at NULLS FIRST) and 10 concurrent in-flight polls. Manual “Poll now” rate-limited to 1/min/source (HTTP 429 + UI cooldown badge); manual polls bypass cadence skip but still observe the concurrency cap. Scheduler language and SLA align with gr-regulatory-change-watcher behavior and classification fallback retry policy. DB trigger on gr_regulatory_change_events insert kicks off classification synchronously (then handed to the cron fallback if the worker errors).

Pending Contract Items

ItemBlocked OnNotes
Final gr_regulatory_change_detected and gr_regulatory_change_approved payload schemasGR-17 Phase 2 implementationConfirm field names with GR-06-EN-01, GR-03, GR-08 consumers
PF-61 ingestion API contract for regulatory_source document typePF-61 implementation statusConfirm source_type string and metadata schema
GR-03 gr_compliance_checks insert helper signatureGR-17 Phase 3 implementationConfirm whether GR-03 exposes a typed mutation API or DB function (avoid duplicate insert logic)
AHCCCS AMPM source canonical URL list (per Arizona profile)PF-96 Arizona profile finalizationSeed migration for the default Arizona profile registers AMPM index source
See PENDING_CONTRACTS.md for tracking.

Contract Validation

Validated against CONTRACT_VALIDATION_CHECKLIST.md:
  • Event payload schemas finalized (GR-17 Phase 2)
  • Publisher / subscriber declared for each event
  • Auth and tenant isolation documented per function
  • PHI restrictions documented (NO PHI in gr_regulatory_* tables; AI prompts metadata-only)
  • Platform layer usage documented (PF-10, PF-27, PF-30, PF-46, PF-60, PF-61, PF-96)
  • Integration matrix updated in CROSS_CORE_INTEGRATIONS.md (planned with Phase 1 implementation)

References