Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix the CBO Social Security secondary earnings threshold reform to include self-employment earnings, avoid negative SECA and overlapping tax bases, activate for future-dated thresholds, and preserve Connecticut and Delaware paid-leave contribution bases.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
description: The US levies payroll taxes on earnings greater than this amount, in addition to earnings below the maximum taxable amount under current law.
description: The US levies payroll taxes on earnings greater than this amount, in addition to earnings below the maximum taxable amount under current law. With a fixed $250,000 threshold, the model's current-law cap of $254,400 closes the donut in 2035, one year before the 2036 date projected in CBO's 2024 option.
values:
2021-01-01: .inf
metadata:
unit: USD
label: Social Security payroll tax secondary earnings threshold
reference:
- title: Increase the Maximum Taxable Earnings That Are Subject to Social Security Payroll Taxes, option alternative 2
href: https://www.cbo.gov/budget-options/58630
href: https://www.cbo.gov/budget-options/60955
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,53 @@ class taxable_earnings_for_social_security(Variable):
label = "Taxable gross earnings for OASDI FICA"
definition_period = YEAR
unit = USD
reference = (
"https://www.cbo.gov/budget-options/60955",
"https://www.ssa.gov/OACT/solvency/provisions_tr2025/charts/chart_run418.html",
)

def formula(person, period, parameters):
earnings = person("payroll_tax_gross_wages", period)
p = parameters(period).gov
base_taxable = min_(earnings, p.irs.payroll.social_security.cap)
secondary_taxable = max_(
0,
earnings - p.contrib.cbo.payroll.secondary_earnings_threshold,
cap = p.irs.payroll.social_security.cap
secondary_threshold = max_(
p.contrib.cbo.payroll.secondary_earnings_threshold, cap
)
base_taxable = min_(earnings, cap)
# The bases meet without overlapping once the cap closes the donut.
secondary_taxable = max_(0, earnings - secondary_threshold)
return base_taxable + secondary_taxable

class social_security_taxable_self_employment_income(Variable):
value_type = float
entity = Person
label = "Taxable self-employment income for computing Social Security tax"
definition_period = YEAR
unit = USD
reference = (
"https://www.cbo.gov/budget-options/60955",
"https://www.law.cornell.edu/uscode/text/26/1402#b",
"https://www.ssa.gov/OACT/solvency/provisions_tr2025/charts/chart_run418.html",
)

def formula(person, period, parameters):
earnings = person("taxable_self_employment_income", period)
wages = person("payroll_tax_gross_wages", period)
p = parameters(period).gov
cap = p.irs.payroll.social_security.cap
secondary_threshold = max_(
p.contrib.cbo.payroll.secondary_earnings_threshold, cap
)
# Wages fill the combined base first, both below the cap and
# above the secondary threshold. Only the remaining SE is taxed.
base_taxable = min_(earnings, max_(0, cap - wages))
secondary_taxable = max_(0, earnings - max_(0, secondary_threshold - wages))
return base_taxable + secondary_taxable

class reform(Reform):
def apply(self):
self.update_variable(taxable_earnings_for_social_security)
self.update_variable(social_security_taxable_self_employment_income)

return reform

Expand All @@ -32,9 +65,10 @@ def create_increase_taxable_earnings_for_social_security_reform(
if bypass:
return create_increase_taxable_earnings_for_social_security()

p = parameters(period).gov.contrib.cbo.payroll

if p.secondary_earnings_threshold < np.inf:
threshold = parameters.gov.contrib.cbo.payroll.secondary_earnings_threshold
# Inspect dated overrides, as in the CA Proposition 3 reform, rather
# than only the simulation's start instant or a fixed lookahead window.
if any(np.isfinite(value.value) for value in threshold.values_list):
return create_increase_taxable_earnings_for_social_security()
else:
return None
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
- name: Default is zero.
period: 2024
output:
social_security_taxable_self_employment_income: 0

- name: Self-employment earnings below the remaining cap are fully taxable.
period: 2024
input:
payroll_tax_gross_wages: 100_000
taxable_self_employment_income: 50_000
output:
social_security_taxable_self_employment_income: 50_000

- name: Self-employment earnings fill the remaining current-law cap.
period: 2024
input:
payroll_tax_gross_wages: 100_000
taxable_self_employment_income: 100_000
output:
# The 168,600 cap leaves 68,600 after wages.
social_security_taxable_self_employment_income: 68_600

- name: Wages at the current-law cap leave no taxable self-employment earnings.
period: 2024
input:
payroll_tax_gross_wages: 168_600
taxable_self_employment_income: 50_000
output:
social_security_taxable_self_employment_income: 0

- name: Wages above the current-law cap leave no taxable self-employment earnings.
period: 2024
input:
payroll_tax_gross_wages: 400_000
taxable_self_employment_income: 50_000
output:
taxable_earnings_for_social_security: 168_600
social_security_taxable_self_employment_income: 0

- name: A reform or direct input exceeding the cap cannot make self-employment tax negative.
period: 2024
input:
taxable_earnings_for_social_security: 400_000
taxable_self_employment_income: 50_000
output:
social_security_taxable_self_employment_income: 0
self_employment_social_security_tax: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- name: Connecticut paid leave retains the federal wage cap under the secondary threshold reform.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
absolute_error_margin: 0.01
input:
state_code: CT
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 400_000
output:
# The federal reform is active, but C.G.S. 31-49g(b)(1) retains the cap.
taxable_earnings_for_social_security: 342_300
# 192,300 * 0.5% = 961.50.
ct_employee_paid_leave_contribution: 961.50
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
- name: Delaware paid leave retains the federal wage cap under the secondary threshold reform.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
absolute_error_margin: 0.01
input:
state_code: DE
employer_headcount: 25
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 400_000
output:
# 19 Del. C. 3701(24) and 19 DE Admin. Code 1401, section 5.5 retain the cap.
taxable_earnings_for_social_security: 342_300
de_paid_leave_contribution_rate: 0.008
# Each share is 192,300 * (0.4% + 0.08% + 0.32%) * 50% = 769.20.
de_employee_paid_leave_contribution: 769.20
de_employer_paid_leave_contribution: 769.20
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
- name: Self-employment fills the remaining cap and crosses the upper edge of the donut.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 180_000
taxable_self_employment_income: 100_000
output:
# Remaining cap = 12,300; combined earnings exceed 250,000 by 30,000.
social_security_taxable_self_employment_income: 42_300

- name: Combined earnings inside the donut do not add taxable self-employment earnings.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 200_000
taxable_self_employment_income: 40_000
output:
taxable_earnings_for_social_security: 192_300
social_security_taxable_self_employment_income: 0

- name: Combined earnings exactly at the upper edge of the donut add no taxable self-employment earnings.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 200_000
taxable_self_employment_income: 50_000
output:
social_security_taxable_self_employment_income: 0

- name: The first dollar above the combined earnings threshold is taxable self-employment income.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 200_000
taxable_self_employment_income: 50_001
output:
social_security_taxable_self_employment_income: 1

- name: Self-employment earnings below the threshold fill only the remaining cap.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 100_000
taxable_self_employment_income: 100_000
output:
taxable_earnings_for_social_security: 100_000
social_security_taxable_self_employment_income: 92_300

- name: Self-employment alone receives both the capped base and earnings above the threshold.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 0
taxable_self_employment_income: 300_000
output:
# 192,300 below the cap plus 50,000 above the threshold.
social_security_taxable_self_employment_income: 242_300

- name: Self-employment dollars are taxed once after the cap exceeds the threshold.
period: 2036
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 263_100
payroll_tax_gross_wages: 240_000
taxable_self_employment_income: 40_000
output:
# 23,100 of remaining cap plus 16,900 above 263,100 equals all 40,000.
social_security_taxable_self_employment_income: 40_000
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
- name: Earnings above the donut threshold do not create negative SECA without self-employment income.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
absolute_error_margin: 0.01
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 400_000
self_employment_income: 0
output:
# Wage base = 192,300 + (400,000 - 250,000) = 342,300.
taxable_earnings_for_social_security: 342_300
social_security_taxable_self_employment_income: 0
# Employee and employer each pay 342,300 * 6.2% = 21,222.60.
employee_social_security_tax: 21_222.60
employer_social_security_tax: 21_222.60
self_employment_social_security_tax: 0

- name: Self-employment earnings above the threshold join wages in the taxable base.
period: 2027
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
absolute_error_margin: 0.01
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 192_300
payroll_tax_gross_wages: 300_000
self_employment_income: 50_000
output:
# Wage base = 192,300 + (300,000 - 250,000) = 242,300.
taxable_earnings_for_social_security: 242_300
# Net SE earnings = 50,000 * 0.9235 = 46,175, all above the threshold.
taxable_self_employment_income: 46_175
social_security_taxable_self_employment_income: 46_175
employee_social_security_tax: 15_022.60
employer_social_security_tax: 15_022.60
# SECA = 46,175 * 12.4% = 5,725.70.
self_employment_social_security_tax: 5_725.70

- name: A cap above the threshold taxes each dollar of wages once.
period: 2036
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
absolute_error_margin: 0.01
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 263_100
payroll_tax_gross_wages: 400_000
self_employment_income: 0
output:
# Wage base = 263,100 + (400,000 - 263,100) = 400,000.
taxable_earnings_for_social_security: 400_000
social_security_taxable_self_employment_income: 0
# Each FICA share = 400,000 * 6.2% = 24,800; SECA remains zero.
employee_social_security_tax: 24_800
employer_social_security_tax: 24_800
self_employment_social_security_tax: 0

- name: Wages between the threshold and a higher cap are taxed once.
period: 2036
reforms: policyengine_us.reforms.cbo.payroll.increase_taxable_earnings_for_social_security.increase_taxable_earnings_for_social_security
input:
gov.contrib.cbo.payroll.secondary_earnings_threshold: 250_000
gov.irs.payroll.social_security.cap: 263_100
payroll_tax_gross_wages: 255_000
output:
taxable_earnings_for_social_security: 255_000
Loading
Loading