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
1 change: 1 addition & 0 deletions changelog.d/ptc-refundable-credit-net-income.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Count the federal premium tax credit in household net income and household tax as a refundable tax credit (household_refundable_tax_credits), whether or not health benefits count in net income, so changes to it reach net income and the budget. income_tax and SPM resources are unchanged.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ values:
- medicaid_cost
- msp_cost
- chip
- assigned_aca_ptc
# The federal premium tax credit counts as a refundable tax credit
# (household_refundable_tax_credits) whether or not health benefits do.
- assigned_ca_premium_subsidy
- basic_health_program
- co_omnisalud
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ description: The government counts these sources as household health out-of-pock
values:
2022-01-01:
- chip_premium
- marketplace_net_premium
# The whole premium: household net income counts the premium tax credit
# that pays part of it as a refundable credit, so the net premium would
# count the credit twice.
- selected_marketplace_plan_premium_proxy

metadata:
unit: list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,8 @@ def test_semi_elasticity_capital_gains_response_end_to_end_from_a_zero_rate():
"""The semi-elasticity form through the model, from a 0% baseline rate.

A Texas filer whose $30,000 of gains sit in the 0% bracket faces a new 10%
rate there. The semi-elasticity response depends only on the change in the
rate there. The filer has employer coverage, so no premium tax credit
phases out with the gains. The semi-elasticity response depends only on the change in the
measured rate, so it is about 29% at 3.4, where the log-rate form's 0.001
floor would remove about 96% (test_capital_gains_response_forms.py covers
the forms' arithmetic without a simulation).
Expand All @@ -659,7 +660,13 @@ def test_semi_elasticity_capital_gains_response_end_to_end_from_a_zero_rate():
year = "2026"
gains = 30_000
situation = {
"people": {"p": {"age": {year: 50}, "long_term_capital_gains": {year: gains}}},
"people": {
"p": {
"age": {year: 50},
"long_term_capital_gains": {year: gains},
"has_esi": {year: True},
}
},
"tax_units": {"tu": {"members": ["p"]}},
"families": {"f": {"members": ["p"]}},
"spm_units": {"s": {"members": ["p"]}},
Expand Down
4 changes: 3 additions & 1 deletion policyengine_us/tests/core/test_estate_income_invariants.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,14 +480,16 @@ def test_estate_income_raises_household_net_income_by_its_after_tax_amount(
A single Texas filer with $50,000 of wages in 2024 receives $10,000 of
estate income, which stays in the 12% bracket. Texas has no income tax
and estate income carries no payroll tax, so household net income rises
by the $10,000 less the federal income tax increase.
by the $10,000 less the federal income tax increase. The filer has
employer coverage, so no premium tax credit falls as income rises.
"""

