Skip to content

Use Louisiana's RIB 26-019 2026 standard deduction and retirement exemption - #9791

Merged
MaxGhenis merged 5 commits into
mainfrom
la-2026-rib-26-019
Oct 5, 2026
Merged

MaxGhenis merged 5 commits into
mainfrom
la-2026-rib-26-019

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Louisiana Department of Revenue Revenue Information Bulletin 26-019, dated September 28, 2026, publishes the 2026 inflation-adjusted amounts. This PR encodes them and projects later years with the statute's annual CPI-U adjustment.

2026 amount Before (main) This PR (RIB 26-019)
Standard deduction, single and married filing separately (R.S. 47:294) $12,835 $12,838
Standard deduction, joint, head of household and surviving spouse $25,670 $25,676
Retirement income exemption, age 65+ (R.S. 47:44.1) $12,000 (held flat, no uprating) $12,324
  • deductions/standard/amount.yaml: replaces the self-computed 2026 entries from Update Louisiana 2026 standard deduction #8411 ($12,500 × 324.054 / 315.605) with RIB 26-019's amounts. It cites the RIB and keeps the R.S. 47:294 reference. It drops the February 20, 2026 Louisiana Register reference: that page is LDR's withholding formula, W = (S − (12875 / N)) * .0309, i.e. the $12,875 withholding amount (LAC 61:I.1501, LR 52:749). That amount does not apply to the return deduction.
  • exempt_income/retirement/cap.yaml: adds 2026-01-01: 12_324 to the 65+ bracket and cites the RIB.
  • Later years: the new extend_la_cpi_u_indexed_amounts in parameters/uprating_extensions.py handles both parameters. It follows the pattern of extend_or_ctc_parameters and extend_wa_millionaires_standard_deduction, and replaces the standard deduction's plain uprating: gov.bls.cpi.cpi_u. The retirement cap previously had no uprating, so every year after 2025 stayed at $12,000.
  • New gov.bls.cpi.cpi_u_nsa_december: BLS's not seasonally adjusted December CPI-U (CUUR0000SA0), 2012–2025. BLS reports the 12-month change from this series. The model's cpi_u is seasonally adjusted from January 2024, so it cannot reproduce BLS's reported percentage (see the review section).
  • Comment fix: la_retirement_exemption_person.py still described the cap as $6,000.

What the statute and the bulletin say (verified 2026-10-05)

  • RIB 26-019: sha256 f22663cde2ebdf56eed6688779d25583e1c8fb86feaa773c8454b8735dd71067 (matches). Its table shows 2025 amounts of $12,500 / $25,000 / $12,000, a "CPI-U Multiplier" of 2.7%, and 2026 amounts of $12,838 / $25,676 / $12,324. A RIB "does not have the force and effect of law". Here it is the agency's published computation of the statutory amount.
  • R.S. 47:294(B) (legis.la.gov, fetched today): "Beginning January 1, 2026, and thereafter, the amount of the standard deduction provided in Subsection A of this Section shall be adjusted annually by an amount calculated by multiplying the amount of the prior year's standard deduction by the percentage increase in the Consumer Price Index United States city average for all urban consumers (CPI-U), as reported by the United States Department of Labor, Bureau of Labor Statistics, or its successor, for the previous calendar year." 47:294(A)(2) sets joint, surviving spouse and head of household at "200% of the dollar amount provided for Single Individuals".
  • R.S. 47:44.1(A) applies the same adjustment, in the same words, to the $12,000 exemption, beginning January 1, 2026.
  • What the RIB's numbers pin down (BLS API, CUUR0000SA0, not seasonally adjusted):
    • The December 2024 to December 2025 change is 315.605 → 324.054, or 2.677%. BLS reports it as 2.7%.
    • The 2025 annual-average change is 313.689 → 321.943, or 2.63%, which rounds to 2.6% and would give $12,825.
    • To get both $12,838 and $12,324 with nearest-dollar rounding, the multiplier must lie in [2.7000%, 2.7042%).
    • So LDR applied BLS's one-decimal December-over-December figure. The unrounded 2.677% gives Update Louisiana 2026 standard deduction #8411's $12,835.
    • The joint amount is 2 × the rounded single amount: 25,000 × 1.027 = 25,675, but the RIB says 25,676.

