Skip to content

Allow non-disaster casualty and theft losses in California and Minnesota itemized deductions - #10068

Merged
MaxGhenis merged 4 commits into
mainfrom
fix-ca-mn-casualty-loss
Oct 11, 2026
Merged

MaxGhenis merged 4 commits into
mainfrom
fix-ca-mn-casualty-loss

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

The bug

California and Minnesota itemized deductions read the federal casualty_loss_deduction. That variable is multiplied by gov.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.

Where Before After
ca_itemized_deductions_pre_limitation federal deduction ($0 from 2018) ca_casualty_loss_deduction
gov.states.ca.tax.income.deductions.itemized.limit.excluded_deductions casualty_loss_deduction ca_casualty_loss_deduction
mn_itemized_deductions (total and the amount exempt from the reduction) federal deduction mn_casualty_loss_deduction
mn_amt_taxable_income federal deduction mn_casualty_loss_deduction
Walz HF1938 repeal reform's mn_itemized_deductions federal deduction mn_casualty_loss_deduction

The 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)".

  • 2024 Schedule M1SA, line 19 (PDF p. 1): "Casualty or theft loss (enclose Schedule M1CAT)". Its instructions (PDF p. 7) allow a loss only to the extent each loss "is more than $100" and the year's losses "reduced by $100" are "more than 10% of the amount on line 1 of Form M1".
  • 2024 Schedule M1CAT (PDF p. 1): line 11 "Enter $100"; line 18 "Enter the amount from line 1 of Form M1" (federal AGI); line 19 "Multiply line 18 by 10%"; line 20 is line 17 less line 19, not below 0, and goes to M1SA line 19. The 2018 Schedule M1CAT has the same $100 reduction and 10% floor, so an ordinary loss is deductible from the first year of the federal limit. It differs in two ways: its line 20 goes to M1SA line 18, and at its line 18 filers of Schedule M1NC (federal adjustments) enter that schedule's line 38 instead of Form M1 line 1.
  • Reduction of itemized deductions: subd. 2(d)(3) leaves out "the deduction for losses under subdivision 8", and the M1SA line 26 worksheets (PDF p. 8) take out "lines 4, 13, and 19".
  • AMT: 2024 Schedule M1MT, line 12 (PDF p. 1): "Casualty and theft losses (from line 19 of Schedule M1SA)".

The fix

ca_casualty_loss_deduction and mn_casualty_loss_deduction both compute

