Feature ID: GR-17Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
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 existinggr_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; writesgr_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’sgr_compliance_checks insert APIStatus: 📝 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 refreshStatus: 📝 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_detectedto surface “rule change detected” notices in the advisor surface (without exposing classification details until human approval). - Consumes
gr_regulatory_change_approvedto 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_requirementsowner that a follow-upgr_compliance_checksrow has been created; CC the org’s compliance officer role. - Source-health: notify org admins when a source has been
erroredfor ≥ 24 hours or when PF-61 re-ingestion fails after approval.
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(snapshotoversized = trueper 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)
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_versionfor audit
- 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.
(change_event_id, requirement_id) updates the existing row; no duplicates.
Integration 5: GR-17 → PF-30 (Platform Layer — Permissions v2)
Pattern: Direct dependencyNew 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):
| Key | Purpose | Default Roles |
|---|---|---|
gr.compliance.regulatory_source.admin | Register / edit / soft-delete sources; manual “Poll now” | gr.compliance.admin, org_admin |
gr.compliance.regulatory_change.view | View change feed and impact details | gr.compliance.admin, gr.compliance.viewer, org_admin |
gr.compliance.regulatory_change.approve | Approve / reject impact rows; triggers gr_compliance_checks insert | gr.compliance.admin, org_admin |
npm run audit:permissions (covered by validate:governance).
Integration 6: GR-17 → PF-46 (Platform Layer — Data Retention)
Pattern: Direct dependencyUsage: 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 fromfetched_atgr_regulatory_change_events— retain 7 years fromcreated_atgr_regulatory_change_impacts— retain 7 years fromapproved_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_failednotification is sent to the org admin (Integration 3). - UI surfaces a
pf_kb_refresh_statusbadge on the approved impact row (queued | running | done | failed).
Integration 8: GR-17 → PF-96 (Platform Layer — Jurisdiction Profiles)
Pattern: Direct dependencyUsage:
- Each
gr_regulatory_sourcesrow binds to exactly onepf_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_opconfidence threshold honors PF-96 jurisdiction-scoped override (policy_overrides.gr_17.ai_auto_no_op_threshold) before falling back to the org’sgr_module_settingsdefault and finally the platform default.
- Frontend:
useJurisdictionProfile(orgId?: string, siteId?: string)— wrapper around the PF-96 canonical contractpf_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_eventsPublisher: 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: gr_regulatory_change_approved
Channel: gr_eventsPublisher: 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
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.approvepermission (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_iddeleted (409 / 23503); sanitized viasanitizeErrorMessage(). - 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).
gr.compliance.regulatory_change.approve). Final signature tracked in PENDING_CONTRACTS.md until GR-17 Phase 3 implementation.
External Integrations
| Source | URL | Auth | Polling | Owner | Status |
|---|---|---|---|---|---|
| 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 sources | per PF-96 profile | None (public, default) | Daily (default) | Compliance officer | 📝 Planned |
docs/architecture/integrations/EXTERNAL_INTEGRATIONS.md on Phase 1 implementation.
Security & Tenant Isolation
- All four GR-17 tables include
organization_idand are RLS-protected viagr_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.tshelpers (verifyOrgAccess()for user-initiated polls; service-role pattern for cron with explicitorganization_idvalidation per call — never inlinepf_user_role_assignmentsqueries). - Sanitized error messages via
sanitizeErrorMessage()for any user-facing error.
Scheduled Processing
| Cron | Cadence | Function |
|---|---|---|
| Source poll | 15-minute tick; per-source skip if now() - last_polled_at < cadence_interval | gr-regulatory-change-watcher |
| Classification fallback retry | Every 15 min for events stuck in classifying ≥ 30 min | gr-classify-regulatory-change-impact |
| Source-health alerts | Daily | inline in watcher; notifies via PF-10 when a source is errored ≥ 24 h |
*/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
| Item | Blocked On | Notes |
|---|---|---|
Final gr_regulatory_change_detected and gr_regulatory_change_approved payload schemas | GR-17 Phase 2 implementation | Confirm field names with GR-06-EN-01, GR-03, GR-08 consumers |
PF-61 ingestion API contract for regulatory_source document type | PF-61 implementation status | Confirm source_type string and metadata schema |
GR-03 gr_compliance_checks insert helper signature | GR-17 Phase 3 implementation | Confirm 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 finalization | Seed migration for the default Arizona profile registers AMPM index source |
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
- GR-17 Spec
- GR-03 Spec
- GR-06-EN-01 Spec
- GR-14 Integration — peer regulator-facing automation (different direction; outbound submissions vs inbound change watching)
- PF-96 Spec
- EVENT_CONTRACTS.md — to add
gr_regulatory_change_detected,gr_regulatory_change_approved - PLATFORM_INTEGRATION_LAYERS.md — PF-10, PF-27, PF-30, PF-46, PF-60, PF-61, PF-96
- CROSS_CORE_INTEGRATIONS.md
- PENDING_CONTRACTS.md