Repository navigation
Encode the 2030 expiry of California's top income tax rates; add Prop 3 (2026) reform - #9601
Conversation
… 3 (2026) reform Under Cal. Const. art. XIII, section 36(f)(2), the 10.3%, 11.3% and 12.3% rates added by Proposition 30 and extended by Proposition 55 apply to taxable years before January 1, 2031. The baseline carried them indefinitely. From 2031 the three brackets now revert to 9.3%, matching the Legislative Analyst's Figure 1 in the 2026 voter guide. Proposition 3 on the November 3, 2026 ballot would make those rates permanent. gov.contrib.states.ca.prop3.in_effect switches on a parameter-only reform that keeps them from 2031 onward. The 1% Mental Health Services Tax is unaffected. Tests: 3 baseline boundary cases (2030 vs 2031) and 6 reform cases, expected values computed by hand from the 2031 thresholds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Program ReviewPR #9601: Encode the 2030 expiry of California's top income tax rates; add Prop 3 (2026) reform The law is encoded correctly. All five filing-status schedules keep 10.3% / 11.3% / 12.3% through tax year 2030 and fall back to 9.3% from 2031-01-01. The Prop 3 reform restores exactly those three rates, on the right brackets, for all five statuses from 2031. Neither PDF audit found a value or date mismatch. The issues below are two citation and hard-coding problems that must be fixed, a reform activation window that cannot reach Prop 3's operative year, and test coverage for the three filing statuses that aren't tested yet. Source Documents
Year(s): TY2025 thresholds (FTB); the TY2030 / TY2031 sunset boundary; Prop 3 reform 2031-01-01 to 2100-12-31. Critical (Must Fix)1. The head-of-household rate file cites the wrong constitutional paragraph: § 36(f)(2) instead of § 36(f)(3)
2. The reform hard-codes the restored rates and bracket indexes
Should Address1. The activation scan cannot see Prop 3's operative year, so a toggle that starts in 2029 or later silently does nothing
2.
3. The joint and surviving-spouse files don't cite RTC § 17045, so the chain from § 36(f)(2) to their 2031 values is broken
4. HEAD_OF_HOUSEHOLD, SEPARATE and SURVIVING_SPOUSE are never tested in 2031, under the baseline or the reform
5. The changelog type covers the baseline fix but not the new contrib reform
6. No test covers the new AMT interaction
Suggestions
Pre-existing (out of PR scope)
Verified correct
PDF Audit SummaryNeither audit reported a value mismatch; only citation and reference items came up. No cross-reference or external-PDF requests were raised, and the PR adds no
Validation Summary
Out-year impact (informational): from 2031, baseline CA income tax revenue falls for every filer above the 10.3% threshold. The LAO puts the rates at $5 billion to $15 billion a year. Saved app policies that edit brackets 6-8 will show larger 2031+ impacts against the new baseline. Review Severity: REQUEST_CHANGESThe two critical items are both citation and encoding-hygiene problems with small, mechanical fixes: the HOH citation points to the wrong constitutional paragraph, and the reform hard-codes its rates and bracket indexes. The law and every value are correct. Should Address item 1 is the most substantive functional issue: enabling Prop 3 from its own operative year does nothing, with no warning. Next StepsTo auto-fix issues: |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes per the program review above (#9601 (comment)). The law is encoded correctly: 2030 is the last year with the 10.3/11.3/12.3% rates ("before January 1, 2031"), all five filing statuses switch on 2031-01-01, there are no value mismatches, and no partner test runs past 2026.
Items to address:
- Head-of-household is governed by Cal. Const. art. XIII §36(f)(3), not (f)(2). The same (f)(2)-only citation appears in in_effect.yaml, the reform comment and the changelog.
ca_prop3_reform.pyhard-codes the rates and bracket indexes {6: 0.103, 7: 0.113, 8: 0.123}. The values match the measure, but copying each bracket's 2030 rate forward would be safer.- The
range(5)activation scan only looks at 2024–2028, so a user who switchesin_effecton for 2029 or later silently gets the baseline. A Reform.from_dict pytest would catch this. - Prop 3 measure-text anchors are missing, and RTC §17045 is missing on joint/surviving-spouse.
- HOH, MFS and QSS have no 2031 cases, and nothing tests the 2031 AMT interaction.
- The changelog needs an
.added.mdfragment for the reform.
- Copy each bracket's 2030 rate forward instead of hard-coding the rates and bracket indexes, so user 2030 edits and schedule changes carry over. - Read activation from the dated in_effect values instead of a five-year scan, and restore the rates only in the years from 2031 to 2100 in which the toggle is true; the bypass instance stays unconditional. - Cite Cal. Const. art. XIII, § 36(f)(3) for head of household and § 36(f)(2)-(3) where both apply; add Prop 3 SEC. 4 and LAO page anchors, dated Prop 55 references, RTC § 17045 on joint and surviving spouse, and RTC § 17041 subsections; drop the stale indexing comment. - Add 2031 cases for every filing status, a 2030 head-of-household case, AMT and MHST stacking cases, and cases inside the first two surcharge brackets; move the contrib YAML to ca/prop3/ and drop redundant toggles. - Add pytest coverage of the app activation path, delayed and bounded toggles, 2030 user rates, and rate, threshold and RTC § 17045 properties. - Group the CA registration, export create_ca_prop3, and add an .added changelog fragment for the reform. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reform now reads each schedule's enacted rates from the file they were loaded from and, inside each active window, gives the 2030 rate only to the brackets the enacted sunset changes and only on intervals where the enacted 9.3% rate still applies. This fixes three cases the January 2031 snapshot got wrong: a 2031-only override equal to the 2030 rate no longer stops the restoration in later years; a bounded 2030 edit to a lower bracket is no longer extended; and explicit future rates survive on both construction paths, so applying the reform twice (as Simulation does) changes nothing. Tests: enacted schedules match the baseline in every year 2021-2101; user edits are kept the same way through CountryTaxBenefitSystem and Simulation; a Hypothesis property checks the restoration against random edits and toggle schedules, including idempotence; the window property now probes both sides of every toggle change and the horizon. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Review (round 2): Encode the 2030 expiry of California's top income tax rates; add Prop 3 (2026) reformPR #9601 (author: MaxGhenis). Round 1 reviewed head
SummaryEvery round-1 item is addressed: both critical items, all six should-address items and all seven suggestions.
The law and the year boundary hold. Cal. Const. art. XIII, § 36(f)(2) and (f)(3) apply the 10.3% / 11.3% / 12.3% rates "for any taxable year beginning on or after January 1, 2012, and before January 1, 2031". So tax year 2030 is the last year with the higher rates, and they stop on 2031-01-01. The title's "2030 expiry" (they expire after TY2030) and the commit's "2031 rate expiry" (the reversion takes effect in 2031) describe the same boundary. The parameters ( The new reform logic is correct. It restores the rates only inside the dated windows where the toggle is true, only on the three brackets the enacted sunset changes, and only where the enacted 9.3% still applies. So it keeps a user's explicit future rates and edits to other brackets, and applying it again changes nothing. No other reform touches the CA rate schedules. The one limit is that a future edit that equals 9.3% can't be told apart from the sunset, and the PR body discloses that. Tests, CI and branch.
There is one new should-address item, and it is small. The round-2 fix for the Hypothesis health-check flake was applied to only one of the two properties that draw from the same toggle generator. There are also three suggestions. Round-1 items
Max answered every item in a table in the PR body. There are no inline review threads. Critical (must fix)None. Should address1. The Hypothesis
New suggestions
VerificationThe law and the year boundary.
Prop 3 (November 3, 2026).
The reform logic,
The property tests.
The YAML Hand checks. These use f2030 = 193 / 172.797 and f2031 = 196.85 / 172.797 on the FTB 2025 thresholds (Schedule X 72,724 / 371,479 / 445,771 / 742,953; Schedule Z 98,990 / 505,208 / 606,251 / 1,010,417). Tax at the 9.3% threshold is 3,201.97f (Schedule X) and 3,616.45f (Schedule Z).
All 17 expectations agree to within half a cent. Local runs (extracted head tree, local policyengine-core 3.26, one process at a time).
Partner contract tests. None are affected. All 144 partner YAML files, at this head and on current Axiom line assessment
Valid. Both issues are OPEN, labelled
CI status
Branch status
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Round 2: all 15 round-1 items are addressed. TY2030 is the last surcharge year under § 36(f)(2)-(3), the parameters and tests agree, the reform restores only the enacted sunset and leaves user edits intact, and the rulespec issues are dispatch-ready. One should item (see the comment above): the Hypothesis too_slow fix covers only the window property. The restore-only property at :420, and the test at :149, draw the same strategies with no derandomize or health-check suppression, so they can hit the same stall on a busy host. Please use shared settings with derandomize=True and suppress too_slow and data_too_large.
|
Thanks, David. Every item from both of your rounds is addressed at
Could you take another look? |
PR Review (round 3): Encode the 2030 expiry of California's top income tax rates; add Prop 3 (2026) reformPR #9601 (author: MaxGhenis). Round 2 reviewed head
SummaryThe round-2 should-address item is fixed: all three properties now share Nothing that affects a calculation has changed since round 2. No parameter, formula, reform logic or expected value moved. The merge kept both sides of each conflict intact. All tests pass: the 33 YAML cases and 15 Python tests locally, and all 27 CI checks at the head. The branch is 0 behind Prior findings status
There are no inline review threads, and no comments since round 2 other than Max's re-review request. New findingsCritical (must fix)None. Should addressNone. Suggestions
VerifiedWhat changed since round 2.
Merge resolutions (
The law is unchanged, and the boundary still holds.
RTC § 17043 is not the sunset provision.
Hand checks. These use the FTB 2025 thresholds with f2030 = 193 / 172.797 and f2031 = 196.85 / 172.797. Schedule X is 72,724 / 371,479 / 445,771 / 742,953, with 3,201.97f of tax at the 9.3% threshold. Schedule Z is 98,990 / 505,208 / 606,251 / 1,010,417, with 3,616.45f.
All 14 expectations agree to within half a cent. Max's "7 new baseline cases fail on main". The PR adds 9 new baseline cases: 7 in
Partner contract tests. None are affected.
Changelog. Both fragments are top-level: Local runs. These used the extracted head tree with policyengine-core 3.32.29, one process at a time.
Axiom line assessment
Valid. Both issues are OPEN and labelled
Both issues still describe the PR's behavior, because no logic changed after the head they name. The stale head pointer is Suggestion 2. CI status
Branch status
Verdict: APPROVE |
DTrim99
left a comment
There was a problem hiding this comment.
Approving round 3; details in the report above. Round 2's should item is fixed: all three Hypothesis properties now share PROPERTY_SETTINGS. The rulespec-us#1565 elision and the enacted-path comment are done, and every round-1 item is still addressed. Merge 1c9510e resolved the ca_amt and before-refundable-credits conflicts correctly, keeping both the PR's 2031 case and main's #10034/#10052 cases. The law is unchanged (Const. art. XIII §36(f)(2)-(3), "before January 1, 2031"). All 14 hand-checked expectations match, 33/33 YAML cases and 15/15 Prop 3 tests pass locally, and CI is 27/27 green. Two optional tidy-ups: drop the remaining host notes and the superseded to-do from the PR body, and refresh the head pointers in rulespec-us #1565/#1566.
|
US + core hub merge audit, us#9601 at
|
What changes
California's rates above 9.3% expire after tax year 2030. All five filing-status schedules revert to 9.3% on January 1, 2031; Proposition 3's contributed reform extends the pre-sunset rates. The legal boundary is established by Prop 55 §4, page 16; Prop 3 removes that boundary in §4, page 6 and page 7. RTC §17045 supplies the joint and surviving-spouse treatment.
The reform identifies the brackets affected by the enacted sunset, snapshots their 2030 rates, honors dated app activation, and preserves future rate overrides that differ from the enacted baseline. Tests cover every filing status, AMT, total tax including MHST, and both construction paths. The baseline retains the sunset; thresholds and their existing CA CPI forecasting assumptions remain in place.
DTrim99's review
The changes-requested review and program review remain open for re-review. Each requested item is addressed as follows:
in_effect.values_list; apply only true intervals intersecting 2031–2100.Reform.from_dicttests cover a 2031 start, 2026-only activation, delayed activation and true/false/true intervals..fixed.mdfor the sunset and add.added.mdfor the public reform and toggle.max(.07 × reduced AMTI − regular tax, 0), and total tax with a $1.4M AMTI / $1M taxable-income case.contrib/states/ca/prop3/ca_prop3.yaml; explain bypass and baseline controls; remove redundant toggle inputs.create_ca_prop3; remove the unused import.The additional independent review identified later-expiry intervals, bounded lower-rate edits, future overrides and endpoint coverage. The implementation addresses those with interval splitting, enacted-schedule comparison, idempotence checks on both construction paths, and transition/adjacent-day probes. Implementing statutory nearest-dollar threshold rounding remains outside this PR.
Response to David Trimmer's review
policyengine_us/tests/policy/contrib/states/ca/prop3/test_ca_prop3_reform.pysharePROPERTY_SETTINGSwithderandomize=True, no deadline, and suppression ofHealthCheck.too_slowandHealthCheck.data_too_large; their example counts and assertions are unchanged._enacted_scheduleinpolicyengine_us/reforms/states/ca/prop3/ca_prop3_reform.pydocuments that the enacted YAML must remain readable at the recorded path, including after moving an unpickled system to another machine.ca_income_tax_before_credits.yamlalready correctly names the 12.3% bracket.#page=1anchors remains out of scope, as reviewed.Activation and rate overrides
The app toggle honors every dated true interval within 2031-01-01 through 2100-12-31. A 2026-only override has no out-year effect; delayed activation begins on its effective date; false gaps retain the sunset. The explicit
ca_prop3bypass used by YAMLreforms:applies unconditionally within the model horizon.Only brackets changed by the enacted sunset are extended. Their user-adjusted 2030 rates are copied where the future rate still equals the enacted baseline. Future overrides with a different rate survive, including on repeated application and both system-construction paths. A future user edit numerically equal to the enacted baseline cannot be distinguished from that baseline and is restored by Prop 3.
Validation
Main 8ae01aa was merged and pushed in 1c9510e. Final head: 2fe6a8a. Each changed test file ran separately with the required thread caps:
ca_income_tax_before_credits.yamlca_prop3.yamlca_amt.yamlca_income_tax_before_refundable_credits.yamltest_ca_prop3_reform.pyBoth passes cover 33 YAML cases and 15 Python cases.
uvx ruff@0.15.5 format .left all 6,954 files unchanged;uvx ruff@0.15.5 check .passed.Current-head CI completed successfully at 2fe6a8a: 27/27 checks passed, including the Contrib Python tests and Household API Partners.
At the earlier reviewed head a72bca9, CI passed all 35 checks, including all 15 Python cases. Those historical checks predate the merge above.
The review fixes change test settings and document the YAML-path requirement; tax calculations and expected amounts are unchanged. No partner test files or expected outputs are changed by this PR.
Hub microsimulation impact (current head)
A real microsimulation on the default dataset, main at the merge base
8ae01aa3cbagainst this PR's head2fe6a8a1b0, for 2026 and 2031. The runs went one at a time under the shared heavy-job lock. Sums are weighted.ca_income_taxca_income_tax_before_creditsstate_income_taxincome_taxhousehold_net_incomehousehold_benefits2026 is unchanged. In 2031, Prop 55's surcharge rates expire under current law (the 2030 sunset), so California income tax falls by $8.29bn: 253 records (about 569,000 weighted tax units), all decreases, with the largest $94,413. Household net income rises by the same $8.29bn (244 household records). Federal income tax and benefits don't change. The Prop 3 reform, which extends the rates, is a reform, not a baseline change, so it is not in these numbers. This supersedes the historical estimates in "Impact and remaining follow-up" below.
Comparison files are in
fixes/9601-impact/on the hub host.Impact and remaining follow-up
Existing population microsimulation at the reviewed head: merge base
dd9cb3f683against reviewed heada72bca942f, onpopulace_us_2024.h5@populace-us-2024-spm-20260909. The hub compared both sides record by record. This is retained impact evidence from the earlier review; it does not validate the current merge or final head.2026 is unchanged because the enacted top rates still apply. 2031 is the first year after they expire, and the drop is the scheduled sunset that the baseline now encodes: the higher rates stop applying, so the affected high-income units pay less. The Prop 3 (2026) reform is opt-in (
gov.contrib.states.ca.prop3.in_effect), so it is not in the baseline.The hub should compare main, corrected baseline and Prop 3 enabled for 2025, 2026, 2030, 2031 and 2035, using identical cached data, entity order and weights. Calculate
ca_income_tax_before_credits,ca_amt,ca_mental_health_services_tax,ca_income_tax_before_refundable_credits,ca_income_tax,ca_withheld_income_tax,income_taxandhousehold_net_income; exclude enum arrays from numerical comparison. Expect zero direct effects before 2031, a regular-tax reduction after the sunset, possible AMT offsets, unchanged MHST, and reversal of the regular-tax reduction when Prop 3 is enabled.The existing forecast gives these hand-computed 2031 examples; they are household test expectations, not population estimates:
Differences are rounded from unrounded hand calculations; displayed taxes are rounded independently.
The $1.4M AMTI example has $98,000 tentative minimum tax: baseline AMT is $9,057.10, while Prop 3 AMT is zero. Dollar expectations still use
gov.states.ca.cpi; #9621 remains OPEN and its IRS-uprating change requires reconciliation when it lands. Rate/date properties do not depend on forecasts. Check the certified election result after November 3, 2026.axiom: CA Constitution XIII §36(f)(2)-(3) TheAxiomFoundation/rulespec-us#1565 queued | CA Prop 3 (2026) §4 TheAxiomFoundation/rulespec-us#1566 queued