max(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_reduction and …casualty.floor. Neither reads the federal active switch. 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 main and conflict with it, and #10034 has since rewritten ca_itemized_deductions_pre_limitation, so a stacked branch could not run CI. Instead this branch is based on current main and 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:

Methodology notes and choices for the reviewer

  • Federal AGI, not state AGI, for the 10% floor. California: Form 4684 line 17 and Publication 1034 both name federal AGI. Publication 1034's passage is about disaster losses, which California computes on the same second Form 4684; no FTB text names a different base for other casualties. A YAML case and the property test hold California AGI at a different value to pin this. Minnesota: M1CAT line 18 is Form M1 line 1 (for 2018, Schedule M1NC line 38 for filers of that schedule, which PolicyEngine does not model, so 2018 also uses federal AGI).
  • The federal parameters, not state ones. Neither state fixes its own $100 or 10%: California takes 165(h)(1)–(2) through § 17201, and Minnesota's statute incorporates 165(h). M1CAT prints $100. The federal parameter is $100 for every year from 2010.
  • One casualty per return. PolicyEngine records one loss per person and no event count, so a return's losses are treated as one casualty and the $100 applies once (165(h)(4)(B) treats a joint return as one individual). Count a Montana casualty loss once per joint return and only for the spouse who had it #9888, Apply the Form 4684 $100 per-casualty reduction and drop dependents' losses in the federal, NY, AL and HI casualty deductions #9912 and the Arkansas variables do the same. This under-reduces only for filers with more than one casualty in a year.
  • Negative AGI. Neither Form 4684 line 17 nor M1CAT line 18 says to enter 0. The floor is held at zero (positive_agi), as in the federal deduction, so the deduction never exceeds the reduced loss.
  • California limitation. The Schedule CA line 29 worksheet, line 2 (booklet PDF p. 68) takes out "federal Schedule A (Form 1040), line 4, line 9, and line 15". Read literally, line 15 is the federal casualty amount. R&TC § 17077 adopts 26 U.S.C. 68, whose subsection (c)(3) (before P.L. 119-21) leaves out casualty and theft losses described in 165(c)(3). This PR follows the statute and excludes California's own casualty deduction from the limitation, as the old list did for the federal one.
  • Minnesota AMT. Minn. Stat. § 290.091, subd. 2, describes the exclusion as "the casualty, theft, and disaster loss deduction" among itemized deductions allowed in computing federal alternative minimum taxable income. Schedule M1MT line 12 takes the M1SA line 19 amount. mn_amt_taxable_income already follows the form (it starts from federal AGI), so this PR uses the Minnesota amount.
  • Not modeled. Personal casualty gains (Form 4684 lines 13–16; M1CAT lines 14–17) and the 165(i) prior-year election for disaster losses. PolicyEngine has no disaster input, so it also cannot apply Minnesota's qualified disaster rule: the 2020 Schedule M1SA instructions (PDF pp. 6–7) take a net qualified disaster loss from federal Form 4684 line 15, which is computed with $500 per casualty and no 10% floor, and let it be deducted without itemizing. The 2021, 2022 and 2024 M1SA instructions have no such passage. And for 2018 PolicyEngine has no Schedule M1NC (see above). The formula and the invariants below are for an ordinary loss.

Invariants

For every tax unit and year, for each of the two new variables (an ordinary loss; see "Not modeled" above):

  1. It equals max(max(L − 100, 0) − 0.1 × max(AGI, 0), 0), where L is the head's and spouse's losses and AGI is federal AGI. Dependents' losses and California AGI never enter.
  2. 0 ≤ deduction ≤ max(L − 100, 0).
  3. It is zero outside its state.
  4. Differential: the California and Minnesota copies agree on the same tax unit.
  5. It rises with the loss and falls with AGI, and is zero for a loss of $100 or less.
  6. It does not depend on the federal active switch, and each state's itemized total counts the loss once when that switch is on.

test_ca_mn_casualty_loss_deduction_properties.py checks 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.

File Cases Result
ca/.../itemized/ca_casualty_loss_deduction.yaml (new) 14 pass
mn/tax/income/mn_casualty_loss_deduction.yaml (new) 12 pass
ca/.../itemized/ca_itemized_deductions_pre_limitation.yaml 13 (2 new) pass
ca/.../itemized/ca_itemized_deductions.yaml 6 (1 new) pass
mn/tax/income/mn_itemized_deductions.yaml 11 (3 new, 1 changed) pass
mn/tax/income/mn_amt_taxable_income.yaml 4 (2 new) pass
contrib/states/mn/walz/mn_walz_hf1938.yaml 5 (1 new) pass
tests/unit/test_ca_mn_casualty_loss_deduction_properties.py (new) 5 pass
ca/.../itemized/test_ca_itemized_conformity.py (existing, from #10034) 1 pass
code_health/test_rest_python_groups.py, test_reference_urls.py, test_no_concatenated_reference_urls.py, test_known_dead_reference_urls.py 12, 16, 42, 39 pass

Independent 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 approved 36412e0aa8 with 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" fed casualty_loss_deduction: 200 to show the casualty loss is exempt from the reduction. It now feeds mn_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/unit runs in the Rest job's Python groups; test_rest_python_groups.py passes 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 is main at 75cdd8019e, the PR is 6d6d633150, 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_loss on 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.

Output Change Records changed (weighted)
ca_casualty_loss_deduction (new) +$6,805 3 tax units (0.23)
ca_itemized_deductions_pre_limitation +$6,805 3
ca_itemized_deductions +$6,805 3
ca_taxable_income −$6,805 3
ca_income_tax −$633 3
mn_casualty_loss_deduction (new) +$26,934,497 2 tax units (6,947)
mn_itemized_deductions +$26,934,497 2
mn_amt_taxable_income −$696 1
mn_amt $0 0
mn_income_tax −$69 1
state_income_tax −$701 4
income_tax (federal) $0 0
household_net_income +$701 4 households
of which California +$633 3 households
of which Minnesota +$69 1 household
household_benefits $0 0
casualty_loss_deduction (federal) $0 in both runs 0

The effect on tax is small because the five records carry little weight where it matters:

  • Minnesota. Almost all of the $26.9M is one tax unit with weight 6,947 whose itemized deductions go from $0 to $3,877. It does not itemize (its AMT taxable income, which subtracts the loss only for itemizers, is unchanged), so its tax does not move. The other unit has weight 0.0025: it deducts $283,030 and its Minnesota tax falls by $27,878.
  • California. The three units have a combined weight of 0.23. Their deductions are $82,099, $17,905 and $25,276, and their California tax falls by $7,635, $1,665 and $2,351. The third is over the limitation threshold: its limitation is $6,387 before and after, so the casualty loss is not reduced. ca_amt was not saved in this pair. California AMT is part of ca_income_tax, and each unit's tax change equals 9.3% of its deduction, which is the regular-tax effect at that marginal rate.
  • By state. The four households whose net income rises are the three California and one Minnesota tax units above, one each: +$7,635, +$1,665 and +$2,351 in California ($633 weighted) and +$27,878 in Minnesota ($69 weighted).

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 commits 36412e0aa8 and ac929133fc change 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:

  • California's limitation list excludes non_mortgage_interest (the gross investment interest expense), while the pre-limitation total holds ca_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.
  • Minnesota's reduction exempts medical expenses and casualty losses but not investment interest (Minn. Stat. § 290.0122, subd. 2(d)(1); M1SA worksheet lines 4, 13 and 19). mn_amt_taxable_income subtracts charitable, medical and casualty deductions but not investment interest, impairment-related work expenses or unreimbursed employee expenses (M1MT lines 10, 13 and 14).
  • Once this PR and Apply the Form 4684 $100 per-casualty reduction and drop dependents' losses in the federal, NY, AL and HI casualty deductions #9912 are both on main, fold test_ca_mn_casualty_loss_deduction_properties.py into 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.
  • Unverified leads from a sweep of the other states that reach the federal casualty deduction: no other full decoupling was found. Oregon allows a subtraction for losses in state-declared emergencies (ORS 316.850, 2020–2025), which needs a disaster input. Kansas and Kentucky schedules have no casualty line, so those states may over-allow the federal deduction when active is 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_finding blocks 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

…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>
MaxGhenis and others added 3 commits October 10, 2026 15:33
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>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Hand-off to the US + core hub

Head: 644eba45f677b5e51b060366f4341dd189ad5177: the change (6d6d633150), two comment-only review answers (36412e0aa8, ac929133fc), then a merge of main at 12ea58729c. The merge touched none of this PR's 17 files. Base is main; this PR is not stacked.

Independent review (Subfleet, review tier standard):

  • Round 1 at 6d6d633150: REQUEST_CHANGES, two P2 documentation findings on Minnesota (2018 Schedule M1NC base; 2020 qualified disaster loss), no P1. Answered in 36412e0aa8.
  • Round 2 at 36412e0aa8: APPROVE, three P3 notes. Answered in ac929133fc and the description.
  • Round 3 at ac929133fc: APPROVE, no findings. The current head adds only the merge of main.
  • Reports: ~/reviews/ca-mn-casualty-loss-2026-10/review-r1.md, review-r2.md, review-r3.md.
  • The reviewers checked the law, every cited page and all 36 added or changed YAML cases by hand. None of them ran the test files (sandbox). Runtime evidence is the author's local runs, listed in the description, and this PR's CI.

Passed locally (one file per foreground process): the seven touched YAML files (65 cases), test_ca_mn_casualty_loss_deduction_properties.py (5), test_ca_itemized_conformity.py (1) and four code-health guards. The new aggregator cases fail with the old wiring.

Impact: done, in the description. One real 2026 base/PR microsimulation pair on the default dataset at 6d6d633150 (the later commits change comments only): state income tax −$701 across four records; federal tax and benefits unchanged. Outputs: ~/reviews/ca-mn-casualty-loss-2026-10/impact/.

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 (761aa8336f, the policyengine-core 3.33.1 fix to tests/core/test_spm_system.py) repairs; the job log was not readable while the run was in progress, so the match is by step, not by test name. main with that fix is now merged in and CI is re-running.

Depends on: nothing. It carries gov/irs/deductions/itemized/casualty/per_casualty_reduction.yaml byte-identical to the copy in #9888 and #9912 (43eed2a0f8), so either order merges cleanly unless #9888 edits that file first.

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 ~/reviews/us-hub/FOLLOWUPS.md, section "#10068"): California's limitation excludes the gross investment interest expense where it should exclude California's allowed deduction; Minnesota's reduction and AMT omit investment interest; fold the CA/MN property test into #9912's after both land and add the state-equals-federal assertions; unverified sweep leads for OR, KS, KY, MS and IA.

@MaxGhenis
MaxGhenis merged commit 5df19bb into main Oct 11, 2026
26 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#10068 at 644eba45f677b5e51b060366f4341dd189ad5177 (squash): Allow non-disaster casualty and theft losses in California and Minnesota itemized deductions.

@MaxGhenis
MaxGhenis deleted the fix-ca-mn-casualty-loss branch October 11, 2026 15:03
MaxGhenis added a commit that referenced this pull request Oct 13, 2026
…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>
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