Repository navigation
Share North Carolina's $20,000 mortgage and property tax cap between spouses filing separately - #10029
Merged
Conversation
…spouses filing separately G.S. 105-153.5(a)(2)b caps mortgage interest plus real estate taxes at $20,000 "claimed by both spouses combined" for spouses filing separately, prorated by the share each paid or, for joint obligations paid from joint accounts, by each spouse's income. PE gave each tax unit its own $20,000. Split Form D-400 Schedule A lines 3, 4 and 5 into nc_mortgage_and_property_tax_before_limitation, _limitation and _deduction. Line 4 reaches a separately filing spouse in another tax unit through a two-person marital unit whose members each head a SEPARATE return (the Arkansas medical-floor guard). New MaritalUnit input mortgage_and_real_estate_taxes_paid_from_joint_account switches the shares from line 3 amounts to federal AGI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 12, 2026
Merged
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10029 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 4
Lines 76 73 -3
Branches 2 0 -2
=========================================
- Hits 76 73 -3
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:
|
Contributor
Author
|
US + core hub merge audit, us#10029 at
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
North Carolina caps home mortgage interest plus real estate taxes at $20,000. For spouses filing separately, the $20,000 covers both spouses' returns combined. PolicyEngine gave each tax unit its own $20,000, so spouses filing separately could deduct up to $40,000 between them.
ar_medical_expense_deduction_flooralready uses.What North Carolina law says
N.C. Gen. Stat. 105-153.5(a)(2)b, in force since at least S.L. 2016-6 § 3:
Form D-400 Schedule A, from the D-401 instructions. The text is the same, on PDF p. 20, in 2021, 2022, 2023, 2024 and 2025:
How PE represents spouses filing separately
SEPARATE, and one marital unit holding both spouses. Marital units are not nested in tax units, so this is valid.ar_medical_expense_deduction_floor(Use Arkansas's own medical expense deduction floor #9612) already reaches a separately filing spouse this way. Its tests cover situations without explicit marital units, where policyengine-core puts everyone in one default unit. This PR likewise infers spouses from a two-person marital unit, whether explicit or default, as ruled 4A.populace_us_2024.h5@populace-us-2024-spm-20260909) never splits a married couple across tax units.filing_status_input= SEPARATE each hold one head (plus 28 dependents in all). Every one of those heads is alone in a one-person marital unit and hasis_separated= true; the spouse is not in the data. 28 are in North Carolina (60,047 weighted).filing_status_inputand computes filing status. A computed SEPARATE return never holds a spouse (Count only deductible mortgage interest in Montana, give Maryland spouses their own losses, report the whole Virginia EITC #10004).SEPARATEreturn. A separate filer whose spouse is absent keeps $20,000, which assumes the absent spouse claims nothing (documented below).Changes
Form D-400 Schedule A lines 3 to 5 become three tax-unit variables.
nc_itemized_deductionsreads line 5 in place of its inline cap.nc_mortgage_and_property_tax_before_limitationmortgage_interestplus real estate taxes up to the federal SALT cap. These are the previous implementation's two terms, moved unchanged. This intermediate calculation now also runs for other-state spouses to supply the shared-cap allocation base.nc_mortgage_and_property_tax_limitationnc_mortgage_and_property_tax_deductionmortgage_and_real_estate_taxes_paid_from_joint_account(new input, MaritalUnit, default false)SEPARATEreturn. A married person meeting IRS Publication 501's "considered unmarried" tests may file head of household while the other spouse files separately. NC's text names spouses "filing as married filing separately or married filing jointly", and federal law treats the head-of-household spouse as unmarried, so that mixed-status pair does not share the cap (ruled 4A).Open readings (d1157)
These were the original interpretation questions. The full write-up was expanded to five choices in
~/reviews/us-hub/nc-mfs-cap/decision-v2.md; Max resolved them under d1351, as recorded in the next section.mortgage_interest, including non-deductible interest; the separate federal-interest fix is a prerequisite to excluding that interest from line 3.The 2001 NCDOR hearing describes an audit allocation using gross income (finding 5, PDF p. 3), but its final reasoning uses adjusted gross income (PDF p. 5). 17 NCAC 06B .0112(b) also allocates joint-account deductions by AGI. Both concern joint federal returns with separate NC returns, a related but distinct arrangement.
Holding the line-3 amounts and income definition fixed, the form-based joint-account reading and full-cap income reallocation agree above the cap whenever each spouse's line 3 is at least their income share of $20,000. For the mortgage-interest-only examples here, all three choice-2 readings agree when the entered payments are already split by income. These comparisons concern choice 2; choice 1's allocation bases can produce different results.
Rulings (Max, d1351, 2026-10-12)
mortgage_interest(deductible and non-deductible) until the separate Alabama/North Carolina federal-interest fix lands. Branchal-nc-mortgage-interest-federal-capis not yet a PR, waits on Apply federal mortgage debt limits by loan vintage, including grandfathered pre-1987 debt #10025, and switches line 1 todeductible_mortgage_interest. That change is outside this PR.SEPARATEheads, inferred from a two-person marital unit. The marital unit may be explicit or core's default. A married person meeting IRS Publication 501's "considered unmarried" tests may file head of household while the other spouse files separately. NC names spouses "filing as married filing separately or married filing jointly"; federal law treats the head-of-household spouse as unmarried, so this mixed-status pair does not share the cap.Household example
The original branch's household evidence compared against
mainat ff479aa: two spouses filing separately in 2024, each with $90,000 of wages, $15,000 of mortgage interest and $1,000 of cash charity, in two tax units linked by a marital unit (~/reviews/us-hub/nc-mfs-cap/households.py;evidence/households_{main,branch}.json). These ordinary NC-couple results are unchanged by ruling 5B.main(ff479aa)nc_itemized_deductionsnc_income_taxThe original household evidence showed $146.25 more per spouse in 2024, $138.12 more in 2025 and $111.72 more in 2026. The YAML integration case gives each spouse $5,000 of charity so both keep itemizing: $20,000 of itemized deductions each under the previous implementation, $15,000 here, and NC income tax rises from $3,150 to $3,375 each.
Other 2024 couples from the same original script:
main(ff479aa)The added cross-state cases use equal incomes and mortgage-interest amounts as their line 3, so no property-tax cap changes the arithmetic:
Invariants
The property test samples finite nonnegative line-3 amounts in valid North Carolina tax units with a head role: $0–$45,000 initially, increases of $0–$20,000, and AGI of −$30,000–$300,000 in 2024 or 2026. Shared-cap assertions require two
SEPARATEheads in a two-person marital unit. The generated populations use explicit marital units and NC households; deterministic YAML separately covers implicit units, head-of-household/separate pairs, headless returns, and cross-state spouses.SEPARATEheads.Negative expense inputs are outside the tested domain; the pre-existing minimum can produce a negative deduction for negative line 3. Headless tax units do not satisfy the spouse guard and retain the individual $20,000 limitation. The headless YAML case documents that fallback; the shared-cap invariant does not apply to it.
Tests
nc_mortgage_and_property_tax_limitation.yaml(19 cases): the original 17 cases plus the head-of-household/separate pair and headless-return fallback. Existing coverage includes single; joint; equal, unequal, below-cap and exactly-$20,000 separate couples; joint-account proration with positive, negative and zero income; joint-account payments below the cap; property taxes above the federal cap; a separate return with a dependent; a lone separate filer; implicit marital units containing two separate filers, a separate and single filer, or three separate filers; and 2026.nc_mortgage_and_property_tax_deduction.yaml(10 cases): the original 6 cases (5 calculating person-level expenses and 1 taking line 3 as an input), plus the 4 cross-state cases above using person-levelhome_mortgage_interest. The original coverage includes a joint-account case where line 5 takes line 3 because the income share is larger.nc_mortgage_and_property_tax_before_limitation.yaml(3 cases).nc_itemized_deductions.yaml(6 cases): 5 pre-existing cases, including main's self-employed health insurance regression, and the end-to-end separate-spouse case from wages tonc_income_tax.nc_itemized_deductions.yamlcase failed onmainat ff479aa ($20,000 each instead of $15,000); its other 4 cases passed on both (evidence/yaml_on_main.log). The three new variables did not exist on that baseline. Current verification results are recorded below.tests/core/test_nc_mortgage_and_property_tax_limitation_invariants.pycontains 2 pytest tests and checks invariants 1 to 5 within the domain stated above. It also checks lines 4 and 5 against a separate arithmetic restatement of the chosen interpretation, with $20,000 taken from the statute rather than parameter files. The oracle is computationally separate from production but shares its legal assumptions.coregroup and adds no runner. CI publishes the affected group'srest-python-core.xmltiming andrest-python-core-resources.txtelapsed-time/peak-RSS reports inrest-test-timings. No before/after reports exist in the local evidence, and GitHub API requests for existing runs and artifacts failed with connection errors, so affected-group Linux runtime and peak-memory measurements are unavailable. The Makefile's estimated 142-second note is historical context rather than a measurement of this change.Run by the hub at
0e1277d23afad2b24e2a4430c25777cd974cf997on 2026-10-12, one file per process directly in the assigned sandbox, with thread caps (OMP_NUM_THREADS,OPENBLAS_NUM_THREADS,MKL_NUM_THREADS,VECLIB_MAXIMUM_THREADS, andNUMEXPR_NUM_THREADSall4;OMP_WAIT_POLICY=PASSIVE), without the shared heavy-job lock:itemized/nc_claim_of_right_deduction.yamlmilitary_retirement/nc_military_retirement_deduction.yamlmilitary_retirement/nc_military_retirement_deduction_eligible.yamlnc_child_deduction.yamlnc_itemized_deductions.yamlnc_mortgage_and_property_tax_before_limitation.yamlnc_mortgage_and_property_tax_deduction.yamlnc_mortgage_and_property_tax_limitation.yamlnc_standard_deduction.yamlnc_standard_or_itemized_deductions.yamltests/core/test_nc_mortgage_and_property_tax_limitation_invariants.pyHub microsimulation impact (current head)
A real microsimulation on the default dataset, main at the merge base
de3815f4ccagainst this PR's head0e1277d23a, for 2024 and 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.nc_income_taxnc_itemized_deductionsnc_taxable_incomestate_income_taxincome_taxhousehold_net_incomehousehold_benefitsThe two 2024 nc_taxable_income records differ by less than one cent each (largest $0.0078); no tax, income or benefit output changes in either year.
Comparison files are in
fixes/10029-impact/on the hub host.Microsimulation impact
No main-versus-branch microsimulation output is available for this PR. The existing dataset profile shows zero two-person marital units crossing tax units; each separate filer is alone in their marital unit. Consequently no record in that profiled dataset reaches the shared-cap guard, including the new cross-state path, so its state tax results cannot change from this cap fix. The now unrestricted intermediate line-3 variable can return amounts for non-NC tax units when queried, but the final NC limitation and deduction remain restricted to NC and no other state's tax changes.
Known limitations
Overlaps and merge order
Four pieces of work touch this formula:
al-nc-mortgage-interest-federal-cap, not yet a PR; waits on Apply federal mortgage debt limits by loan vintage, including grandfathered pre-1987 debt #10025): changes line 1 frommortgage_interesttodeductible_mortgage_interest. After this PR that line lives innc_mortgage_and_property_tax_before_limitation.py; the edit is the same one line. This will correct both the NC filer's line 3 and the other-state spouse's shared-cap allocation base.min_(real_estate_taxes, cap)term, in the same new file.other_deductionsinnc_itemized_deductions.py. This PR leaves those lines untouched.Follow-ups
axiom: TheAxiomFoundation/rulespec-us#1723 queued
🤖 Generated with Claude Code