Skip to content

Commit a9c3d5f

Browse files
committed
Create structural reform for house ACA proposal
Fixes #6809
1 parent 7051281 commit a9c3d5f

File tree

7 files changed

+354
-0
lines changed

7 files changed

+354
-0
lines changed

changelog_entry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- bump: minor
2+
changes:
3+
added:
4+
- ACA PTC 600% FPL cliff reform extending 2021 subsidy levels with 8.5% contribution cap to 600% FPL
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# ACA PTC contribution brackets with 2021 subsidy levels extended to 600% FPL.
2+
# Maintains 8.5% contribution rate from 400% to 600% FPL, then ends eligibility.
3+
4+
description: ACA PTC contribution percentages by household income (2021 levels extended to 600% FPL).
5+
6+
metadata:
7+
type: single_amount
8+
threshold_unit: /1
9+
rate_unit: /1
10+
label: ACA PTC contribution rate brackets (600% FPL cliff)
11+
reference:
12+
- title: 26 U.S. Code § 36B(b)(3)(A) - Refundable credit for coverage under a qualified health plan
13+
href: https://www.law.cornell.edu/uscode/text/26/36B#b_3_A
14+
- title: American Rescue Plan Act of 2021 - ACA premium subsidy expansion
15+
href: https://www.congress.gov/bill/117th-congress/house-bill/1319
16+
- title: Inflation Reduction Act of 2022 - ACA subsidy extension through 2025
17+
href: https://www.congress.gov/bill/117th-congress/house-bill/5376
18+
- title: Affordable Care Act Enhancement Act - Proposed subsidy extension to 600% FPL
19+
href: https://www.politico.com/f/?id=0000019a-6b87-dc40-a1bb-6fe74c510000
20+
21+
brackets:
22+
- threshold:
23+
2026-01-01: 0
24+
amount:
25+
2026-01-01: 0
26+
- threshold:
27+
2026-01-01: 1.5
28+
amount:
29+
2026-01-01: 0
30+
- threshold:
31+
2026-01-01: 2.0
32+
amount:
33+
2026-01-01: 0.02
34+
- threshold:
35+
2026-01-01: 2.5
36+
amount:
37+
2026-01-01: 0.04
38+
- threshold:
39+
2026-01-01: 3.0
40+
amount:
41+
2026-01-01: 0.06
42+
- threshold:
43+
2026-01-01: 4.0
44+
amount:
45+
2026-01-01: 0.085
46+
- threshold:
47+
2026-01-01: 6.0
48+
amount:
49+
2026-01-01: 0.085
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
description: Whether the ACA PTC 600% FPL cliff extension is in effect.
2+
3+
values:
4+
0000-01-01: false
5+
6+
metadata:
7+
unit: bool
8+
period: year
9+
label: ACA PTC 600% FPL cliff in effect
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Extended income eligibility for ACA PTC up to 600% FPL.
2+
# Allows subsidies to continue up to 600% FPL with 8.5% contribution cap.
3+
4+
description: Eligibility for ACA Premium Tax Credit by percent of modified AGI to federal poverty line (600% FPL limit).
5+
6+
metadata:
7+
type: single_amount
8+
period: year
9+
threshold_unit: /1
10+
amount_unit: bool
11+
label: ACA PTC income eligibility conditions (600% FPL cliff)
12+
reference:
13+
- title: 26 U.S. Code § 36B(c)(1) - Eligibility requirements
14+
href: https://www.law.cornell.edu/uscode/text/26/36B#c_1
15+
16+
brackets:
17+
- threshold:
18+
2026-01-01: 0
19+
amount:
20+
2026-01-01: false
21+
- threshold:
22+
2026-01-01: 1.00
23+
amount:
24+
2026-01-01: true
25+
- threshold:
26+
2026-01-01: 6.0
27+
amount:
28+
2026-01-01: false

