Skip to content

Implement Iowa State Supplementary Payment (SSP)#8017

Open
hua7450 wants to merge 17 commits intoPolicyEngine:mainfrom
hua7450:ia-ssp
Open

Implement Iowa State Supplementary Payment (SSP)#8017
hua7450 wants to merge 17 commits intoPolicyEngine:mainfrom
hua7450:ia-ssp

Conversation

@hua7450
Copy link
Copy Markdown
Collaborator

@hua7450 hua7450 commented Apr 16, 2026

Summary

Implements Iowa's State Supplementary Assistance (SSA) — a state SSI supplement program administered jointly by the Social Security Administration (federally-administered arrangements) and Iowa Department of Health and Human Services (state-administered arrangements). SSA provides six modeled supplement arrangements for low-income aged, blind, and disabled Iowans who receive or would receive federal SSI.

The design uses a single ia_ssa_living_arrangement enum to route each person to one arrangement, and a single ia_ssa payment formula that selects over that enum. There are no per-arrangement supplement variables — one routing variable, one payment variable.

Closes #7733

Regulatory Authority

Program Overview

  • Administration split per POMS SI 01415.050.F:
    • Federally-administered (SSA issues combined federal SSI + state supplement): Blind, Dependent Person, Family-Life Home
    • State-administered (Iowa HHS pays separately): Residential Care Facility, In-Home Health-Related Care, Supplement for Medicare/Medicaid Eligibles
  • Funding: State funds (supplement paid on top of federal SSI).
  • Agency: Iowa Department of Health and Human Services (HHS, formerly DHS; reorganized 2023).
  • Current caseload: 5,281 recipients in 2011 per SSA State Assistance Programs report (last year SSA published state-level counts).

Six Modeled Living Arrangements

Arrangement Administration Amount (2025) Source
Blind Federal SSA $22/month flat IAC 441—52.1(4)
Dependent Person (DP) Federal SSA 5 configs, $1,470–$1,997 standard IAC 441—52.1(2)
Family-Life Home (FLH) Federal SSA Standard $1,129; max state supplement $142 IAC 441—52.1(1)
Residential Care (RCF) Iowa HHS $37.60/day × 31 days − client participation, $126 PNA IAC 441—52.1(3)
In-Home HRC (IHHRC) Iowa HHS $480.55 per-person cap minus client participation IAC 441—177.4(1)(f), 441—177.10(2)(a), 441—177.10(3)
SMME Iowa HHS $1/month IAC 441—52.1(7)

Priority (highest to lowest, enforced in ia_ssa_living_arrangement): RCF → IHHRC → FLH → DP → Blind → SMME → NONE. Iowa is a "concurrent category State" per POMS — recipients receive the highest-priority supplement they qualify for.

Eligibility

Requirement Source How Modeled
Aged, blind, or disabled Iowa Code §249.3; IAC 441—51.1 is_ssi_eligible (categorical component)
Must apply for or receive SSI IAC 441—51.2 is_ssi_eligible covers categorical + resource + immigration
Resource limit ($2,000 single / $3,000 couple) IAC 441—51.5(2) via federal SSI ia_ssa_resources_eligible sums marital-unit resources for joint claims
Iowa residence IAC 441—51.6 defined_for = StateCode.IA
Arrangement-specific:
RCF: post-PNA client participation < 31 × max_per_diem IAC 441—51.3(3) cross-refs 52.1(3)"a" ia_ssa_living_arrangement gates on post-PNA client participation
IHHRC: combined marital-unit countable, after SSI FBR disregard, ≤ $480.55 (single) or $961.10 (couple) IAC 441—177.4(1)(f) Combined marital-unit income check with FBR disregard, applied symmetrically for single and couple
FLH/DP/Blind: federally-administered V-shape phase-down POMS SI 01415.050.F max(0, state_standard − max(countable, FBR)), plus FBR for Blind
SMME: Medicaid + Part B + income > 120% FPL IAC 441—51.6 ia_ssa_smme_eligible
Full Medicaid (excludes medically-needy/spenddown) IAC 441—51.6(1) ia_ssa_has_full_medicaid — explicit input, default_value = False

Benefit Amount Formulas

All arrangements are computed inside ia_ssa, selected by ia_ssa_living_arrangement.

Federally-administered (Blind, DP, FLH) use the standard SSP V-shape:

supplement = max(0, total_standard − max(countable_income, FBR))

Blind's state portion ($22) is added on top of FBR per POMS guidance; DP/FLH standards are the total payment standards.

RCF uses cost-based reimbursement:

supplement = max(0, cost_of_care − client_participation)
  where cost_of_care          = min(cost_per_diem, $37.60) × 31
  and   client_participation   = max(0, (countable + SSI) − $126 PNA)

Income eligibility uses the same post-PNA client participation: eligibility holds when client_participation < 31 × max_per_diem.

IHHRC uses cost-based reimbursement minus client participation, per person, per IAC 441—177.10(2)(a):

supplement = max(0, min(cost_of_care, $480.55) − client_participation)
  where client_participation = (combined_marital_countable − FBR_disregard) / marital_unit_size

The per-person cap is always $480.55 per IAC 441—177.10(3); the $961.10 in 441—177.4(1)(f) is the combined-couple income cap, not a payment cap.

SMME is a flat $1/month for people with full Medicaid + Medicare Part B + income above 120% FPL.

Historical Coverage

Parameters have multi-tier effective dates with authoritative sources for each:

Tier Source
2011-01-01 SSA State Assistance Programs for SSI Recipients — Iowa (January 2011), Table 1
2017-01-01 Iowa Administrative Code 01-04-2017 supplement, 441—51.3–51.4, 441—52.1
2018-01-01 Iowa Administrative Code 03-28-2018 rule update for 441—52.1
2025-01-01 Iowa HHS General Letter 6-B-46
2026-01-01 Iowa HHS State Supplementary Assistance Standards current page

