Flag Methodology
This page documents exactly how each of the five computable compliance flags — and the operational_stress_indicator_count composite — is calculated in the Nursing Home Compliance Intelligence dataset: the formula as implemented, the threshold values it reads, what makes a value evaluable, and what the flag cannot see. It is written for a buyer who needs to cite the product in a diligence memo, an underwriting model, or a compliance review with confidence.
Signal, not prediction
Every flag in this product is a published, deterministic formula computed over CMS's own data. A flag is a signal about what the federal record shows — never a prediction about what a facility will do, and never a judgment about the quality of care. The formulas are fixed, the thresholds are versioned in a published seed, and every result carries the evidence needed to reproduce it. We date what CMS published and we quote what the record says; we do not infer, score, or forecast.
The flags live on the FACILITY_MONTH table, one set per facility (CCN) per observed month.
The 0 / 1 / NULL contract
Every flag takes exactly one of three values:
1
The condition is met, on the evidence available for this facility-month.
0
The condition is not met, and we had enough evidence to say so.
NULL
Not evaluable — the inputs needed to decide were missing, suppressed, or outside coverage.
NULL is never a silent 0. A facility that never reported payroll staffing for a quarter gets NULL on the staffing flag, not 0 — because "we could not evaluate this" is a different statement from "we evaluated this and found no shortfall." Confusing the two is the single most common way compliance signals get misread, so we keep them structurally distinct. Every flag is therefore paired with two companion columns:
<flag>_reason— a compact code explaining the value (why it is 1, why it is 0, or why it is NULL).<flag>_inputs_coverage— a boolean: were the inputs this flag needs actually present for this facility-month?
Every flag row also stamps method_version (currently v1), so a recomputed number can always be tied back to the formula and thresholds that produced it.
Thresholds are seed-versioned
Every numeric threshold below comes from a published threshold seed, keyed by threshold_name and carrying its own method_version. Changing a threshold is a versioned change to the seed, not an edit buried in query logic. The v1 values are the pre-registered defaults.
staffing_shortfall_hprd_ratio
0.85
staffing_shortfall_flag
repeat_deficiency_min_tag_occurrences
3
repeat_deficiency_flag
ownership_disclosure_min_disclosed_owners
1
ownership_disclosure_gap_flag
enforcement_escalation_fine_ratio
1.5
enforcement_escalation_flag
closure_signal_precision_min
0.90
deactivation_signal_flag (audit gate)
pbj_census_decline_gt20pct_yoy
20
composite component 4
chow_within_months
12
composite component 5
operational_stress_min_evaluable_components
4
composite NULL semantics
Flag 1 — staffing_shortfall_flag
staffing_shortfall_flagWhat it means: the facility's payroll-based reported nurse staffing for the quarter fell materially below what CMS's own case-mix model expects for that facility.
Formula (as implemented): on FACILITY_MONTH, the facility-month's calendar quarter is joined to its STAFFING_COMPLIANCE row. Then:
Inputs:
pbj_total_nurse_hprd— total nurse hours per resident day for the quarter, from the Payroll Based Journal (PBJ). HPRD = (RN + LPN + CNA hours, employee + contract, summed across the quarter) ÷ resident-days, where resident-days is the sum of daily census. It isNULLwhen no resident-days were reported — never0.case_mix_expected_total_nurse_hprd— CMS's case-mix-adjusted expected total nurse HPRD, passed through verbatim from the provider-information snapshot inside the quarter. This is the baseline; the flag is a comparison against CMS's own expectation, not an external standard.pbj_submission_status—reported_fullrequires that the quarter's days are substantially present in PBJ; otherwisepartialormissing.
Evaluability: the flag is only evaluable when pbj_submission_status = 'reported_full'. If PBJ is partial, missing, or the HPRD/case-mix inputs are suppressed, the flag is NULL and staffing_shortfall_inputs_coverage = FALSE.
Reason codes:
Value
staffing_shortfall_reason
1
below_casemix_x_ratio
0
at_or_above_expected
NULL
not_evaluable_pbj_<status> (e.g. not_evaluable_pbj_partial, not_evaluable_pbj_missing)
Worked example. A facility reports PBJ for a quarter as reported_full. Its total nurse HPRD works out to 3.10, and CMS's case-mix expected total nurse HPRD for the facility is 3.85. The threshold ratio is 0.85, so the shortfall line is 0.85 × 3.85 = 3.27. Because 3.10 < 3.27, staffing_shortfall_flag = 1, reason below_casemix_x_ratio, and all three months of that quarter carry the value on FACILITY_MONTH. A neighboring facility whose PBJ that quarter was only partial gets NULL with reason not_evaluable_pbj_partial — not a 0 — because its staffing simply cannot be judged.
Limitations:
PBJ is quarterly and lags roughly two quarters, so the same quarterly value repeats across all three months of the quarter on
FACILITY_MONTH.The comparison is against CMS's case-mix expectation, not any statutory minimum. The rescinded April-2024 federal HPRD minimum appears nowhere in this product.
A ratio below 0.85 is a reported-hours signal, not a finding about staffing adequacy or care.
Flag 2 — repeat_deficiency_flag
repeat_deficiency_flagWhat it means: the same health-deficiency tag has been cited at this facility across enough separate standard surveys to constitute a recurring pattern rather than a one-off.
Formula (as implemented): built from ENFORCEMENT_EVENTS, restricted to standard-survey health deficiencies (event_type = 'health_deficiency' and standard_deficiency in {Y, YES, TRUE, 1, T}). For each facility, the same tag is followed across its distinct standard-survey dates, keyed on (ccn, tag) — regardless of scope/severity. Splitting a tag by severity would dilute true recurrence, so a tag re-cited at a different severity still counts toward the same series. Per facility:
repeat_hit_month= the earliestfirst_reported_monthat which a tag reaches its Nth distinct standard-survey date (N =repeat_deficiency_min_tag_occurrences, default 3).first_std_def_month= the earliest month any standard health deficiency was reported.
Then on each facility-month:
Evaluability: NULL until the facility has an observed standard survey as of the month in question (repeat_deficiency_inputs_coverage requires first_std_def_month present and reached). This prevents a facility that simply has not been surveyed yet from reading as "no repeats."
Reason codes:
Value
repeat_deficiency_reason
1
tag_recurred_ge_n_surveys
0
no_qualifying_repeat
NULL
no_standard_survey_coverage
Worked example. A facility is cited for deficiency tag F-684 (quality of care) on three separate standard-survey dates — say 2022-05, 2023-06, and 2024-07 — even though the scope/severity differed across them. Counting distinct survey dates for (ccn, F-684), the third distinct date reaches N = 3, and its first_reported_month is, say, 2024-09. From September 2024 onward, repeat_deficiency_flag = 1 (reason tag_recurred_ge_n_surveys); for every month before that the flag is 0 (the facility had standard-survey coverage but had not yet accumulated three distinct survey dates for the same tag).
Limitations (read carefully — this is a deliberate v1 simplification):
The threshold is three distinct standard-survey dates citing the same tag, counted regardless of scope/severity. It is not a check that the surveys were literally consecutive with no clean survey in between — the flag is recurring, not necessarily consecutive. A facility cited for the same tag on three separate surveys years apart, with clean surveys between them, meets the condition.
Because severity is not part of the series key, the same tag cited at two different severities counts toward one recurring series, not two.
Only standard-survey health deficiencies count; complaint-only and fire-safety deficiencies do not drive this flag.
Flag 3 — ownership_disclosure_gap_flag
ownership_disclosure_gap_flagWhat it means: for a month inside PECOS ownership coverage, the facility's federal ownership disclosure is either empty, points to another organization with no further disclosure, or (from the facility's most recent PECOS vintage forward) dead-ends in an undisclosed upstream owner.
Formula (as implemented): per PECOS vintage month, from the curated PECOS ownership data, we compute disclosed_owner_count (distinct owners holding an ownership interest) and has_owned_by_another (any owner flagged owned-by-another-org-or-individual). Separately we carry has_undisclosed_upstream_owner — the current-state, facility-level dead-end measure (the same figure FacilityGuard reports). Then:
ownership_disclosure_min_disclosed_owners = 1, so disclosed_owner_count < 1 means zero disclosed owners while enrolled.
Evaluability: NULL for any month before PECOS interval coverage begins (Feb 2023) and for gap vintages (ownership_disclosure_gap_inputs_coverage requires PECOS coverage, a non-gap previous vintage, and a non-null owner count). Ownership disclosure gaps are never inferred outside the window where CMS actually publishes the interval data.
Reason codes. For a 1, the reason is a pipe-composed code naming which trigger(s) fired — any of low_disclosed|, owned_by_another|, undisclosed_upstream_current|:
Value
ownership_disclosure_gap_reason
1
pipe-composed, e.g. owned_by_another| or low_disclosed|undisclosed_upstream_current|
0
owners_disclosed
NULL
outside_pecos_coverage_or_gap
Worked example. For a non-gap PECOS vintage inside coverage, a facility has two disclosed owners, but one is flagged as owned by another organization whose own upstream owner is not disclosed to CMS. disclosed_owner_count = 2, but has_owned_by_another = TRUE, so ownership_disclosure_gap_flag = 1 with reason owned_by_another|. For a vintage that CMS did not publish (a gap month), the same facility carries NULL with reason outside_pecos_coverage_or_gap.
Limitations:
The flag fires on three conditions: zero disclosed owners, owned-by-another, or the current-state
has_undisclosed_upstream_ownerdead-end.has_undisclosed_upstream_owneris a current-state measure. It therefore contributes to the flag only from the facility's most recent observed PECOS vintage month forward — it is never back-dated onto earlier vintages. A facility that dead-ends today does not read as a disclosure gap for months before that dead-end was observed (the per-vintage triggers still apply to those earlier months).Self-reported disclosure is a floor, not a census: absence of a disclosed owner is a gap in the federal record, not proof of no owner.
Flag 4 — enforcement_escalation_flag
enforcement_escalation_flagWhat it means: the facility's federal monetary penalties escalated sharply from one penalty year to the next.
Formula (as implemented): from ENFORCEMENT_EVENTS, penalty events (event_type = 'penalty') are summed into an annual fine total per (ccn, YEAR(event_date)). Across those annual totals, ordered by year, the prior observed penalty year's total is compared. Per facility:
escalation_month= the earliest January-1 of a year whose fine total ≥1.5 ×the prior observed penalty year's total, where the prior total was > 0.observed_fine_years= the count of distinct penalty years observed.
Then on each facility-month:
Evaluability: NULL until at least two penalty years have been observed for the facility (enforcement_escalation_inputs_coverage = observed_fine_years >= 2).
Reason codes:
Value
enforcement_escalation_reason
1
fine_total_escalated_x_ratio
0
no_escalation
NULL
fewer_than_two_observed_cycles
Worked example. A facility has penalty fine totals of $12,000 in 2022 and $31,500 in 2023. 31,500 ≥ 1.5 × 12,000 = 18,000, so escalation_month = 2023-01-01. From January 2023 onward, enforcement_escalation_flag = 1 (reason fine_total_escalated_x_ratio); for months in 2022 it is 0 (two years were not yet both observable). A facility with penalties in only one year carries NULL (reason fewer_than_two_observed_cycles).
Limitations (v1 is narrower than a literal reading of the definition):
"Cycle" is implemented as a calendar year of penalties, not a survey cycle. The comparison is year-over-year fine totals.
Only fine totals drive escalation. A scope/severity-mix escalation path is not implemented in
v1— a facility whose citations grew more severe without a 1.5× fine increase does not flag here.The comparison uses adjacent observed penalty years. If a facility had penalties in 2021 and 2024 but not 2022–2023, those two years are treated as adjacent for the ratio.
Flag 5 — deactivation_signal_flag
deactivation_signal_flagWhat it means: an observed, fixed-rubric closure-type signal fired for the facility — it disappeared from the snapshots (across adjacent months), a certification termination was recorded in the Provider of Services file, or its certified beds went to zero.
Formula (as implemented): from CLOSURE_SIGNALS, per facility we take the earliest observed signal month and the earliest pending-confirmation signal month. Then:
Closure-signal rubric (CLOSURE_SIGNALS, observed-only):
snapshot_disappearance(top tier) — present at the previous available provider-information vintage, absent at this one, and the two vintages are adjacent (no gap between them). A disappearance across a data gap is unattributable and emits nothing.pos_termination(corroborating) — a Provider of Services certification termination.bed_count_zero(corroborating) — certified beds transition from > 0 to 0.
A signal within CMS's official change-of-ownership publication lag, with no official CHOW yet explaining it, is held at signal_status = 'pending_confirmation' — it cannot yet be distinguished from a change-of-ownership re-enrollment. During that window the flag is NULL, not 1.
Evaluability: deactivation_signal_inputs_coverage is always TRUE — a facility present in the snapshots is always evaluable for whether a signal has fired. Absence of a signal is a genuine 0, not a coverage gap.
Reason codes:
Value
deactivation_signal_reason
1
observed_closure_signal
0
no_signal
NULL
pending_confirmation
Worked example. A facility appears in one provider-information snapshot and is absent from the adjacent next snapshot, with no official CHOW on file. During the publication-lag window the signal is pending_confirmation, so deactivation_signal_flag = NULL. Once the window passes with no CHOW explanation, the signal becomes observed and the flag reads 1 (reason observed_closure_signal) from that month forward.
Limitations:
Termination is not physical closure. A certification termination or a snapshot disappearance is a change in the federal record — the building may still operate under a new CCN, a new owner, or a different program. This is a signal about the record, not about the facility's doors.
The top signal tier (
snapshot_disappearance) is subject to a 30-facility precision audit (closure_signal_precision_min = 0.90). If precision falls below 0.90 the top tier is excluded from delivery until it clears the audit.
Composite — operational_stress_indicator_count
operational_stress_indicator_countWhat it means: a simple count, 0–5, of how many of five fixed operational-stress components fired for a facility-month. It is deliberately named a count of indicators, not a "distress score" or "closure risk" — because that is exactly what it is. It is a count, not a prediction.
Components (exactly five, equal weight):
staffing_shortfall_flag = 1enforcement_escalation_flag = 1sff_or_abuse_icon— Special Focus Facility / SFF-candidate status, or the abuse icon set, in the month's snapshot. Always evaluable.pbj_census_decline_gt20pct_yoy— PBJ average daily census down more than 20% versus the same quarter a year earlier.NULLunless both quarters arereported_full; never a silent0.chow_within_12m— this facility has an official, confirmed change-of-ownership with an effective date within the trailing 12 months. Always evaluable.
Two published columns, plus the count:
stress_indicators_evaluated(0–5) — the denominator: how many of the five components were evaluable this month. Components 3 and 5 are always evaluable, so this is always at least 2.operational_stress_indicator_count(0–5) — the numerator (fired components), but NULL unless at leastoperational_stress_min_evaluable_components = 4of the 5 components were evaluable. A count built on too few evaluable inputs is not published as a number.stress_indicator_reason— eitherinsufficient_evaluable_components, or a pipe-delimited code of which components fired, using the tokensSTAFF|,ENF|,SFF|,PBJDECL|,CHOW12|.
Formula (as implemented):
Worked example. In a given month a facility has: staffing_shortfall_flag = 1 (PBJ was reported_full and below the case-mix line); enforcement_escalation_flag = 0 (two penalty years observed, no 1.5× jump); sff_or_abuse_icon = 1 (SFF status in the snapshot); pbj_census_decline_gt20pct_yoy = 0 (both quarters reported_full, census down only 6%); and chow_within_12m = 0 (no confirmed CHOW). All five components are evaluable, so stress_indicators_evaluated = 5 and operational_stress_indicator_count = 2, with reason STAFF|SFF|. Now take a facility where PBJ was partial (component 1 NULL) and the prior-year PBJ quarter was missing (component 4 NULL): only components 2, 3, and 5 are evaluable, stress_indicators_evaluated = 3, which is below 4 — so operational_stress_indicator_count is NULL with reason insufficient_evaluable_components, even though some components fired.
Limitations:
The count is an unweighted tally of five specific, published components. It is not calibrated to any outcome and must not be read as a probability, a grade, or a ranking of care quality.
Because components 4 (census decline) and 1 (staffing) depend on PBJ, facility-months outside the PBJ coverage window are more likely to fall below the 4-of-5 evaluability floor and read as
NULL. ANULLcount means "not enough evaluable inputs," not "no stress."Component 5 (
chow_within_12m) is treated as always evaluable: a facility with no CHOW on file contributes0, neverNULL.
Last updated

