PolicyEngine / policyengine-us

The PolicyEngine US Python package contains a rules engine of the US tax-benefit system, and microdata generation for microsimulation analysis.
https://policyengine.org/us
GNU Affero General Public License v3.0
103 stars 176 forks source link

The taxable_social_security variable formula needs refinement #1653

Closed martinholmer closed 1 year ago

martinholmer commented 1 year ago

In the course of developing pull request #1652, a simple test failed unexpectedly. Here is the test and its failure message:

- name: Test for MD social security AGI subtraction variable formula
  absolute_error_margin: 0.01
  period: 2021
  input:
    people:
      person1:
        is_tax_unit_head: true
        age: 62
        taxable_pension_income: 50_000
        social_security: 10_000
      person2:
        is_tax_unit_spouse: true
        age: 62
        social_security: 10_000
    spm_units:
      spm_unit:
        members: [person1, person2]
    tax_units:
      tax_unit:
        members: [person1, person2]
    households:
      household:
        members: [person1, person2]
        state_code: MD
  output:
    tax_unit_taxable_social_security: 17_000
    md_pension_subtraction_amount: 0
    md_socsec_subtraction: 17_000
    md_socsec_subtraction_amount: [8_500, 8_500]

The first three output variables passed, but the fourth failed unexpectedly. Here is the test failure message:

Test 'Test for MD social security AGI subtraction variable formula':
md_socsec_subtraction_amount@2021: [17000.     0.] differs from [ 8500.  8500.]
  with an absolute margin [8500. 8500.] > 0.01

After reviewing the person-level taxable_social_security variable formula, I now understand why the test failed and why the taxable_social_security formula needs refinement. Here are the details.

The taxable_social_security formula was developed eight months ago when the project was beginning to calculate US income taxes. Here is the key comment from the formula's code:

def formula(person, period, parameters):
    # The taxable amount of Social Security is decided at the tax unit level, but
    # gross income (which contains taxable SS) is person-level. Therefore, we
    # include the taxable SS in gross income by assigning it to the head of the 
    # tax unit: this will not affect overall tax liability.

When that comment was written eight months ago, it was true, and is still true, if "overall tax liability" is understood as US income tax liability. And that statement is true for some state income tax laws (for example, MO) that use the tax-unit sum of taxable_social_security rather than the person-level taxable_social_security amounts.

But for states that use the person-level taxable_social_security amounts to compute other person-level amounts (such as MD), the way in which the variable amount for tax_unit_taxable_social_security is allocated to people in the tax unit will "affect overall [state income] tax liability."

Given this situation, it seems to me that allocating the tax-unit amount to people in proportion to their total social_security amount would be a useful refinement. Making this change would not affect US income tax liability and would not affect MO income tax liability. But making this change would produce the correct MD income tax liability when a tax unit is eligible for the two-income married couple AGI subtraction. If we don't make this change, we will not be able to calculation MD AGI correctly in all cases.

martinholmer commented 1 year ago

After trying to work around the specification of the person-level taxable_social_security variable, I still could not pass a simple MD AGI subtractions test because it turns out the taxable_social_security variable is a component of the person-level irs_gross_income variable, which is also used to compute the MD two-income subtraction amount. Here is the test that failed:

- name: Test 2 for MD two-income AGI subtraction variable formula
  absolute_error_margin: 0.01
  period: 2021
  input:
    people:
      person1:
        is_tax_unit_head: true
        age: 65
        employment_income: 40_000
      person2:
        is_tax_unit_spouse: true
        age: 65
        taxable_pension_income: 10_000
        social_security: 10_000
      person3:
        age: 25
        is_disabled: true
    spm_units:
      spm_unit:
        members: [person1, person2, person3]
    tax_units:
      tax_unit:
        members: [person1, person2, person3]
        tax_unit_childcare_expenses: 6_000
    households:
      household:
        members: [person1, person2, person3]
        state_code: MD
  output:
    # the MD two-income married subtraction worksheet for this case is:
    # --------------------------------------------------
    # VARIABLE               HEAD      SPOUSE      TOTAL
    # --------------------------------------------------
    # US agi               40_000      18_500     58_500
    # care subtr                0           0          0
    # pension subtr             0      10_000     10_000
    # socsec subtr              0       8_500      8_500
    # (*) AGI less subtrs  40_000           0
    # two-income subtr                                 0
    # total subtrs              0      18_500     18_500
    # --------------------------------------------------
    # two-income subtr is min of head and spouse (*) amounts capped at $1200
    adjusted_gross_income: 58_500
    md_dependent_care_subtraction: 0
    md_pension_subtraction: 10_000
    md_pension_subtraction_amount: [0, 10_000, 0]
    md_socsec_subtraction: 8_500
    md_socsec_subtraction_amount: [0, 8_500, 0]
    md_two_income_subtraction: 0
    md_total_subtractions: 18_500

And here is the test failure message:

Test 'Test 2 for MD two-income AGI subtraction variable formula':
md_two_income_subtraction@2021: [750.] differs from 0.0
    with an absolute margin [750.] > 0.01

So, I have concluded there is no other option other than to refine the formula for the person-level taxable_social_security variable.