Values frozen in the IAC rule text ($22 blind, $142 FLH aged max supplement, $480.55/$961.10 IHHRC caps) are dated 2011-01-01 with SSA 2011 as corroborating source. 2012–2016 and 2019–2024 intermediate values are not encoded; PolicyEngine carries the most recent preceding entry forward.

2026 DP Value Anomaly

The 2026 DP configuration "Blind Client + Aged/Disabled Spouse + Dependent Relative" shows $3,031 on the Iowa HHS SSA rates page — a +53.5% jump over 2025 ($1,975) against a ~2.85% COLA on every other configuration. An expected ~$2,031 would be COLA-consistent, so the $3,031 may be an Iowa HHS publication error. Encoded as published; YAML comment documents the anomaly pending Iowa HHS clarification.

Not Modeled (by design)

What Source Why Excluded
Mandatory State Supplement (MSS) Iowa Code §249.3(1); IAC 441—52.1(6) Closed December 1973 grandfather cohort; no input data in PolicyEngine
SMME SGA test IAC 441—51.6(2) SGA not modeled in PolicyEngine
SMME upper-income cap (Medicaid eligibility group income limit) IAC 441—51.6(6) Iowa Medicaid income-limit variable not available; 120% FPL floor IS modeled
Physician certification for IHHRC (Form 470-0673) IAC 441—177.6 Administrative verification
IHHRC 5-step disregard cascade (unmet medical needs, dependents) IAC 441—177.4(1)(f) State-specific disregards require inputs not in PolicyEngine; federal SSI disregards handled via ssi_countable_income
RCF pre-2017-07-01 flat per-diem branch IAC 441—52.1(3) Iowa switched to cost-related-only system on 7/1/2017
Part A vs. Part B Medicare distinction for SMME IAC 441—51.6(4) PolicyEngine's medicare_enrolled does not distinguish Part A vs B; ia_ssa_has_medicare_part_b is an explicit input (default_value = False)
SSN requirement and apply-for-other-benefits administrative rules IAC 441—51.2, 441—51.9 Administrative verification
Medically-needy / spenddown Medicaid routed to SMME IAC 441—51.6(1) ia_ssa_has_full_medicaid is an explicit input so only full-Medicaid recipients trigger SMME

Files

policyengine_us/parameters/gov/states/ia/hhs/ssa/
  blind.yaml
  dp/
    assistance_standard.yaml       # breakdown by ia_ssa_dp_configuration enum
    dependent_income_limit.yaml
    max_per_person_cap.yaml
  flh/
    assistance_standard.yaml
    max_supplement.yaml
  ihhrc/
    max_cost_single.yaml
    max_cost_couple.yaml
  rcf/
    days_multiplier.yaml
    max_per_diem.yaml
    personal_needs_allowance.yaml
  smme/
    amount.yaml
    minimum_income_fpl_multiplier.yaml

policyengine_us/variables/gov/states/ia/hhs/ssa/
  ia_ssa.py                          # single payment formula, selects over living_arrangement
  ia_ssa_living_arrangement.py       # enum + routing formula
  ia_ssa_eligible.py
  ia_ssa_resources_eligible.py       # sums marital-unit resources for joint claims
  dp/
    ia_ssa_dp_configuration.py
    ia_ssa_dp_has_eligible_dependent.py
    ia_ssa_dp_dependent_countable_income.py
  flh/
    ia_ssa_resides_in_family_life_home.py
  ihhrc/
    ia_ssa_ihhrc_cost_of_care.py
    ia_ssa_needs_in_home_health_related_care.py
    ia_ssa_ihhrc_both_need_care.py
  rcf/
    ia_ssa_rcf_cost_per_diem.py
    ia_ssa_resides_in_residential_care_facility.py
  smme/
    ia_ssa_has_full_medicaid.py      # explicit input, default_value = False
    ia_ssa_has_medicare_part_b.py    # explicit input, default_value = False
    ia_ssa_smme_eligible.py

policyengine_us/tests/policy/baseline/gov/states/ia/hhs/ssa/
  ia_ssa.yaml                        # consolidated payment tests (all 6 arrangements)
  ia_ssa_living_arrangement.yaml     # routing / priority tests
  ia_ssa_eligible.yaml
  ia_ssa_resources_eligible.yaml
  ia_ssa_dp_configuration.yaml

policyengine_us/parameters/gov/household/household_state_benefits.yaml  [adds ia_ssa]
policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py [adds ia_ssa]
policyengine_us/programs.yaml                                            [IA SSA status → complete]
changelog.d/ia-ssp.added.md

Test plan

  • 77 tests pass across 5 YAML files — real federal+state income inputs, includes 2017/2018/2025/2026 historical tiers and boundary cases for each arrangement
  • make format clean
  • Microsimulation regression test passes
  • Branch synced with upstream/main
  • CI passes

🤖 Generated with Claude Code

hua7450 added 2 commits April 16, 2026 12:59
Adds Iowa SSA (Iowa Code Ch 249; IAC 441 Chs 50-52, 54, 177) covering:
- Blind supplement (flat $22/month)
- Dependent Person (DP) supplement (5 household configurations)
- Family-Life Home (FLH) supplement (max $142/month)
- In-Home Health-Related Care (IHHRC) supplement (cost-based, max $480.55/$961.10)
- Residential Care Facility (RCF) supplement (cost-related per diem)
- Supplement for Medicare and Medicaid Eligibles (SMME) (flat $1/month)

Closes PolicyEngine#7733
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.67%. Comparing base (20705b0) to head (4f0bbd3).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #8017       +/-   ##
===========================================
+ Coverage   85.36%   97.67%   +12.30%     
===========================================
  Files           3       17       +14     
  Lines          41      258      +217     
  Branches        2        2               
