Skip to content

Fix Arkansas 2014-2020 income tax rate schedules - #9611

Merged
MaxGhenis merged 4 commits into
mainfrom
fix-ar-pre-2021-rate-schedules
Sep 26, 2026
Merged

MaxGhenis merged 4 commits into
mainfrom
fix-ar-pre-2021-rate-schedules

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Arkansas income tax for 2014-2020 did not match DFA's published schedules. ar_income_tax_before_non_refundable_credits_{indiv,joint} compute rate.calc(x) * x - reduction.calc(x), and two things were wrong:

  1. No pre-2021 subtraction amounts. rates/main/reduction.yaml started in 2021. backdate_parameters (system.py, first_instant="2015-01-01") copied the 2021 subtraction amounts back to 2015-2020, and 2014 had none, so all of 2014 income was taxed at the top rate reached. The reviewer's 2015 spot check ($20,050: PE $634.03 vs table $607) is 4.4% × 20,050 minus the 2021 amount of $248.17.
  2. 2016-2018 used the 2015 schedule. rates/main/rate.yaml carried 2015's rates and thresholds through 2018. Act 22 of 2015 moved 2016+ to 5% and 6% for the middle table and a 6.9% high-income table, with a bracket adjustment for net income just above $75,000, and the brackets were re-indexed every year.

This PR transcribes DFA's Indexed Tax Brackets for each year into the two parameter files. For 2014, whose sheet survives only in the Wayback Machine, the derived constants match that archived sheet exactly.

Before and after

ar_income_tax_before_non_refundable_credits_indiv at a given net taxable income. "Table" is DFA's Regular Tax Table cell for the row whose midpoint is that income. "Sheet" is the bracket formula above the table's range.

Year Net taxable income Before After DFA
2014 $14,850 $668.25 $389.49 $389 (table)
2014 $100,000 $7,000.00 $6,055.26 $6,055.26 (sheet)
2015 $20,050 $634.03 $606.73 $607 (table)
2015 $50,050 $2,706.25 $2,554.26 $2,554.26 (sheet)
2016 $50,050 $2,706.25 $2,268.25 $2,268 (table)
2017 $50,050 $2,706.25 $2,243.15 $2,243 (table)
2018 $100,000 $6,752.50 $5,937.26 $5,937.26 (sheet)
2019 $14,850 $256.73 $267.13 $267 (table)
2019 $100,000 $6,652.50 $5,918.36 $5,918.36 (sheet)
2020 $50,050 $2,155.70 $2,178.75 $2,179 (table)

The error was not always an overstatement. In 2019 and 2020, lower incomes were understated, because the backdated 2021 subtraction amounts are larger than the real 2019-2020 ones.

Changes

  • rates/main/reduction.yaml: 2014-2020 values for brackets 1-12. Brackets 1-6 are the ordinary brackets. Brackets 7-12 are the high-income bracket adjustment rows for 2016-2020, and .inf for 2014-2015.
  • rates/main/rate.yaml:
    • 2016-2018 thresholds for brackets 2-6.
    • The 5% and 6% rates from 2016, where they were previously dated 2019.
    • The 6.9% high-income bracket from $75,001 / $77,401 / $79,301 in 2016 / 2017 / 2018.
    • The 2019 and 2020 values are unchanged.
  • References:
    • Each year's DFA bracket sheet, and the archived 2014 sheet.
    • The 2014 booklet table.
    • The governing Acts: 1459 of 2013, 22 of 2015, 78 of 2017, and 182 of 2019, each linked to the arkleg PDF.
  • ar_income_tax_before_non_refundable_credits_2014_2020.yaml: 116 cases. Inputs are row midpoints; expected values are DFA table cells.
    • Every bracket in every year.
    • Each high-income adjustment row for 2016-2020.
    • Both sides of the jump into the high-income table.
    • The last table row.
    • One case above the table per year.
    • One joint-path case per year.

Verification

  • Full table match. Every row of DFA's 2014-2020 Regular Tax Tables (500 / 500 / 860 / 860 / 860 / 870 / 880 rows, parsed from the booklets) equals the new formula at the row midpoint, rounded half up. That is 5,330 of 5,330.
  • Parameter evaluation. Evaluated through system.parameters, the new scales equal DFA's sheet formulas at about 3,500 incomes per year from 2014 to 2020, including ±$1 and ±$0.50 around every threshold. An independent reviewer checked every dollar from $0 to $200,000 and found no difference.
  • Tests.
    • The new test file fails 109 of 116 cases against main's parameters. The 7 that pass are first-bracket rows, where neither version subtracts anything.
    • policyengine-core test on gov/states/ar plus contrib/states/ar: 629 passed.
    • An independent reviewer ran every other AR-touching test (CHIP, Medicaid, FUTA, SNAP income, TX CEAP, MT) under CI's update_itemization.sh setting: 647 passed.
    • ruff format and ruff check pass. The parameter and unit pytest files pass (632).
    • No partner contract test has an AR household.
  • Unchanged years. 2021-2035 thresholds and amounts are identical to main's at 01-01, 06-01 and 12-31 of each year, so uprating is unchanged too. The diff only adds pre-2021 dates, and drops the 2019 rate entries that now take effect from 2016 at the same value.

Notes

  • Midpoint rounding. DFA computes each table row at its midpoint and rounds to whole dollars. PE computes at the exact income, as it already does for 2021+, so PE matches the table at row midpoints and is within one row's rounding elsewhere.
  • Above the table. The booklets' shortcut for incomes above the table (for example, "$5,021 + 6.9% of the excess over $86,000" in 2016) starts from the rounded tax at the last row's midpoint. It comes out $3.19-$3.69 below the bracket formula this PR encodes. The above-table test cases state both numbers.
  • Cliffs are statutory. The jumps at the table switches follow the statute's "having net income less than $X" structure (for example, 2016 at $75,000 → $75,001, or 2015 at $21,100) and are intended.
  • Other pre-2021 AR errors. While auditing this, I found other Arkansas parameters that are wrong before 2021 through the same backdating: the low income tax tables, the personal credit amount, the tuition caps, unemployment compensation in 2015-2017, and the additional tax credit for qualified individuals leaking into ar_files_separately. They are fixed separately in Give Arkansas 2015-2020 income tax parameters their own values #9615 and are not changed here.

Related: #6128 (general AR rate parameters issue).

axiom: TheAxiomFoundation/rulespec-us#1405 debt

🤖 Generated with Claude Code

MaxGhenis and others added 4 commits September 25, 2026 04:22
Add the 2014-2020 subtraction amounts from DFA's Indexed Tax Brackets to
rates/main/reduction.yaml (2015-2020 were silently using the backdated 2021
amounts, and 2014 had none), and correct the 2016-2018 rates, thresholds and
high-income bracket adjustments in rates/main/rate.yaml. Every row of DFA's
2014-2020 Regular Tax Tables (5,330 rows) now matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s variables

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Admin-merged (squash, --match-head-commit 7c4cb40) under Max's 2026-09-26 ruling (d399: obvious improvements need no permission; admin-merge when the only block is a required review only Max could give). Gates at the reviewed head: gh pr checks exit 0, MERGEABLE, no CHANGES_REQUESTED. Approvals: an independent adversarial Opus 5.5 review of the final head (workflow wf_bfc37ebf, no blocker or major findings) plus the session-management main session's own diff review. Closes decision d283.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant