From 1428a05c2ac9f1425496f83b426b4a0336938a0d Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Tue, 10 Mar 2026 16:43:47 -0400 Subject: [PATCH 1/6] Moving disabled veteran for HR1 to own variable --- .../veteran_disability_minimum.yaml | 14 ++++++++++ .../is_disabled_veteran.yaml | 26 +++++++++++++++++++ .../work_requirements/is_disabled_veteran.py | 20 ++++++++++++++ .../person/veteran_disability_rating.py | 11 ++++++++ 4 files changed, 71 insertions(+) create mode 100644 policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py create mode 100644 policyengine_us/variables/household/demographic/person/veteran_disability_rating.py diff --git a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml new file mode 100644 index 00000000000..cdb428cddef --- /dev/null +++ b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml @@ -0,0 +1,14 @@ +description: The Department of Health and Human Services exempts Medicaid work requirement for veterans with an overall disability rating of 100 + +values: + 2027-01-01: 100 + +metadata: + unit: year + label: Veteran Disability Rating Minimum + period: year + reference: + - title: H.R.1 - One Big Beautiful Bill Act + href: https://www.congress.gov/bill/119th-congress/house-bill/1/text + - title: 38 U.S. Code ยง 1155 - Authority for schedule for rating disabilities + href: https://www.law.cornell.edu/uscode/text/38/1155 diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml new file mode 100644 index 00000000000..5b68ff3195f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml @@ -0,0 +1,26 @@ +- name: Return false if is_veteran is not set + period: 2027 + input: + is_veteran: false + veteran_disability_rating: 100 + output: + is_disabled_veteran: false + + +- name: Return false if veteran_disability_rating < 100 + period: 2027 + input: + is_veteran: true + veteran_disability_rating: 90 + output: + is_disabled_veteran: false + + +- name: Return true if veteran and veteran_disability_rating >= 100 + period: 2027 + input: + is_veteran: true + veteran_disability_rating: 100 + output: + is_disabled_veteran: true + diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py new file mode 100644 index 00000000000..57fc4840321 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class is_disabled_veteran(Variable): + value_type = bool + entity = Person + label = "Eligible for Medicaid CE exemption for disabled veterans" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters): + vet_disability_minimum: int = parameters(period).gov.hhs.medicaid.eligibility.work_requirements.veteran_disability_minimum + + is_veteran = person("is_veteran", period) + veteran_disability_rating = person( + "veteran_disability_rating", period + ) + + return is_veteran and veteran_disability_rating >= vet_disability_minimum + diff --git a/policyengine_us/variables/household/demographic/person/veteran_disability_rating.py b/policyengine_us/variables/household/demographic/person/veteran_disability_rating.py new file mode 100644 index 00000000000..6c1b39857e4 --- /dev/null +++ b/policyengine_us/variables/household/demographic/person/veteran_disability_rating.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class veteran_disability_rating(Variable): + value_type = int + entity = Person + label = "The overall veteran disability rating for the individual" + definition_period = YEAR + default_value = 0 + reference = "https://www.law.cornell.edu/uscode/text/38/1155" + From 1e715e7bd0f087c08a5dcbf291ee91f3bfe0b044 Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Tue, 10 Mar 2026 16:57:02 -0400 Subject: [PATCH 2/6] Renaming to totally_disabled_veteran --- ...y_minimum.yaml => total_veteran_disability_minimum.yaml} | 0 ...sabled_veteran.yaml => is_totally_disabled_veteran.yaml} | 6 +++--- ...s_disabled_veteran.py => is_totally_disabled_veteran.py} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/{veteran_disability_minimum.yaml => total_veteran_disability_minimum.yaml} (100%) rename policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/{is_disabled_veteran.yaml => is_totally_disabled_veteran.yaml} (79%) rename policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/{is_disabled_veteran.py => is_totally_disabled_veteran.py} (84%) diff --git a/policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml b/policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/total_veteran_disability_minimum.yaml similarity index 100% rename from policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/veteran_disability_minimum.yaml rename to policyengine_us/parameters/gov/hhs/medicaid/eligibility/work_requirements/total_veteran_disability_minimum.yaml diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.yaml similarity index 79% rename from policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml rename to policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.yaml index 5b68ff3195f..a17832188e8 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.yaml @@ -4,7 +4,7 @@ is_veteran: false veteran_disability_rating: 100 output: - is_disabled_veteran: false + is_totally_disabled_veteran: false - name: Return false if veteran_disability_rating < 100 @@ -13,7 +13,7 @@ is_veteran: true veteran_disability_rating: 90 output: - is_disabled_veteran: false + is_totally_disabled_veteran: false - name: Return true if veteran and veteran_disability_rating >= 100 @@ -22,5 +22,5 @@ is_veteran: true veteran_disability_rating: 100 output: - is_disabled_veteran: true + is_totally_disabled_veteran: true diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.py similarity index 84% rename from policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py rename to policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.py index 57fc4840321..5849e5bbc5a 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled_veteran.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_totally_disabled_veteran.py @@ -1,7 +1,7 @@ from policyengine_us.model_api import * -class is_disabled_veteran(Variable): +class is_totally_disabled_veteran(Variable): value_type = bool entity = Person label = "Eligible for Medicaid CE exemption for disabled veterans" @@ -9,7 +9,7 @@ class is_disabled_veteran(Variable): reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" def formula(person, period, parameters): - vet_disability_minimum: int = parameters(period).gov.hhs.medicaid.eligibility.work_requirements.veteran_disability_minimum + vet_disability_minimum: int = parameters(period).gov.hhs.medicaid.eligibility.work_requirements.total_veteran_disability_minimum is_veteran = person("is_veteran", period) veteran_disability_rating = person( From 21e7b4b213a7519d22308f321077d2e83d5a2711 Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Thu, 12 Mar 2026 14:58:24 -0400 Subject: [PATCH 3/6] Adding an has_exemption variable for Medicaid work requirements and some supporting variables for medically frail --- ...s_medicaid_work_requirement_exemption.yaml | 20 +++++++ .../work_requirements/is_medically_frail.yaml | 52 +++++++++++++++++++ ...has_medicaid_work_requirement_exemption.py | 18 +++++++ .../work_requirements/has_adl_impairment.py | 11 ++++ .../has_disabling_mental_disorder.py | 11 ++++ ...as_serious_or_complex_medical_condition.py | 14 +++++ .../has_substance_use_disorder.py | 13 +++++ .../work_requirements/is_disabled.py | 2 + .../work_requirements/is_medically_frail.py | 27 ++++++++++ 9 files changed, 168 insertions(+) create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.yaml create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_adl_impairment.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabling_mental_disorder.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_serious_or_complex_medical_condition.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_substance_use_disorder.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.py diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml new file mode 100644 index 00000000000..3bfdfc28677 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml @@ -0,0 +1,20 @@ +- name: Return false if no conditions set + period: 2027 + output: + has_medicaid_work_requirement_exemption: false + +- name: Return true if is_totally_disabled_veteran + period: 2027 + input: + is_totally_disabled_veteran: true + output: + has_medicaid_work_requirement_exemption: true + +- name: Return true if is_medically_frail + period: 2027 + input: + is_medically_frail: true + output: + has_medicaid_work_requirement_exemption: true + + diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.yaml new file mode 100644 index 00000000000..e616ff38bbc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.yaml @@ -0,0 +1,52 @@ +- name: Return false if no conditions set + period: 2027 + output: + is_medically_frail: false + + +- name: return true if blind + period: 2027 + input: + is_blind: true + output: + is_medically_frail: true + + +- name: return true if has disability as defined by SSI + period: 2027 + input: + is_ssi_disabled: true + output: + is_medically_frail: true + + +- name: return true if has substance_use_disorder + period: 2027 + input: + has_substance_use_disorder: true + output: + is_medically_frail: true + + +- name: return true if has_disabling_mental_disorder + period: 2027 + input: + has_disabling_mental_disorder: true + output: + is_medically_frail: true + + +- name: return true if has_adl_impairment + period: 2027 + input: + has_adl_impairment: true + output: + is_medically_frail: true + + +- name: return true if has_serious_or_complex_medical_condition + period: 2027 + input: + has_serious_or_complex_medical_condition: true + output: + is_medically_frail: true diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py new file mode 100644 index 00000000000..3a47bab97a3 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class has_medicaid_work_requirement_exemption(Variable): + value_type = bool + entity = Person + label = "Has an exemption for Medicaid work requirements" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters): + is_totally_disabled_veteran = person("is_totally_disabled_veteran", period) + is_medically_frail = person("is_medically_frail", period) + + return ( + is_totally_disabled_veteran or + is_medically_frail + ) diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_adl_impairment.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_adl_impairment.py new file mode 100644 index 00000000000..a882c18d568 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_adl_impairment.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class has_adl_impairment(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = bool + entity = Person + label = "Is unable to perform 1 or more Activities of Daily Living" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = False diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabling_mental_disorder.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabling_mental_disorder.py new file mode 100644 index 00000000000..b299f733069 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabling_mental_disorder.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class has_disabling_mental_disorder(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = bool + entity = Person + label = "Has a disabling mental health condition as defined for HR. 1" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = False diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_serious_or_complex_medical_condition.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_serious_or_complex_medical_condition.py new file mode 100644 index 00000000000..57e7953afdc --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_serious_or_complex_medical_condition.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +from policyengine_us.model_api import * + + +class has_serious_or_complex_medical_condition(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = bool + entity = Person + label = "Has a serious or complex medical condition" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = False + diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_substance_use_disorder.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_substance_use_disorder.py new file mode 100644 index 00000000000..21bd668440c --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_substance_use_disorder.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +from policyengine_us.model_api import * + + +class has_substance_use_disorder(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = bool + entity = Person + label = "Substance Use Disorder as a measure of medically frail" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = False diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled.py new file mode 100644 index 00000000000..63f77b6be18 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_disabled.py @@ -0,0 +1,2 @@ +#!/usr/bin/env python3 + diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.py new file mode 100644 index 00000000000..44da0cd2ef3 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/is_medically_frail.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class is_medically_frail(Variable): + value_type = bool + entity = Person + label = "The community engagement rules for Medicaid CE define a few different conditions for medical frailty or special needs" + definition_period = YEAR + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> bool: + is_blind: bool = person("is_blind", period) + is_ssi_disabled: bool = person("is_ssi_disabled", period) + has_substance_use_disorder: bool = person("has_substance_use_disorder", period) + has_disabling_mental_disorder: bool = person("has_disabling_mental_disorder", period) + has_adl_impairment: bool = person("has_adl_impairment", period) + has_serious_or_complex_medical_condition: bool = person("has_serious_or_complex_medical_condition", period) + + + return ( + is_blind or + is_ssi_disabled or + has_substance_use_disorder or + has_disabling_mental_disorder or + has_adl_impairment or + has_serious_or_complex_medical_condition + ) From 52f2822945beaf38d0e48eb2cbf6a3d189c64260 Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Fri, 13 Mar 2026 11:49:12 -0400 Subject: [PATCH 4/6] Computed income threshold for Medicaid from params --- .../medicaid_work_income_threshold.yaml | 4 ++++ .../medicaid_work_income_threshold.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.yaml create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.py diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.yaml new file mode 100644 index 00000000000..a801e5fd78a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.yaml @@ -0,0 +1,4 @@ +- name: should equal the federal minimum wage multiplied by the work hours requirement + period: 2027-01 + output: + medicaid_work_income_threshold: 580 diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.py new file mode 100644 index 00000000000..01cf8b8defc --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/medicaid_work_income_threshold.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class medicaid_work_income_threshold(Variable): + value_type = float + entity = Person + label = "The monthly income threshold for a person to demonstrate Community Engagement (CE) for Medicaid" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> float: + p = parameters(period).gov + federal_min_wage: float = p.dol.minimum_wage + hours: int = p.hhs.medicaid.eligibility.work_requirements.monthly_hours_threshold + + return federal_min_wage * hours + From 630b891e69c8801432c399c8a55e1ce45c7ef3c5 Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Fri, 27 Mar 2026 15:51:16 -0400 Subject: [PATCH 5/6] Capturing the Medicaid CE requirements Adding logic to pass work requirements based on community engagement. For now, these are simple variables, but may later be changed into computed variables. --- .../has_medicaid_work_requirement_ce.yaml | 39 +++++++++++++++++++ .../has_medicaid_work_requirement_ce.py | 22 +++++++++++ ...has_medicaid_work_requirement_exemption.py | 2 +- .../work_requirements/ce_activity_hours.py | 13 +++++++ .../work_requirements/ce_activity_income.py | 13 +++++++ .../enrolled_half_time_or_more.py | 13 +++++++ 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_ce.yaml create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_ce.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_hours.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_income.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/enrolled_half_time_or_more.py diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_ce.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_ce.yaml new file mode 100644 index 00000000000..dc191db1363 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_ce.yaml @@ -0,0 +1,39 @@ +- name: Return false if no conditions set + period: 2027-03 + output: + has_medicaid_work_requirement_ce: false + +- name: Return true if enrolled at least half-time + period: 2027-03 + input: + enrolled_half_time_or_more: true + output: + has_medicaid_work_requirement_ce: true + +- name: Return false if hours are too low + period: 2027-03 + input: + ce_activity_hours: 79.5 + output: + has_medicaid_work_requirement_ce: false + +- name: Return true if hours >= 80 + period: 2027-03 + input: + ce_activity_hours: 80 + output: + has_medicaid_work_requirement_ce: true + +- name: Return false if income < 580 + period: 2027-03 + input: + ce_activity_income: 579.50 + output: + has_medicaid_work_requirement_ce: false + +- name: Return true if income >= 580 + period: 2027-03 + input: + ce_activity_income: 580 + output: + has_medicaid_work_requirement_ce: true diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_ce.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_ce.py new file mode 100644 index 00000000000..f90723ea3f1 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_ce.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class has_medicaid_work_requirement_ce(Variable): + value_type = bool + entity = Person + label = "Has demonstrated Community Engagement (CE) compliance for Medicaid work requirements" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> bool: + enrolled_half_time = person("enrolled_half_time_or_more", period) + + monthly_hours_worked = person("ce_activity_hours", period) + hours_threshold = parameters(period).gov.hhs.medicaid.eligibility.work_requirements.monthly_hours_threshold + passed_hours: bool = monthly_hours_worked >= hours_threshold + + monthly_income_earned = person("ce_activity_income", period) + income_threshold = person("medicaid_work_income_threshold", period) + passed_income: bool = monthly_income_earned >= income_threshold + + return enrolled_half_time or passed_hours or passed_income diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py index 3a47bab97a3..899bee76639 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py @@ -5,7 +5,7 @@ class has_medicaid_work_requirement_exemption(Variable): value_type = bool entity = Person label = "Has an exemption for Medicaid work requirements" - definition_period = YEAR + definition_period = MONTH reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_hours.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_hours.py new file mode 100644 index 00000000000..53c46a3ae53 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_hours.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +from policyengine_us.model_api import * + + +class ce_activity_hours(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = float + entity = Person + label = "The sum of all hours spent working, doing commmunity service or in a job-training program in the specific month" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = 0 diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_income.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_income.py new file mode 100644 index 00000000000..ec768e01619 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/ce_activity_income.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +from policyengine_us.model_api import * + + +class ce_activity_income(Variable): + # Letting this be set for now, might later derive it + value_type = float + entity = Person + label = "The sum of all income earned during the month that can be counted toward work requirements" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = 0 diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/enrolled_half_time_or_more.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/enrolled_half_time_or_more.py new file mode 100644 index 00000000000..f14f5772f1f --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/enrolled_half_time_or_more.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +from policyengine_us.model_api import * + + +class enrolled_half_time_or_more(Variable): + # criteria not yet defined by CMS, so treating as simple boolean for now + value_type = bool + entity = Person + label = "The individual is enrolled in an educational program at least half-time." + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value = False From 8c492c4caa2b90c15d0fe5f486635510ff63d1de Mon Sep 17 00:00:00 2001 From: Jacob Harris Date: Fri, 27 Mar 2026 19:04:13 -0400 Subject: [PATCH 6/6] Mismatch between year and month period The law involves checking for conditions in a month, but this might be too granular to do in the policy engine. Tests currently failing for this reason. --- .../medicaid_work_requirement_eligible.yaml | 32 +++---- .../work_requirements/has_age_exemption.yaml | 19 ++++ ...s_medicaid_work_requirement_exemption.yaml | 25 +++++- ...has_medicaid_work_requirement_exemption.py | 13 ++- .../eligibility/in_medicaid_expansion.py | 11 +++ .../medicaid_work_requirement_eligible.py | 88 ++++++++++--------- .../work_requirements/has_age_exemption.py | 14 +++ .../has_disabled_dependent.py | 18 ++++ .../work_requirements/has_young_dependent.py | 21 +++++ 9 files changed, 180 insertions(+), 61 deletions(-) create mode 100644 policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.yaml create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/in_medicaid_expansion.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabled_dependent.py create mode 100644 policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_young_dependent.py diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.yaml index 888e7edf766..0b4c8ce0d52 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.yaml @@ -1,72 +1,72 @@ - name: Case 1, age 18, work exempted age. - period: 2026 + period: 2027-03 input: age: 18 output: medicaid_work_requirement_eligible: true - name: Case 2, age 65, work exempted age. - period: 2026 + period: 2027-03 input: age: 65 output: medicaid_work_requirement_eligible: true - name: Case 3, age 19, need working. - period: 2026 + period: 2027-03 input: age: 19 output: medicaid_work_requirement_eligible: false - name: Case 4, age 30, working 79 hours per month. - period: 2026 + period: 2027-03 input: age: 30 - monthly_hours_worked: 79 + ce_activity_hours: 79 output: medicaid_work_requirement_eligible: false - name: Case 5, age 30, working 80 hours per month. - period: 2026 + period: 2027-03 input: age: 30 - monthly_hours_worked: 80 + ce_activity_hours: 80 output: medicaid_work_requirement_eligible: true - name: Case 6, age 30, is disabled. - period: 2026 + period: 2027-03 input: age: 19 - monthly_hours_worked: 5 + ce_activity_hours: 5 is_disabled: true output: medicaid_work_requirement_eligible: true - name: Case 7, integration. - period: 2026 + period: 2027-03 input: people: person1: age: 30 is_tax_unit_head_or_spouse: true - monthly_hours_worked: 80 + ce_activity_hours: 80 person2: age: 30 is_tax_unit_head_or_spouse: true - monthly_hours_worked: 79 + ce_activity_hours: 79 output: medicaid_work_requirement_eligible: [true, false] - name: Case 8, not working, but has child at age 13. - period: 2026 + period: 2027-03 input: people: person1: age: 30 is_tax_unit_head_or_spouse: true - monthly_hours_worked: 0 + ce_activity_hours: 0 person2: age: 13 is_tax_unit_dependent: true @@ -74,13 +74,13 @@ medicaid_work_requirement_eligible: [true, true] - name: Case 9, not working, has child at age 14, ineligible under Senate Version. - period: 2026 + period: 2027-03 input: people: person1: age: 30 is_tax_unit_head_or_spouse: true - monthly_hours_worked: 0 + ce_activity_hours: 0 person2: age: 14 is_tax_unit_dependent: true diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.yaml new file mode 100644 index 00000000000..90785104361 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.yaml @@ -0,0 +1,19 @@ +- name: Return false if no conditions set + period: 2027-03 + output: + has_age_exemption: false + +- name: Return true if less than 19 + period: 2027-03 + input: + age: 18 + output: + has_age_exemption: true + +- name: Return true if greater than or equal to 65 + period: 2027-03 + input: + age: 65 + output: + has_age_exemption: true + diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml index 3bfdfc28677..3899e1cc6ff 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicaid/eligibility/work_requirements/has_medicaid_work_requirement_exemption.yaml @@ -1,20 +1,39 @@ - name: Return false if no conditions set - period: 2027 + period: '2027-03' output: has_medicaid_work_requirement_exemption: false - name: Return true if is_totally_disabled_veteran - period: 2027 + period: '2027-03' input: is_totally_disabled_veteran: true output: has_medicaid_work_requirement_exemption: true - name: Return true if is_medically_frail - period: 2027 + period: '2027-03' input: is_medically_frail: true output: has_medicaid_work_requirement_exemption: true +- name: Return true if is_pregnant + period: '2027-03' + input: + is_pregnant: true + output: + has_medicaid_work_requirement_exemption: true + +- name: Return true if <19 years old + period: '2027-03' + input: + age: 18 + output: + has_medicaid_work_requirement_exemption: true +- name: Return true if 65 or older + period: '2027-03' + input: + age: 65 + output: + has_medicaid_work_requirement_exemption: true diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py index 899bee76639..2e2cf5d00ce 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/has_medicaid_work_requirement_exemption.py @@ -9,10 +9,21 @@ class has_medicaid_work_requirement_exemption(Variable): reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" def formula(person, period, parameters): + has_age_exemption = person("has_age_exemption", period) is_totally_disabled_veteran = person("is_totally_disabled_veteran", period) is_medically_frail = person("is_medically_frail", period) + is_pregnant = person("is_pregnant", period) + has_young_dependent = person("has_young_dependent", period) + is_disabled = person("is_disabled", period) + has_disabled_dependent = person("has_disabled_dependent", period) + return ( + has_age_exemption or + is_pregnant or is_totally_disabled_veteran or - is_medically_frail + is_medically_frail or + is_disabled or + has_disabled_dependent or + has_young_dependent ) diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/in_medicaid_expansion.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/in_medicaid_expansion.py new file mode 100644 index 00000000000..42ef2e0d852 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/in_medicaid_expansion.py @@ -0,0 +1,11 @@ +from policyengine_us.model_api import * + + +class has_work_requirement(Variable): + # FIXME Replace with formula based on MAGI and needing financial qualifications + value_type = bool + entity = Person + label = "Required to do the Medicaid work requirement" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + default_value: False diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.py index 70c8c042819..857ccc07b22 100644 --- a/policyengine_us/variables/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.py +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/medicaid_work_requirement_eligible.py @@ -5,47 +5,53 @@ class medicaid_work_requirement_eligible(Variable): value_type = bool entity = Person label = "Eligible person for Medicaid via work requirement" - definition_period = YEAR + definition_period = MONTH reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" def formula(person, period, parameters): - p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements - # Works no less than 80 hours p.680 (2)(A) - monthly_hours_worked = person("monthly_hours_worked", period) - meets_monthly_work_hours = monthly_hours_worked >= p.monthly_hours_threshold - # The individual is enrolled in an educational program at least half-time. p.680 (2)(D) - is_full_time_student = person("is_full_time_student", period) - # pregnant or postpartum medical assistance p.681 (3)(A)(i)(II)(bb) - is_pregnant = person("is_pregnant", period) - # Has attained age of 19 and is under 65 is require to work p.693 (bb) - age = person("age", period) - work_required_age = p.age_range.calc(age) - # parent, guardian, caretaker of a disabled person - is_dependent = person("is_tax_unit_dependent", period) - is_disabled = person("is_disabled", period) - has_disabled = person.tax_unit.any(is_dependent & is_disabled) - # veteran and is_permanently_and_totally_disabled p.694 (IV) - is_veteran = person("is_veteran", period) - is_permanently_and_totally_disabled = person( - "is_permanently_and_totally_disabled", period - ) - eligible_veteran = is_veteran & is_permanently_and_totally_disabled - # blind or disabled or is_incapable_of_self_care p.694 (V) - is_blind = person("is_blind", period) - is_incapable_of_self_care = person("is_incapable_of_self_care", period) - eligible_disabled = is_blind | is_disabled | is_incapable_of_self_care - # parent, guardian, caretaker of a dependent child 13 years of age or under p.694 (III) - child_age_eligible = age <= p.dependent_age_limit - has_eligible_dependent_child = person.tax_unit.any( - is_dependent & child_age_eligible - ) - exempted_from_work = ( - is_full_time_student - | is_pregnant - | has_disabled - | eligible_veteran - | eligible_disabled - ) - meets_base_requirement = meets_monthly_work_hours | exempted_from_work - meets_conditions = meets_base_requirement | has_eligible_dependent_child - return where(work_required_age, meets_conditions, True) + has_exemption = person("has_medicaid_work_requirement_exemption", period) + has_ce = person("has_medicaid_work_requirement_ce", period) + + return has_exemption or has_ce + + # def formula(person, period, parameters): + # p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements + # # Works no less than 80 hours p.680 (2)(A) + # monthly_hours_worked = person("monthly_hours_worked", period) + # meets_monthly_work_hours = monthly_hours_worked >= p.monthly_hours_threshold + # # The individual is enrolled in an educational program at least half-time. p.680 (2)(D) + # is_full_time_student = person("is_full_time_student", period) + # # pregnant or postpartum medical assistance p.681 (3)(A)(i)(II)(bb) + # is_pregnant = person("is_pregnant", period) + # # Has attained age of 19 and is under 65 is require to work p.693 (bb) + # age = person("age", period) + # work_required_age = p.age_range.calc(age) + # # parent, guardian, caretaker of a disabled person + # is_dependent = person("is_tax_unit_dependent", period) + # is_disabled = person("is_disabled", period) + # has_disabled = person.tax_unit.any(is_dependent & is_disabled) + # # veteran and is_permanently_and_totally_disabled p.694 (IV) + # is_veteran = person("is_veteran", period) + # is_permanently_and_totally_disabled = person( + # "is_permanently_and_totally_disabled", period + # ) + # eligible_veteran = is_veteran & is_permanently_and_totally_disabled + # # blind or disabled or is_incapable_of_self_care p.694 (V) + # is_blind = person("is_blind", period) + # is_incapable_of_self_care = person("is_incapable_of_self_care", period) + # eligible_disabled = is_blind | is_disabled | is_incapable_of_self_care + # # parent, guardian, caretaker of a dependent child 13 years of age or under p.694 (III) + # child_age_eligible = age <= p.dependent_age_limit + # has_eligible_dependent_child = person.tax_unit.any( + # is_dependent & child_age_eligible + # ) + # exempted_from_work = ( + # is_full_time_student + # | is_pregnant + # | has_disabled + # | eligible_veteran + # | eligible_disabled + # ) + # meets_base_requirement = meets_monthly_work_hours | exempted_from_work + # meets_conditions = meets_base_requirement | has_eligible_dependent_child + # return where(work_required_age, meets_conditions, True) diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.py new file mode 100644 index 00000000000..f24929ed0f8 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_age_exemption.py @@ -0,0 +1,14 @@ +from policyengine_us.model_api import * + + +class has_age_exemption(Variable): + value_type = bool + entity = Person + label = "Persons under 19 and 65 or older are exempt from Medicaid work requirements" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> bool: + age = person("age", period) + p = parameters(period).gov.hhs.medicaid.eligibility.work_requirements + return p.age_range.calc(age) diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabled_dependent.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabled_dependent.py new file mode 100644 index 00000000000..b83fe067e01 --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_disabled_dependent.py @@ -0,0 +1,18 @@ +from policyengine_us.model_api import * + + +class has_disabled_dependent(Variable): + # FIXME: What if the person isn't a dependent? + value_type = bool + entity = Person + label = "Is taking care of a person with a disability" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> bool: + is_dependent = person("is_tax_unit_dependent", period) + is_disabled = person("is_disabled", period) + + return person.tax_unit.any( + is_dependent & is_disabled + ) diff --git a/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_young_dependent.py b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_young_dependent.py new file mode 100644 index 00000000000..2b31dec96ac --- /dev/null +++ b/policyengine_us/variables/gov/hhs/medicaid/eligibility/work_requirements/has_young_dependent.py @@ -0,0 +1,21 @@ +from policyengine_us.model_api import * + + +class has_young_dependent(Variable): + value_type = bool + entity = Person + label = "Is taking care of a child 13 years or younger" + definition_period = MONTH + reference = "https://www.congress.gov/bill/119th-congress/house-bill/1/text" + + def formula(person, period, parameters) -> bool: + age = person("age", period) + is_dependent = person("is_tax_unit_dependent", period) + + dependent_age_limit = parameters(period).gov.hhs.medicaid.eligibility.work_requirements.dependent_age_limit + child_age_eligible = age <= dependent_age_limit + has_eligible_dependent_child = person.tax_unit.any( + is_dependent & child_age_eligible + ) + + return has_eligible_dependent_child