draft, human-merge (regulated CL/SUD core)
Companion trace: DS4P label propagation is documented separately in
CL-29-EN-66-DS4P-PROPAGATION.md — this doc does not restate it.
Regulatory: NCQA HEDIS FUA/FUI (MY2025 + MY2026), CMS Medicaid Adult Core Set / SUPPORT Act §5001,
42 CFR Part 2, HIPAA 45 CFR 164, AHCCCS DAP, Information Blocking (21st Century Cures).
Sign-off: specs/cl/reviews/CL-29-EN-66-COMPLIANCE-SIGNOFF.md (Approved with Conditions).
This is the integration picture for the two NCQA HEDIS SUD follow-up measures —
FUA (Follow-Up After ED Visit for Substance Use) and FUI (Follow-Up After
High-Intensity SUD Care) — each computed as a 7-day and a 30-day rate. CL-29-EN-66 is a
measures-only spec: it emits an at-risk cohort to CL-35 and owns no outreach, and it
extends the shipped EN-65 FUH/FUM substrate rather than standing up a parallel surface.
Honest status: the measure engine, substrate, RLS, ADT chokepoint, MY-versioned persistence, payer-export gate, and DS4P fail-close are built and tested on branchfeat/cl-29-en-66-fua-fui. The runtime invoker that computes the FUA/FUI set under a resolved PF-96 Measurement Year and drives the persist / cohort-emit / CL-51 registration is the future CL-51 eCQM runner / PM-03 canonical path, which has not landed — several typed service wrappers (fuaAdtIngest.ts,hedisMeasurePersist.ts) intentionally have no production call site yet and are exercised by integration tests. Four external compliance gates ship fail-closed and remain human-verify-open (see §7).
1. PF-108 Contexture ADT consumer contract
Out-of-network ED-for-SUD visits are not visible inpm_encounters (the patient was seen at
another facility), so FUA’s denominator needs an external admit/discharge/transfer (ADT) feed.
That feed is PF-108 Contexture HIE. EN-66 consumes it into a dedicated table,
cl_fua_adt_events — the sanctioned FR-7 exception (ADT shape ≠ aftercare-plan shape).
- Ingest path. The sanctioned write surface is the SECURITY DEFINER RPC
cl_ingest_fua_adt_event(...)(typed wrappersrc/cores/cl/services/fuaAdtIngest.ts). It re-asserts tenancy server-side (cl_has_org_access→42501; chart∈org →42501) because DEFINER bypasses RLS. ANULL auth.uid()(service-role feed) is the accepted-risk H-2 path, mirroring PM-75 — the feed runs asservice_role, not as an end user. - Direct-write chokepoint. The table is also directly writable (RLS only checks
cl_has_org_access(organization_id)), so two BEFORE-row triggers fire on every write path (direct PostgREST, service-role feed, and the RPC) and cannot be bypassed:cl_fua_adt_events_derive_biu()derivessud_indicatedfail-closed — an absent / indeterminate / unparseable SUD signal resolves totrue(presumed SUD, maximum Part 2 protection) — and setsds4p_confidentiality_code := 'R'for SUD rows. It also enforces the chart∈org chokepoint (42501).cl_fua_adt_events_ds4p_label_biu()fail-closesds4p_security_label(see §5 / the DS4P trace doc).
- SUD derivation is never a hardcoded code list.
sud_indicatedis derived from dx / CL-62 episode metadata + instrument NOMs domains, never an inline F10–F19 list (the CL-69 lesson; the SUD flag is also the RLS read-gate key). - Planning-stub caveat. PF-108 is a planning stub, not a live feed. The chokepoint, fail-close, and RLS isolation are proven by tests; live end-to-end ADT ingest is human-verify-open (gate, §7).
2. CL-51 measure-spec registration
The four measure variants —FUA-7, FUA-30, FUI-7, FUI-30 — are registered as
MY-stamped snapshots in cl_quality_measure_periods via the hardened RPC
cl_persist_hedis_measure_period(...) (typed wrapper
src/cores/cl/services/hedisMeasurePersist.ts; measureId is the variant key).
- MY selected from PF-96 at evaluation time. The active Measurement Year ruleset
(
MY2025vsMY2026) is read from PF-96ComplianceRules.active_measurement_year_versionat evaluation time — nevernew Date().getFullYear()(AC-2). MY2025 applies the principal-position SUD-dx denominator rule; MY2026 applies any-position SUD dx and counts peer support + residential as qualifying follow-up. The measure-spec loader (src/cores/cl/utils/fua-fui-measure-spec.ts) builds all params from PF-96. - No hardcoded NCQA OIDs (NFR-config-1). The loader carries no NCQA value-set codes. Per-MY value-set OIDs are expected to be loaded into the CL-51 measure-spec registry from the licensed NCQA portal — that acquisition is gate 6, human-verify-open (§7). The engine encodes only the documented MY2025/MY2026 ruleset shape; the codes themselves come from the registry, not from source.
3. Denominator sourcing — interim proxy decision (PM-03 pending)
The canonicalpm_encounters.encounter_type enum
(outpatient | iop | php | crisis | group | telehealth | evaluation | residential_daily) has
no ED or acute-inpatient value. Until PM-03 lands canonical encounter classes, EN-66 uses an
EN-65-consistent interim proxy, entirely behind PF-96 config:
- FUA denominator →
crisis/evaluationencounters with a SUD indication (plus the PF-108 ADT out-of-network ED events from §1). - FUI denominator →
residential_dailyencounters. The NCQA-default high-intensity scope is residential + acute-inpatient SUD; the PF-96 opt-infui_high_intensity_expansionadds PHP/IOP (FUI_HIGH_INTENSITY_EXPANSION_TYPES) — see the admin guide for the benchmarkability trade-off.
TODO(PM-03) in code. This is a known interim
decision, the same approach shipped and approved in EN-65; correctness is refined when PM-03
delivers canonical encounter types. The FUA/FUI denominator also enforces an explicit age floor —
FUA_MIN_AGE = FUI_MIN_AGE = 13 (src/cores/cl/types/discharge.ts) — closing sign-off residual
item 4 (NCQA SUD measures are 13+).
4. CL-35 care-gap emit
EN-66 is downstream of CL-35 for outreach: a member who is in the FUA/FUI denominator but has no qualifying follow-up within the 7- or 30-day window is surfaced to CL-35 as a care gap rather than acted on by EN-66 itself. The intended emit shape writescl_care_gaps with
gap_type = 'follow_up_not_scheduled' (a real CL-35 care-gap type) and a source_rule naming the
measure/window (e.g. EN-66-FUA-7DAY, EN-66-FUI-30DAY). EN-66 owns no work-list UI — CL-35’s
care-gap work list, clinician panels, and supervisor view consume the gap. As with §2/§3, the
emit is driven by the not-yet-wired CL-51/PM-03 eCQM runner (the cohort capability is built and
tested; the production call site lands with the runner).
5. DS4P leg (cross-link, not restated)
SUD ADT rows incl_fua_adt_events are DS4P-labeled fail-closed at the DB chokepoint
(ds4p_confidentiality_code = 'R', ds4p_security_label = '42CFRPart2,ETH|NORDSLCD'), and that
label’s redisclosure obligation is operationalized as BLOCKING before any payer export by the
T4.1 consent gate (cl_fua_payer_export_gate). The full propagation chain, the TS↔DB SSOT
drift-trap test, the trigger fire-order, and the CL-63 boundary are documented in
CL-29-EN-66-DS4P-PROPAGATION.md. A SUD row cannot reach a
payer destination without active 42 CFR Part 2 consent.
6. T4.3 hardening-audit evidence
Read-only audit of every new DB security object on the branch. Columns:SD? = SECURITY DEFINER; sp? = SET search_path = public; own? = OWNER TO postgres; rev? = REVOKE EXECUTE FROM anon, PUBLIC; org-guard? = server-side tenancy re-assert raising 42501.
Per-object verdict: all seven objects are hardened to the CL/SUD regulated bar. Every
SECURITY DEFINER object carries
search_path = public + OWNER postgres + a REVOKE that removes
the repo baseline’s auto-EXECUTE from anon/PUBLIC. The four DEFINER objects that read or
write cross-tenant data (the derive trigger, the ingest RPC, the persist RPC, and the export gate)
each re-assert tenancy server-side and raise 42501. The two label/derive-only triggers and the
immutability guard are correctly marked org-guard N/A (no cross-tenant read — tenancy is
enforced by their callers or co-located triggers). The immutability guard is intentionally not
DEFINER (a RAISE-only trigger needs no elevated privilege).
Substrate anon-grant note: the Phase-1 substrate (20260701000016) copied a non-Part-2
sibling’s GRANT ALL ON TABLE cl_fua_adt_events TO anon; the very next migration
(20260701000017) REVOKE ALL ON TABLE public.cl_fua_adt_events FROM anon, so the net state is
no anon access to the SUD ADT table.
Redisclosure-log immutability — verified, not recreated. The append-only immutability trigger
for the payer-export-request ledger, cl_fua_payer_export_requests_immutable() /
trg_cl_fua_payer_export_requests_immutable, already exists in 20260701000020 and is not
recreated by any later migration. The CL-11 cl_redisclosure_log itself is owned by CL-11;
20260701000020 only INSERTs into it on the allowed-payer path and does not redefine the
table or its CL-11 immutability trigger.
Denominator-bridge VIEW — security_invoker confirmed. cl_hedis_fuh_fum_summary is created
WITH (security_invoker = 'true') in both 20260701000016 (substrate) and 20260701000018
(denominator bridge) — the cross-tenant PHI-leak guard (the CL-69 lesson) is preserved across the
recreate.
7. Human-verify-open compliance gates
Four external gates ship fail-closed and remain human-verify-open (same bar as PM-75 / CL-69; seeCL-29-EN-66-COMPLIANCE-SIGNOFF.md
items 6 / 10a-b / 10c / 8):
- Gate 6 — NCQA value-set OID acquisition (sign-off item 6). Ships: a measure-spec loader that hydrates OIDs from the CL-51 registry with zero NCQA codes inline (NFR-config-1). Human must verify: per-MY (MY2025 + MY2026) value-set OIDs acquired from the licensed NCQA portal and loaded into the CL-51 registry before denominator logic ships to prod.
- Gate 10a-b — CL-11 Part 2 export consent (sign-off item 10a-b). Ships:
cl_fua_payer_export_gatefail-closes any payer-facing SUD export at the DB unless activecl_check_sud_consent()and an explicitly-enabled org payer-export flag, writingcl_redisclosure_logon every permitted redisclosure; internal org-scoped computation is allowed, payer-facing export disabled until live. Human must verify: a valid TPO consent / individual authorization / QSOA covers the disclosure purpose, and ADT-derived events are not stored with identifiable SUD dx absent active Part 2 consent. - Gate 10c — DS4P label-propagation trace vs CL-63 (sign-off item 10c). Now documented — the T2/T4.2 trace CL-29-EN-66-DS4P-PROPAGATION.md proves the DB fail-close, the TS↔DB SSOT agreement, and BLOCKING-before-payer-export. Human must verify: live PF-108 / Contexture feed end-to-end propagation (PF-108 is a planning stub).
- Gate 8 — AHCCCS DAP per-year measure weighting (sign-off item 8). Ships: per-MY weighting externalized to PF-96 (no hardcoded weights). Human must verify: direct AHCCCS QM-team confirmation of whether FUA/FUI feed DAP for a given AZ payment year, recorded in the tracker before the first DAP submission that uses platform-generated rates.
FUI_MIN_AGE = 13; FUA_MIN_AGE = 13).