diff --git a/changelog.d/statute-first-state-income-tax.fixed.md b/changelog.d/statute-first-state-income-tax.fixed.md new file mode 100644 index 00000000000..854195d277d --- /dev/null +++ b/changelog.d/statute-first-state-income-tax.fixed.md @@ -0,0 +1 @@ +Follow the statute where state forms differ: New Mexico's senior medical exemption needs expenses over $28,000; Vermont's 2021 low-income child care credit needs AGI under the threshold; the New York and New York City household credits count the federal exemptions of married, head-of-household and surviving-spouse filers instead of denying the credit when a filer can be claimed (Tax Law 606(b), 1310(d)), and the New York City credit for a married couple filing separately uses the couple's AGI and exemptions; and Puerto Rico's earned income credit uses Hacienda's 2024 and 2025 inflation-adjusted schedules. diff --git a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/household/separate_per_dependent.yaml b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/household/separate_per_dependent.yaml index 93b9f764442..00bfeece18e 100644 --- a/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/household/separate_per_dependent.yaml +++ b/policyengine_us/parameters/gov/local/ny/nyc/tax/income/credits/household/separate_per_dependent.yaml @@ -1,4 +1,8 @@ -description: NYC provides a household credit of this amount per dependent for separate filers. +description: IT-201 Table 6 lists this NYC household credit amount per dependent for separate filers. +# Not used by nyc_household_credit: Tax Law 1310(d) gives a separate filer +# "one-half the credit otherwise allowed his or her household", which the +# model computes from the married amounts (other_per_dependent). Table 6 +# rounds the half amount per exemption, which can differ by a dollar or more. metadata: type: single_amount threshold_unit: currency-USD diff --git a/policyengine_us/parameters/gov/states/nm/tax/income/exemptions/unreimbursed_medical_care_expense/min_expenses.yaml b/policyengine_us/parameters/gov/states/nm/tax/income/exemptions/unreimbursed_medical_care_expense/min_expenses.yaml index 5aaca843301..d02feaad554 100644 --- a/policyengine_us/parameters/gov/states/nm/tax/income/exemptions/unreimbursed_medical_care_expense/min_expenses.yaml +++ b/policyengine_us/parameters/gov/states/nm/tax/income/exemptions/unreimbursed_medical_care_expense/min_expenses.yaml @@ -1,4 +1,4 @@ -description: New Mexico provides the unreimbursed medical care expense exemption for filers with expenses at or above this amount. +description: New Mexico provides the unreimbursed medical care expense exemption for filers with expenses above this amount. values: 2005-01-01: 28_000 metadata: diff --git a/policyengine_us/parameters/gov/states/vt/tax/income/credits/cdcc/income_limit_in_effect.yaml b/policyengine_us/parameters/gov/states/vt/tax/income/credits/cdcc/income_limit_in_effect.yaml index 3e736d244b6..3e7124523e0 100644 --- a/policyengine_us/parameters/gov/states/vt/tax/income/credits/cdcc/income_limit_in_effect.yaml +++ b/policyengine_us/parameters/gov/states/vt/tax/income/credits/cdcc/income_limit_in_effect.yaml @@ -1,4 +1,4 @@ -description: Vermont limits the Child and Dependent Care Credit to filers with adjusted gross income at or below the low-income threshold when this is in effect. +description: Vermont limits the Child and Dependent Care Credit to filers with adjusted gross income below the low-income threshold when this is in effect. values: # Through 2021 the Vermont credit under 32 V.S.A. § 5828c was the low-income # child and dependent care credit, limited to filers with AGI below the diff --git a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/max_amount.yaml b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/max_amount.yaml index ce5d03dd662..324c3e19ee4 100644 --- a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/max_amount.yaml +++ b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/max_amount.yaml @@ -4,18 +4,26 @@ brackets: 2023-01-01: 0 amount: 2023-01-01: 1_656 + 2024-01-01: 1_745 + 2025-01-01: 1_794 - threshold: 2023-01-01: 1 amount: 2023-01-01: 3_864 + 2024-01-01: 4_071 + 2025-01-01: 4_186 - threshold: 2023-01-01: 2 amount: 2023-01-01: 6_072 + 2024-01-01: 6_400 + 2025-01-01: 6_576 - threshold: 2023-01-01: 3 amount: 2023-01-01: 7_173 + 2024-01-01: 7_563 + 2025-01-01: 7_774 metadata: amount_unit: currency-USD threshold_unit: child @@ -23,7 +31,12 @@ metadata: label: Puerto Rico earned income credit max amount period: year reference: - # discrepancy: legal statute max amount doesn't correspond with tax form values + - title: "Hacienda Boletín Informativo de Rentas Internas 24-04, inflation adjustment to the earned income credit for 2024 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2024/12/bi_ri_24-04_-_credito_por_trabajo_-_ajuste_por_inflacion_2024_firmada_23-dic-2024.pdf#page=1 + - title: "Hacienda Boletín Informativo de Rentas Internas 26-01, inflation adjustment to the earned income credit for 2025 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2026/02/bi_ri_26-01_ajuste_por_inflacion_al_credito_por_trabajo_para_el_ano_2025_signed.pdf#page=1 + - title: P.R. Internal Revenue Code § 1052.01(i), 13 L.P.R.A. § 30211(i) (inflation adjustment as adjusted by the federal IRS) + href: https://docs.pr.gov/files/OCIF/LEYES-REGLAMENTOS-CARTAS-CIRCULARES/Leyes-delegan-Facultad-OCIF/Ley%20N%C3%BAm.%201-2011%20-%20C%C3%B3digo%20de%20Rentas%20Internas%20para%20un%20Nuevo%20Puerto%20Rico.pdf#page=300 - title: P.R. Laws tit. 13, § 30211 (1)-(6) href: https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1007/subchapter-b/30211/ - title: Schedule CT Individual, Earned Income Credit, 2023 diff --git a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/joint.yaml b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/joint.yaml index b8742b1404a..4d136070e9a 100644 --- a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/joint.yaml +++ b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/joint.yaml @@ -5,18 +5,26 @@ brackets: 2023-01-01: 0 amount: 2023-01-01: 19_870 + 2024-01-01: 20_940 + 2025-01-01: 21_530 - threshold: 2023-01-01: 1 amount: 2023-01-01: 24_280 + 2024-01-01: 25_590 + 2025-01-01: 26_310 - threshold: 2023-01-01: 2 amount: 2023-01-01: 27_590 + 2024-01-01: 29_080 + 2025-01-01: 29_900 - threshold: 2023-01-01: 3 amount: 2023-01-01: 27_590 + 2024-01-01: 29_080 + 2025-01-01: 29_900 metadata: amount_unit: currency-USD threshold_unit: child @@ -24,8 +32,13 @@ metadata: label: Puerto Rico earned income credit phase out threshold period: year reference: + - title: "Hacienda Boletín Informativo de Rentas Internas 24-04, inflation adjustment to the earned income credit for 2024 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2024/12/bi_ri_24-04_-_credito_por_trabajo_-_ajuste_por_inflacion_2024_firmada_23-dic-2024.pdf#page=1 + - title: "Hacienda Boletín Informativo de Rentas Internas 26-01, inflation adjustment to the earned income credit for 2025 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2026/02/bi_ri_26-01_ajuste_por_inflacion_al_credito_por_trabajo_para_el_ano_2025_signed.pdf#page=1 + - title: P.R. Internal Revenue Code § 1052.01(i), 13 L.P.R.A. § 30211(i) (inflation adjustment as adjusted by the federal IRS) + href: https://docs.pr.gov/files/OCIF/LEYES-REGLAMENTOS-CARTAS-CIRCULARES/Leyes-delegan-Facultad-OCIF/Ley%20N%C3%BAm.%201-2011%20-%20C%C3%B3digo%20de%20Rentas%20Internas%20para%20un%20Nuevo%20Puerto%20Rico.pdf#page=300 - title: Schedule CT Individual, Earned Income Credit, 2023 href: https://hacienda.pr.gov/sites/default/files/schedule_ct_rev._jul_5_23_informative_-_instructions.pdf#page=2 - # discrepancy: legal statute phase out thresholds do not correspond with tax form values - title: P.R. Laws tit. 13, § 30211 (1) - (6) href: https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1007/subchapter-b/30211/ diff --git a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/single.yaml b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/single.yaml index 3f25534d252..0446792fce9 100644 --- a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/single.yaml +++ b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/phase_out/threshold/single.yaml @@ -5,18 +5,26 @@ brackets: 2023-01-01: 0 amount: 2023-01-01: 17_660 + 2024-01-01: 18_610 + 2025-01-01: 19_130 - threshold: 2023-01-01: 1 amount: 2023-01-01: 19_870 + 2024-01-01: 20_940 + 2025-01-01: 21_530 - threshold: 2023-01-01: 2 amount: 2023-01-01: 23_180 + 2024-01-01: 24_430 + 2025-01-01: 25_110 - threshold: 2023-01-01: 3 amount: 2023-01-01: 23_180 + 2024-01-01: 24_430 + 2025-01-01: 25_110 metadata: amount_unit: currency-USD threshold_unit: child @@ -24,8 +32,13 @@ metadata: label: Puerto Rico earned income credit phase out threshold period: year reference: + - title: "Hacienda Boletín Informativo de Rentas Internas 24-04, inflation adjustment to the earned income credit for 2024 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2024/12/bi_ri_24-04_-_credito_por_trabajo_-_ajuste_por_inflacion_2024_firmada_23-dic-2024.pdf#page=1 + - title: "Hacienda Boletín Informativo de Rentas Internas 26-01, inflation adjustment to the earned income credit for 2025 #page 1-3" + href: https://hacienda.pr.gov/sites/default/files/publicaciones/2026/02/bi_ri_26-01_ajuste_por_inflacion_al_credito_por_trabajo_para_el_ano_2025_signed.pdf#page=1 + - title: P.R. Internal Revenue Code § 1052.01(i), 13 L.P.R.A. § 30211(i) (inflation adjustment as adjusted by the federal IRS) + href: https://docs.pr.gov/files/OCIF/LEYES-REGLAMENTOS-CARTAS-CIRCULARES/Leyes-delegan-Facultad-OCIF/Ley%20N%C3%BAm.%201-2011%20-%20C%C3%B3digo%20de%20Rentas%20Internas%20para%20un%20Nuevo%20Puerto%20Rico.pdf#page=300 - title: Schedule CT Individual, Earned Income Credit, 2023 href: https://hacienda.pr.gov/sites/default/files/schedule_ct_rev._jul_5_23_informative_-_instructions.pdf#page=2 - # discrepancy: legal statute phase out thresholds do not correspond with tax form values - title: P.R. Laws tit. 13, § 30211 (1) - (6) href: https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1007/subchapter-b/30211/ diff --git a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/unearned_income/limit.yaml b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/unearned_income/limit.yaml index 6ed10b22989..c173e04814c 100644 --- a/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/unearned_income/limit.yaml +++ b/policyengine_us/parameters/gov/territories/pr/tax/income/credits/earned_income/unearned_income/limit.yaml @@ -6,7 +6,9 @@ metadata: label: Puerto Rico earned income credit unearned income limit period: year reference: - # discrepancy: legal statute lists unearned income as 2_200 + # Section 1052.01(e) keeps older $2,200 wording but adds a proviso for + # taxable years after 2020 allowing other income, including exempt + # unearned income, equal to or below $10,000. - title: P.R. Laws tit. 13, § 30211 (6)(e) href: https://law.justia.com/codes/puerto-rico/title-thirteen/subtitle-17/part-ii/chapter-1007/subchapter-b/30211/ - title: Schedule CT Individual, Earned Income Credit, 2023 diff --git a/policyengine_us/tests/core/test_medical_expense_premium_conservation.py b/policyengine_us/tests/core/test_medical_expense_premium_conservation.py index 5734523889c..1618a6dc584 100644 --- a/policyengine_us/tests/core/test_medical_expense_premium_conservation.py +++ b/policyengine_us/tests/core/test_medical_expense_premium_conservation.py @@ -395,7 +395,10 @@ def _state_simulation(cases, reference_system, with_se_deduction): # deduction. The oracle preserves the supplied amount exactly as main # does; only the computed path restores an applied federal exclusion. main_base = case["subtotal"] if supplied else gross + # The credit (NMSA 7-2-18.13) takes expenses of $28,000 or more; the + # exemption (NMSA 7-2-5.9(A)) takes expenses that "exceed" $28,000. senior_eligible = case["age"] >= 65 and main_base >= 28_000 + senior_exemption_eligible = case["age"] >= 65 and main_base > 28_000 denominator = 2 if case["filing_status"] == "SEPARATE" else 1 for state in ("ND", "NM"): @@ -464,7 +467,7 @@ def _state_simulation(cases, reference_system, with_se_deduction): ) # NMSA 7-2-5.9 and PIT-ADJ line 18 allow the full exemption. expectations["nm_medical_expense_exemption"].append( - 3_000 if state == "NM" and senior_eligible else 0 + 3_000 if state == "NM" and senior_exemption_eligible else 0 ) simulation = Simulation( tax_benefit_system=reference_system, diff --git a/policyengine_us/tests/core/test_nm_ctc_children_medical_exemption_invariants.py b/policyengine_us/tests/core/test_nm_ctc_children_medical_exemption_invariants.py index 96154868af8..c778364bfcb 100644 --- a/policyengine_us/tests/core/test_nm_ctc_children_medical_exemption_invariants.py +++ b/policyengine_us/tests/core/test_nm_ctc_children_medical_exemption_invariants.py @@ -4,8 +4,9 @@ by IRC 152(c), which has no taxpayer identification number requirement, so `nm_ctc_qualifying_children` counts 152(c) children whatever their Social Security number status. NMSA 7-2-5.9 gives $3,000 to a filer or spouse 65 or -older with at least $28,000 of medical care expenses (the PIT-ADJ reading of -the threshold), with no halving for married filing separately. +older with more than $28,000 of medical care expenses (NMSA 7-2-5.9(A); the +PIT-ADJ instructions' "$28,000 or more" is not followed), with no halving for +married filing separately. For households drawn by Hypothesis and a seeded population, in 2023-2026: @@ -25,8 +26,8 @@ 5. Separate filing: a single adult filing separately gets half of `nm_ctc` (7-2-18.34(G)) and the whole `nm_medical_expense_exemption`. 6. Reference exemption: `nm_medical_expense_exemption` is $3,000 exactly when - a filer (not a dependent) is 65 or older and medical expenses are at least - $28,000, and 0 otherwise. + a filer (not a dependent) is 65 or older and medical expenses are more than + $28,000 (NMSA 7-2-5.9(A)), and 0 otherwise. """ import numpy as np @@ -182,7 +183,7 @@ def unit(adults, dependents, expenses=0.0): unit([adult(25), adult(20)], [dependent(22, student=True)]), # The only 65+ person is a dependent parent. unit([adult(40)], [elderly_parent], expenses=30_000.0), - # A 65+ filer with exactly $28,000 of expenses. + # A 65+ filer with exactly $28,000 of expenses (not over $28,000). unit([adult(70)], [], expenses=28_000.0), ] @@ -268,7 +269,8 @@ def _reference_exemption(unit): if unit["state"] != "NM": return 0 filer_65 = any(a["age"] >= 65 for a in unit["adults"]) - return EXEMPTION * (filer_65 and unit["medical_expenses"] >= MIN_EXPENSES) + # NMSA 7-2-5.9(A): expenses that "exceed" $28,000. + return EXEMPTION * (filer_65 and unit["medical_expenses"] > MIN_EXPENSES) def _describe(unit): @@ -336,7 +338,7 @@ def _assert_coverage(drawn_units, credit, exemption): u["state"] == "NM" and all(a["age"] < 65 for a in u["adults"]) and any(d["age"] >= 65 for d in u["dependents"]) - and u["medical_expenses"] >= MIN_EXPENSES + and u["medical_expenses"] > MIN_EXPENSES for u in drawn_units ] ) diff --git a/policyengine_us/tests/core/test_state_medical_expense_input_deletion.py b/policyengine_us/tests/core/test_state_medical_expense_input_deletion.py index 8f700ae0cae..c48a55b7835 100644 --- a/policyengine_us/tests/core/test_state_medical_expense_input_deletion.py +++ b/policyengine_us/tests/core/test_state_medical_expense_input_deletion.py @@ -69,13 +69,14 @@ def test_nd_paid_cost_base_after_medical_subtotal_deletion(delete_subtotal): @pytest.mark.parametrize("delete_subtotal", SUBTOTAL_DELETION_CASES) def test_nm_senior_benefits_after_medical_subtotal_deletion(delete_subtotal): - simulation = _simulation("NM", other_expenses=22_000) + simulation = _simulation("NM", other_expenses=22_001) if delete_subtotal: simulation.delete_arrays("itemized_medical_expenses", PERIOD) - # The recomputed federal subtotal is 27,000, but restoring its 1,000 - # exclusion meets NM's 28,000 paid-cost threshold. Calculate both before - # asserting to preserve evidence. + # The recomputed federal subtotal is 27,001, but restoring its 1,000 + # exclusion gives 28,001 of paid costs, which meets the credit's $28,000 + # threshold and exceeds the exemption's. Calculate both before asserting + # to preserve evidence. benefits = tuple( simulation.calculate(variable, PERIOD).item() for variable in ( diff --git a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.yaml b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.yaml index 43eeabb49b8..35d0c19d297 100644 --- a/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.yaml @@ -186,52 +186,84 @@ output: nyc_household_credit: 0 -- name: Separate filers making $15k or less get $15 per tax unit dependent (size=2). +# Tax Law 1310(d) and IT-201 Table 6: a married couple filing separately is +# one household, keyed on federal AGI and dependents "from both returns" plus +# one for each spouse, and each spouse gets half the household amount. +- name: Separate filers with household AGI of $15k or less get half of $30 per exemption of the couple. period: 2022 absolute_error_margin: 0 input: state_code: NY in_nyc: true - adjusted_gross_income: 15_000 + adjusted_gross_income: 7_500 + spouse_separate_adjusted_gross_income: 7_500 filing_status: SEPARATE tax_unit_size: 2 + spouse_separate_tax_unit_size: 2 output: - nyc_household_credit: 30 + # Household AGI $15,000: $30 x (2 + 2) = $120, halved. + nyc_household_credit: 60 -- name: Separate filers making $18k get $8 per tax unit dependent (size=4). +- name: Separate filers with household AGI of $18k get half of $15 per exemption of the couple. period: 2022 - absolute_error_margin: 3 # Table has some rounding. + absolute_error_margin: 0 input: state_code: NY in_nyc: true - adjusted_gross_income: 18_000 + adjusted_gross_income: 9_000 + spouse_separate_adjusted_gross_income: 9_000 filing_status: SEPARATE tax_unit_size: 4 + spouse_separate_tax_unit_size: 4 output: - nyc_household_credit: 32 + # Household AGI $18,000: the married amount is $15 per exemption, so the + # household credit is $15 x 8 = $120 and each spouse gets half, $60. + # IT-201 Table 6 rounds the half amount to $8 per exemption ($53 + $8 = + # $61 with its over-seven note); the model follows Tax Law 1310(d). + nyc_household_credit: 60 -- name: Separate filers making $21k get $5 per tax unit dependent. +- name: Separate filers with household AGI of $21k get half of $10 per exemption of the couple. period: 2022 - absolute_error_margin: 3 # Table has some rounding. + absolute_error_margin: 0 input: state_code: NY in_nyc: true - adjusted_gross_income: 21_000 + adjusted_gross_income: 10_500 + spouse_separate_adjusted_gross_income: 10_500 filing_status: SEPARATE tax_unit_size: 6 + spouse_separate_tax_unit_size: 6 output: - nyc_household_credit: 30 + # Household AGI $21,000: $10 x (6 + 6) = $120, halved. + nyc_household_credit: 60 -- name: Separate filers making over $22.5k gets no credit. +- name: Separate filers with household AGI over $22.5k get no credit. period: 2022 absolute_error_margin: 0 input: state_code: NY in_nyc: true - adjusted_gross_income: 22_501 + adjusted_gross_income: 11_251 + spouse_separate_adjusted_gross_income: 11_251 filing_status: SEPARATE tax_unit_size: 4 + spouse_separate_tax_unit_size: 4 + output: + nyc_household_credit: 0 + +- name: A separate filer's own AGI alone does not set the bracket. + period: 2022 + absolute_error_margin: 0 + input: + state_code: NY + in_nyc: true + adjusted_gross_income: 15_000 + spouse_separate_adjusted_gross_income: 15_000 + filing_status: SEPARATE + tax_unit_size: 2 + spouse_separate_tax_unit_size: 2 output: + # Household AGI $30,000 is over $22,500. nyc_household_credit: 0 @@ -273,7 +305,7 @@ output: nyc_household_credit: 15 -- name: 2025 joint return with one claimable spouse gets no NYC household credit (the claimable spouse is the head) +- name: 2025 joint return with one claimable spouse counts the other spouse's exemption for the NYC credit (the claimable spouse is the head) period: 2025 input: people: @@ -298,9 +330,12 @@ state_code: NY in_nyc: true output: - nyc_household_credit: 0 + # Tax Law 1310(d) counts the exemptions the couple is entitled to: one. + # $30 x 1. IT-201 line 48 would deny the credit; the model follows the + # statute. + nyc_household_credit: 30 -- name: 2025 joint return with one claimable spouse gets no NYC household credit (the claimable spouse is the spouse) +- name: 2025 joint return with one claimable spouse counts the other spouse's exemption for the NYC credit (the claimable spouse is the spouse) period: 2025 input: people: @@ -325,7 +360,7 @@ state_code: NY in_nyc: true output: - nyc_household_credit: 0 + nyc_household_credit: 30 - name: 2025 joint return with neither spouse claimable gets the NYC household credit period: 2025 @@ -349,3 +384,78 @@ output: # $30 x 2. nyc_household_credit: 60 + +# Tax Law 1310(d): only an unmarried individual is excluded for being +# claimable; other households count the exemptions they are entitled to. +- name: 2025 separate filer who can be claimed gets half the household credit for the spouse's exemption + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + filing_status: SEPARATE + households: + household: + members: [person_a] + state_code: NY + in_nyc: true + output: + # Household AGI $10,000 (the spouse's return is assumed alike); the + # couple's exemptions: 0 for the claimable filer plus 1 for the spouse. + # $30 x 1, halved. + nyc_household_credit: 15 + +- name: 2025 joint return where both spouses can be claimed has no exemptions for the NYC credit + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + person_b: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NY + in_nyc: true + output: + nyc_household_credit: 0 + +- name: 2025 head of household who can be claimed counts the dependent's exemption + period: 2025 + input: + people: + parent: + age: 22 + employment_income: 10_000 + claimed_as_dependent_on_another_return: true + child: + age: 2 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + # The would-be claimant need not file, so the parent may still claim + # the child (Publication 501, Dependent Taxpayer Test). + head_or_spouse_is_dependent_elsewhere_without_filing_exception: false + households: + household: + members: [parent, child] + state_code: NY + in_nyc: true + output: + # One exemption (the child); $30 x 1. + nyc_household_credit: 30 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.yaml index fbc36a3d88e..c0abdd891c8 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.yaml @@ -15,10 +15,12 @@ age: 65 medicare_enrolled: false health_insurance_premiums: 6_000 - other_medical_expenses: 22_000 + other_medical_expenses: 22_001 self_employed_health_insurance_ald: 1_000 output: - itemized_medical_expenses: 27_000 + # Gross paid: 6,000 + 22,001 = 28,001, over $28,000; the federal + # subtotal (27,001) excludes the 1,000 deducted premium. + itemized_medical_expenses: 27_001 nm_medical_expense_exemption: 3_000 - name: New Mexico senior exemption preserves caller-supplied medical expenses @@ -27,7 +29,7 @@ state_code: NM age: 65 medicare_enrolled: false - itemized_medical_expenses: 28_000 + itemized_medical_expenses: 28_001 output: nm_medical_expense_exemption: 3_000 @@ -58,7 +60,7 @@ input: state_code: NM age: 65 - other_medical_expenses: 28_000 + other_medical_expenses: 28_001 filing_status: JOINT output: nm_medical_expense_exemption: 3_000 @@ -68,7 +70,7 @@ input: state_code: NM age: 65 - other_medical_expenses: 28_000 + other_medical_expenses: 28_001 filing_status: SEPARATE output: # Neither NMSA 7-2-5.9 nor the PIT-ADJ line 18 instructions halve the @@ -87,7 +89,7 @@ # PIT-ADJ line 18: "enter $3,000 on line 18 to claim the exemption". nm_medical_expense_exemption: 3_000 -- name: 2025 expenses of exactly $28,000 qualify under the PIT-ADJ instructions +- name: 2025 expenses of exactly $28,000 do not qualify under the statute period: 2025 input: state_code: NM @@ -96,8 +98,20 @@ other_medical_expenses: 28_000 filing_status: SINGLE output: - # PIT-ADJ line 18: expenses "of $28,000 or more". NMSA 7-2-5.9(A) says - # expenses that "exceed" $28,000, which would give 0 here. + # NMSA 7-2-5.9(A): expenses that "exceed twenty-eight thousand dollars". + # The PIT-ADJ line 18 instructions say "of $28,000 or more", which would + # give 3,000; the model follows the statute. + nm_medical_expense_exemption: 0 + +- name: 2025 expenses one dollar over $28,000 qualify + period: 2025 + input: + state_code: NM + age: 70 + medicare_enrolled: false + other_medical_expenses: 28_001 + filing_status: SINGLE + output: nm_medical_expense_exemption: 3_000 - name: 2025 expenses one dollar under $28,000 do not qualify diff --git a/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/credits/ny_household_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/credits/ny_household_credit.yaml index 75ecd16039e..f73505ce3ad 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/credits/ny_household_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ny/tax/income/credits/ny_household_credit.yaml @@ -127,7 +127,7 @@ output: ny_household_credit_potential: 45 -- name: 2025 joint return with one claimable spouse gets no household credit (the claimable spouse is the head) +- name: 2025 joint return with one claimable spouse counts the other spouse's exemption (the claimable spouse is the head) period: 2025 input: people: @@ -151,10 +151,13 @@ members: [person_a, person_b] state_code: NY output: - # Item C is one box per return; either spouse marks it. - ny_household_credit_potential: 0 + # Tax Law 606(b) counts the exemptions the couple is entitled to: one, + # for the spouse who cannot be claimed. $60 base at $10,000 of AGI plus + # $15 x (1 - 1). IT-201 line 40 would deny the credit because item C is + # marked; the model follows the statute. + ny_household_credit_potential: 60 -- name: 2025 joint return with one claimable spouse gets no household credit (the claimable spouse is the spouse) +- name: 2025 joint return with one claimable spouse counts the other spouse's exemption (the claimable spouse is the spouse) period: 2025 input: people: @@ -178,7 +181,7 @@ members: [person_b, person_a] state_code: NY output: - ny_household_credit_potential: 0 + ny_household_credit_potential: 60 - name: 2025 joint return with neither spouse claimable gets the household credit period: 2025 @@ -201,3 +204,78 @@ output: # $60 + $15 x (2 - 1). ny_household_credit_potential: 75 + +# Tax Law 606(b)(3)(B): a husband and wife, a head of household and a +# surviving spouse are households in their own right; only an unmarried +# individual is excluded for being claimable. IT-201 line 40 denies every +# return with item C marked; the model follows the statute. +- name: 2025 separate filer who can be claimed counts the couple's exemptions + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a] + filing_status: SEPARATE + households: + household: + members: [person_a] + state_code: NY + output: + # Combined AGI $10,000 (the spouse's separate return is assumed alike); + # exemptions: 0 for the claimable filer plus 1 for the spouse's unit. + # $60 base + $15 x (1 - 1) = $60, halved for a separate return. + ny_household_credit_potential: 30 + +- name: 2025 joint return where both spouses can be claimed reduces the base by one additional amount + period: 2025 + input: + people: + person_a: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + person_b: + age: 22 + employment_income: 5_000 + claimed_as_dependent_on_another_return: true + tax_units: + tax_unit: + members: [person_a, person_b] + filing_status: JOINT + households: + household: + members: [person_a, person_b] + state_code: NY + output: + # No exemptions: $60 base + $15 x (0 - 1) = $45. + ny_household_credit_potential: 45 + +- name: 2025 head of household who can be claimed counts the dependent's exemption + period: 2025 + input: + people: + parent: + age: 22 + employment_income: 10_000 + claimed_as_dependent_on_another_return: true + child: + age: 2 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + # The would-be claimant need not file, so the parent may still claim + # the child (Publication 501, Dependent Taxpayer Test). + head_or_spouse_is_dependent_elsewhere_without_filing_exception: false + households: + household: + members: [parent, child] + state_code: NY + output: + # One exemption: $60 base + $15 x (1 - 1). + ny_household_credit_potential: 60 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.yaml index 2bd8ce741df..0dc4cac1263 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.yaml @@ -1,3 +1,8 @@ +# 32 V.S.A. 5828c as in effect for 2021: federal adjusted gross income "less +# than $30,000.00 (or $40,000.00 for married, filing jointly)". The 2021 +# Schedule IN-112 says "$30,000 (or $40,000 for Married Filing Jointly) or +# less"; the model follows the statute, so income at the threshold does not +# qualify. - name: Vermont low-income CDCC single filer not eligible period: 2021 input: @@ -7,12 +12,21 @@ output: vt_low_income_cdcc_eligible: false -- name: Vermont low-income CDCC single filer eligible +- name: Vermont low-income CDCC single filer at the threshold not eligible period: 2021 input: state_code: VT adjusted_gross_income: 30_000 filing_status: SINGLE + output: + vt_low_income_cdcc_eligible: false + +- name: Vermont low-income CDCC single filer below the threshold eligible + period: 2021 + input: + state_code: VT + adjusted_gross_income: 29_999 + filing_status: SINGLE output: vt_low_income_cdcc_eligible: true @@ -25,14 +39,20 @@ output: vt_low_income_cdcc_eligible: false -- name: Vermont low-income CDCC joint filer eligible +- name: Vermont low-income CDCC joint filer at the threshold not eligible period: 2021 input: state_code: VT adjusted_gross_income: 40_000 filing_status: JOINT output: - vt_low_income_cdcc_eligible: true + vt_low_income_cdcc_eligible: false - - +- name: Vermont low-income CDCC joint filer below the threshold eligible + period: 2021 + input: + state_code: VT + adjusted_gross_income: 39_999 + filing_status: JOINT + output: + vt_low_income_cdcc_eligible: true diff --git a/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/integration.yaml b/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/integration.yaml index 218cfb9da86..90853e2571d 100644 --- a/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/integration.yaml @@ -1,5 +1,5 @@ - name: integration test 1, a married couple with 2 dependents - period: 2024 + period: 2023 input: people: person1: @@ -29,7 +29,7 @@ pr_earned_income_credit: 6_072 - name: integration test 2, individual with 4 dependents - period: 2024 + period: 2023 input: people: person1: diff --git a/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/pr_earned_income_credit.yaml b/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/pr_earned_income_credit.yaml index 78abde891bf..92fbdcf688d 100644 --- a/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/pr_earned_income_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/territories/pr/tax/income/credits/earned_income/pr_earned_income_credit.yaml @@ -25,7 +25,7 @@ pr_earned_income_credit: 0 - name: Eligible person, 0 children with max credit - period: 2024 + period: 2023 input: people: person1: @@ -45,7 +45,7 @@ pr_earned_income_credit: 1_656 - name: Eligible person, 1 child and higher bracket - period: 2024 + period: 2023 input: people: person1: @@ -68,7 +68,7 @@ pr_earned_income_credit: 2_483.004 - name: Eligible person, 0 child and filing jointly - period: 2024 + period: 2023 input: people: person1: @@ -91,7 +91,7 @@ pr_earned_income_credit: 1_656 - name: Eligible person, 1 child, filing jointly, higher bracket - period: 2024 + period: 2023 input: people: person1: @@ -152,7 +152,7 @@ pr_earned_income_credit: 0 - name: Eligible HEAD_OF_HOUSEHOLD filer gets the individual phase-out threshold - period: 2024 + period: 2023 input: people: person1: @@ -176,7 +176,7 @@ pr_earned_income_credit: 1_656 - name: Eligible SURVIVING_SPOUSE filer gets the joint phase-out threshold - period: 2024 + period: 2023 input: people: person1: @@ -198,3 +198,70 @@ # (joint threshold = 19_870), so the full max credit applies. output: pr_earned_income_credit: 1_656 + +# Section 1052.01(i) indexes the credit "según ajustado por el Servicio de +# Rentas Internas Federal"; Hacienda publishes the adjusted amounts in BI RI +# 24-04 (2024) and BI RI 26-01 (2025). +- name: 2024 three or more children, single, phase-out under the 2024 threshold + period: 2024 + input: + people: + person1: + pr_gross_income_person: 25_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + eitc_child_count: 3 + pr_earned_income_credit_eligible: true + households: + household: + members: [person1] + state_code: PR + output: + # 2024 maximum $7,563 less 34.21% of ($25,000 - $24,430) = $194.997. + pr_earned_income_credit: 7_368.003 + +- name: 2025 three or more children, single, under the 2025 threshold + period: 2025 + input: + people: + person1: + pr_gross_income_person: 25_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + eitc_child_count: 3 + pr_earned_income_credit_eligible: true + households: + household: + members: [person1] + state_code: PR + output: + # $25,000 is under the $25,110 threshold, so the $7,774 maximum applies + # (the 2023 schedule would give $7,173 - 34.21% x $1,820 = $6,550.378). + pr_earned_income_credit: 7_774 + +- name: 2025 one child, joint, phase-out over the 2025 threshold + period: 2025 + input: + people: + person1: + pr_gross_income_person: 30_000 + is_tax_unit_head_or_spouse: true + tax_units: + tax_unit: + members: [person1] + filing_status: JOINT + eitc_child_count: 1 + pr_earned_income_credit_eligible: true + households: + household: + members: [person1] + state_code: PR + output: + # $4,186 less 26.92% of ($30,000 - $26,310) = $993.348. + pr_earned_income_credit: 3_192.652 diff --git a/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.py b/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.py index c919d1626d0..0ae037ce399 100644 --- a/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.py +++ b/policyengine_us/variables/gov/local/ny/nyc/tax/income/credits/household/nyc_household_credit.py @@ -8,6 +8,10 @@ class nyc_household_credit(Variable): unit = USD definition_period = YEAR defined_for = "in_nyc" + reference = ( + "https://www.nysenate.gov/legislation/laws/TAX/1310", + "https://www.tax.ny.gov/pdf/2025/inc/it201i_2025.pdf#page=13", + ) def formula(tax_unit, period, parameters): # First get their federal AGI. @@ -20,15 +24,31 @@ def formula(tax_unit, period, parameters): # Then get the household credit part of the parameter tree. p = parameters(period).gov.local.ny.nyc.tax.income.credits.household - # Then get their number of people. - tax_unit_size = tax_unit("tax_unit_size", period) - filing_statuses = filing_status.possible_values - # Tax Law 1310(d) excludes an individual whom another taxpayer can - # claim as a dependent; IT-201 line 48: "If you marked the Yes box at - # item C ... you do not qualify for this credit". + # Tax Law 1310(d) counts the exemptions each household is entitled to + # and excludes, among unmarried individuals, one whom another taxpayer + # can claim; a husband and wife, a head of household and a surviving + # spouse are households in their own right. IT-201 line 48 says "If + # you marked the Yes box at item C ... you do not qualify for this + # credit" for every return; the model follows the statute. dependent_filer = tax_unit("head_or_spouse_is_dependent_elsewhere", period) + single = filing_status == filing_statuses.SINGLE + exemptions = tax_unit("exemptions_count", period) + # A husband and wife filing separately are one household: 1310(d) + # aggregates "their federal adjusted gross incomes ... irrespective + # of whether joint or separate city income tax returns are filed", + # and each spouse gets "one-half the credit otherwise allowed his or + # her household" (IT-201 Table 6: AGI and dependents "from both + # returns", plus one for each spouse). The model has no record of the + # other spouse's return, so it is assumed alike, as for New York + # State: its AGI and its unit's size are added. + separate_agi = federal_agi + tax_unit( + "spouse_separate_adjusted_gross_income", period + ) + separate_exemptions = exemptions + tax_unit( + "spouse_separate_tax_unit_size", period + ) amount = select( [ filing_status == filing_statuses.SINGLE, @@ -37,12 +57,17 @@ def formula(tax_unit, period, parameters): [ # Single filers get a flat amount. p.flat_amount.calc(federal_agi, right=True), - # Separate filers get an amount for each person in the tax - # unit, varying with AGI. - p.separate_per_dependent.calc(federal_agi, right=True) * tax_unit_size, + # Separate filers get "one-half the credit otherwise allowed his + # or her household": the married amount per exemption at the + # couple's AGI, times the couple's exemptions, halved. IT-201 + # Table 6 instead rounds a per-exemption half amount, which can + # differ by a dollar or more; the model follows the statute. + p.other_per_dependent.calc(separate_agi, right=True) + * separate_exemptions + / 2, ], # Joint, head of household, and surviving spouse filers have a different - # amount per person, varying with AGI. - default=p.other_per_dependent.calc(federal_agi, right=True) * tax_unit_size, + # amount per exemption, varying with AGI. + default=p.other_per_dependent.calc(federal_agi, right=True) * exemptions, ) - return where(dependent_filer, 0, amount) + return where(dependent_filer & single, 0, amount) diff --git a/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.py b/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.py index 1efcc1a8ac3..0e6a54aac29 100644 --- a/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.py +++ b/policyengine_us/variables/gov/states/nm/tax/income/exemptions/nm_medical_expense_exemption.py @@ -51,9 +51,9 @@ def formula(tax_unit, period, parameters): age_eligible = tax_unit.any(filer & (age >= p.age_eligibility)) # NMSA 7-2-5.9(A) requires expenses that "exceed twenty-eight thousand # dollars ($28,000)"; PIT-ADJ line 18 instructions allow expenses "of - # $28,000 or more". This keeps the instructions' reading, under which - # expenses of exactly $28,000 qualify, until the conflict is resolved. - expense_eligible = medical_expense >= p.min_expenses + # $28,000 or more". The model follows the statute, so expenses of + # exactly $28,000 do not qualify. + expense_eligible = medical_expense > p.min_expenses eligible = age_eligible & expense_eligible # Neither 7-2-5.9 nor the PIT-ADJ line 18 instructions halve the # exemption for married individuals filing separately. Sections that diff --git a/policyengine_us/variables/gov/states/ny/tax/income/credits/ny_household_credit_potential.py b/policyengine_us/variables/gov/states/ny/tax/income/credits/ny_household_credit_potential.py index b71524d37c8..a5045e0f2df 100644 --- a/policyengine_us/variables/gov/states/ny/tax/income/credits/ny_household_credit_potential.py +++ b/policyengine_us/variables/gov/states/ny/tax/income/credits/ny_household_credit_potential.py @@ -25,27 +25,38 @@ def formula(tax_unit, period, parameters): # Use `right=True` to reflect "over...but not over". amount_if_single = p.single.calc(agi, right=True) single_amount = single * amount_if_single - # All others are based on AGI & size. - # In the case of married filing separate, based on the combined AGI and size. - size = add( - tax_unit, - period, - ["tax_unit_size", "spouse_separate_tax_unit_size"], - ) + # All others are based on AGI and the number of exemptions. Tax Law + # 606(b)(2)(B) and (3)(B) count "the number of exemptions for which + # the taxpayer (or in the case of a husband and wife, taxpayers) is + # entitled to a deduction" for federal purposes, which leaves out a + # filer whom another taxpayer can claim (exemptions_count). A married + # couple filing separately uses the couple's combined AGI and + # exemptions; the model has no record of the other spouse's + # claimability, so the spouse's separate unit counts at its size. separate = filing_status == filing_statuses.SEPARATE + size = tax_unit("exemptions_count", period) + tax_unit( + "spouse_separate_tax_unit_size", period + ) non_single_base = p.non_single.base.calc(agi, right=True) non_single_additional = p.non_single.additional.calc(agi, right=True) - total_amount_if_not_single = non_single_base + non_single_additional * ( - size - 1 + # The statute adds the additional amount for each exemption beyond one. + # With no exemptions (both spouses of a refund-only joint return can + # be claimed) that is one less than none, so the base is reduced; + # the credit is not negative. + total_amount_if_not_single = max_( + non_single_base + non_single_additional * (size - 1), 0 ) amount_if_not_single = np.ceil( total_amount_if_not_single / where(separate, 2, 1) ) non_single_amount = amount_if_not_single * ~single - # Tax Law 606(b)(3)(B) excludes an individual for whom a deduction - # under IRC 151(c) "is allowable to another taxpayer", and IT-201 line - # 40 says "If you marked the Yes box at item C ... you do not qualify - # for this credit". Item C is one box per return; this formula reads - # it as marked when either spouse of a joint return can be claimed. + # Tax Law 606(b)(3)(B) defines a household as a husband and wife, a + # head of household, a surviving spouse, or an unmarried individual + # for whom a deduction under IRC 151(c) is not "allowable to another + # taxpayer". Only a single filer is excluded for being claimable; the + # other households count only the exemptions they are entitled to. + # IT-201 line 40 says "If you marked the Yes box at item C ... you do + # not qualify for this credit" for every return; the model follows the + # statute. dependent_filer = tax_unit("head_or_spouse_is_dependent_elsewhere", period) - return where(dependent_filer, 0, single_amount + non_single_amount) + return where(dependent_filer & single, 0, single_amount + non_single_amount) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_cdcc.py b/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_cdcc.py index 6b613164326..a3da549d124 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_cdcc.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_cdcc.py @@ -27,10 +27,10 @@ def formula(tax_unit, period, parameters): federal_cdcc = tax_unit("pre_obbba_capped_cdcc", period) else: federal_cdcc = tax_unit("capped_cdcc", period) - # 2022 Act 138 raised the 5828c match to 72 percent but retained the - # low-income adjusted gross income cap and the certified-facility - # requirement for 2022; 2023 Act 72 removed them effective 2023. We - # do not track facility certification or in-state care at the moment. + # 2022 Act 138 raised the 5828c match to 72 percent from 2022, and the + # 2022 Schedule IN-112 applies it with no income test (see + # income_limit_in_effect). We do not track facility certification or + # in-state care at the moment. if p.income_limit_in_effect: income_eligible = tax_unit("vt_low_income_cdcc_eligible", period) return income_eligible * federal_cdcc * p.rate diff --git a/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.py b/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.py index 5299936f491..f62072dfe6f 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/credits/cdcc/vt_low_income_cdcc_eligible.py @@ -9,6 +9,8 @@ class vt_low_income_cdcc_eligible(Variable): reference = ( "https://tax.vermont.gov/sites/tax/files/documents/IN-112-2021.pdf#page=2", "https://law.justia.com/codes/vermont/2021/title-32/chapter-151/section-5828c/", + # 2022 Act 138 section 3 reproduces the pre-2022 text it amended. + "https://legislature.vermont.gov/Documents/2022/Docs/ACTS/ACT138/ACT138%20As%20Enacted.pdf#page=3", ) defined_for = StateCode.VT @@ -17,5 +19,8 @@ def formula(tax_unit, period, parameters): filing_status = tax_unit("filing_status", period) federal_agi_threshold = p.income_threshold[filing_status] federal_agi = tax_unit("adjusted_gross_income", period) - # Law says "less than" but tax form says "$x or less". We apply form rules. - return federal_agi <= federal_agi_threshold + # 32 V.S.A. 5828c (as in effect through 2021) requires federal adjusted + # gross income "less than $30,000.00 (or $40,000.00 for married, + # filing jointly)"; the 2021 Schedule IN-112 says "$30,000 (or $40,000 + # for Married Filing Jointly) or less". The model follows the statute. + return federal_agi < federal_agi_threshold