diff --git a/changelog.d/medicaid-medically-needy-blind-unit.fixed.md b/changelog.d/medicaid-medically-needy-blind-unit.fixed.md new file mode 100644 index 00000000000..9be6e5a9889 --- /dev/null +++ b/changelog.d/medicaid-medically-needy-blind-unit.fixed.md @@ -0,0 +1 @@ +Count blind people in the Medicaid medically needy disabled group, and test medically needy income and resources over the individual or married couple instead of the tax unit, counting a parent's excess resources and medical expenses for a child. diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.yaml index 001b939bc35..b0321c9414c 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.yaml @@ -13,3 +13,21 @@ state_code: MA output: is_in_medicaid_medically_needy_category: false + +- name: Case 1, blind adult under 65 who is not SSI-disabled is in the medically needy disabled group. + period: 2026 + input: + age: 40 + is_blind: true + state_code: MA + output: + is_in_medicaid_medically_needy_category: true + +- name: Case 2, blind adult is not in a medically needy category in a state without the disabled group. + period: 2026 + input: + age: 40 + is_blind: true + state_code: TX + output: + is_in_medicaid_medically_needy_category: false diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml index 4c889ee6e99..5cf50414394 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.yaml @@ -50,3 +50,285 @@ state_code: MA output: is_medically_needy_for_medicaid: false + +- name: Case 3, aged parent claimed as a tax dependent does not add income or resources to the filer's test. + period: 2026 + input: + people: + person1: + age: 70 + # $18,000 Social Security - $240 general exclusion. + ssi_countable_income: 17_760 + medicaid_medically_needy_medical_expenses: 13_000 + ssi_countable_resources: 500 + is_optional_senior_or_disabled_for_medicaid: false + person2: + age: 92 + is_tax_unit_dependent: true + # $4,000 pension - $240 general exclusion. + ssi_countable_income: 3_760 + ssi_countable_resources: 1_800 + tax_units: + tax_unit: + members: [person1, person2] + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: MA + output: + # person1: 17,760 - 13,000 = 4,760 <= 522 x 12 = 6,264; resources 500 <= 2,000. + # Summing over the tax unit would give 8,520 and 2,300, both over the limits. + # person2 receives SSI (3,760 < 994 x 12), so is covered through SSI instead. + is_medically_needy_for_medicaid: [true, false] + +- name: Case 4, married couple filing separately is tested on combined income against the couple limit. + period: 2026 + input: + people: + person1: + age: 68 + # Couple's $26,400 Social Security - $240 general exclusion, split + # equally between the two aged spouses. + ssi_countable_income: 13_080 + medicaid_medically_needy_medical_expenses: 8_000 + ssi_countable_resources: 1_000 + is_optional_senior_or_disabled_for_medicaid: false + person2: + age: 66 + ssi_countable_income: 13_080 + medicaid_medically_needy_medical_expenses: 8_000 + ssi_countable_resources: 1_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MA + output: + # 2 x (13,080 - 8,000) = 10,160 > 650 x 12 = 7,800. + # Each spouse alone would pass the individual limit: 5,080 <= 6,264. + is_medically_needy_for_medicaid: [false, false] + +- name: Case 5, disabled child's resource test counts the parents' savings above the SSI couple allowance. + period: 2026 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 10_000 + person2: + age: 38 + is_tax_unit_spouse: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 10_000 + person3: + age: 10 + is_tax_unit_dependent: true + is_ssi_disabled: true + # Parents' $6,666.67 monthly wages deemed to the child (20 CFR 416.1165): + # (6,666.67 - 20 - 65) / 2 - 1,491 couple allowance = 1,799.83, less + # the child's $20 general exclusion = 1,779.83 a month. + ssi_countable_income: 21_358 + medicaid_medically_needy_medical_expenses: 16_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit: + members: [person1, person2, person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + households: + household: + members: [person1, person2, person3] + state_code: MA + output: + # person3: income 21,358 - 16,000 = 5,358 <= 522 x 12 = 6,264, but resources + # 0 + (20,000 - 3,000 two-parent allowance) = 17,000 > 2,000 (20 CFR 416.1202(b)). + is_medically_needy_for_medicaid: [false, false, false] + +- name: Case 6, disabled child qualifies when the parents' savings are within the SSI couple allowance. + period: 2026 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + person2: + age: 38 + is_tax_unit_spouse: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + person3: + age: 10 + is_tax_unit_dependent: true + is_ssi_disabled: true + # Deemed parental income as in Case 5. + ssi_countable_income: 21_358 + medicaid_medically_needy_medical_expenses: 16_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit: + members: [person1, person2, person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + households: + household: + members: [person1, person2, person3] + state_code: MA + output: + # person3: income 5,358 <= 6,264; resources 0 + max(2,400 - 3,000, 0) = 0 <= 2,000. + # Counting the parents' full 2,400 would exceed the child's 2,000 limit. + is_medically_needy_for_medicaid: [false, false, true] + +- name: Case 7, married couple filing separately qualifies on the couple limit when combined net income is between the two limits. + period: 2026 + input: + people: + person1: + age: 68 + ssi_countable_income: 10_000 + medicaid_medically_needy_medical_expenses: 6_500 + ssi_countable_resources: 1_000 + is_optional_senior_or_disabled_for_medicaid: false + person2: + age: 66 + ssi_countable_income: 10_000 + medicaid_medically_needy_medical_expenses: 6_500 + ssi_countable_resources: 1_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + marital_units: + marital_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: MA + output: + # 2 x (10,000 - 6,500) = 7,000: above 6,264, at or below 7,800. + is_medically_needy_for_medicaid: [true, true] + +- name: Case 8, disabled child in a joint tax unit is tested against the individual limit. + period: 2026 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + person2: + age: 38 + is_tax_unit_spouse: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + person3: + age: 10 + is_tax_unit_dependent: true + is_ssi_disabled: true + ssi_countable_income: 21_358 + medicaid_medically_needy_medical_expenses: 15_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit: + members: [person1, person2, person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + households: + household: + members: [person1, person2, person3] + state_code: MA + output: + # 21,358 - 15,000 = 6,358 > 6,264 (the couple limit 7,800 would pass). + is_medically_needy_for_medicaid: [false, false, false] + +- name: Case 9, a parent's medical expenses reduce a disabled child's countable income. + period: 2026 + input: + people: + person1: + age: 40 + is_tax_unit_head: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + medicaid_medically_needy_medical_expenses: 8_000 + person2: + age: 38 + is_tax_unit_spouse: true + is_parent: true + employment_income_before_lsr: 40_000 + ssi_countable_resources: 1_200 + person3: + age: 10 + is_tax_unit_dependent: true + is_ssi_disabled: true + ssi_countable_income: 21_358 + medicaid_medically_needy_medical_expenses: 10_000 + is_optional_senior_or_disabled_for_medicaid: false + tax_units: + tax_unit: + members: [person1, person2, person3] + marital_units: + marital_unit1: + members: [person1, person2] + marital_unit2: + members: [person3] + households: + household: + members: [person1, person2, person3] + state_code: MA + output: + # 42 CFR 435.831(d): 21,358 - (10,000 own + 8,000 parent's) = 3,358 + # <= 522 x 12 = 6,264. Resources: nothing deemed (2,400 < 3,000). + is_medically_needy_for_medicaid: [false, false, true] + +- name: Case 10, blind adult under 65 who is not SSI-disabled qualifies after spenddown. + period: 2026 + input: + age: 40 + is_blind: true + is_adult_for_medicaid: false + is_optional_senior_or_disabled_for_medicaid: false + ssi_countable_income: 12_000 + medicaid_medically_needy_medical_expenses: 6_000 + ssi_countable_resources: 1_000 + state_code: MA + output: + # 12,000 - 6,000 = 6,000 <= 6,264; resources 1,000 <= 2,000. + is_in_medicaid_medically_needy_category: true + is_medically_needy_for_medicaid: true diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.py index 7c0ef4771d2..6f4056d8241 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_in_medicaid_medically_needy_category.py @@ -7,6 +7,12 @@ class is_in_medicaid_medically_needy_category(Variable): label = "In Medicaid medically needy category" documentation = "Whether this person is in a Medicaid category for which there is a medically needy pathway." definition_period = YEAR + reference = ( + "https://www.ecfr.gov/current/title-42/section-435.301#p-435.301(b)(2)", + "https://www.ecfr.gov/current/title-42/section-435.322", + "https://www.ecfr.gov/current/title-42/section-435.324", + "https://www.kff.org/report-section/medicaid-financial-eligibility-for-seniors-and-people-with-disabilities-findings-from-a-50-state-survey-appendix-tables/", + ) def formula(person, period, parameters): mn_categories = parameters( @@ -14,7 +20,10 @@ def formula(person, period, parameters): ).gov.hhs.medicaid.eligibility.categories.medically_needy.categories aged_threshold = parameters(period).gov.ssa.ssi.eligibility.aged_threshold is_child = any_(person, period, mn_categories.child.child_categories) - is_disabled = person("is_ssi_disabled", period) + # The disabled flag follows KFF's "people with disabilities", which + # includes blind people; federal rules list blind (42 CFR 435.322) + # and disabled (42 CFR 435.324) as parallel medically needy groups. + is_blind_or_disabled = any_(person, period, ["is_blind", "is_ssi_disabled"]) is_senior = person("age", period) >= aged_threshold is_pregnant = person("is_pregnant_for_medicaid_nfc", period) is_parent = person("is_parent_for_medicaid_nfc", period) @@ -30,7 +39,7 @@ def formula(person, period, parameters): category_covered = [parameter[state] > 0 for parameter in categories] in_category = [ is_child, - is_disabled, + is_blind_or_disabled, is_parent, is_pregnant, is_senior, diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.py index cbf50d31400..01e6b76825e 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/categories/medically_needy/is_medically_needy_for_medicaid.py @@ -15,20 +15,52 @@ class is_medically_needy_for_medicaid(Variable): "administration beyond the annual expense proxy." ) definition_period = YEAR - reference = "https://www.law.cornell.edu/cfr/text/42/part-435/subpart-D" + reference = ( + "https://www.law.cornell.edu/cfr/text/42/part-435/subpart-D", + "https://www.ecfr.gov/current/title-42/section-435.602#p-435.602(a)(2)(i)", + "https://www.ecfr.gov/current/title-42/section-435.831#p-435.831(d)", + "https://www.ecfr.gov/current/title-42/section-435.845#p-435.845(a)", + "https://www.ecfr.gov/current/title-20/section-416.1202#p-416.1202(b)", + ) def formula(person, period, parameters): in_category = person("is_in_medicaid_medically_needy_category", period) is_aged_blind_or_disabled = person("is_ssi_aged_blind_disabled", period) personal_income = person("ssi_countable_income", period) medical_expenses = person("medicaid_medically_needy_medical_expenses", period) - personal_assets = person("ssi_countable_resources", period) + # A child's resources include the excess of ineligible parents' + # resources (20 CFR 416.1202(b)), as ssi_countable_income already + # includes their deemed income. SSI's allocation gates apply: a child + # whose own resources exceed the SSI individual limit, or who fails + # SSI's immigration test, is deemed nothing. + personal_assets = person("ssi_countable_resources", period) + person( + "ssi_resources_deemed_from_ineligible_parent", period.first_month + ) + # SSI financial responsibility rules (42 CFR 435.602): the unit is + # the individual or the married couple, plus parents for a child, + # not the tax filing unit. + marital_unit = person.marital_unit + # 42 CFR 435.831(d) deducts expenses of financially responsible + # relatives. For a child these are the ineligible parents whose + # income SSI deems (20 CFR 416.1165); split their expenses among the + # eligible children as the deemed income is split, so that an + # expense is deducted once. tax_unit = person.tax_unit - income = tax_unit.sum(personal_income - medical_expenses) - assets = tax_unit.sum(personal_assets) + eligible_child = is_aged_blind_or_disabled & person("is_child", period) + parental_expenses = tax_unit.sum( + medical_expenses * person("is_ssi_ineligible_parent", period) + ) + eligible_children = tax_unit.sum(eligible_child) + parental_expense_share = where( + eligible_child, parental_expenses / max_(eligible_children, 1), 0 + ) + income = marital_unit.sum( + personal_income - medical_expenses - parental_expense_share + ) + assets = marital_unit.sum(personal_assets) ma = parameters(period).gov.hhs.medicaid mn = ma.eligibility.categories.medically_needy - is_joint = person.tax_unit("tax_unit_is_joint", period) + is_joint = marital_unit.nb_persons() == 2 state = person.household("state_code_str", period) income_limit = MONTHS_IN_YEAR * where( is_joint,