Conversation
…esholds The 2024 Arkansas low-income tax table for head of household and surviving spouse filers with two or more dependents keyed its $92 row at $24,200, the threshold of the $104 row. ParameterScale._get_at_instant passes each bracket to add_bracket, which sums the amounts of equal thresholds, so the 2024 scale became [(0, 0), (24200, 196), (24300, 116), ...]: AGI of $24,177-$24,200 got $0 instead of $92 and $24,201-$24,300 got $196 instead of $104. The official table (2024 AR1000F/AR1000NR instructions, PDF page 28) reads $0-$24,176 -> $0 and $24,177-$24,200 -> $92. The tables are evaluated with right=True, so the threshold is the upper bound of the $0 row: 24_176. The 2024 reference anchor now points at PDF page 28. calibration/gov/irs/soi/agi/total_agi repeated its $10,000,000-or-more bracket, which doubled the top bucket when loaded. Its 18 values match IRS SOI Table 1.1 for tax year 2020 (20in11si.xls, column 3), where the top bucket appears once. No code reads this parameter. Add YAML tests for AGI of $24,100-$24,401 for both filing statuses and a repo-level test that fails when any parameter scale has two brackets with the same finite threshold at any instant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
calibration/gov/irs/soi/agi/total_agi.yaml.The bug
ParameterScale._get_at_instantpasses each bracket toadd_bracket, andAmountTaxScaleLike.add_bracketadds the amount to an existing row when the threshold is already present (read in policyengine-core 3.30.2, the version inuv.lock). Before this PR, the 2024 scale was:ar_low_income_tax_jointevaluates it withright=True, so:The official 2024 AR1000F/AR1000NR instructions (PDF page 28, Rev 09/23/2024) list $0–$24,176 → $0 and $24,177–$24,200 → $92. With
right=True, each threshold is the inclusive upper bound of the preceding published row, so the first bracket's 2024 threshold is 24_176. This matches the 2024 single (14_265) and HoH/surviving spouse 0–1 dependent (20_282) tables. The duplicate predates 875b73a (#9068) and d8a4317, which both edited this line without catching it. This PR also moves the 2024 reference anchor from#page=24(now the self-employed health insurance worksheet in DFA's current PDF) to#page=28.Verification against the official tables
I parsed every Arkansas low-income table from the DFA PDFs for 2021 (PDF pp. 26–27), 2022 (pp. 29–30), 2023 (pp. 29–30), 2024 (pp. 28–29), and 2025 (pp. 28–29), plus the standalone
TaxTables_FI_2024.pdfandTaxTables_FI_2025.pdf. I parsed deterministically with pdfplumber and checked that each column is contiguous from $0 to its "Above $X" cutoff. Then I comparedscale.calc(agi, right=True)from the loaded model against the published tax for every integer AGI from $0 to cutoff + $200:soi/agi/total_agitriage20in11si.xls, column 3, "Adjusted gross income less deficit"). The "$10,000,000 or more" row appears once, so the second bracket is a copy.soi.long_term_capital_gains), policyengine.py, and policyengine-api, and ran an org-wide GitHub code search. The only reference is an inventory CSV in ai-inequality. The duplicate predates 5dd64eb, the root of the current history.The new test
policyengine_us/tests/test_parameter_scale_thresholds.pywalks everyParameterScalein the loaded system (867 scales). For every instant at which any bracket's threshold changes, including uprated values, it flags two brackets with the same finite threshold. It reads each threshold's step function fromvalues_listdirectly:_get_at_instantwould already have merged the duplicates, and some parameters carry padded0000-01-01entries that core cannot turn into a date. On base it finds exactly these three scales. The scan takes under a second on top of the system load.Two self-tests pin the guard: it flags a collision that starts at a later instant (and confirms core's silent sum), and it ignores duplicate
.infthresholds, which are common and harmless because tables that change length park unused brackets at infinity. It deliberately does not check ordering:add_bracketbisect-inserts brackets, so out-of-order YAML (for examplegov.states.la.tax.income.credits.school_readiness.rate, listed 5→1) evaluates correctly.Tests
pytest policyengine_us/tests/test_parameter_scale_thresholds.py policyengine_us/tests/test_parameter_files.py policyengine_us/tests/test_system_import.py: 15 passed.policyengine-core test policyengine_us/tests/policy/baseline/gov/states/ar -c policyengine_us: 498 passed.Out of scope
total_agi.yamlkeys the tax year 2020 values at2015-01-01, and its reference reads "IRS SOI PUF 2015 (20in11.xls)" with no href. Rekeying changes the uprated values, so it belongs in its own change.ParameterScale, not inadd_bracket, becauseMarginalRateTaxScale.combine_bracketrelies on the summing: Reject duplicate finite thresholds within a single parameter scale policyengine-core#550.🤖 Generated with Claude Code