policyengine_us/reforms/aca/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
from policyengine_us.reforms.aca.aca_ptc_simplified_bracket import (
55
create_aca_ptc_simplified_bracket_reform,
66
)
7+
from policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff import (
8+
create_aca_ptc_600_fpl_cliff_reform,
9+
)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from policyengine_us.model_api import *
2+
from policyengine_core.periods import period as period_
3+
4+
5+
def create_aca_ptc_600_fpl_cliff() -> Reform:
6+
class aca_required_contribution_percentage(Variable):
7+
"""
8+
ACA required contribution percentage with 2021 subsidy levels extended to 600% FPL.
9+
10+
This reform extends the enhanced ACA premium subsidies enacted under the
11+
American Rescue Plan Act of 2021 (ARPA), but moves the eligibility cliff
12+
from 400% FPL to 600% FPL. The reform maintains the 8.5% maximum
13+
contribution rate for households between 400% and 600% FPL.
14+
15+
Under this reform:
16+
- 0-150% FPL: 0% contribution
17+
- 150-200% FPL: 0-2% contribution
18+
- 200-250% FPL: 2-4% contribution
19+
- 250-300% FPL: 4-6% contribution
20+
- 300-400% FPL: 6-8.5% contribution
21+
- 400-600% FPL: 8.5% contribution (extended)
22+
- Above 600% FPL: No subsidy eligibility
23+
24+
This eliminates the subsidy cliff that would otherwise occur at 400% FPL,
25+
making more middle-income households eligible for ACA subsidies while
26+
maintaining a cap on contribution percentages.
27+
"""
28+
29+
value_type = float
30+
entity = TaxUnit
31+
label = "ACA required contribution percentage with 600% FPL cliff (i.e., IRS Form 8962 'applicable figure')"
32+
unit = "/1"
33+
definition_period = YEAR
34+
reference = [
35+
"26 U.S. Code § 36B(b)(3)(A) - Refundable credit for coverage under a qualified health plan",
36+
"https://www.law.cornell.edu/uscode/text/26/36B#b_3_A",
37+
"American Rescue Plan Act of 2021",
38+
"https://www.congress.gov/bill/117th-congress/house-bill/1319",
39+
"Affordable Care Act Enhancement Act - Proposed subsidy extension to 600% FPL",
40+
"https://www.politico.com/f/?id=0000019a-6b87-dc40-a1bb-6fe74c510000",
41+
]
42+
43+
def formula(tax_unit, period, parameters):
44+
magi_frac = tax_unit("aca_magi_fraction", period)
45+
p = parameters(period).gov.contrib.aca.ptc_600_fpl_cliff.brackets
46+
return np.interp(magi_frac, p.thresholds, p.amounts)
47+
48+
class is_aca_ptc_eligible(Variable):
49+
"""
50+
Extended ACA PTC eligibility up to 600% FPL.
51+
"""
52+
53+
value_type = bool
54+
entity = Person
55+
label = "Person is eligible for ACA premium tax credit and pays ACA premium"
56+
definition_period = YEAR
57+
58+
def formula(person, period, parameters):
59+
# determine status eligibility for ACA PTC
60+
fstatus = person.tax_unit("filing_status", period)
61+
separate = fstatus == fstatus.possible_values.SEPARATE
62+
immigration_eligible = person(
63+
"is_aca_ptc_immigration_status_eligible", period
64+
)
65+
taxpayer_has_itin = person.tax_unit("taxpayer_has_itin", period)
66+
is_status_eligible = (
67+
taxpayer_has_itin & ~separate & immigration_eligible
68+
)
69+
70+
# determine coverage eligibility for ACA plan
71+
INELIGIBLE_COVERAGE = [
72+
"is_medicaid_eligible",
73+
"is_chip_eligible",
74+
"is_aca_eshi_eligible",
75+
"is_medicare_eligible",
76+
]
77+
is_coverage_eligible = (
78+
add(person, period, INELIGIBLE_COVERAGE) == 0
79+
)
80+
81+
# determine income eligibility for ACA PTC (using reform parameter)
82+
p = parameters(period).gov.contrib.aca.ptc_600_fpl_cliff
83+
magi_frac = person.tax_unit("aca_magi_fraction", period)
84+
is_income_eligible = p.income_eligibility.calc(magi_frac)
85+
86+
# determine which people pay an age-based ACA plan premium
87+
p_aca = parameters(period).gov.aca
88+
is_aca_adult = person("age", period) > p_aca.slcsp.max_child_age
89+
child_pays = (
90+
person("aca_child_index", period) <= p_aca.max_child_count
91+
)
92+
pays_aca_premium = is_aca_adult | child_pays
93+
94+
return (
95+
is_status_eligible
96+
& is_coverage_eligible
97+
& is_income_eligible
98+
& pays_aca_premium
99+
)
100+
101+
class reform(Reform):
102+
def apply(self):
103+
self.update_variable(aca_required_contribution_percentage)
104+
self.update_variable(is_aca_ptc_eligible)
105+
106+
return reform
107+
108+
109+
def create_aca_ptc_600_fpl_cliff_reform(
110+
parameters, period, bypass: bool = False
111+
):
112+
if bypass:
113+
return create_aca_ptc_600_fpl_cliff()
114+
115+
p = parameters.gov.contrib.aca.ptc_600_fpl_cliff
116+
current_period = period_(period)
117+
118+
# Check if reform is active within a 5-year lookahead window
119+
# This allows the reform to be selected in the web app interface
120+
# even if it's scheduled to start in a future year
121+
reform_active = False
122+
for i in range(5):
123+
if p(current_period).in_effect:
124+
reform_active = True
125+
break
126+
current_period = current_period.offset(1, "year")
127+
128+
if reform_active:
129+
return create_aca_ptc_600_fpl_cliff()
130+
else:
131+
return None
132+
133+
134+
aca_ptc_600_fpl_cliff = create_aca_ptc_600_fpl_cliff_reform(
135+
None, None, bypass=True
136+
)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
- name: Single filer at 0% FPL - zero contribution
2+
period: 2026
3+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
4+
absolute_error_margin: 0.00001
5+
input:
6+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
7+
aca_magi_fraction: 0.0
8+
output:
9+
aca_required_contribution_percentage: 0.0
10+
11+
- name: Single filer at 150% FPL - zero contribution
12+
period: 2026
13+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
14+
absolute_error_margin: 0.00001
15+
input:
16+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
17+
aca_magi_fraction: 1.5
18+
output:
19+
aca_required_contribution_percentage: 0.0
20+
21+
- name: Single filer at 200% FPL - 2% contribution
22+
period: 2026
23+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
24+
absolute_error_margin: 0.00001
25+
input:
26+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
27+
aca_magi_fraction: 2.0
28+
output:
29+
aca_required_contribution_percentage: 0.02
30+
31+
- name: Single filer at 250% FPL - 4% contribution
32+
period: 2026
33+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
34+
absolute_error_margin: 0.00001
35+
input:
36+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
37+
aca_magi_fraction: 2.5
38+
output:
39+
aca_required_contribution_percentage: 0.04
40+
41+
- name: Single filer at 300% FPL - 6% contribution
42+
period: 2026
43+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
44+
absolute_error_margin: 0.00001
45+
input:
46+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
47+
aca_magi_fraction: 3.0
48+
output:
49+
aca_required_contribution_percentage: 0.06
50+
51+
- name: Single filer at 400% FPL - 8.5% contribution (old cliff point)
52+
period: 2026
53+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
54+
absolute_error_margin: 0.00001
55+
input:
56+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
57+
aca_magi_fraction: 4.0
58+
output:
59+
aca_required_contribution_percentage: 0.085
60+
61+
- name: Single filer at 500% FPL - 8.5% contribution (flat rate)
62+
period: 2026
63+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
64+
absolute_error_margin: 0.00001
65+
input:
66+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
67+
aca_magi_fraction: 5.0
68+
output:
69+
aca_required_contribution_percentage: 0.085
70+
71+
- name: Single filer at 600% FPL - 8.5% contribution (new cliff point)
72+
period: 2026
73+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
74+
absolute_error_margin: 0.00001
75+
input:
76+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
77+
aca_magi_fraction: 6.0
78+
output:
79+
aca_required_contribution_percentage: 0.085
80+
81+
- name: Single filer at 175% FPL - interpolated 1% contribution
82+
period: 2026
83+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
84+
absolute_error_margin: 0.00001
85+
input:
86+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
87+
aca_magi_fraction: 1.75
88+
output:
89+
aca_required_contribution_percentage: 0.01
90+
91+
- name: Single filer at 350% FPL - interpolated 7.25% contribution
92+
period: 2026
93+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
94+
absolute_error_margin: 0.00001
95+
input:
96+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
97+
aca_magi_fraction: 3.5
98+
output:
99+
aca_required_contribution_percentage: 0.0725
100+
101+
- name: Baseline comparison at 400% FPL - shows elimination of cliff
102+
period: 2026
103+
absolute_error_margin: 0.00001
104+
input:
105+
aca_magi_fraction: 4.0
106+
output:
107+
aca_required_contribution_percentage: 0.0996
108+
109+
- name: Baseline comparison at 500% FPL - shows new eligibility
110+
period: 2026
111+
absolute_error_margin: 0.00001
112+
input:
113+
aca_magi_fraction: 5.0
114+
output:
115+
aca_required_contribution_percentage: 0.0996
116+
117+
- name: Edge case - Very high income at 700% FPL extends last bracket
118+
period: 2026
119+
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
120+
absolute_error_margin: 0.00001
121+
input:
122+
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
123+
aca_magi_fraction: 7.0
124+
output:
125+
aca_required_contribution_percentage: 0.085

0 commit comments

Comments
 (0)