Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog_entry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- bump: minor
changes:
added:
- ACA PTC 600% FPL cliff reform extending 2021 subsidy levels with 8.5% contribution cap to 600% FPL
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ACA PTC contribution brackets with 2021 subsidy levels extended to 600% FPL.
# Maintains 8.5% contribution rate from 400% to 600% FPL, then ends eligibility.

description: ACA PTC contribution percentages by household income (2021 levels extended to 600% FPL).

metadata:
type: single_amount
threshold_unit: /1
rate_unit: /1
label: ACA PTC contribution rate brackets (600% FPL cliff)
reference:
- title: 26 U.S. Code § 36B(b)(3)(A) - Refundable credit for coverage under a qualified health plan
href: https://www.law.cornell.edu/uscode/text/26/36B#b_3_A
- title: American Rescue Plan Act of 2021 - ACA premium subsidy expansion
href: https://www.congress.gov/bill/117th-congress/house-bill/1319
- title: Inflation Reduction Act of 2022 - ACA subsidy extension through 2025
href: https://www.congress.gov/bill/117th-congress/house-bill/5376
- title: Affordable Care Act Enhancement Act - Proposed subsidy extension to 600% FPL
href: https://www.politico.com/f/?id=0000019a-6b87-dc40-a1bb-6fe74c510000

brackets:
- threshold:
2026-01-01: 0
amount:
2026-01-01: 0
- threshold:
2026-01-01: 1.5
amount:
2026-01-01: 0
- threshold:
2026-01-01: 2.0
amount:
2026-01-01: 0.02
- threshold:
2026-01-01: 2.5
amount:
2026-01-01: 0.04
- threshold:
2026-01-01: 3.0
amount:
2026-01-01: 0.06
- threshold:
2026-01-01: 4.0
amount:
2026-01-01: 0.085
- threshold:
2026-01-01: 6.0
amount:
2026-01-01: 0.085
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Whether the ACA PTC 600% FPL cliff extension is in effect.

values:
0000-01-01: false

metadata:
unit: bool
period: year
label: ACA PTC 600% FPL cliff in effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Extended income eligibility for ACA PTC up to 600% FPL.
# Allows subsidies to continue up to 600% FPL with 8.5% contribution cap.

description: Eligibility for ACA Premium Tax Credit by percent of modified AGI to federal poverty line (600% FPL limit).

metadata:
type: single_amount
period: year
threshold_unit: /1
amount_unit: bool
label: ACA PTC income eligibility conditions (600% FPL cliff)
reference:
- title: 26 U.S. Code § 36B(c)(1) - Eligibility requirements
href: https://www.law.cornell.edu/uscode/text/26/36B#c_1

brackets:
- threshold:
2026-01-01: 0
amount:
2026-01-01: false
- threshold:
2026-01-01: 1.00
amount:
2026-01-01: true
- threshold:
2026-01-01: 6.0
amount:
2026-01-01: false
3 changes: 3 additions & 0 deletions policyengine_us/reforms/aca/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
from policyengine_us.reforms.aca.aca_ptc_simplified_bracket import (
create_aca_ptc_simplified_bracket_reform,
)
from policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff import (
create_aca_ptc_600_fpl_cliff_reform,
)
136 changes: 136 additions & 0 deletions policyengine_us/reforms/aca/aca_ptc_600_fpl_cliff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
from policyengine_us.model_api import *
from policyengine_core.periods import period as period_


def create_aca_ptc_600_fpl_cliff() -> Reform:
class aca_required_contribution_percentage(Variable):
"""
ACA required contribution percentage with 2021 subsidy levels extended to 600% FPL.

This reform extends the enhanced ACA premium subsidies enacted under the
American Rescue Plan Act of 2021 (ARPA), but moves the eligibility cliff
from 400% FPL to 600% FPL. The reform maintains the 8.5% maximum
contribution rate for households between 400% and 600% FPL.

Under this reform:
- 0-150% FPL: 0% contribution
- 150-200% FPL: 0-2% contribution
- 200-250% FPL: 2-4% contribution
- 250-300% FPL: 4-6% contribution
- 300-400% FPL: 6-8.5% contribution
- 400-600% FPL: 8.5% contribution (extended)
- Above 600% FPL: No subsidy eligibility

This eliminates the subsidy cliff that would otherwise occur at 400% FPL,
making more middle-income households eligible for ACA subsidies while
maintaining a cap on contribution percentages.
"""

value_type = float
entity = TaxUnit
label = "ACA required contribution percentage with 600% FPL cliff (i.e., IRS Form 8962 'applicable figure')"
unit = "/1"
definition_period = YEAR
reference = [
"26 U.S. Code § 36B(b)(3)(A) - Refundable credit for coverage under a qualified health plan",
"https://www.law.cornell.edu/uscode/text/26/36B#b_3_A",
"American Rescue Plan Act of 2021",
"https://www.congress.gov/bill/117th-congress/house-bill/1319",
"Affordable Care Act Enhancement Act - Proposed subsidy extension to 600% FPL",
"https://www.politico.com/f/?id=0000019a-6b87-dc40-a1bb-6fe74c510000",
]

def formula(tax_unit, period, parameters):
magi_frac = tax_unit("aca_magi_fraction", period)
p = parameters(period).gov.contrib.aca.ptc_600_fpl_cliff.brackets
return np.interp(magi_frac, p.thresholds, p.amounts)

class is_aca_ptc_eligible(Variable):
"""
Extended ACA PTC eligibility up to 600% FPL.
"""

value_type = bool
entity = Person
label = "Person is eligible for ACA premium tax credit and pays ACA premium"
definition_period = YEAR

