Skip to content

Repoint Arkansas DFA references off the dead images/uploads/incomeTaxOffice path - #9494

Merged
MaxGhenis merged 2 commits into
mainfrom
fix/ar-dfa-dead-links
Sep 25, 2026
Merged

MaxGhenis merged 2 commits into
mainfrom
fix/ar-dfa-dead-links

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Arkansas DFA moved its income-tax PDFs off https://www.dfa.arkansas.gov/images/uploads/incomeTaxOffice/…; those URLs now return 404 (two of them 301 to the new location). The same filenames live under https://www.dfa.arkansas.gov/wp-content/uploads/…, which is where DFA's own 2021–2024 tax-forms pages link them today.

This PR rewrites every remaining images/uploads/incomeTaxOffice/ href in the repo to the wp-content/uploads/ equivalent, keeping filenames and #page= anchors byte-identical.

  • 123 hrefs across 59 files: 25 parameter files under parameters/gov/states/ar/, the contrib AR dependent-credit parameter, and 33 AR variable reference strings (extended beyond the parameter files because the variables carried the same dead host path).
  • parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml and joint.yaml were left to Exclude Arkansas unemployment compensation from gross income in 2021 #9451, which merged on 2026-09-16; main was merged into this branch on 2026-09-20, so the branch now has zero images/uploads/incomeTaxOffice hrefs.
  • Ruff re-wrapped the now-shorter reference string in ar_itemized_deductions_indiv.py / _joint.py (required by ruff format --check).

Filename that did not resolve under wp-content/uploads

TaxBrackets_2014.pdf (the "2014 Indexed Tax Brackets" reference in parameters/gov/states/ar/tax/income/rates/main/rate.yaml) is 404 under both paths, is absent from DFA's Forms Archive (which lists bracket sheets for 2003–2013 and 2015–2018 but not 2014), and no filename variant resolves. The reference now points at the DFA-hosted 2014 AR1000F/AR1000NR instruction booklet, LongBookwTaxTables_2014.pdf:

  • #page=6 — "Tax Bracket Reduced (Act 1459 of 2013)": the 1% bracket reduced to 0.9% on income $0–$4,299 for tax year 2014.
  • #page=28 — "2014 Regular Tax Table" (PDF page numbers match the booklet's printed index).

The booklet states the 0.9% bottom bracket explicitly (page 6) and the 7% top rate (page 30 note) but does not print the indexed bracket schedule the retired sheet did. An independent check recomputed every one of the 503 rows of the 2014 Regular Tax Table (pages 28–30) as round-half-up tax at the cell midpoint under the yaml's 2014 schedule (0.9/2.5/3.5/4.5/6/7% at $0/4,300/8,400/12,600/21,000/35,100); all 503 match, and the 2015 schedule or a 1% bottom rate mismatch hundreds of rows. No parameter values changed. The Wayback Machine was offline/rate-limiting throughout this session, so an archived copy of the retired sheet could not be checked; adding one as a third reference is a possible follow-up.

Verification

  • All 17 distinct rewritten URLs return HTTP 200 with content-type: application/pdf and no redirects (curl). The 16 unchanged filenames match the hrefs on DFA's 2021, 2022, 2023, and 2024 tax-forms pages. Of the old URLs, 15 return 404 and two return 301: the 2024 booklet redirects to the exact new URL, and the 2023 booklet redirects to a -1.pdf re-render (Aug 2024) that is content-identical on every anchored page; this PR keeps the un-suffixed 2023 filename that DFA's 2023 forms page links.
  • Removed lines, after the prefix substitution, are a multiset-identical match to the added lines; the only anchor changes are the two 2014 ones above.
  • uv run ruff format --check . and uv run ruff check . pass (locked ruff 0.15.5).
  • YAML tests: policyengine-core test policyengine_us/tests/policy/baseline/gov/states/ar (480 passed) and policyengine_us/tests/policy/contrib/states/ar (17 passed) against this branch.

axiom: n/a: reference-URL maintenance only; no rule, parameter, or eligibility logic changed.

🤖 Generated with Claude Code

…Office path

DFA moved its income-tax PDFs to wp-content/uploads; the old
images/uploads/incomeTaxOffice URLs return 404. Rewrite every remaining
href/reference to the same filename under wp-content/uploads, preserving
#page anchors, across the AR parameters, the contrib AR dependent-credit
parameter, and the AR variable reference strings. Leave the two
gross_income/sources files to #9451.

