Skip to content

Pay no Colorado sales tax refund for tax year 2026 (C.R.S. 39-22-2003(2)) - #9946

Merged
MaxGhenis merged 4 commits into
mainfrom
co-sales-tax-refund-2026-no-surplus
Oct 9, 2026
Merged

MaxGhenis merged 4 commits into
mainfrom
co-sales-tax-refund-2026-no-surplus

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Summary

policyengine-us paid Colorado's six-tier state sales tax refund in tax year 2026 by carrying the tax year 2025 table forward ($19 to $59 per eligible filer). No tax year 2026 refund exists: the statute pays it only when the fiscal year ending in that tax year had excess state revenues, and FY 2025-26 did not.

The law

  • C.R.S. 39-22-2003(2): "... for each subsequent taxable year, there shall be allowed to each qualified individual a state sales tax refund in an amount specified in subsection (3) of this section ... if there were excess state revenues for the fiscal year ending in that tax year that voters statewide have not authorized the state to retain and spend and that are required to be refunded pursuant to section 20 (7)(d) of article X of the state constitution." (colorado.public.law, read 2026-10-06.)
  • Colorado's fiscal year runs July to June, so FY 2025-26 (ending 2026-06-30) funds tax year 2026.
  • LCS Economic and Revenue Forecast, June 2026 (PDF created 2026-06-17): p. 31, Table 9, "Tax Year 2026 / Refunds from FY 2025-26 TABOR Refund Obligation": $0 for single and joint filers in all six tiers. p. 30: "The six-tier sales tax refund mechanism is expected to apply for tax years 2027 and 2028."
  • LCS Economic and Revenue Forecast, September 2026, p. 9: "The State Controller certified on September 8, 2026, that state revenue fell short of the Referendum C cap by $175.9 million. The state did not incur a TABOR refund obligation for FY 2025-26, and no refunds will be paid to taxpayers for tax year 2026."

The defect

co_sales_tax_refund multiplied the eligible-filer count by the tier amount with no test of the subsection (2) condition, and amount/scale.yaml has no 2026 entry, so the 2025 amounts carried into 2026.

The fix

  • New parameter gov.states.co.tax.income.credits.sales_tax_refund.in_effect: true from 2021, false for 2026, true again from 2027 (the LCS June 2026 forecast expects the six-tier refund for tax years 2027 and 2028).
  • co_sales_tax_refund multiplies the refund by it.

The 2027 setting keeps the model's existing behavior for 2027 on (the 2025 tier table carried forward until CDOR publishes each year's table). LCS projects somewhat higher 2027 amounts ($21 to $65 single, at higher thresholds); encoding forecast amounts is out of scope here. This PR does not touch co_tabor_cash_back, which #9584 handles.

Invariants

In policyengine_us/tests/core/test_co_sales_tax_refund_invariants.py: Hypothesis draws batches of single, joint and head-of-household units (modified AGI from -$50,000 to $400,000 plus tier edges, filer ages 14 to 90, wages), plus a seeded population of 100 units, each run as one vectorized simulation per year.

  1. Gate: in 2026 the refund is $0 for every unit.
  2. Differential: in 2025 the refund equals eligible filers × the published tier amount, with tiers taken from LCS March 2026 Table 8 ("up to $52,000 $19 ... $299,001 and up $59"), not from the parameters.
  3. Bounds: 0 ≤ refund ≤ 2 × $59 in every year, and in 2025 the refund is positive exactly when a filer is eligible.
  4. Intended carry-forward: the 2027 refund equals the 2025 refund (labelled intended in the test).

Tests

  • co_sales_tax_refund.yaml: 2026 single (scenario_043 shape: age 66, modified AGI $4,625) and 2026 joint, highest tier, both $0; a scenario_043 household (age 66, $4,088 wages, $553 taxable pension) with co_eitc $0, co_sales_tax_refund $0 and co_refundable_credits $0.
  • On main the three new cases fail with $19, $118 and $19.
  • With the fix: sales_tax_refund/ YAML 41 passed; invariants 2 passed.

Evidence

PolicyBench reference audit, scenario_043 × state_refundable_credits: the reference was $19 and the law gives $0 (39 of 46 models answered $0).

  • Verification: PolicyEngine/policybench-wt/reference-adversary/reference_audit/2026-10-05-reference-adversary/verification/independent/co_043.md
  • Case: .../reference_audit/2026-10-05-reference-adversary/runs/claude/cases/us__scenario_043__state_refundable_credits/