def formula(person, period, parameters):
# determine status eligibility for ACA PTC
fstatus = person.tax_unit("filing_status", period)
separate = fstatus == fstatus.possible_values.SEPARATE
immigration_eligible = person(
"is_aca_ptc_immigration_status_eligible", period
)
taxpayer_has_itin = person.tax_unit("taxpayer_has_itin", period)
is_status_eligible = (
taxpayer_has_itin & ~separate & immigration_eligible
)

# determine coverage eligibility for ACA plan
INELIGIBLE_COVERAGE = [
"is_medicaid_eligible",
"is_chip_eligible",
"is_aca_eshi_eligible",
"is_medicare_eligible",
]
is_coverage_eligible = (
add(person, period, INELIGIBLE_COVERAGE) == 0
)

# determine income eligibility for ACA PTC (using reform parameter)
p = parameters(period).gov.contrib.aca.ptc_600_fpl_cliff
magi_frac = person.tax_unit("aca_magi_fraction", period)
is_income_eligible = p.income_eligibility.calc(magi_frac)

# determine which people pay an age-based ACA plan premium
p_aca = parameters(period).gov.aca
is_aca_adult = person("age", period) > p_aca.slcsp.max_child_age
child_pays = (
person("aca_child_index", period) <= p_aca.max_child_count
)
pays_aca_premium = is_aca_adult | child_pays

return (
is_status_eligible
& is_coverage_eligible
& is_income_eligible
& pays_aca_premium
)

class reform(Reform):
def apply(self):
self.update_variable(aca_required_contribution_percentage)
self.update_variable(is_aca_ptc_eligible)

return reform


def create_aca_ptc_600_fpl_cliff_reform(
parameters, period, bypass: bool = False
):
if bypass:
return create_aca_ptc_600_fpl_cliff()

p = parameters.gov.contrib.aca.ptc_600_fpl_cliff
current_period = period_(period)

# Check if reform is active within a 5-year lookahead window
# This allows the reform to be selected in the web app interface
# even if it's scheduled to start in a future year
reform_active = False
for i in range(5):
if p(current_period).in_effect:
reform_active = True
break
current_period = current_period.offset(1, "year")

if reform_active:
return create_aca_ptc_600_fpl_cliff()
else:
return None


aca_ptc_600_fpl_cliff = create_aca_ptc_600_fpl_cliff_reform(
None, None, bypass=True
)
5 changes: 5 additions & 0 deletions policyengine_us/reforms/reforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
from .aca import (
create_aca_ptc_additional_bracket_reform,
create_aca_ptc_simplified_bracket_reform,
create_aca_ptc_600_fpl_cliff_reform,
)


Expand Down Expand Up @@ -269,6 +270,9 @@ def create_structural_reforms_from_parameters(parameters, period):
aca_ptc_simplified_bracket = create_aca_ptc_simplified_bracket_reform(
parameters, period
)
aca_ptc_600_fpl_cliff = create_aca_ptc_600_fpl_cliff_reform(
parameters, period
)

reforms = [
afa_reform,
Expand Down Expand Up @@ -324,6 +328,7 @@ def create_structural_reforms_from_parameters(parameters, period):
ri_exemption,
aca_ptc_additional_bracket,
aca_ptc_simplified_bracket,
aca_ptc_600_fpl_cliff,
]
reforms = tuple(filter(lambda x: x is not None, reforms))

Expand Down
125 changes: 125 additions & 0 deletions policyengine_us/tests/policy/contrib/aca/ptc_600_fpl_cliff.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
- name: Single filer at 0% FPL - zero contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 0.0
output:
aca_required_contribution_percentage: 0.0

- name: Single filer at 150% FPL - zero contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 1.5
output:
aca_required_contribution_percentage: 0.0

- name: Single filer at 200% FPL - 2% contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 2.0
output:
aca_required_contribution_percentage: 0.02

- name: Single filer at 250% FPL - 4% contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 2.5
output:
aca_required_contribution_percentage: 0.04

- name: Single filer at 300% FPL - 6% contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 3.0
output:
aca_required_contribution_percentage: 0.06

- name: Single filer at 400% FPL - 8.5% contribution (old cliff point)
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 4.0
output:
aca_required_contribution_percentage: 0.085

- name: Single filer at 500% FPL - 8.5% contribution (flat rate)
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 5.0
output:
aca_required_contribution_percentage: 0.085

- name: Single filer at 600% FPL - 8.5% contribution (new cliff point)
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 6.0
output:
aca_required_contribution_percentage: 0.085

- name: Single filer at 175% FPL - interpolated 1% contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 1.75
output:
aca_required_contribution_percentage: 0.01

- name: Single filer at 350% FPL - interpolated 7.25% contribution
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 3.5
output:
aca_required_contribution_percentage: 0.0725

- name: Baseline comparison at 400% FPL - shows elimination of cliff
period: 2026
absolute_error_margin: 0.00001
input:
aca_magi_fraction: 4.0
output:
aca_required_contribution_percentage: 0.0996

- name: Baseline comparison at 500% FPL - shows new eligibility
period: 2026
absolute_error_margin: 0.00001
input:
aca_magi_fraction: 5.0
output:
aca_required_contribution_percentage: 0.0996

- name: Edge case - Very high income at 700% FPL extends last bracket
period: 2026
reforms: policyengine_us.reforms.aca.aca_ptc_600_fpl_cliff.aca_ptc_600_fpl_cliff
absolute_error_margin: 0.00001
input:
gov.contrib.aca.ptc_600_fpl_cliff.in_effect: true
aca_magi_fraction: 7.0
output:
aca_required_contribution_percentage: 0.085