TaxBrackets_2014.pdf no longer exists on dfa.arkansas.gov, so the 2014
bracket reference in rates/main/rate.yaml now points at the 2014
AR1000F/AR1000NR instruction booklet (page 6 bracket change, page 28
Regular Tax Table).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (909176a) to head (311ec1c).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #9494    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            4        32    +28     
  Lines           76       501   +425     
  Branches         2         2            
==========================================
+ Hits            76       501   +425     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Heads up: #9451 merged just now (bd58a92) and rewrote the same three Arkansas DFA hrefs in gov/states/ar/tax/income/gross_income/sources/individual.yaml and joint.yaml to the /wp-content/uploads/ path, so this branch will need a rebase; the remaining 70 links are untouched.

One conflict, in ar_retirement_or_disability_benefits_exemption_person.py.
Main already repointed that file's reference (#9507) and rewrote its formula
(#9423, #9510), so main's version is kept whole; the branch's side carried the
old formula body. No images/uploads/incomeTaxOffice path remains in the tree.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Main (including #9451's fix to gross_income/sources/individual.yaml and joint.yaml) is merged into this branch as of 311ec1c, so the branch tip has zero images/uploads/incomeTaxOffice hrefs left; git diff upstream/main... is still the same 59 files. All 37 checks pass and the PR is mergeable. Only a review approval is outstanding.

@MaxGhenis
MaxGhenis merged commit d24d5d4 into main Sep 25, 2026
37 checks passed
@MaxGhenis
MaxGhenis deleted the fix/ar-dfa-dead-links branch September 25, 2026 01:56
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merge audit

Admin-merged at the reviewed head 311ec1cc53 because branch protection requires one approving review and the author can't approve his own PR. Two independent approvals stood in for that review:

  1. Main session review (Claude Opus 5.5): after swapping the old URL prefix for the new one, every removed line matches an added line. The only content change is the 2014 reference in rate.yaml. All 17 new URLs return 200 application/pdf with no redirect. Merging this head into current main is conflict-free and leaves no images/uploads/incomeTaxOffice link outside the changelog fragment. The 2014 booklet's page 6 (Act 1459 of 2013, 0.9% on $0–$4,299) and page 28 (2014 Regular Tax Table) say what the new titles claim.
  2. Adversarial review (6 independent reviewers, each told to find reasons not to merge): all approved, with no blocker or major finding. They checked:

CI was 37/37 green on the reviewed head, checked with a fail-closed gate immediately before the merge (--match-head-commit).

Corrections to the description

  • The 2014 Regular Tax Table has 500 rows ($0–$49,999 in $100 steps), not 503. Every row matches.
  • The PR touches 32 variable files, not 33 (one was already fixed on main by Clean up reference links for AR, RI, and WI retirement exclusions #9507). The AR baseline suite is now 495 tests at the head and 496 after merging into main.
  • TaxBrackets_2014.pdf was never captured by the Wayback Machine, which does have 52 other 2014 files from the same old path, so the proposed archived-copy follow-up would find nothing.

Pre-existing issues found in review (not caused by this PR)

  • Ten AR variables list their reference URLs without commas, so Python joins them into one dead link. They are ar_personal_credit* (5), ar_taxable_income_{indiv,joint} and ar_income_tax_before_non_refundable_credits_{indiv,joint,unit}.
  • Several anchors land on the wrong page:
    • 2023 low-income tables use #page=25/26; the tables are on 29/30.
    • 2024 low-income tables use #page=24/25; the tables are on 28/29.
    • The 2021 retirement cap uses #page=13; it should be 12.
    • Others are smaller.
  • Model bug: for 2014–2020, ar_income_tax_before_non_refundable_credits_* applies the rate of the highest bracket reached to all taxable income (rate.yaml is single_amount, and reduction.yaml starts in 2021). That overstates tax against the DFA tax table this PR now cites.
  • Model bug: the AR medical-expense deduction uses the federal 7.5% floor for 2017 onward. The Arkansas AR3 instructions say 10% (2022 booklet, PDF p. 21, Line 3).

The follow-ups are queued as separate tasks.

🤖 Generated with Claude Code

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