Projection method for 2027 onward

For each year after the last published amount, extend_la_cpi_u_indexed_amounts sets:

  • single = separate = prior year's single × (1 + p/100), rounded to the nearest dollar with halves rounding up (Decimal);
  • joint = head of household = surviving spouse = 2 × single;
  • 65+ retirement cap = prior year's cap × (1 + p/100), rounded the same way.

p is the CPI-U December-over-December change for the prior calendar year, rounded half up to one decimal in Decimal and floored at 0, since "percentage increase" excludes a decrease. Its source depends on what is published:

  • Both Decembers published: p comes from cpi_u_nsa_december. It reproduces BLS's published change for every year 2013–2025 (2021 7.0, 2022 6.5, 2023 3.4, 2024 2.9, 2025 2.7).

  • Otherwise: both Decembers come from the model's cpi_u, never one from each series. An unobserved December is interpolated geometrically by month from the last observation toward CBO's projection points. Those points are calendar-year averages (CPI projection points in c_cpi_u.yaml and cpi_u.yaml are calendar-year averages, not the 12-months-ending-August averages their comment describes #9608), so each is placed halfway between June and July of its year; past the last point the index holds flat.

    With observations through June 2026, December 2026 interpolates to 336.26 against an observed 326.03 for December 2025, so 2027 gets 3.1%. Carrying June forward would give 2.0%, about six months of inflation.

Each future RIB should still be encoded when published, and published YAML values take precedence over the projection for their years. Like the other extension-projected parameters, the projection is fixed when the parameter tree is built, so a reform to the single amount does not carry through to the other statuses or later years (documented in the docstring).

Floating-point note: 12,500 × 1.027 is 12,837.4999… in binary, so float rounding gives $12,837. The back-test caught this, and a parametrized test pins three half-dollar cases that misround under float arithmetic, including (20,500, 1.1%), which misrounds under both prior × (1 + p/100) and prior × (100 + p)/100.

Projected values on the current CPI-U series (these move with BLS/CBO refreshes):

Year Single (main → PR) Joint (main → PR) 65+ retirement cap (main → PR)
2027 13,070.02 → 13,236 26,140.03 → 26,472 12,000 → 12,706
2028 13,373.89 → 13,540 26,747.77 → 27,080 12,000 → 12,998
2030 14,002.69 → 14,170 28,005.38 → 28,340 12,000 → 13,603

Main's plain uprating ratios CPI-U at January 1 against January 2026, without the dollar rounding or the 200% rule. Its 2027 value reads June 2026, so it gets about six months of inflation.

Invariants (stated and tested)

policyengine_us/tests/policy/baseline/gov/states/la/tax/income/test_la_cpi_u_indexing.py (32 tests) checks these:

  1. Differential, computation vs. published figures:
    • the projection rule reproduces every RIB 26-019 amount from the 2025 amounts (2.7% → $12,838, $25,676, $12,324);
    • the encoded 2026 YAML values equal that computation;
    • p equals BLS's published December-over-December change for every year 2013–2025.
  2. The alternative readings are pinned as wrong: the unrounded change gives $12,835, the annual average gives $12,825, and adjusting joint separately gives $25,675.
  3. 200% rule: every year 2027–2100, separate = single, and joint = head of household = surviving spouse = 2 × single.
  4. Recurrence: every projected year equals adjust(prior year, p(prior calendar year)), for the standard deduction and the retirement cap (through the scale's calc).
  5. Whole dollars and no decrease: amounts are integers and non-decreasing, values hold after 2100, and the under-65 bracket stays 0.
  6. Published values take precedence: published NSA Decembers are used when both exist and are never mixed with the model series. On a synthetic tree, encoded years are kept, and a later encoded single amount drives separate and joint.
  7. Interpolation:
    • unobserved months follow the mid-year-anchored geometric path and hold flat past the last point (synthetic);
    • on the live series, December 2026 lies strictly between the last observation and the 2027 point;
    • a property test checks interpolated months lie between their anchors and are non-decreasing when the anchors are;
    • a February in the last observed year is never an anchor, whether it holds a projection or a refreshed observation, so a CPI refresh cannot move later months through it;
    • a tripwire fails if cpi_u is refreshed past a December that cpi_u_nsa_december lacks.
  8. Property-based (Hypothesis):
    • the adjustment is within $0.50 of the exact product, rounds halves up, is ≥ the prior amount, and is monotone in the percentage;
    • a 0% adjustment is the identity;
    • p is ≥ 0, has one decimal, is within 0.05 of the true change, and is monotone in the December index.
  9. Mutation check. I ran 14 mutants of the new code against this module, at 498b776.
    • 12 were killed. These were:
      • float rounding in either form;
      • joint adjusted on its own;
      • unrounded or float-rounded p;
      • ignoring the NSA Decembers;
      • mixing NSA and model Decembers;
      • no floor at 0;
      • the current year's CPI;
      • carry-forward instead of interpolation;
      • anchoring projection points at February;
      • linear interpolation;
      • no February filter (round 2's defect).
    • ROUND_HALF_EVEN survived. Every half-dollar case then in the module rounds up to an even dollar, so banker's rounding agreed with half-up on all of them. f9a82d6 adds 10,100 × 1.005 = 10,150.50, which goes to 10,151 under half-up and to the even 10,150 under half-even. Re-run, the mutant now fails.
    • Float rounding of p survived. It is an equivalent mutant on published indexes. p is computed exactly in Decimal. With 3-decimal December indexes, a ratio within float error of an x.x5 tie must be an exact tie, and at every exact tie from 0.05 to 39.95 the float path agrees with half-up (checked exhaustively).
      • Interpolated projection levels are arbitrary doubles, so there the two forms can differ only inside a window about 1e-15 wide around a tie. Inside that window the interpolation's own float error makes neither answer more correct.
      • Round 5 agreed it is not blocking.

Tests

  • la_standard_deduction.yaml: 2026 cases for all five filing statuses (12,838 / 25,676).
  • integration.yaml: the 2026 single case becomes 12,838 / 27,162 / 814.86, i.e. 3% × (40,000 − 12,838), down from 814.95.
  • la_retirement_exemption_person.yaml: a 2025 above-cap case (12,000), and 2026 cases above the cap (12,324), between the 2025 and 2026 caps (12,200), and a head and spouse pair (0 for the under-65 head, 12,324 for the spouse).
  • integration.yaml: 17 more cases that mirror the Axiom companion tests in Repair Louisiana's 2026 standard deduction and encode the indexed retirement exemption (LDR RIB 26-019; R.S. 47:294, 47:44.1) TheAxiomFoundation/rulespec-us#1493, from the same RIB ground truth. They cover:
    • federal AGI 50,000 for every filing status (1,114.86 single and separate; 729.72 joint, head of household and surviving spouse);
    • the 12,838 / 25,676 boundaries, where 25,676 rejects 25,000 × 1.027;
    • the 12,324 cap below, at and above;
    • retirement income flowing through la_agi to tax (745.14 for a 65+ single; 890.28 for a 65+ couple);
    • a public pension exempted through sources.yaml that does not use the 47:44.1 amount (64.86).
  • Local runs at the final test content:
    • all Louisiana YAML tests: 348 passed;
    • the new module, test_uprating_extensions.py, the Oregon extension tests and the BLS CPI actuals tests: 65 passed;
    • tests/code_health: 136 passed.
  • tests/core had one failure in the combined local run, in test_ald_determinism.py::test_household_float32_deductions_are_identical_across_hash_seeds.
    • That test runs subprocesses under different hash seeds, with a 180 s timeout on each, and the host was saturated at the time.
    • Re-run alone at this head it passes (105 s).
    • CI is authoritative for tests/core.

Impact

Every figure is a policyengine-us microsimulation on the default dataset: two full runs per year, this branch against a reform restoring main's values.

  • For 2026, main's values are 12,835 / 25,670 and a 12,000 cap.
  • For 2027, main's values are its CPI-uprated 13,070.02 / 26,140.03 and a 12,000 cap.
  • The script is microsim_impact.py; its output is kept with the evidence.
  • The 2026 runs used 51cfffe. No later commit changes a 2026 value: the projection only fills years after the last published one. The 2027 runs used the final projection code.
Year Louisiana income tax (main → PR) Change Tax units paying less / more (of all Louisiana units) Largest cut
2026 $2,870.36M → $2,869.63M −$0.73M 871,768 / 0 (of 1,556,946) $19.62
2027 $2,986.01M → $2,976.78M −$9.23M 891,335 / 0 (of 1,565,771) $52.32

The largest cuts reconcile with the parameter changes for a 65+ joint couple whose tax is 3% of taxable income:

  • 2026: (6 + 2 × 324) × 3% = $19.62.
  • 2027: (331.97 + 2 × 706) × 3% = $52.32.

PolicyBench. The audit PolicyEngine/policybench#192 (reference_audit/2026-10-05-louisiana, branch la-2026-standard-deduction) found the engine's $12,835 within $0.09 of RIB 26-019 on PolicyBench's two scored Louisiana outputs. PolicyBench builds references from the newest policyengine-us release. Once this merges, a later reference rebuild will see scenario_051 and scenario_077 move by −$0.09, within the $1 tolerance. The audit also found that the $12,324 retirement cap changes none of the 1,984 outputs. How PolicyBench's publication convention treats an amount announced after its 2026-07-03 freeze is pending Max's ruling on that audit. This PR encodes the law regardless.

Review

Independent review was by Subfleet Opus 5.5, in four rounds:

  1. Round 1 at 51cfffe: REQUEST_CHANGES.
    • (a) p came from the model's seasonally adjusted CPI-U. 2025 cleared the 2.65 rounding boundary by 0.004 points, and 2022 and 2023 would round to 6.4% and 3.3% instead of BLS's 6.5% and 3.4%.
    • (b) An unobserved December read the last observation (June 2026), so 2027 got 2.0%.
    • Both were fixed in 33ba01b, by adding cpi_u_nsa_december and the interpolation.
  2. Round 2 at 33ba01b: REQUEST_CHANGES. A February observation (data ending exactly at February) would be read as a calendar-year anchor. Fixed in 498b776, along with its nits.
  3. Round 3 at 498b776: APPROVE.
  4. Round 4 at 0240a16 (the 17 mirrored test cases and a docstring): APPROVE. Its nits: a comment on AGI inputs, now added; some person-level cases overlap the unit file, kept so the set stays a one-to-one mirror of the Axiom cases.
  5. Round 5 at f9a82d6 (the half-even test case and the comment): APPROVE, at the current head.

Axiom

axiom: TheAxiomFoundation/rulespec-us#1493 queued

The Axiom side is wrong today:

  • us-la:statutes/47:294 encodes only the 2025 base and defers the indexed deduction.
  • R.S. 47:44.1 is unencoded.
  • us-la:policies/income_tax/2026_resident_core uses the 2026 IT-540ESi estimated-tax amounts ($12,875 / $25,750), which are the withholding figures, as the return deduction.

None of it can be fixed by a PR:

  • the signed encoder needs an encoder pin advance;
  • RIB 26-019 must first be ingested into axiom-corpus and released;
  • 2026_resident_core has no signed edit path today;
  • the OpenAI-billed signed run needs Max's approval (cos d971).

#1493 is dispatch-ready. It has:

  • module paths, corpus citations, verbatim law and workflow inputs;
  • pasteable review_finding text for 47:44.1 and the RIB module;
  • companion tests from the same RIB 26-019 ground truth as these PE tests.

Its 41-case resident-core test file passes on the pinned Axiom engine (scratch copy), and its negative controls fail on 12,875, 12,835 and 25,675.

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 5, 2026 11:25
…mption

LDR Revenue Information Bulletin 26-019 (2026-09-28) sets the 2026
standard deduction at $12,838 single/separate and $25,676 joint, head of
household and surviving spouse, and the age-65 retirement income
exemption at $12,324: each 2025 amount times a 2.7% CPI-U multiplier,
rounded to the dollar, with the joint amount twice the rounded single
amount. PolicyEngine carried a self-computed $12,835 / $25,670 (PR #8411,
unrounded 2.677%) and held the retirement cap at $12,000.

Later years follow La. R.S. 47:294(B) and 47:44.1(A): the prior year's
amount times the prior calendar year's CPI-U increase. The new
extend_la_cpi_u_indexed_amounts reproduces RIB 26-019 from the 2025
amounts (BLS's one-decimal December-over-December change, decimal
half-up rounding, joint = 2 x single) and replaces the plain CPI-U
metadata uprating, which had no joint-doubling or rounding rule.

The February 20, 2026 Louisiana Register reference is dropped from the
return-deduction parameter: it is LDR's withholding formula ($12,875),
not the return amount.

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

Review of #9791 found two problems in the Louisiana projection:

- BLS reports the CPI-U December-over-December change from the not
  seasonally adjusted index, but the model's cpi_u is seasonally adjusted
  from January 2024. 2025 rounded to 2.7% by a 0.004-point margin, and
  2022 and 2023 would round to 6.4% and 3.3% instead of BLS's 6.5% and
  3.4%. Add gov.bls.cpi.cpi_u_nsa_december (CUUR0000SA0, 2012-2025) and
  use it whenever both Decembers are published.
- An unobserved December read the last observation, so 2027 got only
  January-June 2026 inflation (2.0%). Interpolate geometrically from the
  last observation toward CBO's calendar-year projection points, placed
  halfway between June and July of their year (#9608); 2027 is now 3.1%.

Also round the percentage in Decimal, raise a descriptive error if the
age-65 bracket is missing, note that reforms to the single amount do not
carry through, and pin half-dollar float traps and BLS's published
2013-2025 changes in tests.

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

codecov Bot commented Oct 5, 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 (f9a82d6).
⚠️ Report is 196 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #9791   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         1    -3     
  Lines           76        17   -59     
  Branches         2         0    -2     
=========================================
- Hits            76        17   -59     
Flag Coverage Δ
unittests 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.

Round-2 review of #9791: when monthly CPI-U data ends at February Y, the
February instant holds an observation but was read as CBO's calendar-year
Y average anchored halfway through Y, moving later projected percentages
by about 0.4 points until the next refresh. Only Februaries in years after
the last observation's year are now anchors, so no branch reads an
instant a refresh could turn from projection into observation.

Also add a tripwire that cpi_u_nsa_december keeps up with the monthly
series, test the missing age-65 bracket error, note that cpi_u.yaml's
"# YYYY value" comments are tax-year labels, and mention the NSA series
in the changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 5, 2026 12:42
Add 17 end-to-end, boundary and retirement-exemption cases to the
Louisiana integration tests that mirror the companion tests proposed in
TheAxiomFoundation/rulespec-us#1493, with expectations from the same RIB
26-019 amounts: federal AGI 50,000 for every filing status, the
12,838 / 25,676 boundaries (25,676 rejects 25,000 x 1.027), the 12,324
cap at, below and above, and retirement income flowing through la_agi to
tax, including a public pension exempted under sources.yaml that does not
use the R.S. 47:44.1 amount.

Also clarify that the February anchor rule only matters when CPI-U
observations end in January.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mutation run at 498b776 found that switching the dollar rounding to
half-even survived: each deterministic half-dollar case (12,837.50,
10,311.50, 20,725.50) rounds up to an even dollar, so banker's rounding
agrees with half-up on all of them, and the Hypothesis property only
catches it when it draws an exact half. Add 10,100 x 1.005 = 10,150.50,
which rounds up to 10,151 but to the even 10,150 under half-even (and
under float prior x (1 + p / 100)).

Also note that the retirement end-to-end cases set federal AGI directly.

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

Copy link
Copy Markdown
Contributor Author

Hand-off to the US + core hub

  • Head: f9a82d605ae7a3a9d0cbc7f51e6f31cf716c596f. Not a draft, MERGEABLE.
  • Review: independent Subfleet Opus 5.5 review, five rounds.
    • Rounds 1–2 requested changes; all were fixed.
    • Rounds 3, 4 and 5 APPROVE. Round 5 is at the current head.
    • Verdicts are in ~/TheAxiomFoundation/_axiom-runs/la-rib-26-019-2026-10-05/review-out*.md; round 5 is review-out-r5.md.
  • Passed locally:
    • Louisiana YAML tests: 348 passed.
    • New module test_la_cpi_u_indexing.py (32), test_uprating_extensions.py, the Oregon extension tests and the BLS CPI actuals tests: 65 passed.
    • tests/code_health: 136 passed.
    • 14 mutants run: 12 killed at 498b776; g (half-even) killed after f9a82d6; j is equivalent.
    • tests/core: one subprocess-timeout determinism test failed once under host load and passes when re-run alone. CI is authoritative.
  • CI at this head: 17 pass, 20 pending, 0 failing when handed off.
  • Pending: CI, and the required approving review.
  • Depends on: none. This PR has no textual overlap with open Keep dependents' retirement income out of state subtractions #9699 or Replace dead reference URLs found behind bot walls #9774 (checked by round 4).
  • Decisions: none for this merge. It is a correction to the law and its published source. Per Max's 2026-10-02 rule, a bug fix that moves aggregates needs no approval; the impact is stated in the body (2026 −$0.73M, 2027 −$9.23M Louisiana income tax).
  • Follow-ups owed (not in this PR):
    • Refresh the CPI actuals past June 2026 and fix the CPI-U NSA/SA seam at January 2024. This is a separate chip.
    • Add the December 2026 NSA CPI-U to cpi_u_nsa_december.yaml in January 2027. The new tripwire test enforces this once cpi_u observes that December.
    • Encode LDR's 2027 bulletin when it is published.

@MaxGhenis
MaxGhenis merged commit 3f15391 into main Oct 5, 2026
37 checks passed
@MaxGhenis
MaxGhenis deleted the la-2026-rib-26-019 branch October 5, 2026 19:07
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Landed by the US + core hub, after session 4be2b2e0 handed it off, at head f9a82d605ae7a3a9d0cbc7f51e6f31cf716c596f. Squash merge, --admin --match-head-commit; the only block was the required approving review, which no one else can give on Max's PRs.

Gates:

  • Reviews: an independent Opus 5.5 review ran five rounds. Rounds 1–2 requested changes, and all were fixed. Rounds 3–5 approved; round 5 covers the delta 0240a163..f9a82d60, which is this head.
  • Combined with main: the hub ran Louisiana's tests on the tree GitHub's merge produces, main 18cc357b86 plus this PR: test_la_cpi_u_indexing.py 32 passed, and the gov/states/la YAML 348 passed. There is no file overlap with main's changes since its base.
  • CI: gh pr checks exits 0, and every check run on f9a82d605a succeeded.
  • State: MERGEABLE; not a draft; no CHANGES_REQUESTED review.
  • Impact: real microsimulation in the body: Louisiana income tax −$0.73M (2026) and −$9.23M (2027). This is a correction to LDR RIB 26-019.

The Axiom side (rulespec-us#1493) and its signed dispatch (cos d971) don't block this merge.

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