From bb32e0c18220daa1b40bf5499241ae9a1762537e Mon Sep 17 00:00:00 2001 From: Ziming Date: Mon, 12 Oct 2026 14:35:28 -0400 Subject: [PATCH 1/4] Add Vermont state supplementation for 2026 --- changelog.d/vt-ssp-2026.added.md | 1 + .../household/household_state_benefits.yaml | 4 + .../hud/annual_income/sources/unearned.yaml | 3 +- .../ssi/state_supplement/minimum_payment.yaml | 12 + .../gov/states/vt/dcf/aabd/amount/couple.yaml | 24 ++ .../states/vt/dcf/aabd/amount/individual.yaml | 24 ++ .../aabd/ep/another_household_maximum.yaml | 11 + .../states/vt/dcf/aabd/ep/couple_maximum.yaml | 10 + .../vt/dcf/aabd/ep/employment_expense.yaml | 10 + .../vt/dcf/aabd/ep/individual_maximum.yaml | 10 + .../gov/states/vt/dcf/aabd/ep/rate.yaml | 17 + .../usda/snap/income/sources/unearned.yaml | 7 +- policyengine_us/programs.yaml | 11 + .../gov/states/vt/dcf/aabd/integration.yaml | 293 ++++++++++++++++++ .../gov/states/vt/dcf/aabd/vt_aabd.yaml | 129 ++++++++ .../gov/states/vt/dcf/aabd/vt_aabd_ep.yaml | 202 ++++++++++++ .../gov/ssa/ssi/_ssi_state_supplement.py | 53 ++++ .../gov/states/vt/dcf/aabd/vt_aabd.py | 15 + .../vt/dcf/aabd/vt_aabd_countable_for_hud.py | 22 ++ .../gov/states/vt/dcf/aabd/vt_aabd_ep.py | 63 ++++ .../vt_aabd_ep_additional_countable_income.py | 11 + .../dcf/aabd/vt_aabd_ep_countable_income.py | 40 +++ .../vt/dcf/aabd/vt_aabd_ep_is_spouse.py | 9 + .../states/vt/dcf/aabd/vt_aabd_ep_level.py | 27 ++ .../vt/dcf/aabd/vt_aabd_ep_proration.py | 11 + .../dcf/aabd/vt_aabd_ep_resources_eligible.py | 14 + .../gov/states/vt/dcf/aabd/vt_aabd_federal.py | 21 ++ .../vt/dcf/aabd/vt_aabd_living_arrangement.py | 50 +++ .../income/spm_unit/spm_unit_benefits.py | 1 + 29 files changed, 1100 insertions(+), 5 deletions(-) create mode 100644 changelog.d/vt-ssp-2026.added.md create mode 100644 policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml create mode 100644 policyengine_us/variables/gov/ssa/ssi/_ssi_state_supplement.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py diff --git a/changelog.d/vt-ssp-2026.added.md b/changelog.d/vt-ssp-2026.added.md new file mode 100644 index 00000000000..20d0d98ce03 --- /dev/null +++ b/changelog.d/vt-ssp-2026.added.md @@ -0,0 +1 @@ +Add Vermont federally administered optional AABD supplement rates and calculations for 2026. Add Vermont 2026 Essential Person grants alongside federally administered AABD. diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index d2cbd6ba2d4..a8195ed9cce 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -78,6 +78,7 @@ values: # DC benefits - dc_ossp # Kansas benefits + - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -176,6 +177,7 @@ values: # DC benefits - dc_ossp # Kansas benefits + - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -279,6 +281,7 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits + - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -382,6 +385,7 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits + - vt_aabd - ks_sspp # Hawaii benefits - hi_oss diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index d2b2bbd8675..b4b0e377b0d 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -19,6 +19,7 @@ values: - strike_benefits - social_security - ssi + - vt_aabd_countable_for_hud - general_assistance - unemployment_compensation - child_support_received @@ -34,5 +35,5 @@ metadata: period: year label: HUD unearned income sources reference: - - title: 24 CFR § 5.609(a)(1), (a)(2) + - title: 24 CFR § 5.609(a)(1), (a)(2), (b)(6), (b)(19) href: https://www.law.cornell.edu/cfr/text/24/5.609 diff --git a/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml b/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml new file mode 100644 index 00000000000..96464c8c040 --- /dev/null +++ b/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml @@ -0,0 +1,12 @@ +description: The Social Security Administration pays at least this monthly amount to each recipient of a positive federally administered optional state supplement. +values: + 2026-01-01: 1 +metadata: + unit: currency-USD + period: month + label: SSI optional state supplement minimum payment + reference: + - title: 20 CFR 416.2020(c) - Minimum federally administered supplementary payment + href: https://www.ssa.gov/OP_Home/cfr20/416/416-2020.htm + - title: POMS SI 02001.005 A.2 and B.2 - Minimum benefit for individuals and members of couples + href: https://secure.ssa.gov/poms.nsf/lnx/0502001005 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml new file mode 100644 index 00000000000..d7fa3f40e01 --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml @@ -0,0 +1,24 @@ +description: Vermont provides these monthly optional AABD state supplement rates for an eligible couple. +metadata: + unit: currency-USD + period: month + label: Vermont AABD couple payment rate + breakdown: + - vt_aabd_living_arrangement + reference: + - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m +INDEPENDENT: + 2026-01-01: 105.8 +HOUSEHOLD_OF_ANOTHER: + 2026-01-01: 51.69 +RESIDENTIAL_CARE_LEVEL_III: + 2026-01-01: 103.54 +RESIDENTIAL_CARE_LEVEL_IV: + 2026-01-01: 601.4 +CUSTODIAL_CARE: + 2026-01-01: 356.12 +MEDICAID_INSTITUTION: + 2026-01-01: 99.85 +NONE: + 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml new file mode 100644 index 00000000000..9b3afa6fecd --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml @@ -0,0 +1,24 @@ +description: Vermont provides these monthly optional AABD state supplement rates for an eligible individual. +metadata: + unit: currency-USD + period: month + label: Vermont AABD individual payment rate + breakdown: + - vt_aabd_living_arrangement + reference: + - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m +INDEPENDENT: + 2026-01-01: 55.68 +HOUSEHOLD_OF_ANOTHER: + 2026-01-01: 42.05 +RESIDENTIAL_CARE_LEVEL_III: + 2026-01-01: 51.77 +RESIDENTIAL_CARE_LEVEL_IV: + 2026-01-01: 239.62 +CUSTODIAL_CARE: + 2026-01-01: 105.6 +MEDICAID_INSTITUTION: + 2026-01-01: 49.93 +NONE: + 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml new file mode 100644 index 00000000000..0b5859d0d03 --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml @@ -0,0 +1,11 @@ +description: Vermont uses this amount as its Essential Person payment maximum with an ineligible spouse + in another household. +values: + '2026-01-01': 1049.68 +metadata: + unit: currency-USD + label: Vermont Essential Person payment maximum with an ineligible spouse in another household + reference: + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf + period: month diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml new file mode 100644 index 00000000000..a67a9327010 --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml @@ -0,0 +1,10 @@ +description: Vermont uses this amount as its Essential Person independent eligible-couple payment maximum. +values: + '2026-01-01': 1780.64 +metadata: + unit: currency-USD + label: Vermont Essential Person independent eligible-couple payment maximum + reference: + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf + period: month diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml new file mode 100644 index 00000000000..d27ee74fc47 --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml @@ -0,0 +1,10 @@ +description: Vermont uses this amount as its Essential Person employment expense deduction per worker. +values: + '2026-01-01': 90 +metadata: + unit: currency-USD + label: Vermont Essential Person employment expense deduction per worker + reference: + - title: AABD rules 2786 interpretive memo + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf + period: month diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml new file mode 100644 index 00000000000..9551669110a --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml @@ -0,0 +1,10 @@ +description: Vermont uses this amount as its Essential Person independent individual payment maximum. +values: + '2026-01-01': 1596.8 +metadata: + unit: currency-USD + label: Vermont Essential Person independent individual payment maximum + reference: + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf + period: month diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml new file mode 100644 index 00000000000..9e6cda2fbee --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml @@ -0,0 +1,17 @@ +description: Vermont sets the Essential Person increment at this fraction for the certified care level. +NONE: + '2026-01-01': 0 +FULL: + '2026-01-01': 1 +PARTIAL_67: + '2026-01-01': 0.67 +PARTIAL_34: + '2026-01-01': 0.34 +metadata: + unit: /1 + label: Vermont Essential Person care fraction + breakdown: + - vt_aabd_ep_level + reference: + - title: AABD rules 2784(A) + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index 6f94d3d09b2..ce5a55d689c 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -36,6 +36,7 @@ values: - hi_oss - id_aabd - in_ssp + - vt_aabd - ks_sspp - ky_ssp - la_oss @@ -95,9 +96,7 @@ values: metadata: reference: - - title: 7 CFR 273.9(b)(2) - href: https://www.law.cornell.edu/cfr/text/7/273.9#b_2 - - title: 7 CFR 273.9(c)(1) - href: https://www.law.cornell.edu/cfr/text/7/273.9#c_1 + - title: 7 CFR 273.9(b)(2) and (c)(1), (5) + href: https://www.law.cornell.edu/cfr/text/7/273.9 - title: POMS SI 01401.001 General Information about State Supplementation href: https://secure.ssa.gov/poms.nsf/lnx/0501401001 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 05cb1d13747..1c672ca6ac7 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1090,6 +1090,17 @@ programs: tracks. Unmodeled paths: grandfathered medically-needy-in-medical- institution recipients per WAC 388-478-0055(2)(b); DDA-determined / PVL track per (2)(f); and foster child in BRS per (2)(g). + - state: VT + status: partial + name: Vermont optional AABD + full_name: Vermont Aid to the Aged, Blind or Disabled optional supplement + variable: vt_aabd + parameter_prefix: gov.states.vt.dcf.aabd + verified_years: "2026" + notes: >- + Models federally administered supplements and Essential Person grants. + Essential Person care, nonspouse budgets and state-only resource eligibility + require certified inputs. Mandatory grandfathered payments are excluded. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml new file mode 100644 index 00000000000..8fcc5dd038a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml @@ -0,0 +1,293 @@ +- name: Case 1, independent couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: INDEPENDENT + second: + age: 65 + vt_aabd_living_arrangement: INDEPENDENT + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 52.9 + - 52.9 +- name: Case 2, residential_care_level_iii couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + second: + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 51.77 + - 51.77 +- name: Case 3, residential_care_level_iv couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + second: + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 300.7 + - 300.7 +- name: Case 4, custodial_care couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: CUSTODIAL_CARE + second: + age: 65 + vt_aabd_living_arrangement: CUSTODIAL_CARE + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 178.06 + - 178.06 +- name: Case 5, household_of_another couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + second: + age: 65 + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 25.85 + - 25.85 +- name: Case 6, medicaid_institution couple. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + first: + age: 65 + vt_aabd_living_arrangement: MEDICAID_INSTITUTION + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + second: + age: 65 + vt_aabd_living_arrangement: MEDICAID_INSTITUTION + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + marital_units: + couple: + members: + - first + - second + tax_units: + unit: + members: + - first + - second + households: + household: + members: + - first + - second + state_code: VT + output: + vt_aabd: + - 49.93 + - 49.93 +- name: Case 7, annual benefits and SNAP income. + period: 2026 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + output: + vt_aabd: 668.16 + household_state_benefits: 668.16 + snap_unearned_income: 12596.16 +- name: Essential-person grant enters the annual Vermont benefit total + period: '2026' + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + vt_aabd_ep_level: + '2026': FULL + output: + ssi: 11928 + vt_aabd_federal: 668.16 + vt_aabd_ep: 6564 + vt_aabd: 7232.16 + snap_unearned_income: 19160.16 +- name: Two eligible spouses share one essential-person grant + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + a: + age: 70 + vt_aabd_ep_level: FULL + b: + age: 70 + vt_aabd_ep_level: FULL + marital_units: + couple: + members: + - a + - b + households: + home: + members: + - a + - b + state_code: VT + output: + vt_aabd_ep: + - 91.5 + - 91.5 + vt_aabd: + - 144.4 + - 144.4 +- name: Ineligible spouse earnings do not get the ABD half-earnings deduction + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + a: + age: 70 + vt_aabd_ep_level: FULL + vt_aabd_ep_is_spouse: true + vt_aabd_ep_resources_eligible: true + b: + age: 40 + employment_income: 6000 + marital_units: + couple: + members: + - a + - b + households: + home: + members: + - a + - b + state_code: VT + output: + vt_aabd_ep_countable_income: + - 1439.68 + - 1439.68 + vt_aabd_ep: + - 157 + - 0 +- name: Vermont essential care for a disabled member is excluded for HUD + period: '2026' + absolute_error_margin: 0.01 + input: + state_code: VT + age: 40 + meets_ssi_disability_criteria: true + is_disabled: true + vt_aabd_ep_level: FULL + output: + vt_aabd: 7232.16 + snap_unearned_income: 19160.16 + hud_unearned_income: 12596.16 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml new file mode 100644 index 00000000000..5e7660900c9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml @@ -0,0 +1,129 @@ +# POMS SI 01415.058 M, Vermont January 2026 optional supplement schedule. +- name: Case 1, independent individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: INDEPENDENT + output: + vt_aabd: 55.68 +- name: Case 2, residential care level iii individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + output: + vt_aabd: 51.77 +- name: Case 3, residential care level iv individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + output: + vt_aabd: 239.62 +- name: Case 4, custodial care individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: CUSTODIAL_CARE + output: + vt_aabd: 105.6 +- name: Case 5, household of another individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + output: + vt_aabd: 42.05 +- name: Case 6, medicaid institution individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: MEDICAID_INSTITUTION + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + output: + vt_aabd: 49.93 +- name: Case 7, none individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + vt_aabd_living_arrangement: NONE + output: + vt_aabd: 0 +- name: Case 8, automatic independent classification. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + output: + vt_aabd: 55.68 +- name: Case 9, income above federal SSI standard. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + social_security_retirement: 12360 + output: + vt_aabd: 39.68 +- name: Case 10, income at combined cutoff. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + social_security_retirement: 12836.16 + output: + vt_aabd: 0 +- name: Case 11, minimum positive payment. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + social_security_retirement: 12836.04 + output: + vt_aabd: 1 +- name: Case 12, excess resources. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + ssi_countable_resources: 2001 + output: + vt_aabd: 0 +- name: Case 13, not aged blind or disabled. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 30 + output: + vt_aabd: 0 +- name: Case 14, non Vermont resident. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 65 + output: + vt_aabd: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml new file mode 100644 index 00000000000..3e185908f56 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml @@ -0,0 +1,202 @@ +- name: Full essential-person payment supplements existing SSI and AABD + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + output: + vt_aabd_ep: 547 +- name: Sixty-seven percent care level + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: PARTIAL_67 + output: + vt_aabd_ep: 366 +- name: Thirty-four percent care level + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: PARTIAL_34 + output: + vt_aabd_ep: 186 +- name: No certified essential-person arrangement + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: NONE + output: + vt_aabd_ep: 0 +- name: An ineligible spouse cannot qualify at the 34 percent service level + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: PARTIAL_34 + vt_aabd_ep_is_spouse: true + output: + vt_aabd_ep: 0 +- name: Prorated nonspouse essential-person net income counts + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_ep_additional_countable_income: 100 + output: + vt_aabd_ep: 447 +- name: Income at payment maximum + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_ep_countable_income: 1596.8 + output: + vt_aabd_ep: 0 +- name: Countable-income override applies to specialized dependent allocations + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_ep_countable_income: 1000 + output: + vt_aabd_ep: 596 +- name: A certified half-month grant is truncated after proration + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_ep_proration: 0.5 + output: + vt_aabd_ep: 273 +- name: Essential-person coverage does not extend to residential care + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + output: + vt_aabd_ep: 0 +- name: Nonspouse essential person cannot qualify in another household + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + output: + vt_aabd_ep: 0 +- name: Ineligible spouse qualifies in another household + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 662.67 + vt_aabd_federal: 42.05 + vt_aabd_ep_level: FULL + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + vt_aabd_ep_is_spouse: true + output: + vt_aabd_ep: 344 +- name: Non-SSI recipient requires verified resource eligibility + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 0 + vt_aabd_federal: 0 + vt_aabd_ep_level: FULL + output: + vt_aabd_ep: 0 +- name: State-only essential-person grant with verified resources + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 0 + vt_aabd_federal: 0 + vt_aabd_ep_level: FULL + vt_aabd_ep_resources_eligible: true + social_security_retirement: 12000 + output: + vt_aabd_ep: 616 +- name: A worker receives the state employment-expense deduction + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 0 + vt_aabd_federal: 0 + vt_aabd_ep_level: FULL + vt_aabd_ep_resources_eligible: true + employment_income: 24000 + output: + vt_aabd_ep: 684 +- name: Needs-based veterans pension does not get the general exclusion + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 70 + ssi: 0 + vt_aabd_federal: 0 + vt_aabd_ep_level: FULL + vt_aabd_ep_resources_eligible: true + veterans_benefits: 12000 + output: + vt_aabd_ep: 596 +- name: Out of state + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: NH + age: 70 + ssi: 994 + vt_aabd_federal: 55.68 + vt_aabd_ep_level: FULL + output: + vt_aabd_ep: 0 diff --git a/policyengine_us/variables/gov/ssa/ssi/_ssi_state_supplement.py b/policyengine_us/variables/gov/ssa/ssi/_ssi_state_supplement.py new file mode 100644 index 00000000000..5e0c84da3f3 --- /dev/null +++ b/policyengine_us/variables/gov/ssa/ssi/_ssi_state_supplement.py @@ -0,0 +1,53 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +def ssi_state_supplement( + person, period, parameters, individual_rate, couple_rate, federal_payment_rules=True +): + """Apply SSI-based supplement income, couple and spouse-deeming rules. + + Rates are state supplements, excluding federal SSI. Each member supplies + the same-category couple rate; averaging these rates implements mixed + arrangements where the state's published schedule supports that method. + Set federal_payment_rules only for SSA-administered payments; state + administrators do not inherit the federal rounding or minimum payment. + Sources: 20 CFR 416.2025; POMS SI 01320.430 D, SI 02005.030 G, + SI 02001.005 and SI 02001.010. Callers apply state-specific eligibility. + """ + joint = person("ssi_couple_computation_applies", period) + couple_total = person.marital_unit.sum(couple_rate / 2) + standard = where(joint, couple_total / 2, individual_rate) + countable = person("ssi_countable_income", period) + federal_amount = person("ssi_amount_if_eligible", period) + excess = max_(countable - federal_amount, 0) + payment = max_(standard - excess, 0) + + deeming = person("is_ssi_spousal_deeming_applies", period.this_year) + deemed = person("ssi_income_deemed_from_ineligible_spouse", period) + own_income = max_(countable - deemed, 0) + ssi = parameters(period).gov.ssa.ssi + federal_la = person("ssi_federal_living_arrangement", period) + own_federal_amount = ssi.amount.individual * where( + federal_la == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD, + 1 - ssi.amount.one_third_reduction_rate, + 1, + ) + own_payment = max_(individual_rate - max_(own_income - own_federal_amount, 0), 0) + # SI 01320.430 D.2: use the higher individual rate where it exceeds + # the couple rate (including New Jersey's ineligible-spouse variation). + deemed_payment = max_(max_(couple_rate, individual_rate) - excess, 0) + payment = where(deeming, min_(own_payment, deemed_payment), payment) + + eligible = person("is_ssi_eligible", period) & person( + "takes_up_ssi_if_eligible", period.this_year + ) + # Federal administration discards digits beyond the third decimal place, + # rounds up to cents, and pays at least one dollar for a positive amount. + rounded = np.ceil(np.floor(payment * 1_000) / 10) / 100 + federal_payment = where( + rounded > 0, max_(rounded, ssi.state_supplement.minimum_payment), 0 + ) + return eligible * where(federal_payment_rules, federal_payment, payment) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py new file mode 100644 index 00000000000..2c774b4a0c8 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py @@ -0,0 +1,15 @@ +from policyengine_us.model_api import * + + +class vt_aabd(Variable): + value_type = float + entity = Person + label = "Vermont Aid to the Aged, Blind or Disabled supplements" + definition_period = MONTH + unit = USD + defined_for = StateCode.VT + reference = ( + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m", + "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf", + ) + adds = ["vt_aabd_federal", "vt_aabd_ep"] diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py new file mode 100644 index 00000000000..9666d313a83 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class vt_aabd_countable_for_hud(Variable): + value_type = float + entity = Person + label = "Vermont AABD countable for HUD" + definition_period = MONTH + unit = USD + reference = ( + "https://www.ecfr.gov/current/title-24/section-5.609", + "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf", + ) + documentation = "Applies 24 CFR 5.609(b)(19) to Essential Person care payments enabling a disabled family member to remain at home. This is an interpretation of the federal exclusion and the certified care purpose in Vermont rule 2781, not an express Vermont HUD instruction. Ordinary aged-person income support remains countable. Override if the housing agency determines a different countable amount or disability status." + + def formula(person, period, parameters): + disabled = person("is_disabled", period.this_year) | person( + "is_blind", period.this_year + ) + return person("vt_aabd_federal", period) + ~disabled * person( + "vt_aabd_ep", period + ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py new file mode 100644 index 00000000000..bf478505fa9 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py @@ -0,0 +1,63 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep(Variable): + value_type = float + entity = Person + label = "Vermont state-administered Essential Person grant" + definition_period = MONTH + unit = USD + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + defined_for = StateCode.VT + + def formula(person, period, parameters): + p = parameters(period).gov.states.vt.dcf.aabd + level = person("vt_aabd_ep_level", period) + arrangement = person("vt_aabd_living_arrangement", period) + la = arrangement.possible_values + independent = arrangement == la.INDEPENDENT + other = arrangement == la.HOUSEHOLD_OF_ANOTHER + spouse = person("vt_aabd_ep_is_spouse", period) + abd = person("is_ssi_aged_blind_disabled", period.this_year) + participants = abd & (level != level.possible_values.NONE) + count = person.marital_unit.sum(participants) + couple = count > 1 + federal = parameters(period).gov.ssa.ssi + # Both 2026 geographic schedules have the same amounts. Derive the + # partial levels from rule 2784 and round the standard to cents. + maximum = where( + other, + p.ep.another_household_maximum, + where(couple, p.ep.couple_maximum, p.ep.individual_maximum), + ) + base = where( + couple, + federal.amount.couple + p.amount.couple.INDEPENDENT, + where( + other, + federal.amount.individual + * (1 - federal.amount.one_third_reduction_rate) + + p.amount.individual.HOUSEHOLD_OF_ANOTHER, + federal.amount.individual + p.amount.individual.INDEPENDENT, + ), + ) + standard = np.round(base + p.ep.rate[level] * (maximum - base), 2) + valid_level = (level != level.possible_values.NONE) & ~( + spouse & (level == level.possible_values.PARTIAL_34) + ) + immigration = person("immigration_status", period.this_year) + immigrant = (immigration == immigration.possible_values.CITIZEN) | person( + "is_ssi_qualified_noncitizen", period.this_year + ) + eligible = ( + valid_level + & abd + & immigrant + & (independent | (other & spouse & ~couple)) + & person("vt_aabd_ep_resources_eligible", period) + & ~person("is_incarcerated", period) + & person("takes_up_ssi_if_eligible", period) + ) + amount = max_(standard - person("vt_aabd_ep_countable_income", period), 0) + grant = np.floor(amount * clip(person("vt_aabd_ep_proration", period), 0, 1)) + return eligible * grant / max_(count, 1) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py new file mode 100644 index 00000000000..50344eb8f2c --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_additional_countable_income(Variable): + value_type = float + entity = Person + label = "Vermont Essential Person income outside the marital group" + definition_period = MONTH + unit = USD + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + documentation = "Verified net income of a nonspouse essential person and any parental allocation. Apply the Reach Up exclusions, dependent proration, worker expense allowance and any unused share of the single group general exclusion before entering this amount; do not duplicate the marital group income." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py new file mode 100644 index 00000000000..949b88d17d5 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py @@ -0,0 +1,40 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_countable_income(Variable): + value_type = float + entity = Person + label = "Vermont Essential Person assistance-group countable income" + definition_period = MONTH + unit = USD + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + documentation = "Whole marital-group income plus the verified net allocation for nonspouse essential persons/parents. Override for Reach Up income sources/exclusions absent from SSI inputs or an agency allocation of the shared general disregard." + + def formula(person, period, parameters): + p = parameters(period).gov.states.vt.dcf.aabd.ep + exclusions = parameters(period).gov.ssa.ssi.income.exclusions + abd = person("is_ssi_aged_blind_disabled", period.this_year) + earned = max_(person("ssi_earned_income", period) - p.employment_expense, 0) + abd_earned = person.marital_unit.sum(earned * abd) + other_earned = person.marital_unit.sum(earned * ~abd) + veterans = max_(person("veterans_benefits", period), 0) + unearned = person.marital_unit.sum( + max_(person("ssi_unearned_income", period) - veterans, 0) + ) + general = exclusions.general + remaining_general = max_(general - unearned, 0) + unearned = max_(unearned - general, 0) + # Apply any remaining group disregard to non-ABD earnings first, + # since only the ABD members receive the half-earnings exclusion. + remaining_general_abd = max_(remaining_general - other_earned, 0) + other_earned = max_(other_earned - remaining_general, 0) + abd_earned = max_(abd_earned - remaining_general_abd - exclusions.earned, 0) * ( + 1 - exclusions.earned_share + ) + needs_based = person.marital_unit.sum( + veterans + person("ssi", period) + person("vt_aabd_federal", period) + ) + additional = person.marital_unit.max( + max_(person("vt_aabd_ep_additional_countable_income", period), 0) + ) + return unearned + abd_earned + other_earned + needs_based + additional diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py new file mode 100644 index 00000000000..96d3db167c3 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py @@ -0,0 +1,9 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_is_spouse(Variable): + value_type = bool + entity = Person + label = "Vermont essential person is an ineligible spouse" + definition_period = MONTH + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py new file mode 100644 index 00000000000..a51f550a2e3 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class VTAABDEssentialPersonLevel(Enum): + NONE = "No certified Essential Person arrangement" + FULL = "Certified full Essential Person care level" + PARTIAL_67 = "Certified 67 percent Essential Person care level" + PARTIAL_34 = "Certified 34 percent Essential Person care level" + + +class vt_aabd_ep_level(Variable): + value_type = Enum + entity = Person + label = "Vermont certified Essential Person care level" + definition_period = MONTH + possible_values = VTAABDEssentialPersonLevel + default_value = VTAABDEssentialPersonLevel.NONE + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + documentation = """ + Certified co-resident essential person under rules 2781-2784: full for + an ineligible spouse 55 or older, or required personal care, or seven + homemaker services; 67 percent for a younger spouse unable to work who + provides qualifying care, or a nonspouse providing four to six services; + 34 percent for a nonspouse providing one to three services. Certification + includes benefit pursuit and care preventing institutionalization. Set + both eligible spouses to the same level for a shared nonspouse caregiver. + """ diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py new file mode 100644 index 00000000000..ae64ace17e1 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_proration(Variable): + value_type = float + entity = Person + label = "Vermont Essential Person certified payment fraction" + definition_period = MONTH + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + default_value = 1 + documentation = "Agency-certified fraction payable in the application month under rule 2784; a first-working-day application receives the full month." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py new file mode 100644 index 00000000000..278aa7a6df2 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_resources_eligible(Variable): + value_type = bool + entity = Person + label = "Vermont Essential Person resource eligibility" + definition_period = MONTH + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + documentation = "SSI/AABD receipt automatically passes the resource test. For state-only applicants, explicitly supply the resource determination under rule 2785, including Reach Up resource exclusions as of August 2024, Medicaid limits, and nonspouse dependent proration." + + def formula(person, period, parameters): + received = person("ssi", period) + person("vt_aabd_federal", period) + return person.marital_unit.any(received > 0) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py new file mode 100644 index 00000000000..3b0a6b7b197 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi._ssi_state_supplement import ( + ssi_state_supplement, +) + + +class vt_aabd_federal(Variable): + value_type = float + entity = Person + label = "Vermont federally administered AABD supplement" + definition_period = MONTH + unit = USD + defined_for = StateCode.VT + reference = "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m" + + def formula(person, period, parameters): + p = parameters(period).gov.states.vt.dcf.aabd.amount + arrangement = person("vt_aabd_living_arrangement", period) + return ssi_state_supplement( + person, period, parameters, p.individual[arrangement], p.couple[arrangement] + ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py new file mode 100644 index 00000000000..2013d56f244 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py @@ -0,0 +1,50 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.ssa.ssi.eligibility.status.ssi_federal_living_arrangement import ( + SSIFederalLivingArrangement, +) + + +class VTAABDLivingArrangement(Enum): + INDEPENDENT = "Independent living" + HOUSEHOLD_OF_ANOTHER = "Living in another household" + RESIDENTIAL_CARE_LEVEL_III = ( + "State-identified Level III residential or assisted living care" + ) + RESIDENTIAL_CARE_LEVEL_IV = ( + "State-identified Level IV residential or therapeutic care" + ) + CUSTODIAL_CARE = "Qualifying custodial family home" + MEDICAID_INSTITUTION = "Title XIX medical institution" + NONE = "Supplement waived or no qualifying arrangement" + + +class vt_aabd_living_arrangement(Variable): + value_type = Enum + entity = Person + label = "Vermont AABD living arrangement" + definition_period = MONTH + defined_for = StateCode.VT + possible_values = VTAABDLivingArrangement + default_value = VTAABDLivingArrangement.NONE + reference = "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m" + documentation = """ + Defaults follow federal SSI living arrangements. Residential and custodial + care require an explicit setting that meets the state's certification and + service rules. Independent rates are identical inside and outside Chittenden + County in 2026. Private-insurance-funded institutional children use an + explicit independent arrangement under SI BOS01415.013. + """ + + def formula(person, period, parameters): + federal = person("ssi_federal_living_arrangement", period) + return select( + [ + federal == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY, + federal == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD, + ], + [ + VTAABDLivingArrangement.MEDICAID_INSTITUTION, + VTAABDLivingArrangement.HOUSEHOLD_OF_ANOTHER, + ], + default=VTAABDLivingArrangement.INDEPENDENT, + ) diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index 41ead044f46..ad6c9983639 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -22,6 +22,7 @@ def formula(spm_unit, period, parameters): "ky_ssp", # Kentucky benefits "de_ssp", # Delaware benefits "fl_oss", + "vt_aabd", "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits From e76caf838826b4ea09d9b61e4b0ccaf400d81654 Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 13 Oct 2026 01:06:40 -0400 Subject: [PATCH 2/4] Normalize Vermont SSP parameter and test formatting --- .../household/household_state_benefits.yaml | 1 + .../hud/annual_income/sources/unearned.yaml | 1 + .../ssi/state_supplement/minimum_payment.yaml | 1 + .../gov/states/vt/dcf/aabd/amount/couple.yaml | 14 +- .../states/vt/dcf/aabd/amount/individual.yaml | 14 +- .../aabd/ep/another_household_maximum.yaml | 12 +- .../states/vt/dcf/aabd/ep/couple_maximum.yaml | 9 +- .../vt/dcf/aabd/ep/employment_expense.yaml | 9 +- .../vt/dcf/aabd/ep/individual_maximum.yaml | 9 +- .../gov/states/vt/dcf/aabd/ep/rate.yaml | 27 ++- .../gov/states/vt/dcf/aabd/integration.yaml | 202 +++++++----------- .../gov/states/vt/dcf/aabd/vt_aabd.yaml | 21 +- .../gov/states/vt/dcf/aabd/vt_aabd_ep.yaml | 60 ++++-- 13 files changed, 191 insertions(+), 189 deletions(-) diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index a8195ed9cce..f04b573918f 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -405,6 +405,7 @@ values: - nj_property_tax_relief # New York benefits - ny_child_care_subsidies + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index b4b0e377b0d..c865d29c98e 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -30,6 +30,7 @@ values: - disability_benefits - survivor_benefits - financial_assistance + metadata: unit: list period: year diff --git a/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml b/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml index 96464c8c040..1d3e6e2e6b6 100644 --- a/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml +++ b/policyengine_us/parameters/gov/ssa/ssi/state_supplement/minimum_payment.yaml @@ -1,6 +1,7 @@ description: The Social Security Administration pays at least this monthly amount to each recipient of a positive federally administered optional state supplement. values: 2026-01-01: 1 + metadata: unit: currency-USD period: month diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml index d7fa3f40e01..d0541e2f8b5 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml @@ -1,24 +1,32 @@ description: Vermont provides these monthly optional AABD state supplement rates for an eligible couple. + metadata: unit: currency-USD period: month label: Vermont AABD couple payment rate breakdown: - - vt_aabd_living_arrangement + - vt_aabd_living_arrangement reference: - - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels - href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + INDEPENDENT: 2026-01-01: 105.8 + HOUSEHOLD_OF_ANOTHER: 2026-01-01: 51.69 + RESIDENTIAL_CARE_LEVEL_III: 2026-01-01: 103.54 + RESIDENTIAL_CARE_LEVEL_IV: 2026-01-01: 601.4 + CUSTODIAL_CARE: 2026-01-01: 356.12 + MEDICAID_INSTITUTION: 2026-01-01: 99.85 + NONE: 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml index 9b3afa6fecd..1bff6f0851d 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml @@ -1,24 +1,32 @@ description: Vermont provides these monthly optional AABD state supplement rates for an eligible individual. + metadata: unit: currency-USD period: month label: Vermont AABD individual payment rate breakdown: - - vt_aabd_living_arrangement + - vt_aabd_living_arrangement reference: - - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels - href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + INDEPENDENT: 2026-01-01: 55.68 + HOUSEHOLD_OF_ANOTHER: 2026-01-01: 42.05 + RESIDENTIAL_CARE_LEVEL_III: 2026-01-01: 51.77 + RESIDENTIAL_CARE_LEVEL_IV: 2026-01-01: 239.62 + CUSTODIAL_CARE: 2026-01-01: 105.6 + MEDICAID_INSTITUTION: 2026-01-01: 49.93 + NONE: 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml index 0b5859d0d03..2dd865bb9c6 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml @@ -1,11 +1,11 @@ -description: Vermont uses this amount as its Essential Person payment maximum with an ineligible spouse - in another household. +description: Vermont uses this amount as its Essential Person payment maximum with an ineligible spouse in another household. values: - '2026-01-01': 1049.68 + 2026-01-01: 1_049.68 + metadata: unit: currency-USD + period: month label: Vermont Essential Person payment maximum with an ineligible spouse in another household reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf - period: month + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml index a67a9327010..170320c8100 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml @@ -1,10 +1,11 @@ description: Vermont uses this amount as its Essential Person independent eligible-couple payment maximum. values: - '2026-01-01': 1780.64 + 2026-01-01: 1_780.64 + metadata: unit: currency-USD + period: month label: Vermont Essential Person independent eligible-couple payment maximum reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf - period: month + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml index d27ee74fc47..4493ed07e86 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml @@ -1,10 +1,11 @@ description: Vermont uses this amount as its Essential Person employment expense deduction per worker. values: - '2026-01-01': 90 + 2026-01-01: 90 + metadata: unit: currency-USD + period: month label: Vermont Essential Person employment expense deduction per worker reference: - - title: AABD rules 2786 interpretive memo - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf - period: month + - title: AABD rules 2786 interpretive memo + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml index 9551669110a..98f0653ac9b 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml @@ -1,10 +1,11 @@ description: Vermont uses this amount as its Essential Person independent individual payment maximum. values: - '2026-01-01': 1596.8 + 2026-01-01: 1_596.8 + metadata: unit: currency-USD + period: month label: Vermont Essential Person independent individual payment maximum reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf - period: month + - title: Bulletin 25-26, P2740B, 2026 payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml index 9e6cda2fbee..3c9e34b890c 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml @@ -1,17 +1,22 @@ description: Vermont sets the Essential Person increment at this fraction for the certified care level. -NONE: - '2026-01-01': 0 -FULL: - '2026-01-01': 1 -PARTIAL_67: - '2026-01-01': 0.67 -PARTIAL_34: - '2026-01-01': 0.34 + metadata: unit: /1 label: Vermont Essential Person care fraction breakdown: - - vt_aabd_ep_level + - vt_aabd_ep_level reference: - - title: AABD rules 2784(A) - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf + - title: AABD rules 2784(A) + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf + +NONE: + 2026-01-01: 0 + +FULL: + 2026-01-01: 1 + +PARTIAL_67: + 2026-01-01: 0.67 + +PARTIAL_34: + 2026-01-01: 0.34 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml index 8fcc5dd038a..0c53bca5951 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml @@ -3,137 +3,109 @@ absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: INDEPENDENT - second: + person2: age: 65 vt_aabd_living_arrangement: INDEPENDENT marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 52.9 - - 52.9 + vt_aabd: [52.9, 52.9] + - name: Case 2, residential_care_level_iii couple. period: 2026-01 absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III - second: + person2: age: 65 vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 51.77 - - 51.77 + vt_aabd: [51.77, 51.77] + - name: Case 3, residential_care_level_iv couple. period: 2026-01 absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV - second: + person2: age: 65 vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 300.7 - - 300.7 + vt_aabd: [300.7, 300.7] + - name: Case 4, custodial_care couple. period: 2026-01 absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: CUSTODIAL_CARE - second: + person2: age: 65 vt_aabd_living_arrangement: CUSTODIAL_CARE marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 178.06 - - 178.06 + vt_aabd: [178.06, 178.06] + - name: Case 5, household_of_another couple. period: 2026-01 absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER ssi_lives_in_another_persons_household: true ssi_receives_shelter_from_others_in_household: true ssi_others_pay_all_meals: true - second: + person2: age: 65 vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER ssi_lives_in_another_persons_household: true @@ -141,59 +113,45 @@ ssi_others_pay_all_meals: true marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 25.85 - - 25.85 + vt_aabd: [25.85, 25.85] + - name: Case 6, medicaid_institution couple. period: 2026-01 absolute_error_margin: 0.01 input: people: - first: + person1: age: 65 vt_aabd_living_arrangement: MEDICAID_INSTITUTION ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true - second: + person2: age: 65 vt_aabd_living_arrangement: MEDICAID_INSTITUTION ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true marital_units: couple: - members: - - first - - second + members: [person1, person2] tax_units: unit: - members: - - first - - second + members: [person1, person2] households: household: - members: - - first - - second + members: [person1, person2] state_code: VT output: - vt_aabd: - - 49.93 - - 49.93 + vt_aabd: [49.93, 49.93] + - name: Case 7, annual benefits and SNAP income. period: 2026 absolute_error_margin: 0.01 @@ -203,83 +161,71 @@ output: vt_aabd: 668.16 household_state_benefits: 668.16 - snap_unearned_income: 12596.16 -- name: Essential-person grant enters the annual Vermont benefit total - period: '2026' + snap_unearned_income: 12_596.16 + +- name: Case 8, Essential-person grant enters the annual Vermont benefit total. + period: 2026 absolute_error_margin: 0.01 input: state_code: VT age: 70 vt_aabd_ep_level: - '2026': FULL + 2026: FULL output: - ssi: 11928 + ssi: 11_928 vt_aabd_federal: 668.16 - vt_aabd_ep: 6564 - vt_aabd: 7232.16 - snap_unearned_income: 19160.16 -- name: Two eligible spouses share one essential-person grant + vt_aabd_ep: 6_564 + vt_aabd: 7_232.16 + snap_unearned_income: 19_160.16 + +- name: Case 9, Two eligible spouses share one essential-person grant. period: 2026-01 absolute_error_margin: 0.01 input: people: - a: + person1: age: 70 vt_aabd_ep_level: FULL - b: + person2: age: 70 vt_aabd_ep_level: FULL marital_units: couple: - members: - - a - - b + members: [person1, person2] households: home: - members: - - a - - b + members: [person1, person2] state_code: VT output: - vt_aabd_ep: - - 91.5 - - 91.5 - vt_aabd: - - 144.4 - - 144.4 -- name: Ineligible spouse earnings do not get the ABD half-earnings deduction + vt_aabd_ep: [91.5, 91.5] + vt_aabd: [144.4, 144.4] + +- name: Case 10, Ineligible spouse earnings do not get the ABD half-earnings deduction. period: 2026-01 absolute_error_margin: 0.01 input: people: - a: + person1: age: 70 vt_aabd_ep_level: FULL vt_aabd_ep_is_spouse: true vt_aabd_ep_resources_eligible: true - b: + person2: age: 40 - employment_income: 6000 + employment_income: 6_000 marital_units: couple: - members: - - a - - b + members: [person1, person2] households: home: - members: - - a - - b + members: [person1, person2] state_code: VT output: - vt_aabd_ep_countable_income: - - 1439.68 - - 1439.68 - vt_aabd_ep: - - 157 - - 0 -- name: Vermont essential care for a disabled member is excluded for HUD - period: '2026' + vt_aabd_ep_countable_income: [1_439.68, 1_439.68] + vt_aabd_ep: [157, 0] + +- name: Case 11, Vermont essential care for a disabled member is excluded for HUD. + period: 2026 absolute_error_margin: 0.01 input: state_code: VT @@ -288,6 +234,6 @@ is_disabled: true vt_aabd_ep_level: FULL output: - vt_aabd: 7232.16 - snap_unearned_income: 19160.16 - hud_unearned_income: 12596.16 + vt_aabd: 7_232.16 + snap_unearned_income: 19_160.16 + hud_unearned_income: 12_596.16 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml index 5e7660900c9..c7555cc5cc4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml @@ -8,6 +8,7 @@ vt_aabd_living_arrangement: INDEPENDENT output: vt_aabd: 55.68 + - name: Case 2, residential care level iii individual. period: 2026-01 absolute_error_margin: 0.01 @@ -17,6 +18,7 @@ vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III output: vt_aabd: 51.77 + - name: Case 3, residential care level iv individual. period: 2026-01 absolute_error_margin: 0.01 @@ -26,6 +28,7 @@ vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV output: vt_aabd: 239.62 + - name: Case 4, custodial care individual. period: 2026-01 absolute_error_margin: 0.01 @@ -35,6 +38,7 @@ vt_aabd_living_arrangement: CUSTODIAL_CARE output: vt_aabd: 105.6 + - name: Case 5, household of another individual. period: 2026-01 absolute_error_margin: 0.01 @@ -47,6 +51,7 @@ ssi_others_pay_all_meals: true output: vt_aabd: 42.05 + - name: Case 6, medicaid institution individual. period: 2026-01 absolute_error_margin: 0.01 @@ -58,6 +63,7 @@ ssi_medicaid_pays_majority_of_care: true output: vt_aabd: 49.93 + - name: Case 7, none individual. period: 2026-01 absolute_error_margin: 0.01 @@ -67,6 +73,7 @@ vt_aabd_living_arrangement: NONE output: vt_aabd: 0 + - name: Case 8, automatic independent classification. period: 2026-01 absolute_error_margin: 0.01 @@ -75,42 +82,47 @@ age: 65 output: vt_aabd: 55.68 + - name: Case 9, income above federal SSI standard. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT age: 65 - social_security_retirement: 12360 + social_security_retirement: 12_360 output: vt_aabd: 39.68 + - name: Case 10, income at combined cutoff. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT age: 65 - social_security_retirement: 12836.16 + social_security_retirement: 12_836.16 output: vt_aabd: 0 + - name: Case 11, minimum positive payment. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT age: 65 - social_security_retirement: 12836.04 + social_security_retirement: 12_836.04 output: vt_aabd: 1 + - name: Case 12, excess resources. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT age: 65 - ssi_countable_resources: 2001 + ssi_countable_resources: 2_001 output: vt_aabd: 0 + - name: Case 13, not aged blind or disabled. period: 2026-01 absolute_error_margin: 0.01 @@ -119,6 +131,7 @@ age: 30 output: vt_aabd: 0 + - name: Case 14, non Vermont resident. period: 2026-01 absolute_error_margin: 0.01 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml index 3e185908f56..7acbe6ae716 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml @@ -1,4 +1,4 @@ -- name: Full essential-person payment supplements existing SSI and AABD +- name: Case 1, Full essential-person payment supplements existing SSI and AABD. period: 2026-01 absolute_error_margin: 0.01 input: @@ -9,7 +9,8 @@ vt_aabd_ep_level: FULL output: vt_aabd_ep: 547 -- name: Sixty-seven percent care level + +- name: Case 2, Sixty-seven percent care level. period: 2026-01 absolute_error_margin: 0.01 input: @@ -20,7 +21,8 @@ vt_aabd_ep_level: PARTIAL_67 output: vt_aabd_ep: 366 -- name: Thirty-four percent care level + +- name: Case 3, Thirty-four percent care level. period: 2026-01 absolute_error_margin: 0.01 input: @@ -31,7 +33,8 @@ vt_aabd_ep_level: PARTIAL_34 output: vt_aabd_ep: 186 -- name: No certified essential-person arrangement + +- name: Case 4, No certified essential-person arrangement. period: 2026-01 absolute_error_margin: 0.01 input: @@ -42,7 +45,8 @@ vt_aabd_ep_level: NONE output: vt_aabd_ep: 0 -- name: An ineligible spouse cannot qualify at the 34 percent service level + +- name: Case 5, An ineligible spouse cannot qualify at the 34 percent service level. period: 2026-01 absolute_error_margin: 0.01 input: @@ -54,7 +58,8 @@ vt_aabd_ep_is_spouse: true output: vt_aabd_ep: 0 -- name: Prorated nonspouse essential-person net income counts + +- name: Case 6, Prorated nonspouse essential-person net income counts. period: 2026-01 absolute_error_margin: 0.01 input: @@ -66,7 +71,8 @@ vt_aabd_ep_additional_countable_income: 100 output: vt_aabd_ep: 447 -- name: Income at payment maximum + +- name: Case 7, Income at payment maximum. period: 2026-01 absolute_error_margin: 0.01 input: @@ -75,10 +81,11 @@ ssi: 994 vt_aabd_federal: 55.68 vt_aabd_ep_level: FULL - vt_aabd_ep_countable_income: 1596.8 + vt_aabd_ep_countable_income: 1_596.8 output: vt_aabd_ep: 0 -- name: Countable-income override applies to specialized dependent allocations + +- name: Case 8, Countable-income override applies to specialized dependent allocations. period: 2026-01 absolute_error_margin: 0.01 input: @@ -87,10 +94,11 @@ ssi: 994 vt_aabd_federal: 55.68 vt_aabd_ep_level: FULL - vt_aabd_ep_countable_income: 1000 + vt_aabd_ep_countable_income: 1_000 output: vt_aabd_ep: 596 -- name: A certified half-month grant is truncated after proration + +- name: Case 9, A certified half-month grant is truncated after proration. period: 2026-01 absolute_error_margin: 0.01 input: @@ -102,7 +110,8 @@ vt_aabd_ep_proration: 0.5 output: vt_aabd_ep: 273 -- name: Essential-person coverage does not extend to residential care + +- name: Case 10, Essential-person coverage does not extend to residential care. period: 2026-01 absolute_error_margin: 0.01 input: @@ -114,7 +123,8 @@ vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III output: vt_aabd_ep: 0 -- name: Nonspouse essential person cannot qualify in another household + +- name: Case 11, Nonspouse essential person cannot qualify in another household. period: 2026-01 absolute_error_margin: 0.01 input: @@ -126,7 +136,8 @@ vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER output: vt_aabd_ep: 0 -- name: Ineligible spouse qualifies in another household + +- name: Case 12, Ineligible spouse qualifies in another household. period: 2026-01 absolute_error_margin: 0.01 input: @@ -139,7 +150,8 @@ vt_aabd_ep_is_spouse: true output: vt_aabd_ep: 344 -- name: Non-SSI recipient requires verified resource eligibility + +- name: Case 13, Non-SSI recipient requires verified resource eligibility. period: 2026-01 absolute_error_margin: 0.01 input: @@ -150,7 +162,8 @@ vt_aabd_ep_level: FULL output: vt_aabd_ep: 0 -- name: State-only essential-person grant with verified resources + +- name: Case 14, State-only essential-person grant with verified resources. period: 2026-01 absolute_error_margin: 0.01 input: @@ -160,10 +173,11 @@ vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - social_security_retirement: 12000 + social_security_retirement: 12_000 output: vt_aabd_ep: 616 -- name: A worker receives the state employment-expense deduction + +- name: Case 15, A worker receives the state employment-expense deduction. period: 2026-01 absolute_error_margin: 0.01 input: @@ -173,10 +187,11 @@ vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - employment_income: 24000 + employment_income: 24_000 output: vt_aabd_ep: 684 -- name: Needs-based veterans pension does not get the general exclusion + +- name: Case 16, Needs-based veterans pension does not get the general exclusion. period: 2026-01 absolute_error_margin: 0.01 input: @@ -186,10 +201,11 @@ vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - veterans_benefits: 12000 + veterans_benefits: 12_000 output: vt_aabd_ep: 596 -- name: Out of state + +- name: Case 17, Out of state. period: 2026-01 absolute_error_margin: 0.01 input: From 6842ff568d224fe31f6da1c8a8769b0d8b94ff7d Mon Sep 17 00:00:00 2001 From: Ziming Date: Tue, 13 Oct 2026 02:57:09 -0400 Subject: [PATCH 3/4] Fix issues from review: Vermont AABD HUD income, Essential Person maxima and tests - Count the AABD payment, including the Essential Person grant, as HUD income; drop the HUD helper and shared metadata edit - Derive Essential Person maxima from the SSI and AABD rates plus one increment parameter - Name the unmodeled limited-nursing Level III arrangement; clarify the Level III label and POMS citation - Essential Person gates: receives_ssi auto-pass, no unsourced immigration gate, take-up period, eligible-member couple count - Spouse flag defaults from the marital unit; drop the application-month proration input - Registry placement and comments, SNAP reference title, programs.yaml note, page anchors - Realistic state-only cases; exercise the living-arrangement mapping and HUD counting Co-Authored-By: Claude Opus 5.5 --- .../household/household_state_benefits.yaml | 12 ++- .../hud/annual_income/sources/unearned.yaml | 4 +- .../gov/states/vt/dcf/aabd/amount/couple.yaml | 2 +- .../states/vt/dcf/aabd/amount/individual.yaml | 2 +- .../aabd/ep/another_household_maximum.yaml | 11 --- .../vt/dcf/aabd/ep/couple_increment.yaml | 14 +++ .../states/vt/dcf/aabd/ep/couple_maximum.yaml | 11 --- .../vt/dcf/aabd/ep/employment_expense.yaml | 4 +- .../vt/dcf/aabd/ep/individual_maximum.yaml | 11 --- .../gov/states/vt/dcf/aabd/ep/rate.yaml | 5 +- .../usda/snap/income/sources/unearned.yaml | 4 +- policyengine_us/programs.yaml | 6 +- .../gov/states/vt/dcf/aabd/integration.yaml | 33 ++++++- .../gov/states/vt/dcf/aabd/vt_aabd.yaml | 8 +- .../gov/states/vt/dcf/aabd/vt_aabd_ep.yaml | 92 ++++++++++++++----- .../gov/states/vt/dcf/aabd/vt_aabd.py | 3 +- .../vt/dcf/aabd/vt_aabd_countable_for_hud.py | 22 ----- .../gov/states/vt/dcf/aabd/vt_aabd_ep.py | 61 ++++++------ .../vt_aabd_ep_additional_countable_income.py | 3 +- .../dcf/aabd/vt_aabd_ep_countable_income.py | 5 +- .../vt/dcf/aabd/vt_aabd_ep_is_spouse.py | 12 ++- .../states/vt/dcf/aabd/vt_aabd_ep_level.py | 5 +- .../vt/dcf/aabd/vt_aabd_ep_proration.py | 11 --- .../dcf/aabd/vt_aabd_ep_resources_eligible.py | 11 ++- .../vt/dcf/aabd/vt_aabd_living_arrangement.py | 16 +++- .../income/spm_unit/spm_unit_benefits.py | 2 +- 26 files changed, 215 insertions(+), 155 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml create mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml delete mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml delete mode 100644 policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml delete mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py delete mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py diff --git a/policyengine_us/parameters/gov/household/household_state_benefits.yaml b/policyengine_us/parameters/gov/household/household_state_benefits.yaml index f04b573918f..6bc8717d523 100644 --- a/policyengine_us/parameters/gov/household/household_state_benefits.yaml +++ b/policyengine_us/parameters/gov/household/household_state_benefits.yaml @@ -71,6 +71,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Vermont benefits + - vt_aabd # Virginia benefits - va_child_care_subsidies # Massachusetts benefits @@ -78,7 +80,6 @@ values: # DC benefits - dc_ossp # Kansas benefits - - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -164,6 +165,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Vermont benefits + - vt_aabd # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -177,7 +180,6 @@ values: # DC benefits - dc_ossp # Kansas benefits - - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -267,6 +269,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Vermont benefits + - vt_aabd # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -281,7 +285,6 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits - - vt_aabd - ks_sspp # Hawaii benefits - hi_oss @@ -371,6 +374,8 @@ values: - sc_ssi_state_supplement # Texas benefits - tx_ssi_state_supplement + # Vermont benefits + - vt_aabd # Virginia benefits - va_child_care_subsidies # West Virginia benefits @@ -385,7 +390,6 @@ values: - dc_ossp - dc_child_care_subsidies # Kansas benefits - - vt_aabd - ks_sspp # Hawaii benefits - hi_oss diff --git a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml index c865d29c98e..4d564d744da 100644 --- a/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/hud/annual_income/sources/unearned.yaml @@ -19,7 +19,7 @@ values: - strike_benefits - social_security - ssi - - vt_aabd_countable_for_hud + - vt_aabd - general_assistance - unemployment_compensation - child_support_received @@ -36,5 +36,5 @@ metadata: period: year label: HUD unearned income sources reference: - - title: 24 CFR § 5.609(a)(1), (a)(2), (b)(6), (b)(19) + - title: 24 CFR § 5.609(a)(1), (a)(2) href: https://www.law.cornell.edu/cfr/text/24/5.609 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml index d0541e2f8b5..b2f0cdcc069 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml @@ -1,4 +1,4 @@ -description: Vermont provides these monthly optional AABD state supplement rates for an eligible couple. +description: Vermont provides this amount as the optional state supplement for an eligible couple under the Aid to the Aged, Blind or Disabled program. metadata: unit: currency-USD diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml index 1bff6f0851d..454a3eb8e1d 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml @@ -1,4 +1,4 @@ -description: Vermont provides these monthly optional AABD state supplement rates for an eligible individual. +description: Vermont provides this amount as the optional state supplement for an eligible individual under the Aid to the Aged, Blind or Disabled program. metadata: unit: currency-USD diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml deleted file mode 100644 index 2dd865bb9c6..00000000000 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/another_household_maximum.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Vermont uses this amount as its Essential Person payment maximum with an ineligible spouse in another household. -values: - 2026-01-01: 1_049.68 - -metadata: - unit: currency-USD - period: month - label: Vermont Essential Person payment maximum with an ineligible spouse in another household - reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml new file mode 100644 index 00000000000..5a5760564ad --- /dev/null +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml @@ -0,0 +1,14 @@ +description: Vermont provides this amount as the Essential Person increment for an eligible couple under the Aid to the Aged, Blind or Disabled program. +values: + 2025-01-01: 183.84 + 2026-01-01: 183.84 + +metadata: + unit: currency-USD + period: month + label: Vermont Essential Person couple payment increment + reference: + - title: "AABD rule 2784(C) #page 44-45" + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=44 + - title: Bulletin 25-26, P2740B, AABD-EP payment maximums + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf#page=12 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml deleted file mode 100644 index 170320c8100..00000000000 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_maximum.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Vermont uses this amount as its Essential Person independent eligible-couple payment maximum. -values: - 2026-01-01: 1_780.64 - -metadata: - unit: currency-USD - period: month - label: Vermont Essential Person independent eligible-couple payment maximum - reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml index 4493ed07e86..ac961f3ad30 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/employment_expense.yaml @@ -1,4 +1,4 @@ -description: Vermont uses this amount as its Essential Person employment expense deduction per worker. +description: Vermont deducts this amount from each worker's earnings as an Essential Person employment expense under the Aid to the Aged, Blind or Disabled program. values: 2026-01-01: 90 @@ -8,4 +8,4 @@ metadata: label: Vermont Essential Person employment expense deduction per worker reference: - title: AABD rules 2786 interpretive memo - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml deleted file mode 100644 index 98f0653ac9b..00000000000 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/individual_maximum.yaml +++ /dev/null @@ -1,11 +0,0 @@ -description: Vermont uses this amount as its Essential Person independent individual payment maximum. -values: - 2026-01-01: 1_596.8 - -metadata: - unit: currency-USD - period: month - label: Vermont Essential Person independent individual payment maximum - reference: - - title: Bulletin 25-26, P2740B, 2026 payment maximums - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/B25-26.pdf diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml index 3c9e34b890c..00de7ce7524 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/rate.yaml @@ -1,13 +1,14 @@ -description: Vermont sets the Essential Person increment at this fraction for the certified care level. +description: Vermont provides this share of the Essential Person maximum above the combined payment under the Aid to the Aged, Blind or Disabled program. metadata: unit: /1 + period: year label: Vermont Essential Person care fraction breakdown: - vt_aabd_ep_level reference: - title: AABD rules 2784(A) - href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf + href: https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=44 NONE: 2026-01-01: 0 diff --git a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml index ce5a55d689c..0b6c38c50ac 100644 --- a/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml +++ b/policyengine_us/parameters/gov/usda/snap/income/sources/unearned.yaml @@ -36,7 +36,6 @@ values: - hi_oss - id_aabd - in_ssp - - vt_aabd - ks_sspp - ky_ssp - la_oss @@ -50,6 +49,7 @@ values: - nm_ssi_state_supplement - sc_ssi_state_supplement - tx_ssi_state_supplement + - vt_aabd - wa_ssp # Listed elsewhere: ca_state_supplement is an SPM unit variable with no # person-level counterpart. policyengine-core projects a group value onto @@ -96,7 +96,7 @@ values: metadata: reference: - - title: 7 CFR 273.9(b)(2) and (c)(1), (5) + - title: 7 CFR 273.9(b)(2) and (c)(1) href: https://www.law.cornell.edu/cfr/text/7/273.9 - title: POMS SI 01401.001 General Information about State Supplementation href: https://secure.ssa.gov/poms.nsf/lnx/0501401001 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 1c672ca6ac7..d4fb4d11604 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1098,9 +1098,9 @@ programs: parameter_prefix: gov.states.vt.dcf.aabd verified_years: "2026" notes: >- - Models federally administered supplements and Essential Person grants. - Essential Person care, nonspouse budgets and state-only resource eligibility - require certified inputs. Mandatory grandfathered payments are excluded. + Models 2026 federally administered supplements and state Essential Person + grants. Mandatory grandfathered payments and the state-administered + limited-nursing Level III supplement are not modeled. - id: social_security name: Social Security diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml index 0c53bca5951..a7eebe80bd0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml @@ -20,6 +20,7 @@ members: [person1, person2] state_code: VT output: + # Joint couple, no countable income: 105.80 couple rate / 2 = 52.90 each. vt_aabd: [52.9, 52.9] - name: Case 2, residential_care_level_iii couple. @@ -44,6 +45,7 @@ members: [person1, person2] state_code: VT output: + # 103.54 couple rate / 2 = 51.77 each. vt_aabd: [51.77, 51.77] - name: Case 3, residential_care_level_iv couple. @@ -68,6 +70,7 @@ members: [person1, person2] state_code: VT output: + # 601.40 couple rate / 2 = 300.70 each. vt_aabd: [300.7, 300.7] - name: Case 4, custodial_care couple. @@ -92,6 +95,7 @@ members: [person1, person2] state_code: VT output: + # 356.12 couple rate / 2 = 178.06 each. vt_aabd: [178.06, 178.06] - name: Case 5, household_of_another couple. @@ -122,6 +126,7 @@ members: [person1, person2] state_code: VT output: + # 51.69 couple rate / 2 = 25.845, rounded up to the cent = 25.85 each. vt_aabd: [25.85, 25.85] - name: Case 6, medicaid_institution couple. @@ -150,6 +155,8 @@ members: [person1, person2] state_code: VT output: + # Both in the facility, so the couple computation applies: + # 99.85 couple rate / 2 = 49.925, rounded up to the cent = 49.93 each. vt_aabd: [49.93, 49.93] - name: Case 7, annual benefits and SNAP income. @@ -159,8 +166,10 @@ state_code: VT age: 65 output: + # 55.68 independent rate * 12 = 668.16. vt_aabd: 668.16 household_state_benefits: 668.16 + # SSI 994 * 12 = 11,928 + 668.16 = 12,596.16. snap_unearned_income: 12_596.16 - name: Case 8, Essential-person grant enters the annual Vermont benefit total. @@ -172,11 +181,20 @@ vt_aabd_ep_level: 2026: FULL output: + # 994 * 12 = 11,928. ssi: 11_928 + # 55.68 * 12 = 668.16. vt_aabd_federal: 668.16 + # Monthly maximum 1,491 + 105.80 = 1,596.80; countable 994 + 55.68 = 1,049.68; + # floor(1,596.80 - 1,049.68) = floor(547.12) = 547 * 12 = 6,564. vt_aabd_ep: 6_564 + # 668.16 + 6,564 = 7,232.16. vt_aabd: 7_232.16 + # 11,928 + 7,232.16 = 19,160.16. snap_unearned_income: 19_160.16 + # SSI plus the whole AABD payment, including the Essential Person grant: + # 11,928 + 7,232.16 = 19,160.16. + hud_unearned_income: 19_160.16 - name: Case 9, Two eligible spouses share one essential-person grant. period: 2026-01 @@ -197,7 +215,10 @@ members: [person1, person2] state_code: VT output: + # Couple maximum 1,491 + 105.80 + 183.84 = 1,780.64; countable SSI 745.50 * 2 + # + AABD 52.90 * 2 = 1,596.80; floor(183.84) = 183 / 2 = 91.50 each. vt_aabd_ep: [91.5, 91.5] + # 52.90 AABD + 91.50 Essential Person grant = 144.40 each. vt_aabd: [144.4, 144.4] - name: Case 10, Ineligible spouse earnings do not get the ABD half-earnings deduction. @@ -221,10 +242,13 @@ members: [person1, person2] state_code: VT output: + # Spouse earnings 500 - 90 employment expense - 20 general = 390, with no + # half-earnings exclusion, + SSI 994 + AABD 55.68 = 1,439.68. vt_aabd_ep_countable_income: [1_439.68, 1_439.68] + # floor(1,596.80 - 1,439.68) = floor(157.12) = 157 for the recipient only. vt_aabd_ep: [157, 0] -- name: Case 11, Vermont essential care for a disabled member is excluded for HUD. +- name: Case 11, Vermont essential care for a disabled member counts as HUD income. period: 2026 absolute_error_margin: 0.01 input: @@ -234,6 +258,11 @@ is_disabled: true vt_aabd_ep_level: FULL output: + # AABD 55.68 * 12 = 668.16 + Essential Person grant floor(1,596.80 - 1,049.68) + # = 547 * 12 = 6,564; 668.16 + 6,564 = 7,232.16. vt_aabd: 7_232.16 + # SSI 994 * 12 = 11,928 + 7,232.16 = 19,160.16. snap_unearned_income: 19_160.16 - hud_unearned_income: 12_596.16 + # HUD counts the whole AABD payment, including the Essential Person grant: + # 11,928 + 7,232.16 = 19,160.16. + hud_unearned_income: 19_160.16 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml index c7555cc5cc4..05f5f102100 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml @@ -45,11 +45,13 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER ssi_lives_in_another_persons_household: true ssi_receives_shelter_from_others_in_household: true ssi_others_pay_all_meals: true output: + # Federal another person's household maps to HOUSEHOLD_OF_ANOTHER. + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + # No countable income: 42.05 rate - 0 excess over the 662.67 reduced FBR = 42.05. vt_aabd: 42.05 - name: Case 6, medicaid institution individual. @@ -58,10 +60,12 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: MEDICAID_INSTITUTION ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true output: + # Federal Medicaid-paid medical treatment facility maps to MEDICAID_INSTITUTION. + vt_aabd_living_arrangement: MEDICAID_INSTITUTION + # No countable income: 49.93 rate - 0 excess over the $30 facility FBR = 49.93. vt_aabd: 49.93 - name: Case 7, none individual. diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml index 7acbe6ae716..78e13789f58 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml @@ -98,18 +98,40 @@ output: vt_aabd_ep: 596 -- name: Case 9, A certified half-month grant is truncated after proration. +- name: Case 9, A spouse who is not aged, blind or disabled defaults as the essential person in another household. period: 2026-01 absolute_error_margin: 0.01 input: - state_code: VT - age: 70 - ssi: 994 - vt_aabd_federal: 55.68 - vt_aabd_ep_level: FULL - vt_aabd_ep_proration: 0.5 + people: + person1: + age: 70 + vt_aabd_ep_level: FULL + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 60 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT output: - vt_aabd_ep: 273 + # person1 is aged and person2 (60, not blind or disabled) is in the same marital unit. + vt_aabd_ep_is_spouse: [true, false] + vt_aabd_living_arrangement: [HOUSEHOLD_OF_ANOTHER, HOUSEHOLD_OF_ANOTHER] + # No spouse income, so no deeming: 994 * (1 - 1/3) = 662.67 reduced FBR. + ssi: [662.67, 0] + # 42.05 another-household rate - 0 excess = 42.05. + vt_aabd_federal: [42.05, 0] + # Maximum 994 + 55.68 = 1,049.68; countable 662.67 + 42.05 = 704.72; + # floor(1,049.68 - 704.72) = floor(344.96) = 344. + vt_aabd_ep: [344, 0] - name: Case 10, Essential-person coverage does not extend to residential care. period: 2026-01 @@ -157,10 +179,17 @@ input: state_code: VT age: 70 - ssi: 0 - vt_aabd_federal: 0 vt_aabd_ep_level: FULL + # Scaled low earner claiming at 65: $15,238 in 2025 dollars (2025 Trustees + # Report Table V.C7) * 1.028 COLA = about $15,665 a year, $1,305.42 a month. + social_security_retirement: 15_665 output: + # SSI countable 1,305.42 - 20 = 1,285.42 > 994 FBR, so SSI is 0. + ssi: 0 + # 55.68 - (1,285.42 - 994) excess of 291.42 < 0, so no AABD supplement. + vt_aabd_federal: 0 + # No SSI, AABD or reported SSI receipt and no state resource determination. + vt_aabd_ep_resources_eligible: false vt_aabd_ep: 0 - name: Case 14, State-only essential-person grant with verified resources. @@ -169,13 +198,18 @@ input: state_code: VT age: 70 - ssi: 0 - vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - social_security_retirement: 12_000 + # Same scaled low earner Social Security benefit as Case 13: $1,305.42 a month. + social_security_retirement: 15_665 output: - vt_aabd_ep: 616 + # SSI countable 1,285.42 > 994 FBR and 291.42 excess > 55.68 supplement. + ssi: 0 + vt_aabd_federal: 0 + # 1,305.42 - 20 general exclusion = 1,285.42. + vt_aabd_ep_countable_income: 1_285.42 + # Maximum 1,491 + 105.80 = 1,596.80; floor(1,596.80 - 1,285.42) = floor(311.38) = 311. + vt_aabd_ep: 311 - name: Case 15, A worker receives the state employment-expense deduction. period: 2026-01 @@ -183,13 +217,20 @@ input: state_code: VT age: 70 - ssi: 0 - vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - employment_income: 24_000 + # Full time at Vermont's 2026 minimum wage: $14.42 * 2,080 hours = $29,993.60, + # $2,499.47 a month. + employment_income: 29_993.6 output: - vt_aabd_ep: 684 + # SSI countable (2,499.47 - 20 - 65) * 0.5 = 1,207.23 > 994 FBR. + ssi: 0 + # 1,207.23 - 994 = 213.23 excess > 55.68 supplement. + vt_aabd_federal: 0 + # (2,499.47 - 90 employment expense - 20 - 65) * 0.5 = 1,162.23. + vt_aabd_ep_countable_income: 1_162.23 + # floor(1,596.80 - 1,162.23) = floor(434.57) = 434. + vt_aabd_ep: 434 - name: Case 16, Needs-based veterans pension does not get the general exclusion. period: 2026-01 @@ -197,13 +238,20 @@ input: state_code: VT age: 70 - ssi: 0 - vt_aabd_federal: 0 vt_aabd_ep_level: FULL vt_aabd_ep_resources_eligible: true - veterans_benefits: 12_000 + # VA pension MAPR for a veteran with no dependents from December 1, 2025: + # $17,441 a year, $1,453.42 a month, with no other income. + veterans_benefits: 17_441 output: - vt_aabd_ep: 596 + # SSI countable 1,453.42 - 20 = 1,433.42 > 994 FBR. + ssi: 0 + # 1,433.42 - 994 = 439.42 excess > 55.68 supplement. + vt_aabd_federal: 0 + # The needs-based pension counts in full, without the $20 general exclusion. + vt_aabd_ep_countable_income: 1_453.42 + # floor(1,596.80 - 1,453.42) = floor(143.38) = 143. + vt_aabd_ep: 143 - name: Case 17, Out of state. period: 2026-01 diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py index 2c774b4a0c8..5e7612c895b 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py @@ -10,6 +10,7 @@ class vt_aabd(Variable): defined_for = StateCode.VT reference = ( "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m", - "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf", + # PDF pages 27, 36 + "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=27", ) adds = ["vt_aabd_federal", "vt_aabd_ep"] diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py deleted file mode 100644 index 9666d313a83..00000000000 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_countable_for_hud.py +++ /dev/null @@ -1,22 +0,0 @@ -from policyengine_us.model_api import * - - -class vt_aabd_countable_for_hud(Variable): - value_type = float - entity = Person - label = "Vermont AABD countable for HUD" - definition_period = MONTH - unit = USD - reference = ( - "https://www.ecfr.gov/current/title-24/section-5.609", - "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf", - ) - documentation = "Applies 24 CFR 5.609(b)(19) to Essential Person care payments enabling a disabled family member to remain at home. This is an interpretation of the federal exclusion and the certified care purpose in Vermont rule 2781, not an express Vermont HUD instruction. Ordinary aged-person income support remains countable. Override if the housing agency determines a different countable amount or disability status." - - def formula(person, period, parameters): - disabled = person("is_disabled", period.this_year) | person( - "is_blind", period.this_year - ) - return person("vt_aabd_federal", period) + ~disabled * person( - "vt_aabd_ep", period - ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py index bf478505fa9..cbc06e8ccef 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py @@ -7,57 +7,56 @@ class vt_aabd_ep(Variable): label = "Vermont state-administered Essential Person grant" definition_period = MONTH unit = USD - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 36, 44-45, 49-50 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=36" defined_for = StateCode.VT def formula(person, period, parameters): p = parameters(period).gov.states.vt.dcf.aabd + federal = parameters(period).gov.ssa.ssi.amount level = person("vt_aabd_ep_level", period) + levels = level.possible_values arrangement = person("vt_aabd_living_arrangement", period) la = arrangement.possible_values independent = arrangement == la.INDEPENDENT other = arrangement == la.HOUSEHOLD_OF_ANOTHER spouse = person("vt_aabd_ep_is_spouse", period) - abd = person("is_ssi_aged_blind_disabled", period.this_year) - participants = abd & (level != level.possible_values.NONE) - count = person.marital_unit.sum(participants) + valid_level = (level != levels.NONE) & ~(spouse & (level == levels.PARTIAL_34)) + person_eligible = ( + valid_level + & person("is_ssi_aged_blind_disabled", period.this_year) + & (independent | (other & spouse)) + & person("vt_aabd_ep_resources_eligible", period) + & ~person("is_incarcerated", period) + & person("takes_up_ssi_if_eligible", period.this_year) + ) + count = person.marital_unit.sum(person_eligible) couple = count > 1 - federal = parameters(period).gov.ssa.ssi - # Both 2026 geographic schedules have the same amounts. Derive the - # partial levels from rule 2784 and round the standard to cents. + # Rule 2784(B)-(C): the individual maximum is the combined couple + # payment, the another-household maximum is the combined independent + # individual payment, and the couple maximum adds an increment to the + # combined couple payment. Both 2026 geographic schedules have the + # same amounts. + couple_combined = federal.couple + p.amount.couple.INDEPENDENT + individual_combined = federal.individual + p.amount.individual.INDEPENDENT maximum = where( other, - p.ep.another_household_maximum, - where(couple, p.ep.couple_maximum, p.ep.individual_maximum), + individual_combined, + couple_combined + couple * p.ep.couple_increment, ) base = where( couple, - federal.amount.couple + p.amount.couple.INDEPENDENT, + couple_combined, where( other, - federal.amount.individual - * (1 - federal.amount.one_third_reduction_rate) + federal.individual * (1 - federal.one_third_reduction_rate) + p.amount.individual.HOUSEHOLD_OF_ANOTHER, - federal.amount.individual + p.amount.individual.INDEPENDENT, + individual_combined, ), ) + # Derive the partial levels from rule 2784(A) and round to cents. standard = np.round(base + p.ep.rate[level] * (maximum - base), 2) - valid_level = (level != level.possible_values.NONE) & ~( - spouse & (level == level.possible_values.PARTIAL_34) - ) - immigration = person("immigration_status", period.this_year) - immigrant = (immigration == immigration.possible_values.CITIZEN) | person( - "is_ssi_qualified_noncitizen", period.this_year - ) - eligible = ( - valid_level - & abd - & immigrant - & (independent | (other & spouse & ~couple)) - & person("vt_aabd_ep_resources_eligible", period) - & ~person("is_incarcerated", period) - & person("takes_up_ssi_if_eligible", period) - ) amount = max_(standard - person("vt_aabd_ep_countable_income", period), 0) - grant = np.floor(amount * clip(person("vt_aabd_ep_proration", period), 0, 1)) - return eligible * grant / max_(count, 1) + # NOTE: The rule 2784 application-month proration is not modeled. + eligible = person_eligible & (independent | ~couple) + return eligible * np.floor(amount) / max_(count, 1) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py index 50344eb8f2c..a0491978763 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_additional_countable_income.py @@ -7,5 +7,6 @@ class vt_aabd_ep_additional_countable_income(Variable): label = "Vermont Essential Person income outside the marital group" definition_period = MONTH unit = USD - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 48-51 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=48" documentation = "Verified net income of a nonspouse essential person and any parental allocation. Apply the Reach Up exclusions, dependent proration, worker expense allowance and any unused share of the single group general exclusion before entering this amount; do not duplicate the marital group income." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py index 949b88d17d5..da4b434a6e2 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py @@ -7,7 +7,8 @@ class vt_aabd_ep_countable_income(Variable): label = "Vermont Essential Person assistance-group countable income" definition_period = MONTH unit = USD - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 48-51 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=48" documentation = "Whole marital-group income plus the verified net allocation for nonspouse essential persons/parents. Override for Reach Up income sources/exclusions absent from SSI inputs or an agency allocation of the shared general disregard." def formula(person, period, parameters): @@ -17,6 +18,8 @@ def formula(person, period, parameters): earned = max_(person("ssi_earned_income", period) - p.employment_expense, 0) abd_earned = person.marital_unit.sum(earned * abd) other_earned = person.marital_unit.sum(earned * ~abd) + # NOTE: Rule 2786 withholds the $20 exclusion from VA pension only; with + # no pension-specific input, all veterans benefits are treated as pension. veterans = max_(person("veterans_benefits", period), 0) unearned = person.marital_unit.sum( max_(person("ssi_unearned_income", period) - veterans, 0) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py index 96d3db167c3..41f9b420b36 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py @@ -4,6 +4,14 @@ class vt_aabd_ep_is_spouse(Variable): value_type = bool entity = Person - label = "Vermont essential person is an ineligible spouse" + label = "Vermont AABD recipient's Essential Person is an ineligible spouse" definition_period = MONTH - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 38, 44 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=38" + documentation = "Set on the aged, blind or disabled recipient. Defaults to true when the recipient's marital unit includes a spouse who is not aged, blind or disabled; override when a nonspouse is the essential person." + + def formula(person, period, parameters): + abd = person("is_ssi_aged_blind_disabled", period.this_year) + # A marital unit has at most two members, so a non-ABD member of an + # ABD person's marital unit is that person's spouse. + return abd & person.marital_unit.any(~abd) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py index a51f550a2e3..3b4beb03ddb 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py @@ -2,10 +2,10 @@ class VTAABDEssentialPersonLevel(Enum): - NONE = "No certified Essential Person arrangement" FULL = "Certified full Essential Person care level" PARTIAL_67 = "Certified 67 percent Essential Person care level" PARTIAL_34 = "Certified 34 percent Essential Person care level" + NONE = "No certified Essential Person arrangement" class vt_aabd_ep_level(Variable): @@ -15,7 +15,8 @@ class vt_aabd_ep_level(Variable): definition_period = MONTH possible_values = VTAABDEssentialPersonLevel default_value = VTAABDEssentialPersonLevel.NONE - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 38, 40-41, 44 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=38" documentation = """ Certified co-resident essential person under rules 2781-2784: full for an ineligible spouse 55 or older, or required personal care, or seven diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py deleted file mode 100644 index ae64ace17e1..00000000000 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_proration.py +++ /dev/null @@ -1,11 +0,0 @@ -from policyengine_us.model_api import * - - -class vt_aabd_ep_proration(Variable): - value_type = float - entity = Person - label = "Vermont Essential Person certified payment fraction" - definition_period = MONTH - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" - default_value = 1 - documentation = "Agency-certified fraction payable in the application month under rule 2784; a first-working-day application receives the full month." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py index 278aa7a6df2..9bee810060c 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py @@ -6,9 +6,14 @@ class vt_aabd_ep_resources_eligible(Variable): entity = Person label = "Vermont Essential Person resource eligibility" definition_period = MONTH - reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf" + # PDF pages 46-47 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=46" documentation = "SSI/AABD receipt automatically passes the resource test. For state-only applicants, explicitly supply the resource determination under rule 2785, including Reach Up resource exclusions as of August 2024, Medicaid limits, and nonspouse dependent proration." def formula(person, period, parameters): - received = person("ssi", period) + person("vt_aabd_federal", period) - return person.marital_unit.any(received > 0) + receives = ( + (person("ssi", period) > 0) + | person("receives_ssi", period) + | (person("vt_aabd_federal", period) > 0) + ) + return person.marital_unit.any(receives) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py index 2013d56f244..ae9682ce237 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py @@ -8,7 +8,7 @@ class VTAABDLivingArrangement(Enum): INDEPENDENT = "Independent living" HOUSEHOLD_OF_ANOTHER = "Living in another household" RESIDENTIAL_CARE_LEVEL_III = ( - "State-identified Level III residential or assisted living care" + "Level III residential care with assistive community care (PNMI, code C)" ) RESIDENTIAL_CARE_LEVEL_IV = ( "State-identified Level IV residential or therapeutic care" @@ -26,13 +26,21 @@ class vt_aabd_living_arrangement(Variable): defined_for = StateCode.VT possible_values = VTAABDLivingArrangement default_value = VTAABDLivingArrangement.NONE - reference = "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m" + reference = ( + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m", + "https://secure.ssa.gov/poms.nsf/lnx/0501415970BOS", + "https://secure.ssa.gov/poms.nsf/lnx/0501415013BOS", + # PDF pages 28, 31 + "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=28", + ) documentation = """ Defaults follow federal SSI living arrangements. Residential and custodial care require an explicit setting that meets the state's certification and service rules. Independent rates are identical inside and outside Chittenden - County in 2026. Private-insurance-funded institutional children use an - explicit independent arrangement under SI BOS01415.013. + County in 2026. Children under 18 in a facility paid by private health + insurance map to independent living (SI BOS01415.970). The state-administered + Level III residential care home with limited nursing care (rule 2764.2) is + not modeled; SI BOS01415.013 reports that all such homes converted to code C. """ def formula(person, period, parameters): diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py index ad6c9983639..842db47ab99 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py @@ -22,7 +22,7 @@ def formula(spm_unit, period, parameters): "ky_ssp", # Kentucky benefits "de_ssp", # Delaware benefits "fl_oss", - "vt_aabd", + "vt_aabd", # Vermont benefits "ks_sspp", # Kansas benefits "hi_oss", "la_oss", # Louisiana benefits From 61b5d44280315b0468d6b34cb974684c556decd8 Mon Sep 17 00:00:00 2001 From: Ziming Date: Thu, 15 Oct 2026 18:50:48 -0400 Subject: [PATCH 4/4] Address review: Vermont AABD care setting and Essential Person inputs - Enter residential and custodial care through a new vt_aabd_care_setting input, and the nonspouse essential person and state resource test through plain inputs, so formulas no longer reset other household members. - Give an eligible couple one Essential Person grant at the highest level certified for either spouse, and leave a spouse in a facility out of the group income (rule 2782). - Note that a spouse who declines SSI still makes a joint claim (issue 10243), cite 33 V.S.A. ch. 13 and the POMS M.1/M.2 anchors, drop a duplicate parameter value, and add tests. Co-Authored-By: Claude Opus 5.5 --- .../gov/states/vt/dcf/aabd/amount/couple.yaml | 4 +- .../states/vt/dcf/aabd/amount/individual.yaml | 4 +- .../vt/dcf/aabd/ep/couple_increment.yaml | 1 - .../gov/states/vt/dcf/aabd/integration.yaml | 59 +++- .../gov/states/vt/dcf/aabd/vt_aabd.yaml | 64 +++- .../gov/states/vt/dcf/aabd/vt_aabd_ep.yaml | 302 ++++++++++++++++-- .../gov/states/vt/dcf/aabd/vt_aabd.py | 4 +- .../vt/dcf/aabd/vt_aabd_care_setting.py | 28 ++ .../gov/states/vt/dcf/aabd/vt_aabd_ep.py | 17 +- .../dcf/aabd/vt_aabd_ep_countable_income.py | 23 +- .../vt/dcf/aabd/vt_aabd_ep_is_spouse.py | 8 +- .../states/vt/dcf/aabd/vt_aabd_ep_level.py | 6 +- .../vt_aabd_ep_nonspouse_essential_person.py | 13 + .../vt_aabd_ep_passes_state_resource_test.py | 13 + .../dcf/aabd/vt_aabd_ep_resources_eligible.py | 6 +- .../gov/states/vt/dcf/aabd/vt_aabd_federal.py | 3 +- .../vt/dcf/aabd/vt_aabd_living_arrangement.py | 30 +- 17 files changed, 500 insertions(+), 85 deletions(-) create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_care_setting.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_nonspouse_essential_person.py create mode 100644 policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_passes_state_resource_test.py diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml index b2f0cdcc069..2615a7a89f6 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/couple.yaml @@ -7,8 +7,8 @@ metadata: breakdown: - vt_aabd_living_arrangement reference: - - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels - href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + - title: POMS SI 01415.058 M.2.b, Vermont January 2026 couple payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m2b INDEPENDENT: 2026-01-01: 105.8 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml index 454a3eb8e1d..7db6c2a8d35 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/amount/individual.yaml @@ -7,8 +7,8 @@ metadata: breakdown: - vt_aabd_living_arrangement reference: - - title: POMS SI 01415.058 M.2, Vermont January 2026 payment levels - href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m + - title: POMS SI 01415.058 M.2.a, Vermont January 2026 recipient payment levels + href: https://secure.ssa.gov/poms.nsf/lnx/0501415058#m2a INDEPENDENT: 2026-01-01: 55.68 diff --git a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml index 5a5760564ad..8233aa93215 100644 --- a/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml +++ b/policyengine_us/parameters/gov/states/vt/dcf/aabd/ep/couple_increment.yaml @@ -1,7 +1,6 @@ description: Vermont provides this amount as the Essential Person increment for an eligible couple under the Aid to the Aged, Blind or Disabled program. values: 2025-01-01: 183.84 - 2026-01-01: 183.84 metadata: unit: currency-USD diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml index a7eebe80bd0..3821c74ea92 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/integration.yaml @@ -5,10 +5,8 @@ people: person1: age: 65 - vt_aabd_living_arrangement: INDEPENDENT person2: age: 65 - vt_aabd_living_arrangement: INDEPENDENT marital_units: couple: members: [person1, person2] @@ -30,10 +28,10 @@ people: person1: age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_III person2: age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_III marital_units: couple: members: [person1, person2] @@ -55,10 +53,10 @@ people: person1: age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_IV person2: age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_IV marital_units: couple: members: [person1, person2] @@ -80,10 +78,10 @@ people: person1: age: 65 - vt_aabd_living_arrangement: CUSTODIAL_CARE + vt_aabd_care_setting: CUSTODIAL_CARE person2: age: 65 - vt_aabd_living_arrangement: CUSTODIAL_CARE + vt_aabd_care_setting: CUSTODIAL_CARE marital_units: couple: members: [person1, person2] @@ -105,13 +103,11 @@ people: person1: age: 65 - vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER ssi_lives_in_another_persons_household: true ssi_receives_shelter_from_others_in_household: true ssi_others_pay_all_meals: true person2: age: 65 - vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER ssi_lives_in_another_persons_household: true ssi_receives_shelter_from_others_in_household: true ssi_others_pay_all_meals: true @@ -136,12 +132,10 @@ people: person1: age: 65 - vt_aabd_living_arrangement: MEDICAID_INSTITUTION ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true person2: age: 65 - vt_aabd_living_arrangement: MEDICAID_INSTITUTION ssi_lives_in_medical_treatment_facility: true ssi_medicaid_pays_majority_of_care: true marital_units: @@ -165,12 +159,16 @@ input: state_code: VT age: 65 + # SNAP take-up off so spm_unit_benefits does not rest on projected SNAP amounts. + takes_up_snap_if_eligible: false output: # 55.68 independent rate * 12 = 668.16. vt_aabd: 668.16 household_state_benefits: 668.16 # SSI 994 * 12 = 11,928 + 668.16 = 12,596.16. snap_unearned_income: 12_596.16 + # SSI 11,928 + vt_aabd 668.16; SNAP is 0 without take-up. + spm_unit_benefits: 12_596.16 - name: Case 8, Essential-person grant enters the annual Vermont benefit total. period: 2026 @@ -229,8 +227,6 @@ person1: age: 70 vt_aabd_ep_level: FULL - vt_aabd_ep_is_spouse: true - vt_aabd_ep_resources_eligible: true person2: age: 40 employment_income: 6_000 @@ -242,6 +238,10 @@ members: [person1, person2] state_code: VT output: + # person2 (40, not blind or disabled) is the ineligible spouse. + vt_aabd_ep_is_spouse: [true, false] + # SSI receipt passes the resource test for the group. + vt_aabd_ep_resources_eligible: [true, true] # Spouse earnings 500 - 90 employment expense - 20 general = 390, with no # half-earnings exclusion, + SSI 994 + AABD 55.68 = 1,439.68. vt_aabd_ep_countable_income: [1_439.68, 1_439.68] @@ -266,3 +266,34 @@ # HUD counts the whole AABD payment, including the Essential Person grant: # 11,928 + 7,232.16 = 19,160.16. hud_unearned_income: 19_160.16 + +- name: Case 12, One spouse in a Medicaid facility is paid as an individual. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + tax_units: + unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: VT + output: + vt_aabd_living_arrangement: [MEDICAID_INSTITUTION, INDEPENDENT] + # 20 CFR 416.414(b)(3): each spouse is paid at an individual rate. + ssi_couple_computation_applies: [false, false] + # $30 facility rate and the 994 individual FBR. + ssi_amount_if_eligible: [30, 994] + ssi: [30, 994] + # POMS SI 01415.058 M.2.a individual rates: code I 49.93, code A 55.68. + vt_aabd: [49.93, 55.68] diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml index 05f5f102100..9e216d7a7e0 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd.yaml @@ -5,8 +5,8 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: INDEPENDENT output: + vt_aabd_living_arrangement: INDEPENDENT vt_aabd: 55.68 - name: Case 2, residential care level iii individual. @@ -15,7 +15,7 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_III output: vt_aabd: 51.77 @@ -25,7 +25,7 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_IV + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_IV output: vt_aabd: 239.62 @@ -35,7 +35,7 @@ input: state_code: VT age: 65 - vt_aabd_living_arrangement: CUSTODIAL_CARE + vt_aabd_care_setting: CUSTODIAL_CARE output: vt_aabd: 105.6 @@ -68,23 +68,29 @@ # No countable income: 49.93 rate - 0 excess over the $30 facility FBR = 49.93. vt_aabd: 49.93 -- name: Case 7, none individual. +- name: Case 7, a recipient who declines SSI gets no supplement. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT age: 65 - vt_aabd_living_arrangement: NONE + takes_up_ssi_if_eligible: false output: + # 33 V.S.A. § 1301(3) requires SSI receipt if eligible. + ssi: 0 vt_aabd: 0 -- name: Case 8, automatic independent classification. +- name: Case 8, Chittenden County independent living uses the same rate as the rest of the state. period: 2026-01 absolute_error_margin: 0.01 input: state_code: VT + county: CHITTENDEN_COUNTY_VT age: 65 output: + # POMS SI 01415.058 M.2.a: OS code B (Chittenden County) and code A both + # pay 55.68. + vt_aabd_living_arrangement: INDEPENDENT vt_aabd: 55.68 - name: Case 9, income above federal SSI standard. @@ -144,3 +150,47 @@ age: 65 output: vt_aabd: 0 + +- name: Case 15, a care setting for one of two unrelated people leaves the other independent. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_care_setting: CUSTODIAL_CARE + person2: + age: 70 + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: VT + output: + vt_aabd_living_arrangement: [CUSTODIAL_CARE, INDEPENDENT] + # Individual rates with no income: 105.60 custodial care and 55.68 independent. + vt_aabd: [105.6, 55.68] + +- name: Case 16, a Title XIX facility precedes a care setting. + period: 2026-01 + absolute_error_margin: 0.01 + input: + state_code: VT + age: 65 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_III + output: + # POMS SI 01415.058 M.2.a uses code I with federal arrangement D. + vt_aabd_living_arrangement: MEDICAID_INSTITUTION + # 49.93 rate - 0 excess over the $30 facility FBR = 49.93. + vt_aabd: 49.93 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml index 78e13789f58..5c26b2057e4 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/dcf/aabd/vt_aabd_ep.yaml @@ -50,14 +50,27 @@ period: 2026-01 absolute_error_margin: 0.01 input: - state_code: VT - age: 70 - ssi: 994 - vt_aabd_federal: 55.68 - vt_aabd_ep_level: PARTIAL_34 - vt_aabd_ep_is_spouse: true + people: + person1: + age: 70 + vt_aabd_ep_level: PARTIAL_34 + person2: + age: 60 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT output: - vt_aabd_ep: 0 + # person2 (60, not blind or disabled) is the ineligible spouse. + vt_aabd_ep_is_spouse: [true, false] + # No spouse income, so no deeming. + ssi: [994, 0] + vt_aabd_federal: [55.68, 0] + # Rule 2784(A)(3) pays the 34 percent level only for a nonspouse. + vt_aabd_ep: [0, 0] - name: Case 6, Prorated nonspouse essential-person net income counts. period: 2026-01 @@ -81,22 +94,43 @@ ssi: 994 vt_aabd_federal: 55.68 vt_aabd_ep_level: FULL - vt_aabd_ep_countable_income: 1_596.8 + vt_aabd_ep_additional_countable_income: 547.12 output: + # SSI 994 + AABD 55.68 + 547.12 additional = 1,596.80, the payment maximum. + vt_aabd_ep_countable_income: 1_596.8 vt_aabd_ep: 0 -- name: Case 8, Countable-income override applies to specialized dependent allocations. +- name: Case 8, Additional countable income for one of two unrelated recipients stays with that recipient. period: 2026-01 absolute_error_margin: 0.01 input: - state_code: VT - age: 70 - ssi: 994 - vt_aabd_federal: 55.68 - vt_aabd_ep_level: FULL - vt_aabd_ep_countable_income: 1_000 + people: + person1: + age: 70 + vt_aabd_ep_level: FULL + vt_aabd_ep_additional_countable_income: 100 + person2: + age: 70 + vt_aabd_ep_level: FULL + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: VT output: - vt_aabd_ep: 596 + # SSI 994 + AABD 55.68 = 1,049.68, plus 100 additional for person1 only. + vt_aabd_ep_countable_income: [1_149.68, 1_049.68] + # floor(1,596.80 - 1,149.68) = 447; floor(1,596.80 - 1,049.68) = 547. + vt_aabd_ep: [447, 547] - name: Case 9, A spouse who is not aged, blind or disabled defaults as the essential person in another household. period: 2026-01 @@ -139,11 +173,11 @@ input: state_code: VT age: 70 - ssi: 994 - vt_aabd_federal: 55.68 vt_aabd_ep_level: FULL - vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + vt_aabd_care_setting: RESIDENTIAL_CARE_LEVEL_III output: + vt_aabd_living_arrangement: RESIDENTIAL_CARE_LEVEL_III + vt_aabd_federal: 51.77 vt_aabd_ep: 0 - name: Case 11, Nonspouse essential person cannot qualify in another household. @@ -152,26 +186,48 @@ input: state_code: VT age: 70 - ssi: 994 - vt_aabd_federal: 55.68 vt_aabd_ep_level: FULL - vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true output: + vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER + # 994 * (1 - 1/3) = 662.67 reduced FBR. + ssi: 662.67 + vt_aabd_federal: 42.05 + # Rule 2783.2 excludes a nonspouse essential person in another's household. vt_aabd_ep: 0 -- name: Case 12, Ineligible spouse qualifies in another household. +- name: Case 12, Ineligible spouse qualifies at 67 percent in another household. period: 2026-01 absolute_error_margin: 0.01 input: - state_code: VT - age: 70 - ssi: 662.67 - vt_aabd_federal: 42.05 - vt_aabd_ep_level: FULL - vt_aabd_living_arrangement: HOUSEHOLD_OF_ANOTHER - vt_aabd_ep_is_spouse: true + people: + person1: + age: 70 + vt_aabd_ep_level: PARTIAL_67 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person2: + age: 50 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT output: - vt_aabd_ep: 344 + vt_aabd_ep_is_spouse: [true, false] + ssi: [662.67, 0] + vt_aabd_federal: [42.05, 0] + # P2740B 67 percent another's-household maximum 935.84; + # floor(935.84 - (662.67 + 42.05)) = floor(231.12) = 231. + vt_aabd_ep: [231, 0] - name: Case 13, Non-SSI recipient requires verified resource eligibility. period: 2026-01 @@ -199,13 +255,14 @@ state_code: VT age: 70 vt_aabd_ep_level: FULL - vt_aabd_ep_resources_eligible: true + vt_aabd_ep_passes_state_resource_test: true # Same scaled low earner Social Security benefit as Case 13: $1,305.42 a month. social_security_retirement: 15_665 output: # SSI countable 1,285.42 > 994 FBR and 291.42 excess > 55.68 supplement. ssi: 0 vt_aabd_federal: 0 + vt_aabd_ep_resources_eligible: true # 1,305.42 - 20 general exclusion = 1,285.42. vt_aabd_ep_countable_income: 1_285.42 # Maximum 1,491 + 105.80 = 1,596.80; floor(1,596.80 - 1,285.42) = floor(311.38) = 311. @@ -218,7 +275,7 @@ state_code: VT age: 70 vt_aabd_ep_level: FULL - vt_aabd_ep_resources_eligible: true + vt_aabd_ep_passes_state_resource_test: true # Full time at Vermont's 2026 minimum wage: $14.42 * 2,080 hours = $29,993.60, # $2,499.47 a month. employment_income: 29_993.6 @@ -239,7 +296,7 @@ state_code: VT age: 70 vt_aabd_ep_level: FULL - vt_aabd_ep_resources_eligible: true + vt_aabd_ep_passes_state_resource_test: true # VA pension MAPR for a veteran with no dependents from December 1, 2025: # $17,441 a year, $1,453.42 a month, with no other income. veterans_benefits: 17_441 @@ -264,3 +321,180 @@ vt_aabd_ep_level: FULL output: vt_aabd_ep: 0 + +- name: Case 18, A nonspouse essential person qualifies at 34 percent next to an ineligible spouse. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_ep_level: PARTIAL_34 + vt_aabd_ep_nonspouse_essential_person: true + person2: + age: 45 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT + output: + # The certified essential person is not the spouse (rules 2781(E), 2782). + vt_aabd_ep_is_spouse: [false, false] + # SSI 994 + AABD 55.68; the spouse has no income. + vt_aabd_ep_countable_income: [1_049.68, 1_049.68] + # 1,049.68 + 0.34 * (1,596.80 - 1,049.68) = 1,235.70; + # floor(1,235.70 - 1,049.68) = floor(186.02) = 186. + vt_aabd_ep: [186, 0] + # 55.68 AABD + 186 Essential Person grant = 241.68. + vt_aabd: [241.68, 0] + +- name: Case 19, A state resource determination for one of two unrelated recipients stays with that recipient. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_ep_level: FULL + vt_aabd_ep_passes_state_resource_test: true + # Same scaled low earner Social Security benefit as Case 13: $1,305.42 a month. + social_security_retirement: 15_665 + person2: + age: 70 + vt_aabd_ep_level: FULL + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2] + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2] + households: + household: + members: [person1, person2] + state_code: VT + output: + # person1 passes the state test; person2 receives SSI. + vt_aabd_ep_resources_eligible: [true, true] + # floor(1,596.80 - 1,285.42) = 311; floor(1,596.80 - 1,049.68) = 547. + vt_aabd_ep: [311, 547] + # person2: 55.68 AABD + 547 = 602.68. + vt_aabd: [311, 602.68] + +- name: Case 20, A nonspouse flag on one recipient leaves another recipient's spouse as the essential person. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_ep_nonspouse_essential_person: true + person2: + age: 70 + vt_aabd_ep_level: FULL + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + person3: + age: 60 + ssi_lives_in_another_persons_household: true + ssi_receives_shelter_from_others_in_household: true + ssi_others_pay_all_meals: true + marital_units: + marital_unit1: + members: [person1] + marital_unit2: + members: [person2, person3] + tax_units: + tax_unit1: + members: [person1] + tax_unit2: + members: [person2, person3] + households: + household: + members: [person1, person2, person3] + state_code: VT + output: + vt_aabd_ep_is_spouse: [false, true, false] + # person2: floor(1,049.68 - (662.67 + 42.05)) = floor(344.96) = 344. + vt_aabd_ep: [0, 344, 0] + # person1: 55.68 independent rate; person2: 42.05 + 344 = 386.05. + vt_aabd: [55.68, 386.05, 0] + +- name: Case 21, One certified essential person for an eligible couple uses the couple maximum. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_ep_level: FULL + person2: + age: 70 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT + output: + # Rules 2780(A), 2783.1 and 2784(C): one grant for the couple. + # Couple maximum 1,491 + 105.80 + 183.84 = 1,780.64; countable SSI 745.50 * 2 + # + AABD 52.90 * 2 = 1,596.80; floor(183.84) = 183 / 2 = 91.50 each. + vt_aabd_ep: [91.5, 91.5] + +- name: Case 22, An eligible couple certified at different levels uses the higher 67 percent couple level. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + vt_aabd_ep_level: PARTIAL_67 + person2: + age: 70 + vt_aabd_ep_level: PARTIAL_34 + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT + output: + # P2740B 67 percent couple maximum 1,719.97; countable SSI 745.50 * 2 + # + AABD 52.90 * 2 = 1,596.80; floor(123.17) = 123 / 2 = 61.50 each. + vt_aabd_ep: [61.5, 61.5] + +- name: Case 23, A spouse in a Medicaid facility is left out of the at-home spouse's group income. + period: 2026-01 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 70 + ssi_lives_in_medical_treatment_facility: true + ssi_medicaid_pays_majority_of_care: true + social_security_retirement: 15_665 + person2: + age: 70 + vt_aabd_ep_level: FULL + marital_units: + couple: + members: [person1, person2] + households: + home: + members: [person1, person2] + state_code: VT + output: + # Rule 2782: only household members count; the at-home spouse has SSI + # 994 + AABD 55.68 = 1,049.68 against the 1,596.80 individual maximum. + vt_aabd_ep_countable_income: [1_049.68, 1_049.68] + vt_aabd_ep: [0, 547] diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py index 5e7612c895b..0e0494c54cd 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd.py @@ -9,7 +9,9 @@ class vt_aabd(Variable): unit = USD defined_for = StateCode.VT reference = ( - "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m", + # 33 V.S.A. §§ 1301(3), 1309(a) + "https://legislature.vermont.gov/statutes/fullchapter/33/013", + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m2", # PDF pages 27, 36 "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=27", ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_care_setting.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_care_setting.py new file mode 100644 index 00000000000..5b68c7f78d9 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_care_setting.py @@ -0,0 +1,28 @@ +from policyengine_us.model_api import * + + +class VTAABDCareSetting(Enum): + RESIDENTIAL_CARE_LEVEL_III = ( + "Level III residential care home with assistive community care (code C)" + ) + RESIDENTIAL_CARE_LEVEL_IV = ( + "Level IV residential care home or therapeutic community residence (code G)" + ) + CUSTODIAL_CARE = "Custodial care family home (code H)" + NONE = "No state-identified care setting" + + +class vt_aabd_care_setting(Variable): + value_type = Enum + entity = Person + label = "Vermont AABD care setting" + definition_period = MONTH + defined_for = StateCode.VT + possible_values = VTAABDCareSetting + default_value = VTAABDCareSetting.NONE + reference = ( + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m1", + # PDF pages 31-33 + "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=31", + ) + documentation = "Residence in a care setting that meets the state's licensing, certification and service rules (rules 2764.1, 2764.3 and 2766)." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py index cbc06e8ccef..b22032e9017 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep.py @@ -7,7 +7,7 @@ class vt_aabd_ep(Variable): label = "Vermont state-administered Essential Person grant" definition_period = MONTH unit = USD - # PDF pages 36, 44-45, 49-50 + # PDF pages 36, 43-45, 49-50 reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=36" defined_for = StateCode.VT @@ -22,14 +22,21 @@ def formula(person, period, parameters): other = arrangement == la.HOUSEHOLD_OF_ANOTHER spouse = person("vt_aabd_ep_is_spouse", period) valid_level = (level != levels.NONE) & ~(spouse & (level == levels.PARTIAL_34)) - person_eligible = ( - valid_level - & person("is_ssi_aged_blind_disabled", period.this_year) + # vt_aabd_ep_resources_eligible already tests the whole marital unit. + abd_eligible = ( + person("is_ssi_aged_blind_disabled", period.this_year) & (independent | (other & spouse)) & person("vt_aabd_ep_resources_eligible", period) & ~person("is_incarcerated", period) & person("takes_up_ssi_if_eligible", period.this_year) ) + # Rules 2780(A), 2783.1 and 2784(C): an eligible couple receives one + # grant for a shared essential person. The rules do not address + # different levels for each spouse; use the highest level certified for + # either spouse. + certified = abd_eligible & valid_level + person_eligible = abd_eligible & person.marital_unit.any(certified) + rate = person.marital_unit.max(where(certified, p.ep.rate[level], 0)) count = person.marital_unit.sum(person_eligible) couple = count > 1 # Rule 2784(B)-(C): the individual maximum is the combined couple @@ -55,7 +62,7 @@ def formula(person, period, parameters): ), ) # Derive the partial levels from rule 2784(A) and round to cents. - standard = np.round(base + p.ep.rate[level] * (maximum - base), 2) + standard = np.round(base + rate * (maximum - base), 2) amount = max_(standard - person("vt_aabd_ep_countable_income", period), 0) # NOTE: The rule 2784 application-month proration is not modeled. eligible = person_eligible & (independent | ~couple) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py index da4b434a6e2..32ddf63a374 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_countable_income.py @@ -9,20 +9,34 @@ class vt_aabd_ep_countable_income(Variable): unit = USD # PDF pages 48-51 reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=48" - documentation = "Whole marital-group income plus the verified net allocation for nonspouse essential persons/parents. Override for Reach Up income sources/exclusions absent from SSI inputs or an agency allocation of the shared general disregard." + documentation = """ + Income of the marital unit's household members under rule 2786 plus + vt_aabd_ep_additional_countable_income. + NOTE: Reach Up income sources or exclusions without an SSI input are not + modeled. + """ def formula(person, period, parameters): p = parameters(period).gov.states.vt.dcf.aabd.ep exclusions = parameters(period).gov.ssa.ssi.income.exclusions abd = person("is_ssi_aged_blind_disabled", period.this_year) - earned = max_(person("ssi_earned_income", period) - p.employment_expense, 0) + arrangement = person("vt_aabd_living_arrangement", period) + la = arrangement.possible_values + # Rule 2782: the group includes only members living in the same + # household, so a spouse in a facility is left out. + in_household = (arrangement == la.INDEPENDENT) | ( + arrangement == la.HOUSEHOLD_OF_ANOTHER + ) + earned = in_household * max_( + person("ssi_earned_income", period) - p.employment_expense, 0 + ) abd_earned = person.marital_unit.sum(earned * abd) other_earned = person.marital_unit.sum(earned * ~abd) # NOTE: Rule 2786 withholds the $20 exclusion from VA pension only; with # no pension-specific input, all veterans benefits are treated as pension. veterans = max_(person("veterans_benefits", period), 0) unearned = person.marital_unit.sum( - max_(person("ssi_unearned_income", period) - veterans, 0) + in_household * max_(person("ssi_unearned_income", period) - veterans, 0) ) general = exclusions.general remaining_general = max_(general - unearned, 0) @@ -35,7 +49,8 @@ def formula(person, period, parameters): 1 - exclusions.earned_share ) needs_based = person.marital_unit.sum( - veterans + person("ssi", period) + person("vt_aabd_federal", period) + in_household + * (veterans + person("ssi", period) + person("vt_aabd_federal", period)) ) additional = person.marital_unit.max( max_(person("vt_aabd_ep_additional_countable_income", period), 0) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py index 41f9b420b36..c9ea361fbc5 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_is_spouse.py @@ -8,10 +8,14 @@ class vt_aabd_ep_is_spouse(Variable): definition_period = MONTH # PDF pages 38, 44 reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=38" - documentation = "Set on the aged, blind or disabled recipient. Defaults to true when the recipient's marital unit includes a spouse who is not aged, blind or disabled; override when a nonspouse is the essential person." + documentation = "True for an aged, blind or disabled recipient whose marital unit includes a spouse who is not aged, blind or disabled, unless vt_aabd_ep_nonspouse_essential_person is set." def formula(person, period, parameters): abd = person("is_ssi_aged_blind_disabled", period.this_year) # A marital unit has at most two members, so a non-ABD member of an # ABD person's marital unit is that person's spouse. - return abd & person.marital_unit.any(~abd) + return ( + abd + & person.marital_unit.any(~abd) + & ~person("vt_aabd_ep_nonspouse_essential_person", period) + ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py index 3b4beb03ddb..02a5e86c2b1 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_level.py @@ -23,6 +23,8 @@ class vt_aabd_ep_level(Variable): homemaker services; 67 percent for a younger spouse unable to work who provides qualifying care, or a nonspouse providing four to six services; 34 percent for a nonspouse providing one to three services. Certification - includes benefit pursuit and care preventing institutionalization. Set - both eligible spouses to the same level for a shared nonspouse caregiver. + includes benefit pursuit and care preventing institutionalization. Set it + on the aged, blind or disabled recipient, not on the essential person; for + an eligible couple, set it on either spouse and the couple's grant uses the + highest level set on either spouse. """ diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_nonspouse_essential_person.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_nonspouse_essential_person.py new file mode 100644 index 00000000000..f5e5a229a02 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_nonspouse_essential_person.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_nonspouse_essential_person(Variable): + value_type = bool + entity = Person + label = "Vermont AABD recipient's certified Essential Person is not the spouse" + definition_period = MONTH + defined_for = StateCode.VT + default_value = False + # PDF pages 38, 40, 42 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=38" + documentation = "Set on the aged, blind or disabled recipient whose ineligible spouse lives with them but is not the certified essential person (rule 2781(E)); rule 2782 allows both in one assistance group." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_passes_state_resource_test.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_passes_state_resource_test.py new file mode 100644 index 00000000000..e8dd64f7ea0 --- /dev/null +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_passes_state_resource_test.py @@ -0,0 +1,13 @@ +from policyengine_us.model_api import * + + +class vt_aabd_ep_passes_state_resource_test(Variable): + value_type = bool + entity = Person + label = "Vermont Essential Person state resource test passed" + definition_period = MONTH + defined_for = StateCode.VT + default_value = False + # PDF pages 46-48 + reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=46" + documentation = "Resource determination for state-only applicants under rule 2785, including Reach Up resource exclusions as of August 2024, Medicaid limits, and nonspouse dependent proration. SSI/AABD receipt passes the resource test without this input." diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py index 9bee810060c..99b4d2bb810 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_ep_resources_eligible.py @@ -8,7 +8,7 @@ class vt_aabd_ep_resources_eligible(Variable): definition_period = MONTH # PDF pages 46-47 reference = "https://outside.vermont.gov/dept/DCF/Shared%20Documents/ESD/Rules/2700-AABD.pdf#page=46" - documentation = "SSI/AABD receipt automatically passes the resource test. For state-only applicants, explicitly supply the resource determination under rule 2785, including Reach Up resource exclusions as of August 2024, Medicaid limits, and nonspouse dependent proration." + documentation = "SSI/AABD receipt automatically passes the resource test; otherwise the group passes through vt_aabd_ep_passes_state_resource_test." def formula(person, period, parameters): receives = ( @@ -16,4 +16,6 @@ def formula(person, period, parameters): | person("receives_ssi", period) | (person("vt_aabd_federal", period) > 0) ) - return person.marital_unit.any(receives) + passes_state_test = person("vt_aabd_ep_passes_state_resource_test", period) + # Rule 2785 tests the assistance group's combined resources once. + return person.marital_unit.any(receives | passes_state_test) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py index 3b0a6b7b197..7d450b5f1df 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_federal.py @@ -11,11 +11,12 @@ class vt_aabd_federal(Variable): definition_period = MONTH unit = USD defined_for = StateCode.VT - reference = "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m" + reference = "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m2" def formula(person, period, parameters): p = parameters(period).gov.states.vt.dcf.aabd.amount arrangement = person("vt_aabd_living_arrangement", period) + # NOTE: A spouse who declines SSI still makes a joint claim (issue 10243). return ssi_state_supplement( person, period, parameters, p.individual[arrangement], p.couple[arrangement] ) diff --git a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py index ae9682ce237..5b63538d64f 100644 --- a/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py +++ b/policyengine_us/variables/gov/states/vt/dcf/aabd/vt_aabd_living_arrangement.py @@ -15,7 +15,7 @@ class VTAABDLivingArrangement(Enum): ) CUSTODIAL_CARE = "Qualifying custodial family home" MEDICAID_INSTITUTION = "Title XIX medical institution" - NONE = "Supplement waived or no qualifying arrangement" + NONE = "No supplement" class vt_aabd_living_arrangement(Variable): @@ -27,7 +27,7 @@ class vt_aabd_living_arrangement(Variable): possible_values = VTAABDLivingArrangement default_value = VTAABDLivingArrangement.NONE reference = ( - "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m", + "https://secure.ssa.gov/poms.nsf/lnx/0501415058#m1", "https://secure.ssa.gov/poms.nsf/lnx/0501415970BOS", "https://secure.ssa.gov/poms.nsf/lnx/0501415013BOS", # PDF pages 28, 31 @@ -35,23 +35,37 @@ class vt_aabd_living_arrangement(Variable): ) documentation = """ Defaults follow federal SSI living arrangements. Residential and custodial - care require an explicit setting that meets the state's certification and - service rules. Independent rates are identical inside and outside Chittenden - County in 2026. Children under 18 in a facility paid by private health - insurance map to independent living (SI BOS01415.970). The state-administered - Level III residential care home with limited nursing care (rule 2764.2) is - not modeled; SI BOS01415.013 reports that all such homes converted to code C. + care settings come from vt_aabd_care_setting; those residents are in + federal arrangement A, so do not also set the household-of-another SSI + inputs for them. Independent rates are identical inside and outside + Chittenden County in 2026. Children under 18 in a facility paid by private + health insurance map to independent living (SI BOS01415.970). The + state-administered Level III residential care home with limited nursing + care (rule 2764.2) is not modeled; SI BOS01415.013 reports that all such + homes converted to code C. + NOTE: OS code Y (optional supplementation waived) records a recipient's + choice and is not modeled. """ def formula(person, period, parameters): federal = person("ssi_federal_living_arrangement", period) + setting = person("vt_aabd_care_setting", period) + settings = setting.possible_values + # POMS SI 01415.058 M.2.a pairs codes C, G and H only with federal + # arrangement A, and code I only with federal arrangement D. return select( [ federal == SSIFederalLivingArrangement.MEDICAL_TREATMENT_FACILITY, + setting == settings.RESIDENTIAL_CARE_LEVEL_III, + setting == settings.RESIDENTIAL_CARE_LEVEL_IV, + setting == settings.CUSTODIAL_CARE, federal == SSIFederalLivingArrangement.ANOTHER_PERSONS_HOUSEHOLD, ], [ VTAABDLivingArrangement.MEDICAID_INSTITUTION, + VTAABDLivingArrangement.RESIDENTIAL_CARE_LEVEL_III, + VTAABDLivingArrangement.RESIDENTIAL_CARE_LEVEL_IV, + VTAABDLivingArrangement.CUSTODIAL_CARE, VTAABDLivingArrangement.HOUSEHOLD_OF_ANOTHER, ], default=VTAABDLivingArrangement.INDEPENDENT,