Repository navigation
Allow non-disaster casualty and theft losses in California and Minnesota itemized deductions - #10068
Conversation
…ed deductions California and Minnesota read the federal casualty_loss_deduction, which is zero from 2018 under 26 U.S.C. 165(h)(5). Neither state follows that limit: Cal. Rev. & Tax. Code 17204(b) and Schedule CA (540) line 15; Minn. Stat. 290.0122, subd. 8, and Schedule M1CAT. Add ca_casualty_loss_deduction and mn_casualty_loss_deduction: the head's and spouse's loss, less $100, less 10% of federal adjusted gross income. Use them in place of the federal deduction in ca_itemized_deductions_pre_limitation, California's limitation exclusion list, mn_itemized_deductions, mn_amt_taxable_income (Schedule M1MT line 12) and the Walz HF1938 reform. The $100 comes from gov.irs.deductions.itemized.casualty.per_casualty_reduction, the same file #9888 adds, copied unchanged so the two merge cleanly in either order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r1: the 2018 Schedule M1CAT line 18 takes Schedule M1NC line 38 from filers of that schedule, and the 2020 Schedule M1SA takes a net qualified disaster loss from federal Form 4684 line 15 ($500, no 10% floor), deductible without itemizing. The model has neither input, so say so in the variable, the YAML header and the property test. No formula or expected value changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r2 (P3): the 2018 form has the same $100 reduction and 10% floor but a different destination line. Comment only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hand-off to the US + core hubHead: Independent review (Subfleet, review tier standard):
Passed locally (one file per foreground process): the seven touched YAML files (65 cases), Impact: done, in the description. One real 2026 base/PR microsimulation pair on the default dataset at Pending: CI on this head. The previous head had one failed check, "Full Suite - Microsimulation", in its "Run SPM Python tests" step. That is the step #10069 ( Depends on: nothing. It carries Decision or hold: none. The two readings the description flags (California's limitation exclusion; Minnesota AMT following Schedule M1MT) were both judged defensible by the reviewer and both follow the task's instruction to replace the federal deduction in those places. Axiom: TheAxiomFoundation/rulespec-us#1638, queued and dispatch-ready. Follow-ups owed (in |
|
US + core hub merge audit, us#10068 at
|
…ctions Main's #10068 added California's and Minnesota's non-disaster casualty and theft loss deductions in the same itemized-deduction formulas this PR changes. Both survive: each state's casualty deduction replaces the federal amount, and the permitted wagering deduction is protected from the itemized-deduction reduction. No test expectation changed. Resolution notes and 30 passing test files (200 cases) are in the hub's evidence for this merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bug
California and Minnesota itemized deductions read the federal
casualty_loss_deduction. That variable is multiplied bygov.irs.deductions.itemized.casualty.active, which is false from 2018 (26 U.S.C. 165(h)(5) limits personal casualty losses to declared disasters, and PolicyEngine has no disaster input). So PolicyEngine allowed California and Minnesota filers no casualty or theft loss from 2018. Neither state follows the federal limit.ca_itemized_deductions_pre_limitationca_casualty_loss_deductiongov.states.ca.tax.income.deductions.itemized.limit.excluded_deductionscasualty_loss_deductionca_casualty_loss_deductionmn_itemized_deductions(total and the amount exempt from the reduction)mn_casualty_loss_deductionmn_amt_taxable_incomemn_casualty_loss_deductionmn_itemized_deductionsmn_casualty_loss_deductionThe rule, by state
California. Cal. Rev. & Tax. Code § 17201(a) adopts the Internal Revenue Code's itemized deductions, including § 165. § 17204(b) (as amended by SB 711, 2025): "Section 165(h)(5) of the Internal Revenue Code … shall not apply." Subsections (c)–(e) also turn off the federal qualified-disaster rules. For 2018–2024, California's specified date for the Code was January 1, 2015 (§ 17024.5), before (h)(5) existed.
Minnesota. Minn. Stat. § 290.0122, subd. 8 allows "losses described in section 165(c)(3) of the Internal Revenue Code, including the provisions of section 165(h) of the Internal Revenue Code, but disregarding paragraph (h)(5)".
The fix
ca_casualty_loss_deductionandmn_casualty_loss_deductionboth computemax(max(non-dependent loss − $100, 0) − 10% × max(federal AGI, 0), 0)with
tax_unit_non_dep_add(a dependent's loss belongs on the dependent's own return),gov.irs.deductions.itemized.casualty.per_casualty_reductionand…casualty.floor. Neither reads the federalactiveswitch. They replace the federal deduction in the five places in the table above.Relation to #9888 and #9912
This follows #9912's pattern (federal, NY, AL and HI copies) but is not stacked on it. #9877, #9888 and #9912 are each 128 commits behind
mainand conflict with it, and #10034 has since rewrittenca_itemized_deductions_pre_limitation, so a stacked branch could not run CI. Instead this branch is based on currentmainand carries one file from the stack:gov/irs/deductions/itemized/casualty/per_casualty_reduction.yaml, byte-identical to the copy in #9888 and #9912 (git diff 43eed2a0f8 HEAD -- <file>is empty). An identical file added on both sides merges cleanly in either order. If #9888 changes that file before it lands, the later of the two PRs gets a one-file conflict.Two things wait for #9912:
casualty_loss_deductiononmainstill lacks the $100, so these tests do not assert that the state and federal amounts agree when the suspension is lifted. They assert only that the state amount does not move and is counted once.test_casualty_loss_deduction_properties.pyfor its four copies. This PR adds a separatetest_ca_mn_casualty_loss_deduction_properties.pyfor the two new ones. Once both are onmainthe two files can be folded into one.Methodology notes and choices for the reviewer
positive_agi), as in the federal deduction, so the deduction never exceeds the reduced loss.mn_amt_taxable_incomealready follows the form (it starts from federal AGI), so this PR uses the Minnesota amount.Invariants
For every tax unit and year, for each of the two new variables (an ordinary loss; see "Not modeled" above):
max(max(L − 100, 0) − 0.1 × max(AGI, 0), 0), whereLis the head's and spouse's losses and AGI is federal AGI. Dependents' losses and California AGI never enter.0 ≤ deduction ≤ max(L − 100, 0).activeswitch, and each state's itemized total counts the loss once when that switch is on.test_ca_mn_casualty_loss_deduction_properties.pychecks 1–5 with Hypothesis (20 batches of 4–15 drawn tax units, each placed in both states, 2018 and 2026) and a deterministic boundary grid. YAML cases cover 6.Tests
All runs below are local (macOS, Python 3.13), one file per foreground process.
ca/.../itemized/ca_casualty_loss_deduction.yaml(new)mn/tax/income/mn_casualty_loss_deduction.yaml(new)ca/.../itemized/ca_itemized_deductions_pre_limitation.yamlca/.../itemized/ca_itemized_deductions.yamlmn/tax/income/mn_itemized_deductions.yamlmn/tax/income/mn_amt_taxable_income.yamlcontrib/states/mn/walz/mn_walz_hf1938.yamltests/unit/test_ca_mn_casualty_loss_deduction_properties.py(new)ca/.../itemized/test_ca_itemized_conformity.py(existing, from #10034)code_health/test_rest_python_groups.py,test_reference_urls.py,test_no_concatenated_reference_urls.py,test_known_dead_reference_urls.pyIndependent review. Round 1 (Subfleet, GPT-6.1 Sol) asked for two documentation changes and no change to the computation: say that the 2018 M1CAT line 18 uses Schedule M1NC line 38 for filers of that schedule, and describe Minnesota's 2020 qualified disaster rule as a different calculation that is not modeled. Both are in
36412e0aa8(variable documentation, YAML header, property-test docstring) and in this description. The reviewer checked all 36 added or changed YAML cases by hand and read the cited pages, but could not run the tests in its sandbox. Round 2 approved36412e0aa8with three optional documentation notes, all taken: the by-state household split and the California AMT note in the impact section, the 2018 M1CAT's different destination line, and one rounded figure.Fail without the fix. With the five wiring files restored to their base versions (and the two new variables kept so the files load), these cases fail: California pre-limitation "allows a non-disaster casualty loss"; California "not subject to the high-AGI limitation"; Minnesota itemized "unit test 4", "include a non-disaster casualty loss" and "exempt from the high-income reduction"; Minnesota AMT "subtracts the Minnesota casualty loss"; and the Walz reform case. The two new variable files cannot load on
main, where the variables do not exist. That check was run on the first version of this branch (on #9912's head); the wiring and cases are the same here apart from the California list form.Existing case changed.
mn_itemized_deductions.yaml"unit test 4" fedcasualty_loss_deduction: 200to show the casualty loss is exempt from the reduction. It now feedsmn_casualty_loss_deduction: 200; the expected value is unchanged.Mutation checks on the property test. Moving California's floor to California AGI fails 3 of 5 tests; dropping the $100 from Minnesota fails 3 of 5.
Why a Python test. YAML cannot draw random tax units or compare two variables across states. The test has an independent closed-form reference and is the differential check between the two copies.
Cost of the Python test (local, loaded host; not Linux CI). 5 tests, 7.7 s in pytest, 28.7 s wall including the model import, 1.14 GB peak RSS in a fresh process. It builds 21 small household simulations and no dataset or extra tax-benefit system.
tests/unitruns in the Rest job's Python groups;test_rest_python_groups.pypasses with the new file. Linux CI time and memory for that group will come from this PR's run.Impact
A real 2026 microsimulation pair on the default dataset (
populace_us_2024.h5@populace-us-2024-spm-20260909): base ismainat75cdd8019e, the PR is6d6d633150, each run from a frozen package snapshot, back to back under the shared heavy lock. One base run and one PR run back every figure. Sums are weighted.The dataset has a nonzero
casualty_losson 48 of 166,321 person records (30,651 weighted people, $1.69bn of losses). Three California tax units and two Minnesota tax units get a deduction, and no other record changes in any output below.ca_casualty_loss_deduction(new)ca_itemized_deductions_pre_limitationca_itemized_deductionsca_taxable_incomeca_income_taxmn_casualty_loss_deduction(new)mn_itemized_deductionsmn_amt_taxable_incomemn_amtmn_income_taxstate_income_taxincome_tax(federal)household_net_incomehousehold_benefitscasualty_loss_deduction(federal)The effect on tax is small because the five records carry little weight where it matters:
ca_amtwas not saved in this pair. California AMT is part ofca_income_tax, and each unit's tax change equals 9.3% of its deduction, which is the regular-tax effect at that marginal rate.Run outputs and the comparison are in
~/reviews/ca-mn-casualty-loss-2026-10/impact/on the hub host (compare.2026.json,out/). The later commits36412e0aa8andac929133fcchange comments, documentation strings and one reference only, so these figures stand for the current head.Follow-ups found, not in this PR
Recorded in the US + core hub's follow-up list:
non_mortgage_interest(the gross investment interest expense), while the pre-limitation total holdsca_investment_interest_expense_deduction. The two differ whenever FTB 3526 limits the deduction, so the amount taken out before the limitation is not the amount that went in.mn_amt_taxable_incomesubtracts charitable, medical and casualty deductions but not investment interest, impairment-related work expenses or unreimbursed employee expenses (M1MT lines 10, 13 and 14).main, foldtest_ca_mn_casualty_loss_deduction_properties.pyinto Apply the Form 4684 $100 per-casualty reduction and drop dependents' losses in the federal, NY, AL and HI casualty deductions #9912's property test and add the state-equals-federal checks.activeis on.Axiom
Parity issue for Cal. Rev. & Tax. Code §§ 17201, 17204 and Minn. Stat. § 290.0122, subd. 8:
axiom: TheAxiomFoundation/rulespec-us#1638 queued
No rulespec-us module computes either deduction. The issue is dispatch-ready (module paths, corpus rows, verbatim law, required outputs, pasteable
review_findingblocks and companion cases C1–C12 and M1–M12 mirroring this PR's YAML tests). It is blocked on three things: the federal § 165(h) module (TheAxiomFoundation/rulespec-us#1516 Step 1), a rulespec-us corpus pin that carries the 2026-09-14 California and Minnesota income-tax scopes, and ingestion of Schedule CA, FTB Publication 1034 and Schedules M1SA, M1CAT and M1MT. Each signed-encoder run needs Max's approval.🤖 Generated with Claude Code