Impact

Removes every Colorado sales tax refund in tax year 2026 (previously $19 to $59 per eligible filer, doubled for two eligible spouses). Other years are unchanged.

axiom: C.R.S. 39-22-2003(2) queued: rulespec-us us-co/statutes/39/39-22-2003.yaml encodes the qualified-individual rules but defers the refund amount and has no excess-state-revenues condition; the pe-parity issue link is added here before merge.

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 6, 2026 18:15
C.R.S. 39-22-2003(2) allows the state sales tax refund for a tax year
only "if there were excess state revenues for the fiscal year ending in
that tax year". FY 2025-26 ended below the Referendum C cap: the LCS
June 2026 forecast (Table 9) showed $0 in every tax year 2026 tier, and
on 2026-09-08 the State Controller certified a $175.9 million shortfall.
policyengine-us had no such condition and carried the tax year 2025 tier
table ($19 to $59 per person) into 2026.

Add gov.states.co.tax.income.credits.sales_tax_refund.in_effect (false
for 2026; true again from 2027, when the LCS June 2026 forecast expects
the six-tier refund to apply) and multiply the refund by it.

Tests: 2026 single and joint cases and a scenario_043 household with no
Colorado refundable credits (PolicyBench reference audit 2026-10-05),
plus Hypothesis invariants: zero refund in 2026, the 2025 refund equals
eligible filers times the LCS March 2026 Table 8 tier, bounds, and the
intended carry-forward of the 2025 table into 2027.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Key every input by all three years so each Hypothesis draw and the
seeded population build one simulation instead of three, per the
repository's CI-cost rules. Locally (macOS, load average about 60) the
file takes 25.6 s of user CPU for the whole pytest process including
the model import, with 0.91 GB peak RSS.

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

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

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

…er boundary

The review of this PR found that the invariants test pinned the 2027 refund to
the 2025 tier amounts. Those amounts are a placeholder until CDOR publishes the
tax year 2027 table, and LCS's September 2026 forecast projects $43 for the
lowest single tier against the $19 carried forward.

- Drop that check from the invariants test and its docstring.
- Label the 2027 values as placeholders in in_effect.yaml.
- Add YAML cases showing a $0 refund for an eligible single filer at every
  2025 tier boundary in tax year 2026.

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

Copy link
Copy Markdown
Contributor Author

Handing off to the US + core hub.

  • Head: 663956bff983d5b996a0b26a0e955f1f0bab3311
  • Independent review: approve at this head (Subfleet job 20261008-172810-pe-us-9946-rereview; verdict in ~/reviews/policybench-reference-adversary-2026-10/co_rereview.md). The first review's medium finding (a test pinning the placeholder 2027 refund) is fixed in 663956b.
  • CI: gh pr checks exits 0. GitHub reports MERGEABLE, blocked only on the required approving review.
  • Context: found by PolicyBench's reference adversary (Add the reference adversary and record its first run (evidence only; no score changes) policybench#200, decision d1022).

Nothing is pending from the opening session.

@MaxGhenis
MaxGhenis merged commit 997fab9 into main Oct 9, 2026
28 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#9946 at 0cf8ed0758 (squash; branch updated from main; PR diff byte-identical to the reviewed 663956bff9): Pay no Colorado sales tax refund for tax year 2026 (C.R.S. 39-22-2003(2)).

  • Origin: PolicyBench's reference adversary (Add the reference adversary and record its first run (evidence only; no score changes) policybench#200) found the engine defect. Max ruled d1022 on 2026-10-06 to exclude the affected cells until a fixed policyengine-us release lands.
  • Review: independent Opus 5.5 review APPROVE (Subfleet), verdict in ~/reviews/policybench-reference-adversary-2026-10/. The PR's last commit predates the review, so the reviewed head is this head.
  • Hand-off: from local_3dd3d124. Nothing was pending from the opening session.
  • Gates checked live at merge:
    • gh pr checks exits 0;
    • the latest Pull request run at the head concluded success;
    • MERGEABLE;
    • not a draft;
    • no CHANGES_REQUESTED review;
    • the semantic-overlap guard;
    • head pinned.
  • Impact: as stated in the PR body's impact section. This is a bug fix that corrects the model to the cited law.
  • --admin: used only because a required approving review is the sole block.

@MaxGhenis
MaxGhenis deleted the co-sales-tax-refund-2026-no-surplus branch October 9, 2026 04:58
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