===========================================
+ Hits           35      252      +217     
  Misses          6        6               
Flag Coverage Δ
unittests 97.67% <100.00%> (+12.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hua7450 and others added 14 commits April 17, 2026 16:32
- Verified $3,031 DP BLIND_WITH_AGED configuration against Iowa HHS; replaced typo comment with verification note
- Fixed 4 broken PDF page anchors (blind.yaml, SMME + DP docstrings)
- Added formulas to ia_ssa_has_full_medicaid / ia_ssa_has_medicare_part_b delegating to federal medicaid_enrolled / medicare_enrolled, making SMME reachable in microsim
- Added IAC 441-177.4(1)(c) own-home eligibility check to IHHRC category
- Extracted ia_ssa_ihhrc_both_need_care variable; removed hard-coded 2 duplicated in two files
- Reworked 5 non-functional ineligible tests to exercise ia_ssa_resources_eligible via ssi_countable_resources
- Added ia_ssa_resources_eligible.yaml with boundary coverage (single/couple x below/at/above)
- Added couple IHHRC test cases (at cap, above cap, one-spouse fallback)
- Expanded category priority from 4 to 11 cases (IHHRC/DP/BLIND/SMME pairings)
- Locked in blind combinability: blind RCF resident -> $0 blind supplement
- Documented IAC 441-52.1(4) mutual exclusivity in ia_ssa_blind_supplement docstring
- Consolidated test files to one-per-variable: merged integration_* and test_2025_to_2026_transition cases into variable-specific files with ssi + ia_ssa outputs side-by-side

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prior formulas used `max(0, -uncapped_ssi) + ssi` as a proxy for total
monthly income. That expression equals `|FBR − countable_income|`, not
actual income, which caused material errors:

- RCF eligibility and client participation understated income for anyone
  with outside income below the FBR, overpaying the supplement by hundreds
  and classifying high-income residents as eligible.
- IHHRC cap (IAC 441—177.4(1)(f)) was compared against excess-over-FBR
  instead of monthly countable income, letting recipients with countable
  income far above the $480.55 cap qualify whenever they were below the FBR.
- DP and FLH phase-out (federally-administered per POMS SI 01415.050.F) did
  not use the federal SSP formula, paying the full cap in income bands where
  the supplement should phase down dollar-for-dollar.

Fixes:
- RCF and IHHRC (state-administered) use monthly SSI countable income +
  federal SSI payment as total income, matching IAC 441—52.1 rules.
- DP and FLH (federally-administered) use
  `max(0, total_standard − max(countable, FBR))`, matching POMS SSP rules.
- Delete unused flh.personal_needs_allowance parameter (dead code — FLH
  assistance standard is a lumped sum that already includes the allowance).
- Add regression tests for each bug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…into ia-ssp

# Conflicts:
#	policyengine_us/parameters/gov/household/household_state_benefits.yaml
#	policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py
- Add IAC 441—51.7(6) 120% FPL income floor for SMME eligibility
- Restructure smme.yaml to smme/ folder (amount.yaml + minimum_income_fpl_multiplier.yaml)
- Remove documentation= field from 3 variables (not PolicyEngine convention)
- Fix days_multiplier.yaml description wording
- Update programs.yaml: Iowa SSA status in_progress -> complete, add variable=ia_ssa
- Rewrite tests with realistic income inputs (age, social_security_retirement) instead of bypass inputs (is_ssi_eligible, meets_ssi_resource_test, is_ssi_aged_blind_disabled); verify full federal-state chain
- Add boundary and negative cases (SMME 120% FPL boundary, IHHRC countable income cap, FLH phase-down)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
IHHRC (IAC 441—177.10(3) and 441—177.4(1)(f)):
- Maximum benefit payable is $480.55 per person, always — not $961.10
  per person when both need care. The $961.10 is the combined couple
  INCOME cap in 441—177.4(1)(f), not a payment cap.
- Income eligibility now compares combined marital-unit countable
  income against $961.10 when both spouses need care, and individual
  countable income against $480.55 otherwise.
- Updated parameter descriptions and tests; dropped the now-irrelevant
  441—52.1(5) reference on max_cost_couple (that subsection defers to
  Chapter 177, which sets the per-person payment cap at $480.55).

Blind (IAC 441—52.1(4)):
- Applied federally-administered SSP V-shape formula (like DP/FLH):
  max(0, FBR + state_standard - max(countable, FBR)). A blind recipient
  with countable income above $989 now correctly phases to $0 instead
  of receiving a flat $22 regardless of income.

Medicare Part B (IAC 441—51.7(4)):
- Documented that PolicyEngine's medicare_enrolled does not distinguish
  Part A from Part B. SMME statutorily requires Part B; using
  medicare_enrolled as the closest proxy, acknowledging Part A-only
  enrollees are not filtered out.

RCF eligibility PNA check reviewed and confirmed correct per statute:
441—51.4(3) compares "income according to 441—paragraph 52.1(3)(a)"
which already incorporates the PNA as disregard (2) before the
31 × max_per_diem threshold test. No change needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Blind (IAC 441—52.1(4)):
- Added income gate to BLIND category assignment that matches the
  federally-administered V-shape ceiling (FBR + state standard = $989).
  A blind person whose countable income exceeds $989 now falls through
  to the next applicable category (e.g., SMME if income is also above
  120% FPL) rather than being labeled BLIND with a $0 supplement.

Medicare Part B (IAC 441—51.7(4)):
- Converted ia_ssa_has_medicare_part_b to a pure input variable with
  default False. Previously the formula defaulted to medicare_enrolled
  (Part A and/or B), which pulled Part A-only enrollees into SMME.
  SMME is a $1/month program for a narrow dual-eligible population; a
  False default with explicit opt-in matches both the statutory
  requirement ("currently eligible for Medicare Part B") and the real
  caseload better than an overbroad proxy.

RCF eligibility PNA check re-verified: IAC 441—51.4(3) references "the
income according to 441—paragraph 52.1(3)(a)," and 52.1(3)(a) defines
"Income applied to meet the cost of care" as (countable + SSI benefit)
minus five disregards including the PNA (disregard 2). The current
code applies the PNA as the statute directs. No change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
IAC 441—51.4(3) compares "the income according to 441—paragraph
52.1(3)(a)" against 31 × max_per_diem. Section 52.1(3)(a) describes
two concepts: the gross income input (SSI countable + SSI benefit)
and the post-disregard "Income applied to meet the cost of care"
(client participation). The statute is textually ambiguous as to
which "the income" refers to, but:

- 31 × max_per_diem is approximately the monthly cost of RCF care at
  the maximum per-diem rate. Comparing gross monthly income against
  that cost is the meaningful substantive test — it excludes people
  who could afford care on their own income.

- Standard benefit-program convention uses gross income for
  eligibility tests, with disregards (including personal needs
  allowances) applied in the benefit amount calculation.

- Under the post-disregard reading, the test barely screens anyone
  out: income must exceed ~$1,292 (threshold + PNA + other
  disregards) to be ineligible at the 2025 per-diem rate, so the
  eligibility gate had almost no substantive effect.

Switched ia_ssa_category.py to compare total_rcf_income (pre-PNA)
against 31 × max_per_diem. The PNA remains in ia_ssa_rcf_supplement
where it belongs: reducing client participation in the payment
calculation.

Cross-verified against SSA POMS SI 01415.050.F: RCF is state-
administered by Iowa HHS, so this is a state policy interpretation,
not a federal SSP formula question.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prior "2017-07-01" effective date was incorrect — those values were
copied from Iowa HHS's current web page (which shows 2025 values) and
backdated to 2017 without historical verification. Replaced with
properly sourced historical tiers:

- **2011-01-01**: SSA State Assistance Programs for SSI Recipients —
  Iowa (January 2011), Table 1. Provides frozen values ($22 blind, $142
  FLH aged max supplement, $480.55 / $961.10 IHHRC) and 2011 baselines
  for COLA-adjusted parameters.

- **2017-01-01**: Iowa Administrative Code 01-04-2017 supplement.
  Provides 441—52.1 dollar amounts (FLH $897, DP $1,114/$1,482/$1,136/
  $1,504/$1,526, RCF per diem $30.11, PNA $100) and 441—51.4(1)
  dependent-relative income limit $379.

- **2018-01-01**: Iowa Administrative Code 03-28-2018 rule update for
  441—52.1. Provides 2018 COLA values (FLH $912, DP $1,137/$1,512/
  $1,159/$1,534/$1,556, RCF per diem $30.60, PNA $99).

- **2025-01-01**: Iowa HHS General Letter 6-B-46 (effective January 1,
  2025). Corresponds to the values previously misdated 2017-07-01.
  Preserves test expectations at 2025-01 period.

- **2026-01-01**: Iowa HHS current State Supplementary Assistance
  Standards web page (unchanged).

SMME parameters (amount $1, 120% FPL multiplier) start at 2017-01-01 —
the program existed since October 1, 2003 but the SSA 2011 report does
not publish the $1 amount directly, so we cite only what we can verify.

DP dependent_income_limit and max_per_person_cap start at 2017-01-01
because the SSA 2011 report does not publish these specific Iowa-only
concepts; the 2017 IAC supplement is the earliest direct source.

All 73 Iowa SSA tests continue to pass at 2025-01 and 2026-01 periods.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- RCF income gate now compares post-PNA client participation against
  31 x max_per_diem per IAC 441-51.3(3) cross-ref to 52.1(3)"a"
- IHHRC income gate applies the SSI FBR disregard and checks combined
  marital-unit countable against the applicable cap symmetrically
- IHHRC payment subtracts client participation per IAC 441-177.10(2)(a),
  split evenly across marital-unit members
- DP dependent-income-eligible check moved into ia_ssa_category so a
  person with a disqualifying dependent falls through to BLIND / SMME
  instead of receiving a zero DP supplement
- Resource test sums marital-unit resources for joint SSI claims
- ia_ssa_has_full_medicaid converted to an explicit input with
  default_value=False, matching ia_ssa_has_medicare_part_b, so Medicaid
  pathways outside "full Medicaid" (spenddown, MEPD premium) do not
  trigger SMME
- Fix citation typos: SMME minimum_income_fpl_multiplier cites
  441-51.6(6); RCF days_multiplier cites 441-51.3(3) with unit /1 and
  period eternity
- Strengthen 2026 DP BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT
  comment documenting the +53.5% jump vs 2.85% COLA anomaly
- Add 2017 DP and 2018 RCF historical test cases; add DP fallthrough
  category test; update IHHRC and resources tests for new rules; remove
  obsolete sources/working_references.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…into ia-ssp

# Conflicts:
#	policyengine_us/parameters/gov/household/household_state_benefits.yaml
Replace the six supplement variables (ia_ssa_blind_supplement,
ia_ssa_dp_supplement, ia_ssa_flh_supplement, ia_ssa_ihhrc_supplement,
ia_ssa_rcf_supplement, ia_ssa_smme_supplement) with a single
payment formula in ia_ssa that selects over ia_ssa_living_arrangement.

Rename ia_ssa_category -> ia_ssa_living_arrangement (enum and variable)
to match the reality of what the enum represents.

Helper variables that represent genuine inputs (residency flags,
cost-of-care, DP configuration, Medicaid/Part B flags, SMME eligibility,
both-need-care) remain unchanged.

Tests reorganized:
- ia_ssa_living_arrangement.yaml holds routing/priority tests
- ia_ssa.yaml consolidates the six per-category payment tests with
  outputs renamed to ia_ssa; one BLIND-in-RCF case updated to assert
  the routed RCF payment rather than the zero blind value.

All 77 Iowa SSA YAML tests pass; microsim unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parameter normalization:
- Rename dp/assistance_standard.yaml -> dp/state_supplement.yaml
- Rename flh/assistance_standard.yaml -> flh/state_supplement.yaml
- Values are now the state portion above FBR (consistent with blind.yaml),
  so all three federally-administered arrangements use one formula shape:
  max(0, (FBR + state_supplement) - max(countable, FBR)).

P2 #1 — FLH Department top-up for SSI-only recipients:
  The Iowa FLH state supplement ($162 from 2017 onward) exceeds the
  federally-administered max_supplement cap ($142) by exactly $20, the SSI
  general-income disregard. Per IAC 441-52.1(1), when the recipient has
  no other income (so SSA's $20 disregard is unused), Iowa HHS issues an
  additional Department payment equal to (state_supplement - max_supplement)
  to close the gap and bring total income to the full standard. In 2011
  the state supplement equals the cap so no top-up is owed; from 2017
  onward the top-up is $20.

P2 #2 — IHHRC client participation charged to sole recipient:
  When only one spouse needs IHHRC, charge the entire combined client
  participation to that spouse instead of splitting it evenly across the
  marital unit. The split remains correct for both-need-care couples
  where both members compute the supplement independently.

Tests:
- FLH Cases 1 and 4 (zero-income) now expect $162 (was $142)
- New IHHRC Case 12 exercises the sole-recipient participation rule:
  couple with $800/mo SS each, one needs care -> supplement $270 instead
  of $335 under the old 50/50 split.

77 + 1 = 78 Iowa SSA tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review April 23, 2026 04:45
Address three P2 review items:

1. 2026 DP BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT: Iowa HHS's
   published $3,031 breaks the "-$22 when only one spouse is blind"
   footnote rule that's held for 2011/2017/2018/2025 and inflates the
   phase-down ceiling so high-income 2026 cases still receive DP when
   they should phase to zero. Encoded as the COLA-consistent total
   $2,031 (state portion $1,037). YAML comment documents the suspected
   Iowa HHS publication error and the basis for the override.

2. DP max_per_person_cap and dependent_income_limit now carry
   2018-01-01: $387, matching the base state_supplement 2018 tier.
   Prior gap left 2018-2024 DP payments and eligibility understated
   against the 2017 $379 values.

3. FLH blind recipients receive the $22 blind increment on top of the
   federally-administered $142 cap (POMS OS code I: state portion
   $164 for blind FLH residents). The blind increment replaces — not
   adds to — the SSI-only Department top-up; $22 > $20 always. New
   FLH test case 7 locks in the $164 figure for a blind FLH resident.

79 Iowa SSA tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@PavelMakarchuk PavelMakarchuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iowa State Supplementary Payment (SSP) — PR #8017 Review

Source Documents


Critical (Must Fix)

  1. DP supplement formula uses individual FBR for couple configurations and applies an unjustified per-person cap

    • Location: policyengine_us/variables/gov/states/ia/hhs/ssa/ia_ssa.py:39-43; parameters/.../dp/state_supplement.yaml; parameters/.../dp/max_per_person_cap.yaml.
    • The formula is dp_raw = max_(0, (individual_fbr + dp_state_supplement) - countable_or_fbr); dp_amt = min_(dp_raw, p.dp.max_per_person_cap). countable_or_fbr is clamped to individual_fbr ($967) even when the configuration represents an eligible couple — federal SSI for an eligible couple fills to the couple FBR ($1,450), not the individual FBR. The state_supplement YAML is back-calculated against individual_fbr for every configuration, producing wildly inflated raw values that the author then bounds with max_per_person_cap = $503.
    • The $503 cap has no regulatory basis as a payment ceiling — it is the dependent relative's income eligibility limit (per IAC 441-51.5(1) / GL 6-B-46 cover page), repurposed here. max_per_person_cap.yaml and dependent_income_limit.yaml are byte-identical across all four years (379, 387, 503, 518), confirming the conflation.
    • Code-path verifier confirmed: for BLIND_WITH_BLIND_SPOUSE_AND_DEPENDENT 2025 with zero countable income, code returns $503; regulation requires $547 (= $1,997 standard − $1,450 couple FBR). $44/month error, locked in by test ia_ssa.yaml Case 3.
    • Other affected 2025 configurations: BLIND_WITH_DEPENDENT (true $525, code $503); BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT (true $525, code $503).
    • PDF citation: Iowa HHS GL 6-B-46 ("Making the Dependent Person Payment", manual lines 1714–1720): "Only the income of the eligible person or eligible couple is subtracted from the applicable assistance standard." 2025 standards listed at GL pp. 22 (image p. 28).
    • Fix: Parameterize the assistance standard directly per configuration and select individual vs. couple FBR based on whether the configuration includes an eligible spouse, then supplement = max(0, standard − max(countable, applicable_fbr)). Remove max_per_person_cap.
  2. $20 SSI general disregard incorrectly included in RCF/FLH/IHHRC client participation

    • Location: ia_ssa.py:22-26, 56-70, 71-80, 90-100; ia_ssa_living_arrangement.py:28-33, 39-66.
    • All three programs derive countable_monthly = ssi_countable_income / 12, but ssi_countable_income already applies the federal $20 general income exclusion (gov.ssa.ssi.income.exclusions.general) inside _apply_ssi_exclusions.py. The Iowa rules enumerate disregards exhaustively and omit the $20 exclusion:
      • RCF — IAC 441-52.1(3)(a) / GL 6-B-46 p. 58: "NOTE: Do not allow the SSI $20 income disregard."
      • FLH — GL 6-B-46 p. 30: "EXCEPTION: Do not allow the $20 income disregard."
      • IHHRC — IAC 441-177.4(1)(f) / GL 6-B-46 p. 36: "EXCEPTION: Do not allow the $20 disregard."
    • Code-path verifier confirmed: test ia_ssa.yaml RCF Case 6 (SS $1,000/mo) expects $311.60; correct value is $291.60. $20/month understatement of client participation = $20/month overstatement of supplement for any recipient with non-SSI unearned income ≥ $20/mo. The same error contaminates the income-eligibility gates (rcf_income_eligible, ihhrc_income_eligible, blind_income_eligible) within $20 of the cap.
    • Fix: Introduce an Iowa-specific ia_ssa_countable_income_no_disregard helper that adds back min(unearned_monthly, $20), and use it in RCF/FLH/IHHRC payment formulas and in the corresponding routing-layer gates.
  3. Iowa SSA resource-limit dispatcher under-includes ineligible dependent spouses

    • Location: policyengine_us/variables/gov/states/ia/hhs/ssa/ia_ssa_resources_eligible.py:12-24.
    • Code uses joint = ssi_claim_is_joint to flip both the resource pool (individual vs. marital sum) and the cap ($2,000 vs. $3,000). ssi_claim_is_joint returns True only when both spouses are SSI-categorically-eligible heads/spouses. IAC 441-51.5(2) extends the $3,000 cap whenever the recipient has "a dependent spouse," and 51.5(4) defines that to include an "ineligible spouse … who is financially dependent upon the recipient." Also affects the third sentence of 51.5(2): "recipient, spouse, and dependent child or parent: $3,000."
    • Concrete failure: aged SSI recipient married to a 50-year-old non-disabled spouse with no income → ssi_claim_is_joint = False → tested individually against $2,000 instead of marital-unit against $3,000.
    • Fix: Replace the dispatcher with an Iowa-specific ia_ssa_has_dependent_spouse (or extend an ia_ssa_dp_* variable that already enumerates dependents) and sum resources across all 51.5-covered dependent relatives.
  4. Wrong IAC subsection citations (5 locations) — all 4 verifier claims confirmed

    # File Wrong Correct
    1 parameters/.../ssa/smme/minimum_income_fpl_multiplier.yaml (both refs) 441—51.6(6) 441—51.7(6)
    2 parameters/.../ssa/dp/dependent_income_limit.yaml 441—51.4(1) 441—51.5(1)
    3 parameters/.../ssa/dp/max_per_person_cap.yaml 441—51.4(1) 441—51.5(1)
    4 parameters/.../ssa/rcf/days_multiplier.yaml (both refs) 441—51.3(3) 441—51.4(3)
    5 variables/.../ssa/ia_ssa_living_arrangement.py line 39 comment IAC 441—51.3(3) IAC 441—51.4(3)
    • 441-51.3 ("Supplementation") and 441-51.6 ("Residence") have no numbered subsections, so the cited references literally do not exist. The correct subsections (51.7(6) for the 120% FPL rule, 51.5(1) for dependent-relative income, 51.4(3) for RCF income eligibility) all match the parameter content verbatim.
  5. RCF and IHHRC client-participation formulas omit required regulatory deductions

    • Location: ia_ssa.py:71-100.
    • RCF (IAC 441-52.1(3)(a) / GL 6-B-46 p. 57): Required deduction order is (1) impairment-related work expenses, (2) $65 + ½ remaining earned income, (3) $126 PNA, (4) diversion to spouse at home, (5) diversion to dependent child, (6) unmet medical needs of resident, (7) unmet medical needs of spouse/dependent, (8) first-month previous-living expenses. Code applies only #3.
    • IHHRC (IAC 441-177.4(1)(f) / GL 6-B-46 p. 38): Required deductions are basic SSI standard, $65+½ earned income, dependent SSI standard plus unmet medical needs, ineligible-spouse medical needs, applicant medical needs. Code applies only the basic SSI standard. Entire 177.4(1)(g) child-deeming branch (parental income deemed to a child needing IHHRC, with 1/3 child-support disregard etc.) is unmodeled.
    • PR description acknowledges the "5-step disregard cascade not modeled," but at minimum the $65+½ earned income disregard (a federal SSI primitive already in PE) and the $483-per-dependent diversions are computable and materially affect working/dependent households.
    • Minimum recommended fix: Apply $65+½ earned-income disregard and the dependent diversions for RCF and IHHRC; document the omitted deductions explicitly in variable docstrings.

Should Address

  1. FLH state_supplement historical (pre-2025) values disagree with SSA published baselinesflh/state_supplement.yaml encodes $142 (2011), $162 (2017), $162 (2018), but the SSA 2011 Iowa baseline (PDF 4 lines 99–115) shows the Iowa FLH state supplement was $344 (aged/disabled individual) / $366 (blind individual) in January 2011. The encoded $142 appears to be the SSA-administered cap, not the historical state supplement. (Regulatory S1.)

  2. SMME income test uses SPM-unit FPG instead of individual/couple FPGsmme/ia_ssa_smme_eligible.py:27-29: fpg_monthly = person.spm_unit("spm_unit_fpg", period.this_year) / MONTHS_IN_YEAR. IAC 441-51.7(6) tests the recipient's income against 120% FPL for one (or two if joint claim). A single SSI-eligible aged person living with two adult children (SPM unit of 3) faces a 120% threshold of ~$2,665/mo instead of the correct ~$1,565/mo and would fail the test even though they should pass. Use personal_fpg for individual claims and 2-person FPG for joint claims. (Regulatory S2.)

  3. DP max_per_person_cap parameter is duplicative and undocumented — Identical values to dependent_income_limit across all years. Conflates two regulatory concepts. Remove and replace with per-configuration state supplement encoding (related to Critical #1). (Regulatory S3.)

  4. DP/Blind/FLH input variables lack formula derivations and microsim defaultsia_ssa_dp_has_eligible_dependent, ia_ssa_dp_dependent_countable_income, ia_ssa_dp_configuration, ia_ssa_resides_in_family_life_home, ia_ssa_resides_in_residential_care_facility, ia_ssa_needs_in_home_health_related_care, ia_ssa_ihhrc_cost_of_care, ia_ssa_rcf_cost_per_diem are pure user-input variables. In a microsim run on enhanced CPS none will be populated, so DP/FLH/RCF/IHHRC will never fire. Acceptable as a manual-input pathway, but add at least minimal default formulas (e.g., default ia_ssa_has_medicare_part_b to is_medicare_eligible) where a federal PE variable already encodes the concept. (Regulatory S5/S6, Suggestion G1.)

  5. 5 input variables omit default_valueia_ssa_dp_dependent_countable_income, ia_ssa_dp_has_eligible_dependent, ia_ssa_resides_in_family_life_home, ia_ssa_ihhrc_cost_of_care, ia_ssa_needs_in_home_health_related_care, ia_ssa_rcf_cost_per_diem, ia_ssa_resides_in_residential_care_facility. The PR sets default_value = False on ia_ssa_has_full_medicaid and ia_ssa_has_medicare_part_b but is inconsistent for the rest. (Code S2.)

  6. FBR acronym in parameter descriptionsdp/state_supplement.yaml and flh/state_supplement.yaml use "(FBR)" in the description field, violating the parameter-patterns "no acronyms" rule. (Code S4.)

  7. Period-bridging convention undocumentedia_ssa.py:29, ia_ssa_living_arrangement.py:37, ia_ssa_smme_eligible.py:16 access YEAR-period inputs (ssi_claim_is_joint, is_ssi_aged_blind_disabled) with period.this_year from MONTH formulas. Technically correct but consider a single explanatory comment near the top of ia_ssa.py. (Code S1.)

  8. #page= anchor mismatch in IHHRC max_cost_single.yaml — Reference for 441-177.10(3) uses #page=4 but the rule is on file page 5. (Reference S1.)

  9. Iowa Code 249.9A reference missing #page= anchorrcf/personal_needs_allowance.yaml. (Reference S2.)

  10. Iowa HHS GL 6-B-46 download URL has no page anchor — Multiple files cite hhs.iowa.gov/media/15607/download bare. Add #page=1 for explicitness or cite the manual chapter URL. (Reference S3.)

  11. Bare HHS landing page reference for 2026 values is insufficienthhs.iowa.gov/assistance-programs/state-supplementary-assistance is dynamic. Add a Wayback snapshot URL or a (retrieved YYYY-MM-DD) note. (Reference S4.)

  12. Income-eligibility gates inherit the $20-disregard erroria_ssa_living_arrangement.py:39-66: RCF income gate (< $1,165.60), IHHRC gates (<= $480.55 / <= $961.10), and Blind income gate (< $989) all use the contaminated countable_monthly, so cases at or within $20 of the boundary may be mis-classified. (Regulatory S7 — addressed by Critical #2 fix.)

  13. No 2011 historical-tier test anywhere — Parameters define 2011-01-01 values (blind, RCF PNA $93, max_per_diem $28.14, dp.state_supplement, flh.max_supplement, etc.) but no test uses period: 2011-01. The 2011→2017 transitions are unverified. (Test C1.)

  14. Missing payment test for BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT — Only 4 of 5 non-NONE DP configurations are exercised; this config is the one with the disputed 2026 value, so a payment test pinning 2025 and 2026 is essential. (Test C2.)

  15. V-shape boundary at countable == FBR not directly tested — None of the BLIND/DP/FLH cases use a social_security_retirement value engineered to put ssi_countable_income exactly at individual_fbr. (Test C3.)

  16. RCF post-PNA client-participation boundary not tested — Existing cases sit far above or far below the $1,165.60 threshold; no case engineered to land just below, exactly at, or one cent above. (Test C4.)

  17. IHHRC combined countable equal to caps not testedihhrc_countable_after_disregard <= ihhrc_cap uses <=. No case sits exactly at $480.55 single or $961.10 couple. (Test C5.)

  18. Missing pair-wise priority routing tests — RCF > IHHRC, RCF > FLH, RCF > DP, RCF > SMME, FLH > DP, FLH > SMME are not directly tested. Cheap to add and protect against select(...) reordering bugs. (Test S9.)

  19. SMME 120% FPL boundary partially covered, full-Medicaid vs. medically-needy distinction not covered, FLH blind add-on at 2026 not tested, FLH Department top-up countable_monthly == 0 boundary not tested, ineligible-person variants missing, DP has_eligible_dependent: false with non-NONE configuration not tested. (Test S6, S8, S10, S11, S12, S13.)


Suggestions

  1. 2026 BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT $1,037 is an editorial guess — Iowa HHS publishes $3,031 for 2026; PR encodes $1,037 (state portion) on the theory that $3,031 is a typo. Already disclosed in YAML comment and PR description as intentional. Either confirm with Iowa HHS in writing and add response as comment, or fall back to the published $3,031 with a TODO. Documented as intentional — not blocking. (Regulatory S4 / Code G3 / PDF audit b.1.)

  2. Default ia_ssa_has_medicare_part_b to is_medicare_eligible — Would let SMME fire automatically in microsim. (Code G1.)

  3. Extract DRY intermediate variablescountable_monthly, ssi_monthly, basic_ssi_disregard, combined_countable are re-derived in both ia_ssa.py and ia_ssa_living_arrangement.py. Consider shared ia_ssa_countable_income_monthly etc. per the variable-patterns "intermediate variables for code reuse" rule. (Code G1.)

  4. Add YAML comments in dependent_income_limit.yaml and max_per_person_cap.yaml clarifying they are intentionally not breakdowns — Prevents a future contributor from "fixing" them. (Code S3.)

  5. RCF cost_per_diem default to p.rcf.max_per_diem when resident is flagged as in RCF — Behavioral improvement so the default supplement is non-zero. (Code G2.)

  6. ia_ssa_resources_eligible description should note monthly recomputation of an annual SSI resource test. (Code G4.)

  7. Consolidate 2017/2018 IAC supplement citations with effective-date parentheticals. (Reference G1.)

  8. Tighten SSA 2011 footnote-a documentation in dp/state_supplement.yaml. (Reference G2.)

  9. Add YAML comment in rcf/days_multiplier.yaml explaining the "31 = largest possible days-in-a-month" derivation. (Reference G3.)

  10. HHS rates page lists "Flat per Diem Rate $17.86" — likely informational only post-2017 transition to cost-related per diem. Confirm with author whether to encode. (PDF payment-standards audit c.1.)

  11. Standardize absolute_error_margin: 0.01 across YAML test cases. (Test S19.)

  12. Test variants: negative income, explicit ssi_claim_is_joint toggling on couples, RCF per-diem exactly at cap, days-multiplier sensitivity, entity-scaffolding cleanup for ia_ssa_dp_configuration.yaml. (Test S14, S15, S16, S17, S20.)


Investigated and Cleared (False Positives)

  • SMME categorical contradiction (PDF eligibility audit Mismatch #1) — Rejected. Federal is_ssi_eligible checks ABD + resources + immigration only; it does NOT encode an income test. The SMME-target population (income > 120% FPL with full Medicaid + Part B + ABD + SSI resource/immigration eligibility) passes is_ssi_eligible and the SMME branch fires correctly. Verified end-to-end with a worked example (aged 70, $1,600/mo income, $1,500 resources → SMME = $1).
  • IHHRC $961.10 income cap "missing" (PDF IHHRC audit framing concern) — Rejected. The cap IS enforced — at ia_ssa_living_arrangement.py:64 (routing layer), where eligibility cutoffs belong in this codebase's pattern. The reviewer searched only ia_ssa.py (payment layer) and stopped one file short. Same routing/payment split is used for RCF and Blind in the same file.

PDF Audit Summary

Category Count
Confirmed correct (parameters reconciled to PDFs) 27 (8 Ch.52 payment standards, 5 IHHRC 2025 + 2011 baseline values, 7 eligibility/routing rules per Ch.51, 5 DP 2025 standards from GL 6-B-46, 2 SMME)
Mismatches confirmed (deliberate) 1 (2026 DP BLIND_WITH_AGED_OR_DISABLED_SPOUSE_AND_DEPENDENT: repo $1,037 vs HHS $3,031, documented as intentional editorial override)
Mismatches rejected 2 (SMME categorical gate, IHHRC $961.10 income cap routing)
Unmodeled items acknowledged in PR 5+ (5-step IHHRC disregard cascade; RCF disregards #1/2/4-8; child IHHRC deeming branch 177.4(1)(g); first-month proration 177.10(2)(b); 15-day temporary absence rules)
New unmodeled items flagged 8 (FIP application requirement 51.2; supplementation income reduction 51.3; physician-cert / facility-licensing inputs 51.4(1)/(2); RCF couple-room initial-month special rule 51.4(3); dependent earnings $65 work expense 51.5(1); full-month absence rule 51.5(3); SMME living-arrangement enumeration 51.7(5); SSN furnishing 51.9; income from room-and-board 51.8)

Validation Summary

Check Result
Regulatory Accuracy 3 critical (DP couple FBR, $20 disregard, RCF/IHHRC missing deductions), 7 should
Reference Quality 4 critical citation errors (3 YAML + 1 covered under critical #4 group), 4 should
Code Patterns 0 critical, 5 should, 4 suggestions
Test Coverage 5 critical gaps, 8 should
PDF Value Audit 0 unintentional mismatches; 1 deliberate (2026 DP override, documented)
CI Status All 24 checks passing

Review Severity: REQUEST_CHANGES

Justification: four confirmed code/regulatory bugs materially affect output dollars in real cases — (1) DP couple-FBR formula bug is a $44/month error encoded into a passing test; (2) $20 SSI disregard misapplication understates RCF/FLH/IHHRC client participation by $20/month for any recipient with non-trivial unearned income; (3) resource-limit dispatcher under-includes ineligible dependent spouses, denying eligibility to households entitled to the $3,000 cap; (4) five regulatory citations point to non-existent or unrelated subsections, undermining auditability. The deliberate 2026 DP override is acceptable as documented, but the structural bugs warrant fixes before merge.


Top Priorities for Author

  1. Fix DP couple-FBR / per-person-cap issue — Parameterize assistance standard per configuration; pick individual vs couple FBR based on whether configuration has an eligible spouse; remove max_per_person_cap.
  2. Strip $20 disregard for RCF/FLH/IHHRC — Add an ia_ssa_countable_income_no_disregard helper that adds back min(unearned_monthly, $20); use in RCF/FLH/IHHRC payment formulas and routing-layer income gates.
  3. Fix resource-limit dispatcher — Replace ssi_claim_is_joint with an Iowa-specific ia_ssa_has_dependent_spouse that covers ineligible-but-financially-dependent spouses per IAC 441-51.5(4).
  4. Correct IAC subsection citations (5 locations)smme/minimum_income_fpl_multiplier.yaml (51.6(6)→51.7(6)); dp/dependent_income_limit.yaml and dp/max_per_person_cap.yaml (51.4(1)→51.5(1)); rcf/days_multiplier.yaml (51.3(3)→51.4(3)); ia_ssa_living_arrangement.py:39 comment (51.3(3)→51.4(3)).
  5. Add minimum-recommended deductions — $65+½ earned-income disregard and dependent diversions for RCF and IHHRC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Iowa State Supplemental Payment (SSP)

2 participants