def net_income(estate):
head = {
"age": {2024: 40},
"employment_income": {2024: 50_000},
"estate_income": {2024: estate},
"has_esi": {2024: True},
}
if qualified is not None:
head["estate_income_would_be_qualified"] = {2024: qualified}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def test_raising_the_cap_only_adds_people(mtr_by_cap, variable):
# wages less the $14,600 standard deduction ($75,400, $45,400, $15,400), so a
# $1,000 raise is taxed at 22%, 12% and 12%, plus 7.65% employee payroll tax.
# Nobody crosses a bracket or payroll threshold, and Texas has no income tax.
# Each has employer coverage, so no premium tax credit phases out with a raise.
ROOMMATE_WAGES = (90_000, 60_000, 30_000)
ROOMMATE_RATES = {
"marginal_tax_rate": (0.2965, 0.1965, 0.1965),
Expand All @@ -193,7 +194,11 @@ def test_roommates_match_hand_computed_rates(cap):
names = [f"roommate{i}" for i in range(len(ROOMMATE_WAGES))]
situation = {
"people": {
name: {"age": {YEAR: 40 - 5 * i}, "employment_income": {YEAR: wages}}
name: {
"age": {YEAR: 40 - 5 * i},
"employment_income": {YEAR: wages},
"has_esi": {YEAR: True},
}
for i, (name, wages) in enumerate(zip(names, ROOMMATE_WAGES))
},
"tax_units": {f"{name}_tax_unit": {"members": [name]} for name in names},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

- name: Case 1, Military retirement pay flows into federal gross income, AGI, and taxable income.
period: 2024
absolute_error_margin: 0.01
input:
people:
person1:
Expand All @@ -28,7 +29,10 @@
household_market_income: 30_000
snap_unearned_income: 30_000
ssi_unearned_income: 30_000
household_net_income: 28_384
# With no other coverage, a 2024 marketplace credit under the enhanced
# schedule, which household net income counts as a refundable credit.
premium_tax_credit_in_force: 10_323.72
household_net_income: 28_384 + 10_323.72

- name: Case 2, Military retirement pay survivors flows into federal gross income, AGI, and taxable income.
period: 2024
Expand Down Expand Up @@ -56,6 +60,7 @@

- name: Case 3, Military retirement pay adds with employment income.
period: 2024
absolute_error_margin: 0.01
input:
people:
person1:
Expand All @@ -77,7 +82,10 @@
taxable_income: 70_000 - 14_600
market_income: 70_000
household_market_income: 70_000
household_net_income: 59_699
# The enhanced schedule's credit above 400% FPL: the benchmark premium
# minus 8.5% of income.
premium_tax_credit_in_force: 2_846.77
household_net_income: 59_699 + 2_846.77

- name: Case 4, Dependent military retirement pay is excluded from the tax unit filer gross income.
period: 2024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@

- name: Indiana county tax flows from earnings to household and SPM totals
period: 2021
absolute_error_margin: 0.01
input:
state_code: IN
county_str: BOONE_COUNTY_IN
Expand All @@ -101,8 +102,10 @@
local_income_tax: 735
local_income_tax_before_refundable_credits: 735
local_tax: 735
household_tax: 9_037.7
household_net_income: 40_962.3
# The 2021 premium tax credit lowers household tax, not the SPM's taxes.
premium_tax_credit_in_force: 1_275.24
household_tax: 9_037.7 - 1_275.24
household_net_income: 40_962.3 + 1_275.24
spm_unit_local_tax: 735
spm_unit_taxes: 9_037.7
spm_unit_net_income: 36_824.8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,18 @@
# 2,339.51 - 1,250 = 1,089.51.
state_income_tax: 1_089.51
household_refundable_state_tax_credits: 1_250
# Federal 2021 recovery rebate credit 1,400 + MT rebate 1,250 = 2,650.
household_refundable_tax_credits: 2_650
# With no other coverage, a 2021 marketplace credit under the enhanced
# schedule.
premium_tax_credit_in_force: 2_272.79
# Federal 2021 recovery rebate credit 1,400 + MT rebate 1,250 + premium
# tax credit 2,272.79 = 4,922.79.
household_refundable_tax_credits: 4_922.79
# Federal income tax 4,295 (TI = 50,000 - 12,550 = 37,450;
# 10% x 9,950 + 12% x 27,500 = 995 + 3,300) + employee payroll tax
# 3,825 (7.65% x 50,000) + MT line 20 2,339.51 = 10,459.51.
household_tax_before_refundable_credits: 10_459.51
# 50,000 + 2,650 - 10,459.51 = 42,190.49 (40,940.49 without the rebate).
household_net_income: 42_190.49
# 50,000 + 4,922.79 - 10,459.51 = 44,463.28 (43,213.28 without the rebate).
household_net_income: 44_463.28
# SPM resources rise by the same 1,250 through spm_unit_state_tax:
# 36,802.99 without the rebate + 1,250 = 38,052.99.
spm_unit_net_income: 38_052.99
Expand Down Expand Up @@ -744,14 +748,19 @@
# 2,518.22 - 2,500 = 18.22.
state_income_tax: 18.22
household_refundable_state_tax_credits: 2_500
# Federal 2021 recovery rebate credit 2 x 1,400 + MT rebate 2,500 = 5,300.
household_refundable_tax_credits: 5_300
# With no other coverage, a 2021 marketplace credit for both under the
# enhanced schedule.
premium_tax_credit_in_force: 8_500.58
# Federal 2021 recovery rebate credit 2 x 1,400 + MT rebate 2,500 +
# premium tax credit 8,500.58 = 13,800.58.
household_refundable_tax_credits: 13_800.58
# Federal income tax 3,790 (TI = 60,000 - 25,100 = 34,900;
# 10% x 19,900 + 12% x 15,000 = 1,990 + 1,800) + employee payroll tax
# 4,590 (7.65% x 60,000) + MT line 20 2,518.22 = 10,898.22.
household_tax_before_refundable_credits: 10_898.22
# 60,000 + 5,300 - 10,898.22 = 54,401.78 (51,901.78 without the rebate).
household_net_income: 54_401.78
# 60,000 + 13,800.58 - 10,898.22 = 62,902.36 (60,402.36 without the
# rebate).
household_net_income: 62_902.36
# SPM resources rise by the same 2,500 through spm_unit_state_tax:
# 47,581.78 without the rebate + 2,500 = 50,081.78.
spm_unit_net_income: 50_081.78
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
household_health_benefits: 0
household_benefits: 0

- name: Case 2, flag on includes annual canonical ACA PTC and Medicaid value.
- name: Case 2, flag on includes the Medicaid value; the ACA PTC counts as a refundable tax credit instead.
period: 2026
absolute_error_margin: 0.01
input:
Expand All @@ -21,8 +21,8 @@
medicaid_cost: 500
snap: 0
output:
household_health_benefits: 1_500
household_benefits: 1_500
household_health_benefits: 500
household_benefits: 500

- name: Case 3, flag on includes annual MSP and CHIP values.
period: 2026
Expand All @@ -35,8 +35,8 @@
chip: 300
snap: 0
output:
household_health_benefits: 4_234.8
household_benefits: 4_234.8
household_health_benefits: 3_234.8
household_benefits: 3_234.8

- name: Case 4, legacy wrappers do not double count canonical health values.
period: 2026
Expand All @@ -52,8 +52,8 @@
msp_cost: 2_434.8
snap: 0
output:
household_health_benefits: 4_234.8
household_benefits: 4_234.8
household_health_benefits: 3_234.8
household_benefits: 3_234.8

- name: Case 5, flag on includes forced Maryland Premium Assistance value.
# md_premium_assistance is registered in the household_health_benefits list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@
healthcare_benefit_value: 2_000
output:
household_net_income_including_health_benefits: 4_000

- name: The premium tax credit, in both net income and health benefits, counts once
period: 2026
input:
household_net_income: 3_000
healthcare_benefit_value: 1_500
premium_tax_credit_in_force: 1_000
output:
household_net_income_including_health_benefits: 3_000 + 1_500 - 1_000
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@
output:
household_health_costs: 360

- name: Household health costs include Marketplace net premium when health benefits are included in net income.
- name: Household health costs include the whole Marketplace premium when health benefits are included in net income.
period: 2024
input:
gov.simulation.include_health_benefits_in_net_income: true
chip_premium: 360
marketplace_net_premium: 2_000
selected_marketplace_plan_premium_proxy: 2_000
output:
household_health_costs: 2_360

- name: Household health costs include computed unsubsidized Marketplace net premium.
- name: The premium tax credit doesn't lower household health costs, since net income counts it as a refundable credit.
period: 2026
input:
gov.simulation.include_health_benefits_in_net_income: true
chip_premium: 0
selected_marketplace_plan_premium_proxy: 5_000
aca_ptc: 1_000
output:
marketplace_net_premium: 4_000
household_health_costs: 5_000

- name: Household health costs include a computed unsubsidized Marketplace premium.
absolute_error_margin: 0.01
period: 2026
input:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,104 @@
output:
spm_unit_net_income: 500_000 + 1_000 + 200
household_net_income: 500_000 + 1_000 + 200

- name: Household net income counts the premium tax credit as a refundable tax credit.
period: 2026
input:
household_market_income: 30_000
household_benefits: 0
income_tax_refundable_credits_in_force: 0
household_refundable_state_tax_credits: 0
household_refundable_local_tax_credits: 0
used_aca_ptc: 4_000
household_tax_before_refundable_credits: 2_000
household_health_costs: 0
output:
household_tax: 2_000 - 4_000
household_net_income: 30_000 + 4_000 - 2_000

# With health benefits counted, health costs subtract the whole Marketplace
# premium, so a credit that is $1,000 larger raises net income by $1,000, not
# $2,000 (once as a refundable credit and again through a smaller net premium).
- name: With health benefits counted, a $1,000 premium tax credit against a $5,000 premium.
period: 2026
input:
gov.simulation.include_health_benefits_in_net_income: true
household_market_income: 30_000
household_benefits: 0
income_tax_refundable_credits_in_force: 0
household_refundable_state_tax_credits: 0
household_refundable_local_tax_credits: 0
household_tax_before_refundable_credits: 2_000
chip_premium: 0
selected_marketplace_plan_premium_proxy: 5_000
aca_ptc: 1_000
output:
premium_tax_credit_in_force: 1_000
household_health_costs: 5_000
household_net_income: 30_000 + 1_000 - 2_000 - 5_000

- name: With health benefits counted, a $2,000 premium tax credit against the same premium.
period: 2026
input:
gov.simulation.include_health_benefits_in_net_income: true
household_market_income: 30_000
household_benefits: 0
income_tax_refundable_credits_in_force: 0
household_refundable_state_tax_credits: 0
household_refundable_local_tax_credits: 0
household_tax_before_refundable_credits: 2_000
chip_premium: 0
selected_marketplace_plan_premium_proxy: 5_000
aca_ptc: 2_000
output:
premium_tax_credit_in_force: 2_000
household_health_costs: 5_000
household_net_income: 30_000 + 2_000 - 2_000 - 5_000

# A single Texas adult aged 40 in 2025 (the 2017 cliffs analysis household,
# PolicyEngine/us-cliffs-2017 scripts/ptc_household.py), with health benefits
# counted. A $1,000 raise cuts the premium tax credit by $94, and net income
# rises by $709.50 with or without health benefits counted (31,840.09 to
# 32,549.59 without): the cut counts once.
- name: With health benefits counted, a Texas adult earning $30,000 in 2025.
period: 2025
absolute_error_margin: 0.01
input:
gov.simulation.include_health_benefits_in_net_income: true
people:
person1:
age: 40
employment_income: 30_000
tax_units:
tax_unit:
members: [person1]
households:
household:
members: [person1]
state_code: TX
output:
premium_tax_credit_in_force: 5_606.58
household_health_costs: 6_194.58
household_net_income: 25_645.50

- name: With health benefits counted, the same adult earning $31,000.
period: 2025
absolute_error_margin: 0.01
input:
gov.simulation.include_health_benefits_in_net_income: true
people:
person1:
age: 40
employment_income: 31_000
tax_units:
tax_unit:
members: [person1]
households:
household:
members: [person1]
state_code: TX
output:
premium_tax_credit_in_force: 5_512.58
household_health_costs: 6_194.58
household_net_income: 25_645.50 + 709.50
Loading
Loading