Repository navigation
Limit Kansas itemized deductions to the four K.S.A. 79-32,120(a) categories at each year's shares - #10095
Limit Kansas itemized deductions to the four K.S.A. 79-32,120(a) categories at each year's shares#10095MaxGhenis wants to merge 3 commits into
Conversation
…gories Kansas allows charitable contributions (100%), medical care, qualified residence interest and real and personal property taxes (50% in 2015-2017 without medical, 50% in 2018, 75% in 2019, 100% from 2020). Main summed every federal non-SALT itemized deduction, including investment interest, casualty losses, pre-2018 miscellaneous deductions and the 2020-2021 non-itemizer charitable deduction, at 100% in all years. Before 2021, (a)(1)(A) lets only federal itemizers itemize in Kansas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
Bring the branch up to date with main before review; the merge was clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
This PR replaces the comment that quoted the 2021 K-40 instructions, so the file no longer has a conflict-sounding comment and the ratchet in test_source_conflicts.py requires its line to go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
|
Picking this up for the US hub, continuing an earlier session's work on this PR (that session pushed nothing). I'll post a hand-off comment here when it's ready. Generated by Claude Code |
|
Ready for hub review Head: This continues an earlier session that pushed nothing to this PR. The commit from 2026-10-11 is kept unchanged; this session added a clean merge of Blocker: primary sources not re-readThis session's network policy refused The brief also asks how the statute changed from 2013. I couldn't read it, and the parameters start in 2015. The federal model raises Items
Hand computations
Tests run (merged head)
Mutants
CIDraft, so Pull request CI skips it; it has not run at this head. Judgment calls
Proposed follow-up
Generated by Claude Code |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10095 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 1 2 +1
Lines 54 35 -19
Branches 0 1 +1
=========================================
- Hits 54 35 -19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hub review in progress This interim note is superseded by the final review: #10095 (comment) Generated by Claude Code |
|
Ready for hub review The PR's head has not moved past FindingsP1. Qualified residence interest leaves out mortgage insurance premiums
The PR body also states this wrongly: "Qualified residence interest is P2. A direct
|
| Case | Statute | Main | PR | PR + fix |
|---|---|---|---|---|
| 2019, $8,000 interest + $1,000 premiums, wages $40,000 | 0.75 × 9,000 = 6,750 | 9,000 | 6,000 | 6,750 |
| 2021, $1,000 premiums | 1,000 | 1,000 | 0 | 1,000 |
| 2026, $8,000 interest + $1,000 premiums | 9,000 | 9,000 | 8,000 | 9,000 |
2025, deductible_mortgage_interest: 9_000 input |
9,000 | 9,000 | 0 | 9,000 |
(The values are ks_itemized_deductions. Main gives 9,000 in 2019 because it applies 100%, which is the defect this PR fixes.)
Fix: replace lines 26–28 with:
# 26 U.S.C. 163(h)(3)(E) treats deductible mortgage insurance premiums
# as qualified residence interest.
qualified_residence_interest = add(
tax_unit,
period,
["deductible_mortgage_interest", "deductible_mortgage_insurance_premiums"],
)nc_mortgage_and_property_tax_before_limitation.py reads the same two variables. With this change on a scratch copy of the head:
ks_itemized_deductions.yaml: 7 passed.ks_taxable_income.yaml: 6 passed.ks_2025_integration.yaml: 13 passed.ks_integration.yaml: 2 passed.- The four probe cases above: 4 passed.
Cases 1 and 2 still pass with their deductible_mortgage_interest_tax_unit: 9 input, because the person-level variable derives from it.
Add these cases to ks_itemized_deductions.yaml (I hand-computed each from (a)(4) and (a)(5) and 163(h)(3)(E); the 2019 case's wages keep AGI under the $100,000 premium phase-out start):
# K.S.A. 79-32,120(a)(4) counts qualified residence interest under section
# 163(h), and 163(h)(3)(E) treats mortgage insurance premiums as such interest
# (2019 Schedule S, line C4).
- name: Case 8, 2019 mortgage insurance premiums count at the 75% share.
period: 2019
input:
state_code: KS
employment_income: 40_000
home_mortgage_interest: 8_000
mortgage_insurance_premiums: 1_000
output:
# 0.75 * (8,000 + 1,000)
ks_itemized_deductions: 6_750
- name: Case 9, 2025 a direct deductible mortgage interest input counts.
period: 2025
input:
state_code: KS
deductible_mortgage_interest: 9_000
output:
ks_itemized_deductions: 9_000Then change the body sentence to: "Qualified residence interest is federal deductible mortgage interest and points (deductible_mortgage_interest) plus deductible mortgage insurance premiums, which 26 U.S.C. 163(h)(3)(E) treats as qualified residence interest. Investment interest, the rest of interest_deduction, does not count."
P3. The parameter reference title says "lines C3"
policyengine_us/parameters/gov/states/ks/tax/income/deductions/itemized/rate/qualified_residence_interest.yaml:14: 2017 Form K-40 instructions, Schedule S Part C, lines C3 should read line C3. I could not open the 2017 booklet to confirm the line numbers in this file or the other rate files.
P3. The body leaves out (b) and has no quotes
The adopting session removed the statute quotes. From the hub's reading, the body can carry these, each under 25 words:
- (a)(1)(A): "For all tax years prior to tax year 2021, if federal taxable income of an individual is determined by itemizing deductions ..."
- (a)(1)(B): "regardless of whether or not such individual's federal taxable income is determined by itemizing deductions"
- (a)(2): "(B) 50% of the amount of qualified residence interest as provided in section 163(h)"
- (a)(2): "(C) 50% of the amount of taxes on real and personal property as provided in section 164(a)"
- 2019 Schedule S line C2: "Real estate taxes from line 5b of federal Schedule A"
Add this sentence: "K.S.A. 79-32,120(b) reduces the total by income taxes deducted federally and by depreciation claimed for certain credits. None of the four categories includes income taxes, and the model has no input for that depreciation, so (b) changes nothing here."
The hand-off's "Draft, so Pull request CI skips it" is out of date. The PR is not a draft, and the Pull request run at this head concluded success, with every job passing (none were cancelled or skipped).
Overlap with #10038 and #10070
Both PRs conflict with this one at the same places in ks_itemized_deductions.py: the reference tuple (this PR's lines 10–14) and the return (this PR's lines 30–35). I confirmed this from their diffs. If this PR lands first, the second PR to land must make these changes:
- Count gambling winnings in federal gross income and fix the wagering losses deduction #10070: drop its
ks_itemized_deductions.pyedit (thewagering_losses_deductionsubtraction and its reference line) and keep its YAML cases. The closed list never reads wagering losses, so its expected 0 and 3,000 still hold. I worked that out from the formula; I did not run its cases, because they need Count gambling winnings in federal gross income and fix the wagering losses deduction #10070's federal changes. - Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038: drop its formula edit and reference line. In its new case, change
interest_deduction: 9_000tohome_mortgage_interest: 9_000. That input feeds bothinterest_deduction(so itsitemized_deductions_less_salt: 14_000still holds) and this PR's qualified residence interest, with or without the fix above. Its expectedks_itemized_deductions: 12_000then holds. I did not run this, for the same reason.
The open-PR search for ks_itemized_deductions, ks_taxable_income and "kansas itemized" found no other overlap.
Mutants
I ran each mutant in its own process on a scratch worktree, then restored it and confirmed git status was clean.
| Mutant | Killed by |
|---|---|
| Medical share 1 from 2015 (hand-off) | itemized Case 6, 2017 |
federal_itemization_required false from 2015 (hand-off) |
taxable Case 4, 2019 non-itemizer |
| 2018 medical share 0.75 | itemized Case 5, 2018 |
| Federal itemizing gate still applied in 2021 (false moved to 2022) | taxable Case 6, 2021, and taxable unit test 2 |
| Mine: qualified residence interest steps to 75% in 2018 | itemized Case 5, 2018 |
None survived. P1 survives the existing suite, since no case enters mortgage insurance premiums. Case 8 above kills it.
Checked and sound
-
Defect reproduced. I restored main's two formulas over the head and ran the PR's tests. 4 of 7 itemized cases failed (Cases 3, 4, 5, 6) and 1 of 6 taxable cases failed (Case 4), matching the body. Itemized Case 7 passes on main too.
-
Share table. Against the hub's reading of (a)(2)–(a)(5), year by year:
- charity is 100% from 2015;
- medical is 0 in 2015–2017, 50% in 2018, 75% in 2019 and 100% from 2020;
- qualified residence interest and property taxes are 50% in 2015–2018, 75% in 2019 and 100% from 2020.
Every parameter date and value matches.
-
Hand values. I computed each before reading the tests:
- 2017: 1,000 + 0.5 × (8,000 + 4,000) = 7,000;
- 2018: 1,000 + 0.5 × 14,000 = 8,000;
- 2019: 1,000 + 0.75 × 14,000 = 11,500;
- 2025: 3,000 + 2,000 + 9,000 + 5,000 = 19,000.
The tests carry the same values. In full-household runs, a single filer with $2,000 charity, $14,000 mortgage interest and $9,000 real estate taxes gets 13,500 in 2018 (2,000 + 0.5 × 23,000) and 19,250 in 2019 (2,000 + 0.75 × 23,000). Single and joint filers both run, with no cycle through
tax_unit_itemizesin 2018–2021. -
The itemizing gate.
ks_taxable_income.py:23-26appliestax_unit_itemizesonly whilefederal_itemization_requiredis true, which is 2015–2020. That matches (a)(1)(A) and (B). The filer takes the larger deduction only when allowed.tax_unit_itemizescompares federalincome_taxonly, as 35 other state formulas already rely on. -
The SALT cap. "As provided in section 164(a)" names the deductible taxes. The cap sits in 164(b)(6), and line C2 takes line 5b, before line 5e's cap. The formula adds
real_estate_taxesuncapped. Sound. -
(b)'s income tax reduction. None of the four inputs includes income taxes, so the reduction cannot reach the total. I agree.
-
Personal property taxes. Main has no input for them.
personal_propertyis a property value (quantity_type = STOCK), not a tax. The body already states the limit. Follow-up: add a personal property tax input and count it in Kansas (a) and line C3. -
Medical.
medical_expense_deductionis net of the federal AGI floor, which matches section 213 and federal Schedule A line 4. -
Charity.
charitable_deductionis the section 170 itemized amount, after ceilings and the 2026 floor. It does not include the 2021 non-itemizer deduction (Case 7). -
2013–2014. A 2014 Kansas household raises
ParameterNotFoundErrorongov.irs.gross_income.retirement_contributions.limit[401k], so the body's "does not run before 2015" holds. -
Tests run at the head.
ks_itemized_deductions.yaml7 passed;ks_taxable_income.yaml6 passed;test_source_conflicts.py103 passed. TheKNOWN_UNMARKEDdeletion is right, since the counted comment is gone. -
Readers.
ks_taxable_income→ks_income_tax_before_credits. Both variables are also listed in thestate_itemized_deductionsandstate_taxable_incomesaggregates, which only report them. No other reader changes. -
Scope. The PR touches nothing under
.github/ortests/policy/baseline/partners/. The changelog fragment is a top-level.fixed.md. Theimpact:andaxiom:lines are present. -
Baseline. The diff moves outputs at baseline in every year:
- investment interest, casualty and theft losses and miscellaneous deductions leave the Kansas total;
- 2018–2019 shares fall below 100%;
- before 2021, federal non-itemizers lose the Kansas itemized deduction;
- with the PR as it stands, mortgage insurance premiums drop from 2026.
The hub's population check should compare
ks_income_taxon the data years, split by whether the unit hasdeductible_mortgage_insurance_premiumsor investment interest.
What I couldn't check
- Sources. This VM's proxy refused every source host I tried: ksrevisor.gov, ksrevenue.gov (the 2017, 2018, 2019 and 2025 booklets), kslegislature.gov, govinfo.gov, uscode.house.gov, ecfr.gov, law.cornell.edu and web.archive.org. Each statute and booklet reading above is the hub's reading, as the brief gives it. That includes the line numbers in the parameter reference titles and the
#page=anchors. - Overlap. I did not run Model the claim of right repayment deduction and credit (26 U.S.C. 1341) and North Carolina's rules that depend on it #10038's and Count gambling winnings in federal gross income and fix the wagering losses deduction #10070's Kansas cases on a merged tree.
- Population impact. I ran no population-data impact.
Generated by Claude Code
What changes
K.S.A. 79-32,120(a) defines the Kansas itemized deduction as four federal itemized categories, each at a share that has changed by year:
Main computes
itemized_deductions_less_salt + real_estate_taxes, which gives 100% of every federal itemized deduction other than SALT in every year, including investment interest (insideinterest_deduction), casualty and theft losses, and pre-2018 miscellaneous deductions. This PR adds four dated share parameters undergov.states.ks.tax.income.deductions.itemized.rateand sums only those categories. Qualified residence interest isdeductible_mortgage_interest_tax_unit, notinterest_deduction. Personal property taxes have no separate input, so onlyreal_estate_taxesenters, uncapped by the federal SALT limit as before.It also applies (a)(1): before 2021, only a filer who itemizes on the federal return may take the Kansas itemized deduction; from 2021 any filer may take the larger of the two. Main let every filer take the larger in every year. The new
federal_itemization_requiredparameter is true from 2015 to 2020.The parameters start in 2015. The federal model does not run before 2015, so the 2013–2014 Kansas rules are not modeled.
Sources
Overlap
#10038 and #10070 each edit
ks_itemized_deductions.pyto subtract one more federal deduction (claim_of_right_deduction,wagering_losses_deduction) from main's sum. The closed list here never includes either, so whichever lands after this PR drops its Kansas formula edit and reference line. #10070's new Kansas cases still hold here. #10038's new case enters mortgage interest asinterest_deduction: 9_000and expects 12,000; under this PR it must usedeductible_mortgage_interest_tax_unitinstead.This PR also deletes the file's
KNOWN_UNMARKEDline intest_source_conflicts.py, because it replaces the comment that quoted the 2021 instructions.Tests
ks_itemized_deductions.yaml: 7 cases, 5 new (2017, 2018, 2019, 2021 and 2025), each with its arithmetic. 4 fail with main's formula.ks_taxable_income.yaml: 6 cases, 3 new on the federal itemizing condition. 1 fails with main's formula.Invariants
impact: the hub will measure
axiom: (hub files pe-parity before landing)
https://claude.ai/code/session_01LwQq6Fmi4DmuA9GyXnRKdV
Generated by Claude Code