Skip to content
1 change: 1 addition & 0 deletions changelog.d/fix-sehi-earned-income-limit.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Limit the self-employed health insurance deduction to net profit less the deductible part of self-employment tax and self-employed retirement plan deductions, as 26 U.S.C. 162(l)(2)(A) and Form 7206 require.
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ def _assert_conservation(members, simulation):
# non-premium expenses. Check the bound separately from conservation.
assert (schedule_a_premium_use >= 0).all()
assert (schedule_a_premium_use >= dependent_premiums).all()
assert (schedule_a_premium_use + se_deduction <= paid).all()
# The Form 7206 earnings limit leaves cents in the derived deduction, so
# the sums carry float32 rounding: allow a cent.
assert (schedule_a_premium_use + se_deduction <= paid + 0.01).all()
# All premiums here are otherwise eligible: unused premiums remain in
# Schedule A's base, even when earnings cap the SE deduction.
np.testing.assert_array_equal(schedule_a_premium_use + se_deduction, paid)
np.testing.assert_allclose(
schedule_a_premium_use + se_deduction, paid, rtol=0, atol=0.01
)


EXAMPLE_UNITS = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Form 7206 line 14 (Pub. 535 Worksheet 6-A line 14 before 2023; line 3 of the
# Form 1040 instructions worksheet for filers with one source of
# self-employment income): the smaller of the premiums and the earned income
# limit. Expected values are hand-computed from the form.

- name: Case 1, premiums above the limit are capped at net profit less half of self-employment tax.
period: 2022
absolute_error_margin: 0.01
input:
people:
person1:
is_self_employed: true
self_employment_income: 2_000
health_insurance_premiums: 6_000
tax_units:
tax_unit:
members: [person1]
households:
household:
members: [person1]
state_code: TX
output:
# 2022 Form 1040 instructions worksheet: line 1 is 6,000; line 2 is
# 2,000 - 141.2955 (Schedule 1 line 15) = 1,858.7045.
self_employed_health_insurance_ald_person: [1_858.7045]
self_employed_health_insurance_ald: 1_858.7045
# 2,000 - 141.2955 - 1,858.7045.
adjusted_gross_income: 0

- name: Case 2, premiums below the limit are deducted in full.
period: 2022
absolute_error_margin: 0.01
input:
is_self_employed: true
self_employment_income: 50_000
health_insurance_premiums: 6_000
output:
# Line 2: 50,000 - 3,532.3875 = 46,467.6125.
self_employed_health_insurance_earned_income_limit: 46_467.6125
self_employed_health_insurance_ald_person: 6_000

- name: Case 3, the plan deduction and half of self-employment tax both reduce the cap.
period: 2023
absolute_error_margin: 0.01
input:
is_self_employed: true
self_employment_income: 20_000
self_employed_pension_contributions_desired: 3_000
health_insurance_premiums: 20_000
output:
# Form 7206: line 3 is 20,000; line 13 is 20,000 - 1,412.955 - 3,000.
self_employed_health_insurance_ald_person: 15_587.045

- name: Case 4, a farm business takes its share of the self-employment tax deduction.
period: 2024
absolute_error_margin: 0.01
input:
is_self_employed: true
self_employment_income: 30_000
farm_operations_income: 10_000
health_insurance_premiums: 40_000
output:
# Form 7206 line 13: 30,000 - 0.75 x 2,825.91 = 27,880.5675.
self_employed_health_insurance_ald_person: 27_880.5675

- name: Case 5, each spouse's deduction is capped by their own earned income.
period: 2025
absolute_error_margin: 0.01
input:
people:
person1:
is_self_employed: true
self_employment_income: 3_000
health_insurance_premiums: 8_000
person2:
is_self_employed: true
self_employment_income: 40_000
health_insurance_premiums: 2_000
tax_units:
tax_unit:
members: [person1, person2]
marital_units:
marital_unit:
members: [person1, person2]
households:
household:
members: [person1, person2]
state_code: TX
output:
# person1: 3,000 - 3,000 x 0.9235 x 0.153 / 2 = 3,000 - 211.94325.
# person2: premiums of 2,000 are under the limit.
self_employed_health_insurance_ald_person: [2_788.05675, 2_000]
self_employed_health_insurance_ald: 4_788.05675

- name: Case 6, no deduction with a Schedule C loss.
period: 2025
absolute_error_margin: 0.01
input:
is_self_employed: true
self_employment_income: -5_000
health_insurance_premiums: 3_000
output:
self_employed_health_insurance_ald_person: 0

- name: Case 7, spouses on either side of the Social Security wage base each use their own self-employment tax deduction.
period: 2025
absolute_error_margin: 0.01
input:
people:
person1:
is_self_employed: true
employment_income: 200_000
self_employment_income: 10_000
health_insurance_premiums: 20_000
person2:
is_self_employed: true
self_employment_income: 10_000
health_insurance_premiums: 20_000
tax_units:
tax_unit:
members: [person1, person2]
marital_units:
marital_unit:
members: [person1, person2]
households:
household:
members: [person1, person2]
state_code: TX
output:
# person1's wages exceed the $176,100 wage base, so Schedule 1 line 15 is
# 10,000 x 0.9235 x 0.029 / 2 = 133.9075; person2's is
# 10,000 x 0.9235 x 0.153 / 2 = 706.4775.
self_employment_tax_ald_person: [133.9075, 706.4775]
# Form 7206 line 13 for each: 10,000 less their own line 15.
self_employed_health_insurance_ald_person: [9_866.0925, 9_293.5225]
self_employed_health_insurance_ald: 19_159.615

- name: Case 8, a dependent's deduction is capped by their own earned income and stays off the filer's return.
period: 2025
absolute_error_margin: 0.01
input:
people:
parent:
age: 45
employment_income: 50_000
child:
age: 17
is_tax_unit_dependent: true
is_self_employed: true
self_employment_income: 3_000
health_insurance_premiums: 5_000
tax_units:
tax_unit:
members: [parent, child]
households:
household:
members: [parent, child]
state_code: TX
output:
# child: 3,000 - 3,000 x 0.9235 x 0.153 / 2 = 3,000 - 211.94325.
self_employed_health_insurance_ald_person: [0, 2_788.05675]
# The child takes it on their own return.
self_employed_health_insurance_ald: 0
dependents_self_employed_health_insurance_ald: 2_788.05675
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Form 7206 lines 4-13 (Pub. 535 Worksheet 6-A before 2023). Expected values
# are hand-computed from the form: the deductible part of self-employment tax
# is net profit x 0.9235 x 15.3% / 2 below the Social Security wage base.

- name: Case 1, one business, the limit is net profit less half of self-employment tax.
period: 2022
absolute_error_margin: 0.01
input:
self_employment_income: 2_000
output:
# Schedule 1 line 15: 2,000 x 0.9235 x 0.153 / 2 = 141.2955.
self_employment_tax_ald_person: 141.2955
# Line 13: 2,000 - 141.2955.
self_employed_health_insurance_earned_income_limit: 1_858.7045

- name: Case 2, the SEP, SIMPLE and qualified plan deduction also reduces the limit.
period: 2023
absolute_error_margin: 0.01
input:
self_employment_income: 20_000
self_employed_pension_contributions_desired: 3_000
output:
# Schedule 1 line 15: 20,000 x 0.9235 x 0.153 / 2 = 1,412.955.
self_employment_tax_ald_person: 1_412.955
# Schedule 1 line 16 (within the $66,000 annual additions limit).
self_employed_pension_contribution_ald_person: 3_000
# Lines 8 to 10: 20,000 - 1,412.955 - 3,000.
self_employed_health_insurance_earned_income_limit: 15_587.045

- name: Case 3, a farm business takes its share of the self-employment tax deduction.
period: 2024
absolute_error_margin: 0.01
input:
self_employment_income: 30_000
farm_operations_income: 10_000
output:
# Schedule 1 line 15: 40,000 x 0.9235 x 0.153 / 2 = 2,825.91.
self_employment_tax_ald_person: 2_825.91
# Lines 5 to 8: 30,000 / 40,000 = 0.75; 30,000 - 0.75 x 2,825.91.
self_employed_health_insurance_earned_income_limit: 27_880.5675

- name: Case 4, a partnership's self-employment earnings take their share too.
period: 2024
absolute_error_margin: 0.01
input:
self_employment_income: 30_000
partnership_self_employment_net_earnings: 30_000
output:
# Schedule 1 line 15: 60,000 x 0.9235 x 0.153 / 2 = 4,238.865.
self_employment_tax_ald_person: 4_238.865
# Lines 5 to 8: 30,000 / 60,000 = 0.5; 30,000 - 0.5 x 4,238.865.
self_employed_health_insurance_earned_income_limit: 27_880.5675

- name: Case 5, a farm loss is left out of line 5, so the plan business takes the whole deduction.
period: 2024
absolute_error_margin: 0.01
input:
self_employment_income: 30_000
farm_operations_income: -10_000
output:
# Schedule 1 line 15: (30,000 - 10,000) x 0.9235 x 0.153 / 2 = 1,412.955.
self_employment_tax_ald_person: 1_412.955
# Lines 5 to 8: line 5 is 30,000, so line 6 is 1; 30,000 - 1,412.955.
self_employed_health_insurance_earned_income_limit: 28_587.045

- name: Case 6, wages above the Social Security wage base leave only the Medicare part.
period: 2025
absolute_error_margin: 0.01
input:
employment_income: 200_000
self_employment_income: 10_000
output:
# Wages exceed the $176,100 wage base, so Schedule 1 line 15 is
# 10,000 x 0.9235 x 0.029 / 2 = 133.9075.
self_employment_tax_ald_person: 133.9075
self_employed_health_insurance_earned_income_limit: 9_866.0925

- name: Case 7, net earnings under $400 owe no self-employment tax, so the limit is net profit.
period: 2025
absolute_error_margin: 0.01
input:
self_employment_income: 400
output:
# 400 x 0.9235 = 369.40, under the $400 threshold of section 1402(b)(2).
self_employment_tax_ald_person: 0
self_employed_health_insurance_earned_income_limit: 400

- name: Case 8, a Schedule C loss leaves no limit.
period: 2025
absolute_error_margin: 0.01
input:
self_employment_income: -5_000
partnership_self_employment_net_earnings: 20_000
output:
self_employed_health_insurance_earned_income_limit: 0

- name: Case 9, a plan deduction as large as net profit leaves no limit.
period: 2023
absolute_error_margin: 0.01
input:
self_employment_income: 20_000
self_employed_pension_contributions_desired: 20_000
output:
# Schedule 1 line 15: 20,000 x 0.9235 x 0.153 / 2 = 1,412.955.
self_employment_tax_ald_person: 1_412.955
# Schedule 1 line 16: the model caps the plan deduction at net profit.
self_employed_pension_contribution_ald_person: 20_000
# Lines 8 to 13: max(0, 20,000 - 1,412.955 - 20,000).
self_employed_health_insurance_earned_income_limit: 0

- name: Case 10, SSTB and non-SSTB Schedule C income are one plan business, so an SSTB loss reduces line 4.
period: 2025
absolute_error_margin: 0.01
input:
self_employment_income: 30_000
sstb_self_employment_income: -10_000
output:
# Schedule 1 line 15: 20,000 x 0.9235 x 0.153 / 2 = 1,412.955.
self_employment_tax_ald_person: 1_412.955
# Lines 4 and 5 are both 20,000, so line 6 is 1; 20,000 - 1,412.955.
self_employed_health_insurance_earned_income_limit: 18_587.045
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@

- name: Self-employed health insurance ALD uses SSTB income
period: 2024
absolute_error_margin: 0.01
input:
sstb_self_employment_income: 10_000
self_employed_health_insurance_premiums: 12_000
output:
self_employed_health_insurance_ald_person: 10_000
# Form 7206 line 13: 10,000 - 10,000 x 0.9235 x 0.153 / 2.
self_employed_health_insurance_ald_person: 9_293.5225

- name: Self-employed pension ALD uses SSTB income
period: 2024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@

- name: An earnings-limited derived SE deduction leaves unused premiums on Schedule A.
period: 2025
absolute_error_margin: 0.01
input:
is_self_employed: true
health_insurance_premiums: 6_000
self_employment_income: 1_000
other_medical_expenses: 500
adjusted_gross_income: 30_000
output:
self_employed_health_insurance_ald: 1_000
itemized_medical_expenses: 5_500
medical_expense_deduction: 3_250
# Form 7206 line 13: 1,000 - 1,000 x 0.9235 x 0.153 / 2 = 929.35225.
self_employed_health_insurance_ald: 929.35225
# 6,000 - 929.35225 + 500.
itemized_medical_expenses: 5_570.64775
# 5,570.64775 - 7.5% of 30,000.
medical_expense_deduction: 3_320.64775

- name: Fully deducted premiums leave only non-premium medical expenses.
period: 2025
Expand Down Expand Up @@ -87,6 +91,7 @@

- name: Each filing unit excludes its own SE deduction independently of pretax premiums.
period: 2025
absolute_error_margin: 0.01
input:
people:
person1:
Expand Down Expand Up @@ -116,9 +121,11 @@
members: [person3]
adjusted_gross_income: 30_000
output:
self_employed_health_insurance_ald: [1_000, 1_000, 0]
itemized_medical_expenses: [5_500, 5_500, 6_500]
medical_expense_deduction: [3_250, 3_250, 4_250]
# Form 7206 line 13: 1,000 - 1,000 x 0.9235 x 0.153 / 2 = 929.35225.
self_employed_health_insurance_ald: [929.35225, 929.35225, 0]
# 6,000 - 929.35225 + 500; the pretax premiums are not on Schedule A.
itemized_medical_expenses: [5_570.64775, 5_570.64775, 6_500]
medical_expense_deduction: [3_320.64775, 3_320.64775, 4_250]

- name: A filer SE deduction cannot consume premiums attributed to a dependent.
period: 2025
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1125,18 +1125,13 @@
state_code: MI
output:
# Line 14: 40,000. Line 16: 3,000.
# PolicyEngine's pre-existing federal simplification limits the health
# insurance deduction to net self-employment income before deductible
# self-employment tax: 3,000 here.
# Line 30 in PolicyEngine: self-employment tax deduction, half of 3,000 x
# 0.9235 x 15.3% = 211.94, plus health insurance 3,000 = 3,211.94.
# Line 31: premiums of 5,000, less the 3,000 deducted on line 30 = 2,000.
# Line 33: 43,000 - 3,211.94 - 2,000 = 37,788.06. The premiums come off
# once in all: 3,000 on line 30 and 2,000 on line 31.
# 2025 Form 7206 lines 7-8 instead limit the health insurance deduction
# to 3,000 - 211.94 = 2,788.06. Then line 30 is 3,000 and line 31 is
# 5,000 - 2,788.06 = 2,211.94: 43,000 - 3,000 - 2,211.94 = 37,788.06.
# The Michigan total is unchanged because every premium comes off once.
# Line 30: the self-employment tax deduction, half of 3,000 x 0.9235 x
# 15.3% = 211.94, plus the health insurance deduction, which 2025 Form
# 7206 lines 7-8 limit to 3,000 - 211.94 = 2,788.06: 3,000 in all.
# Line 31: premiums of 5,000, less the 2,788.06 deducted on line 30 =
# 2,211.94.
# Line 33: 43,000 - 3,000 - 2,211.94 = 37,788.06. The premiums come off
# once in all: 2,788.06 on line 30 and 2,211.94 on line 31.
mi_household_resources: 37_788.06
absolute_error_margin: 0.01

Expand Down
Loading
Loading