diff --git a/changelog.d/per-return-tax-exempt-ss.fixed.md b/changelog.d/per-return-tax-exempt-ss.fixed.md new file mode 100644 index 00000000000..5ec3f12b530 --- /dev/null +++ b/changelog.d/per-return-tax-exempt-ss.fixed.md @@ -0,0 +1 @@ +Leave a tax unit dependent's Social Security benefits and other nontaxable income out of income measures that describe the filers' own return: the federal Optional State Sales Tax Table income, the Working Americans' Tax Cut Act alternative tax modified AGI, Colorado's sales tax refund modified AGI, Maine's sales and property tax fairness credit income and Washington's senior and disabled property tax exemption combined disposable income. diff --git a/policyengine_us/parameters/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_table/income_sources.yaml b/policyengine_us/parameters/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_table/income_sources.yaml index c3f01b309b2..aec4f8da5f9 100644 --- a/policyengine_us/parameters/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_table/income_sources.yaml +++ b/policyengine_us/parameters/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_table/income_sources.yaml @@ -45,8 +45,9 @@ values: # Nontaxable combat pay - not available. - workers_compensation # Nontaxable part of social security and railroad retirement benefits; - # railroad retirement benefits are not included. - - tax_exempt_social_security + # railroad retirement benefits are not included. The head's and spouse's + # benefits only: a tax unit dependent's benefits are the dependent's own. + - filer_tax_exempt_social_security # Nontaxable IRA, pension, or annuity distributions (excluding rollovers). - tax_exempt_pension_income - tax_exempt_retirement_distributions diff --git a/policyengine_us/parameters/gov/states/co/tax/income/credits/sales_tax_refund/magi_sources.yaml b/policyengine_us/parameters/gov/states/co/tax/income/credits/sales_tax_refund/magi_sources.yaml index 9779bbf72d9..de0b81e062f 100644 --- a/policyengine_us/parameters/gov/states/co/tax/income/credits/sales_tax_refund/magi_sources.yaml +++ b/policyengine_us/parameters/gov/states/co/tax/income/credits/sales_tax_refund/magi_sources.yaml @@ -2,20 +2,25 @@ description: Colorado accounts for these income sources for the modified adjuste values: 1999-01-01: - adjusted_gross_income - - tax_exempt_social_security + # "Social security benefits excluded from federal adjusted gross income": + # the filers' own, Form 1040 line 6a less line 6b (DR 0104 line 35). A tax + # unit dependent's benefits are the dependent's own. + - filer_tax_exempt_social_security # - non_taxable_interest_income_from_state_and_local_bonds metadata: period: year unit: list label: Colorado modified adjusted gross income sources reference: - - title: Colo. Code Regs. 39-22-2003 State Sales Tax Refund (1.5) + - title: C.R.S. 39-22-2003(1.5) href: https://law.justia.com/codes/colorado/2022/title-39/article-22/part-20/section-39-22-2003/ + - title: "Colorado Revised Statutes 2024, Title 39, C.R.S. 39-22-2003(1.5)(b) and (3)(c)-(d) #page 760-762" + href: https://leg.colorado.gov/sites/default/files/images/olls/crs2024-title-39.pdf#page=760 - title: 2021 Colorado Individual Income Tax Filing Guide href: https://tax.colorado.gov/sites/tax/files/documents/DR_104_Book_2021.pdf#page=21 - title: 2022 Colorado Individual Income Tax Filing Guide href: https://tax.colorado.gov/sites/tax/files/documents/DR_104_Book_2022.pdf#page=23 - title: 2024 Colorado State Sales Tax Refund href: https://tax.colorado.gov/income-tax-topics-state-sales-tax-refund - - title: 2025 Colorado Individual Tax Filing Guide 104 Book - href: https://tax.colorado.gov/sites/tax/files/documents/Book104_2025.pdf#page=23 + - title: "2025 Colorado Individual Income Tax Filing Guide (Book 104), DR 0104 lines 34-37 #page 13,42" + href: https://tax.colorado.gov/sites/tax/files/documents/Book104_2025.pdf#page=13 diff --git a/policyengine_us/parameters/gov/states/me/tax/income/credits/fairness/income_sources.yaml b/policyengine_us/parameters/gov/states/me/tax/income/credits/fairness/income_sources.yaml index 69511996e9f..ae4a71b7c17 100644 --- a/policyengine_us/parameters/gov/states/me/tax/income/credits/fairness/income_sources.yaml +++ b/policyengine_us/parameters/gov/states/me/tax/income/credits/fairness/income_sources.yaml @@ -2,13 +2,21 @@ description: Maine accounts for the following income sources for the sales and p values: 2021-01-01: - irs_gross_income - - tax_exempt_social_security + # Social Security "to the extent not included in federal adjusted gross + # income": the filers' own, Form 1040 line 6a less line 6b (Schedule + # PTFC/STFC line 2b). A tax unit dependent's benefits are the dependent's + # own. + - filer_tax_exempt_social_security - tax_exempt_interest_income metadata: unit: list label: Maine sales and property tax credit income sources reference: - - title: §5213-A. Sales tax fairness credit (1) (B) + - title: §5213-A. Sales tax fairness credit (1) (B) href: https://legislature.maine.gov/statutes/36/title36sec5213-A.html - title: §5219-KK. Property tax fairness credit for tax (1) (D) href: https://legislature.maine.gov/statutes/36/title36sec5219-KK.html + - title: "Maine Revenue Services Rule 813, Property Tax Fairness Credit, .01(C) and .03 #page 1,4" + href: https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/Rule_813_May_2023.pdf#page=1 + - title: 2025 Form 1040ME Schedule PTFC/STFC, lines 2a-3 + href: https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/25_1040me_sch_ptfc_fillable.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/sources.yaml b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/sources.yaml index 11b1484dc78..3d51617152f 100644 --- a/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/sources.yaml +++ b/policyengine_us/parameters/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/sources.yaml @@ -12,8 +12,11 @@ values: # dominated by those excluded categories, so adding it back would # systematically over-count CDI. We omit it conservatively at the moment # and don't track the included subcomponents separately. - # RCW 84.36.383(7)(g) — Social Security and Railroad Retirement not in AGI - - tax_exempt_social_security + # RCW 84.36.383(7)(g) — Social Security and Railroad Retirement not in AGI, + # added to the AGI of "the person receiving these benefits" (WAC + # 458-16A-120(2)(b)(vi)). The head's and spouse's benefits only: a tax + # unit dependent's benefits are the dependent's own disposable income. + - filer_tax_exempt_social_security # RCW 84.36.383(7)(i) — state/municipal bond interest not in AGI - tax_exempt_interest_income # RCW 84.36.383(7)(a) — capital gains add-back. AGI already includes diff --git a/policyengine_us/reforms/congress/watca/working_americans_tax_cut_act.py b/policyengine_us/reforms/congress/watca/working_americans_tax_cut_act.py index 27becb3a73f..9cce3b893c0 100644 --- a/policyengine_us/reforms/congress/watca/working_americans_tax_cut_act.py +++ b/policyengine_us/reforms/congress/watca/working_americans_tax_cut_act.py @@ -6,6 +6,10 @@ "title": "Working Americans' Tax Cut Act", "href": "https://www.vanhollen.senate.gov/imo/media/doc/working_americans_tax_cut_act_bill_text.pdf", }, + { + "title": "S. 4083 (119th Congress), Working Americans' Tax Cut Act, as introduced", + "href": "https://www.govinfo.gov/content/pkg/BILLS-119s4083is/html/BILLS-119s4083is.htm", + }, ] @@ -17,14 +21,21 @@ class watca_alternative_tax_magi(Variable): definition_period = YEAR unit = USD reference = WATCA_REFERENCES - documentation = "Section 1A(d): AGI + foreign income exclusions (sec 911, 931, 933) + non-taxable Social Security." + documentation = ( + "Section 1A(d): AGI + foreign income exclusions (sec 911, 931, 933) " + "+ the filers' non-taxable Social Security. A tax unit dependent's " + "benefits are the dependent's own and stay out." + ) adds = [ "adjusted_gross_income", "foreign_earned_income_exclusion", "specified_possession_income", "puerto_rico_income", - "tax_exempt_social_security", + # Section 1A(d)(2): "the portion of the taxpayer's social security + # benefits (as defined in section 86(d)) which is not included in + # gross income under section 86". + "filer_tax_exempt_social_security", ] class watca_surtax_magi(Variable): diff --git a/policyengine_us/tests/core/test_dependent_social_security_per_return_invariants.py b/policyengine_us/tests/core/test_dependent_social_security_per_return_invariants.py new file mode 100644 index 00000000000..7ae51d206cd --- /dev/null +++ b/policyengine_us/tests/core/test_dependent_social_security_per_return_invariants.py @@ -0,0 +1,351 @@ +"""Invariants for a tax unit dependent's Social Security in per-return readers. + +Social Security benefits are income of "the person who has the legal right to +receive the benefits" (IRS Pub. 915, 2025, "Who is taxed"), so a tax unit +dependent's benefits belong on the dependent's own return. +`filer_tax_exempt_social_security` is the nontaxable part of the head's and +spouse's benefits. These measures count the filers' own return: + +- the Optional State Sales Tax Table income row, + `state_sales_tax_income_bracket`: "the amount shown on your Form 1040 or + 1040-SR, line 11b, plus any nontaxable items" (2025 Schedule A + instructions). A dependent's other nontaxable items (SSI, tax-exempt + interest, veterans' benefits, workers' compensation, nontaxable pensions + and retirement distributions) are the dependent's own too; +- Colorado's sales tax refund income, `co_modified_agi`: C.R.S. + 39-22-2003(1.5)(b) adds the "Social security benefits excluded from + federal adjusted gross income", and subsection (3) measures the qualified + individuals' own income; +- Maine's fairness credit income, + `me_sales_and_property_tax_fairness_credit_income`: 36 M.R.S. 5213-A(1)(B) + and 5219-KK(1)(D) add interest and Social Security left out of federal + adjusted gross income, and Rule 813 .03 makes the income "the + taxpayer's"; +- Washington's combined disposable income, + `wa_pte_combined_disposable_income`: RCW 84.36.383(2) combines the + claimant's, spouse's and cotenants' disposable income, and WAC + 458-16A-120(2)(b) adds each item left out of AGI to the AGI of "the person + receiving these benefits". The measure also subtracts members' medical + costs, and a member's net Medicare premium can turn on another member's + income through the Medicare Savings Program, so the population's Medicare + premiums are zero. + +READERS holds the income measures. AMOUNTS holds what they feed: the table +amount, the refund and the credits. These also read the filing status and +who counts as a dependent, which an aged parent's own income can move: a +parent must pass a gross income test to be a dependent, and a filer heads a +household for a parent only if the parent is the filer's dependent. So +AMOUNTS are checked for the units whose dependents are all children. + +`tax_exempt_social_security`, the household amount, still carries a +dependent's whole benefit for the readers whose law counts a household's +income. + +The tests draw a seeded random population of tax units: a single filer or a +married couple filing jointly, whose head and spouse have wages, Social +Security and the nontaxable items above, and whose head may pay rent, with +one to three dependents, each a child or an aged parent. A dependent draws +benefits of $1 to $1,000,000, log-uniformly, and the other nontaxable items, +each of them zero about half the time. Amounts are whole dollars and stay +below 2**24, so their float32 sums, and the subtraction that takes +dependents' benefits out of the tax unit's, are exact. Every unit is placed +in each state in READERS, and each scenario runs as one vectorized +simulation. + +1. Each reader is the same whether the dependents' benefits and nontaxable + items are zero, as drawn, or doubled, and so is each amount for the units + whose dependents are all children. +2. The household amount moves with the dependents' benefits, so the + population exercises the property. +3. Moving the dependents' benefits and items onto the head changes each + reader and each amount for some units, so they count the filers' own + amounts. +""" + +import numpy as np +import pytest + +from policyengine_us import Simulation + +SEED = 20261102 +YEAR = 2025 +N_UNITS = 40 +TOLERANCE = 0.01 # dollars +# The readers that measure the filers' own return, by the state each runs in. +READERS = { + "TX": ["filer_tax_exempt_social_security", "state_sales_tax_income_bracket"], + "CO": ["co_modified_agi"], + "ME": ["me_sales_and_property_tax_fairness_credit_income"], + "WA": ["wa_pte_combined_disposable_income"], +} +# What the readers feed, checked for units whose dependents are all children. +AMOUNTS = { + "TX": ["state_sales_tax"], + "CO": ["co_sales_tax_refund"], + "ME": ["me_sales_tax_fairness_credit", "me_property_tax_fairness_credit"], + "WA": [], +} +STATES = list(READERS) +CHILD_AGE_LIMIT = 18 +# Person-level nontaxable items the sales tax table income counts. +NONTAXABLE_ITEMS = [ + "ssi", + "tax_exempt_interest_income", + "veterans_benefits", + "workers_compensation", + "tax_exempt_pension_income", + "tax_exempt_retirement_distributions", +] +SCENARIOS = {"zero": 0, "as_drawn": 1, "doubled": 2} + + +def _draw_units(n, rng): + def maybe(high): + # Zero about half the time, otherwise a whole-dollar amount. + return float(rng.choice([0, rng.integers(1, high)])) + + def filer(age): + if age >= 62: + benefit = "social_security_retirement" + else: + benefit = "social_security_disability" + return { + "age": age, + "employment_income": maybe(120_000), + "benefit": benefit, + "social_security": maybe(40_000), + "items": {item: maybe(8_000) for item in NONTAXABLE_ITEMS}, + } + + def dependent(): + aged_parent = bool(rng.random() < 0.3) + benefit = ( + "social_security_retirement" + if aged_parent + else str( + rng.choice(["social_security_survivors", "social_security_dependents"]) + ) + ) + # Log-uniform from $1 to $1,000,000. + amount = float(np.floor(10 ** rng.uniform(0, 6))) + return { + "age": int(rng.integers(70, 90)) + if aged_parent + else int(rng.integers(0, 18)), + "benefit": benefit, + "social_security": amount, + "items": {item: maybe(20_000) for item in NONTAXABLE_ITEMS}, + } + + units = [] + for _ in range(n): + joint = bool(rng.random() < 0.5) + head_age = int(rng.integers(25, 85)) + units.append( + { + "joint": joint, + "rent": maybe(24_000), + "head": filer(head_age), + "spouse": filer(int(rng.integers(25, 85))) if joint else None, + "dependents": [dependent() for _ in range(int(rng.integers(1, 4)))], + } + ) + return units + + +def _amounts(person, scale=1): + """A person's benefit and nontaxable items, each multiplied by scale.""" + amounts = { + person["benefit"]: {YEAR: scale * person["social_security"]}, + "medicare_part_b_premium": {YEAR: 0}, + } + for item, value in person["items"].items(): + amounts[item] = {YEAR: scale * value} + return amounts + + +def _moved_to_head(unit): + """The unit's head with every dependent's benefit and items added.""" + head = {**unit["head"], "items": dict(unit["head"]["items"])} + for dependent in unit["dependents"]: + head["social_security"] += dependent["social_security"] + for item, value in dependent["items"].items(): + head["items"][item] += value + return head + + +def _situation(units, scale=1, moved_to_head=False): + people, tax_units, marital_units, spm_units = {}, {}, {}, {} + families, households = {}, {} + for state in STATES: + for i, unit in enumerate(units): + key = f"{state}_{i}" + head = f"head_{key}" + members = [head] + couple = [head] + head_amounts = _moved_to_head(unit) if moved_to_head else unit["head"] + people[head] = { + "age": {YEAR: unit["head"]["age"]}, + "is_tax_unit_head": {YEAR: True}, + "is_tax_unit_spouse": {YEAR: False}, + "is_tax_unit_dependent": {YEAR: False}, + "employment_income": {YEAR: unit["head"]["employment_income"]}, + "rent": {YEAR: unit["rent"]}, + **_amounts(head_amounts), + } + if unit["spouse"] is not None: + spouse = f"spouse_{key}" + members.append(spouse) + couple.append(spouse) + people[spouse] = { + "age": {YEAR: unit["spouse"]["age"]}, + "is_tax_unit_head": {YEAR: False}, + "is_tax_unit_spouse": {YEAR: True}, + "is_tax_unit_dependent": {YEAR: False}, + "employment_income": {YEAR: unit["spouse"]["employment_income"]}, + **_amounts(unit["spouse"]), + } + marital_units[f"mu_{key}"] = {"members": couple} + for j, dependent in enumerate(unit["dependents"]): + person = f"dependent_{key}_{j}" + members.append(person) + marital_units[f"mu_{key}_{j}"] = {"members": [person]} + people[person] = { + "age": {YEAR: dependent["age"]}, + "is_tax_unit_head": {YEAR: False}, + "is_tax_unit_spouse": {YEAR: False}, + "is_tax_unit_dependent": {YEAR: True}, + **_amounts(dependent, scale=0 if moved_to_head else scale), + } + tax_units[f"tu_{key}"] = {"members": members} + spm_units[f"spm_{key}"] = {"members": members} + families[f"fam_{key}"] = {"members": members} + households[f"hh_{key}"] = { + "members": members, + "state_code": {YEAR: state}, + } + return { + "people": people, + "tax_units": tax_units, + "marital_units": marital_units, + "spm_units": spm_units, + "families": families, + "households": households, + } + + +def _state_slice(state): + start = STATES.index(state) * N_UNITS + return slice(start, start + N_UNITS) + + +def _child_dependents_only(units): + return np.array( + [all(d["age"] < CHILD_AGE_LIMIT for d in u["dependents"]) for u in units] + ) + + +@pytest.fixture(scope="module") +def population(): + rng = np.random.default_rng(SEED) + units = _draw_units(N_UNITS, rng) + simulations = { + name: Simulation(situation=_situation(units, scale=scale)) + for name, scale in SCENARIOS.items() + } + simulations["moved_to_head"] = Simulation( + situation=_situation(units, moved_to_head=True) + ) + return units, simulations + + +def test_population_draws_exact_whole_dollar_amounts(population): + units, _ = population + amounts = [ + value + for unit in units + for person in [unit["head"], unit["spouse"], *unit["dependents"]] + if person is not None + for value in [person["social_security"], *person["items"].values()] + ] + assert all(value == int(value) for value in amounts) + # Doubled, a unit's benefits and items still sum below 2**24. + totals = [ + sum( + SCENARIOS["doubled"] + * (person["social_security"] + sum(person["items"].values())) + for person in [unit["head"], unit["spouse"], *unit["dependents"]] + if person is not None + ) + for unit in units + ] + assert max(totals) < 2**24 + + +def test_population_has_units_with_child_and_parent_dependents(population): + units, _ = population + children_only = _child_dependents_only(units) + assert 10 <= children_only.sum() <= len(units) - 10 + + +@pytest.mark.parametrize("scenario", ["as_drawn", "doubled"]) +def test_dependents_benefits_leave_per_return_readers_unchanged(population, scenario): + units, simulations = population + assert any(d["social_security"] for u in units for d in u["dependents"]) + for state, readers in READERS.items(): + rows = _state_slice(state) + for reader in readers: + np.testing.assert_allclose( + simulations[scenario].calculate(reader, YEAR)[rows], + simulations["zero"].calculate(reader, YEAR)[rows], + atol=TOLERANCE, + err_msg=f"{state} {reader} {scenario}", + ) + + +@pytest.mark.parametrize("scenario", ["as_drawn", "doubled"]) +def test_child_dependents_benefits_leave_amounts_unchanged(population, scenario): + units, simulations = population + children_only = _child_dependents_only(units) + for state, amounts in AMOUNTS.items(): + rows = _state_slice(state) + for amount in amounts: + np.testing.assert_allclose( + simulations[scenario].calculate(amount, YEAR)[rows][children_only], + simulations["zero"].calculate(amount, YEAR)[rows][children_only], + atol=TOLERANCE, + err_msg=f"{state} {amount} {scenario}", + ) + + +def test_household_amount_carries_dependents_benefits(population): + units, simulations = population + dependents_benefits = np.array( + [sum(d["social_security"] for d in u["dependents"]) for u in units] + ) + for state in STATES: + rows = _state_slice(state) + # The household amount subtracts the filers' fractional taxable + # benefits from a total of up to a few million dollars, so it is + # exact only to float32's relative precision. + np.testing.assert_allclose( + simulations["as_drawn"].calculate("tax_exempt_social_security", YEAR)[rows] + - simulations["zero"].calculate("tax_exempt_social_security", YEAR)[rows], + dependents_benefits, + rtol=1e-6, + atol=TOLERANCE, + ) + + +def test_readers_and_amounts_count_the_filers_own_amounts(population): + units, simulations = population + children_only = _child_dependents_only(units) + for state in STATES: + rows = _state_slice(state) + checks = [(reader, slice(None)) for reader in READERS[state]] + checks += [(amount, children_only) for amount in AMOUNTS[state]] + for variable, units_checked in checks: + moved = simulations["moved_to_head"].calculate(variable, YEAR)[rows] + kept = simulations["as_drawn"].calculate(variable, YEAR)[rows] + changed = np.abs(moved - kept)[units_checked] > TOLERANCE + assert changed.any(), f"{state} {variable}" diff --git a/policyengine_us/tests/policy/baseline/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.yaml b/policyengine_us/tests/policy/baseline/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.yaml index 1bad25242fc..80b7f7e3d1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.yaml @@ -85,3 +85,142 @@ adjusted_gross_income: 300_000 output: state_sales_tax_income_bracket: 19 + +# Income is "the amount shown on your Form 1040 or 1040-SR, line 11b, plus any +# nontaxable items" (2025 Instructions for Schedule A). A tax unit dependent's +# benefits and nontaxable income are the dependent's own, not the filers'. + +- name: A dependent child's Social Security stays out of the filer's income + period: 2025 + input: + people: + parent: + age: 40 + employment_income: 10_000 + social_security_disability: 18_000 + child: + age: 10 + is_tax_unit_dependent: true + social_security_dependents: 6_000 + tax_units: + tax_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: TX + output: + # Combined income of 10_000 + 18_000 / 2 = 19_000 is below the $25,000 + # head of household base amount, so none of the parent's benefit is + # taxable. + adjusted_gross_income: 10_000 + filer_tax_exempt_social_security: 18_000 + # The household amount carries the child's benefit as well. + tax_exempt_social_security: 24_000 + # 10_000 + 18_000 = 28_000 is in the $20,000-$30,000 row. Counting the + # child's 6_000 would give 34_000, the $30,000-$40,000 row. + state_sales_tax_income_bracket: 2 + +- name: A dependent parent's nontaxable income stays out of the filer's income + period: 2025 + input: + people: + filer: + age: 50 + employment_income: 25_000 + dependent_parent: + age: 80 + is_tax_unit_dependent: true + social_security_retirement: 12_000 + ssi: 4_800 + veterans_benefits: 4_000 + tax_exempt_pension_income: 3_000 + tax_exempt_retirement_distributions: 2_000 + workers_compensation: 1_500 + tax_exempt_interest_income: 500 + tax_units: + tax_unit: + members: [filer, dependent_parent] + households: + household: + members: [filer, dependent_parent] + state_code: TX + output: + adjusted_gross_income: 25_000 + filer_tax_exempt_social_security: 0 + # 25_000 is in the $20,000-$30,000 row. Counting the parent's 27_800 of + # benefits and nontaxable income would give 52_800, the $50,000-$60,000 + # row. + state_sales_tax_income_bracket: 2 + +- name: The filers' own nontaxable items still count beside a dependent's + period: 2025 + input: + people: + head: + age: 70 + is_tax_unit_head: true + social_security_retirement: 20_000 + tax_exempt_interest_income: 4_000 + veterans_benefits: 3_000 + spouse: + age: 68 + is_tax_unit_spouse: true + employment_income: 15_000 + ssi: 2_400 + tax_exempt_pension_income: 11_000 + grandchild: + age: 12 + is_tax_unit_dependent: true + social_security_survivors: 10_000 + ssi: 7_200 + tax_exempt_interest_income: 1_000 + tax_units: + tax_unit: + members: [head, spouse, grandchild] + filing_status: JOINT + households: + household: + members: [head, spouse, grandchild] + state_code: TX + output: + # Combined income: 15_000 + 4_000 of tax-exempt interest + 20_000 / 2 = + # 29_000, below the $32,000 joint base amount, so no benefit is taxable. + adjusted_gross_income: 15_000 + filer_tax_exempt_social_security: 20_000 + # 15_000 + 4_000 + 3_000 + 20_000 + 2_400 + 11_000 = 55_400 is in the + # $50,000-$60,000 row. The grandchild's 10_000 of benefits alone would + # give 65_400, and the grandchild's 7_200 of SSI and 1_000 of interest + # alone 63_600, both in the $60,000-$70,000 row. + state_sales_tax_income_bracket: 5 + +- name: A family's TANF counts in full, the children's shares included + period: 2025 + input: + people: + parent: + age: 30 + employment_income: 15_000 + child_1: + age: 6 + is_tax_unit_dependent: true + child_2: + age: 3 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child_1, child_2] + spm_units: + spm_unit: + members: [parent, child_1, child_2] + tanf: 6_000 + households: + household: + members: [parent, child_1, child_2] + state_code: TX + output: + # TANF is paid to the caretaker for the assistance unit, and the tax + # unit holds the whole SPM unit, so all 6_000 counts: 15_000 + 6_000 = + # 21_000 is in the $20,000-$30,000 row. The parent's per-person share + # alone (2_000) would give 17_000, the first row. + state_sales_tax_income_bracket: 2 diff --git a/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/credits/sales_tax_refund/co_modified_agi.yaml b/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/credits/sales_tax_refund/co_modified_agi.yaml new file mode 100644 index 00000000000..78cbd79283f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/co/tax/income/credits/sales_tax_refund/co_modified_agi.yaml @@ -0,0 +1,68 @@ +# C.R.S. 39-22-2003(1.5)(b) adds to federal adjusted gross income the "Social +# security benefits excluded from federal adjusted gross income for the tax +# year", and subsection (3) measures the qualified individuals' own income. +# DR 0104 line 35 is the filers' Form 1040 line 6a less line 6b (2025 Book 104, +# page 13). A tax unit dependent's benefits are the dependent's own. Refund +# amounts are from the 2025 DR 0104 line 38 table (Book 104, page 42): $19 for +# single filers and $38 for joint filers with modified AGI of $52,000 or less, +# $25 and $50 from $52,001 to $105,000. + +- name: A dependent child's Social Security stays out of the parent's modified AGI + period: 2025 + input: + people: + parent: + age: 40 + employment_income: 50_000 + child: + age: 10 + is_tax_unit_dependent: true + social_security_survivors: 6_000 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + households: + household: + members: [parent, child] + state_code: CO + output: + adjusted_gross_income: 50_000 + filer_tax_exempt_social_security: 0 + # 50_000, not 50_000 + 6_000 = 56_000. + co_modified_agi: 50_000 + # $19, not the $25 that 56_000 would give. + co_sales_tax_refund: 19 + +- name: Joint filers' own nontaxable Social Security counts, a dependent's does not + period: 2025 + input: + people: + head: + age: 70 + employment_income: 10_000 + social_security_retirement: 30_000 + spouse: + age: 68 + social_security_retirement: 10_000 + grandchild: + age: 16 + is_tax_unit_dependent: true + social_security_survivors: 9_000 + tax_units: + tax_unit: + members: [head, spouse, grandchild] + filing_status: JOINT + households: + household: + members: [head, spouse, grandchild] + state_code: CO + output: + # Combined income of 10_000 + (30_000 + 10_000) / 2 = 30_000 is below the + # $32,000 joint base amount, so none of the couple's benefits is taxable. + adjusted_gross_income: 10_000 + filer_tax_exempt_social_security: 40_000 + # 10_000 + 40_000 = 50_000, not 59_000 with the grandchild's 9_000. + co_modified_agi: 50_000 + # $38 for joint filers, not the $50 that 59_000 would give. + co_sales_tax_refund: 38 diff --git a/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.yaml new file mode 100644 index 00000000000..627a703307c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.yaml @@ -0,0 +1,71 @@ +# 36 M.R.S. 5213-A(1)(B) and 5219-KK(1)(D): income is federal adjusted gross +# income increased by interest and "Payments received under the federal Social +# Security Act ... to the extent not included in federal adjusted gross +# income". Rule 813 .03 makes it "the taxpayer's". Schedule PTFC/STFC line 2b +# is the filers' Form 1040 line 6a less line 6b. A tax unit dependent's +# benefits and interest are the dependent's own. Credit amounts follow the +# 2025 Schedule PTFC/STFC. + +- name: A dependent child's Social Security and interest stay out of the parent's income + period: 2025 + input: + people: + parent: + age: 40 + employment_income: 36_000 + rent: 12_000 + child: + age: 10 + is_tax_unit_dependent: true + social_security_survivors: 6_000 + tax_exempt_interest_income: 600 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + households: + household: + members: [parent, child] + state_code: ME + output: + # Line 3: the parent's 36_000, not 36_000 + 6_000 + 600 = 42_600. + me_sales_and_property_tax_fairness_credit_income: 36_000 + # Line 17, head of household with one child: $215 up to $38,200 ($125 + # from $41,951 to $42,700). + me_sales_tax_fairness_credit: 215 + # Line 5e: 15% of 12_000 = 1_800; line 9: min(1_800, 3_300) = 1_800; + # line 10: 4% of 36_000 = 1_440; line 13: min(360, 1_000) = 360 (with + # 42_600: 1_800 - 1_704 = 96). + me_property_tax_fairness_credit: 360 + +- name: Joint filers' own nontaxable Social Security counts, a dependent's does not + period: 2025 + input: + people: + head: + age: 66 + social_security_retirement: 20_000 + real_estate_taxes: 2_500 + spouse: + age: 60 + child: + age: 12 + is_tax_unit_dependent: true + social_security_dependents: 5_000 + tax_units: + tax_unit: + members: [head, spouse, child] + filing_status: JOINT + households: + household: + members: [head, spouse, child] + state_code: ME + output: + # Combined income of 20_000 / 2 = 10_000 is below the $32,000 joint base + # amount, so line 2a is 0 and line 2b is the head's 20_000; the child's + # 5_000 would make it 25_000. + me_sales_and_property_tax_fairness_credit_income: 20_000 + # Line 8: $4,100 (a filer is 65 or older); line 9: min(2_500, 4_100) = + # 2_500; line 10: 4% of 20_000 = 800; line 13: min(1_700, 2_000) = 1_700 + # (with 25_000: 2_500 - 1_000 = 1_500). + me_property_tax_fairness_credit: 1_700 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_household_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_household_income.yaml new file mode 100644 index 00000000000..f16e184ca23 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ri/tax/income/credits/property_tax/ri_property_tax_household_income.yaml @@ -0,0 +1,31 @@ +# R.I. Gen. Laws 44-33-3(6): "Household income" means all income received by +# all persons of a household, and 44-33-3(7) counts all payments received +# under the federal Social Security Act. Unlike the per-return readers, this +# household amount keeps a dependent's benefits. + +- name: A dependent grandchild's Social Security counts in household income + period: 2025 + input: + people: + grandparent: + age: 70 + employment_income: 5_000 + social_security_retirement: 10_000 + grandchild: + age: 12 + is_tax_unit_dependent: true + social_security_survivors: 6_000 + tax_units: + tax_unit: + members: [grandparent, grandchild] + households: + household: + members: [grandparent, grandchild] + state_code: RI + output: + # Combined income of 5_000 + 10_000 / 2 = 10_000 is below the $25,000 + # base amount, so none of the grandparent's benefit is taxable. + adjusted_gross_income: 5_000 + filer_tax_exempt_social_security: 10_000 + # 5_000 + 10_000 + the grandchild's 6_000. + ri_property_tax_household_income: 21_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_combined_disposable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_combined_disposable_income.yaml index 8d5b9246b16..cfe8365a790 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_combined_disposable_income.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/wa_pte_combined_disposable_income.yaml @@ -29,7 +29,7 @@ tax_unit: members: [person1] adjusted_gross_income: 30_000 - tax_exempt_social_security: 12_000 + filer_tax_exempt_social_security: 12_000 spm_units: spm_unit: members: [person1] @@ -55,7 +55,7 @@ tax_unit: members: [person1] adjusted_gross_income: 20_000 - tax_exempt_social_security: 10_000 + filer_tax_exempt_social_security: 10_000 spm_units: spm_unit: members: [person1] @@ -107,7 +107,7 @@ tax_unit: members: [person1, person2] adjusted_gross_income: 30_000 - tax_exempt_social_security: 14_000 + filer_tax_exempt_social_security: 14_000 spm_units: spm_unit: members: [person1, person2] @@ -217,3 +217,68 @@ # Cotenant filed a separate return; statute folds their disposable income # into the combined total. 30,000 + 25,000 = 55,000. wa_pte_combined_disposable_income: 55_000 + +- name: Case 10, a dependent child's Social Security and interest stay out of combined disposable income. + period: 2024 + input: + people: + person1: + age: 64 + social_security_retirement: 20_000 + person2: + age: 10 + is_tax_unit_dependent: true + social_security_dependents: 6_000 + tax_exempt_interest_income: 500 + tax_units: + tax_unit: + members: [person1, person2] + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WA + output: + # Combined income of 20_000 / 2 = 10_000 is below the $25,000 base + # amount, so none of the head's benefit is taxable and AGI is 0. The + # child's 6_000 and 500 are the child's own disposable income (WAC + # 458-16A-120(2)(b)(vi) and (x)), and the child owns no part of the + # residence. 0 + 20_000 = 20_000, not 26_500. + filer_tax_exempt_social_security: 20_000 + wa_pte_combined_disposable_income: 20_000 + +- name: Case 11, a dependent who co-owns the residence counts once, through the cotenant input. + period: 2024 + input: + people: + person1: + age: 64 + social_security_retirement: 18_000 + person2: + # A sibling claimed as a qualifying relative. Both are under 65, so + # no Medicare premium enters the deductions. + age: 63 + is_tax_unit_dependent: true + social_security_retirement: 14_000 + tax_exempt_pension_income: 2_000 + tax_units: + tax_unit: + members: [person1, person2] + # The sibling co-owns the residence, so is a cotenant (RCW + # 84.36.383(3)): AGI 0 (14_000 / 2 = 7_000 is below the $25,000 base + # amount) + 14_000 + 2_000 = 16_000. + wa_pte_cotenant_disposable_income: 16_000 + spm_units: + spm_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: WA + output: + # 18_000 / 2 = 9_000 is below the $25,000 base amount, so the head's AGI + # is 0. 0 + 18_000 + 16_000 = 34_000; the sibling's benefits and pension + # would otherwise count twice (50_000). + wa_pte_combined_disposable_income: 34_000 diff --git a/policyengine_us/tests/policy/contrib/congress/watca.yaml b/policyengine_us/tests/policy/contrib/congress/watca.yaml index 2b40103ff7f..ae588fb38c0 100644 --- a/policyengine_us/tests/policy/contrib/congress/watca.yaml +++ b/policyengine_us/tests/policy/contrib/congress/watca.yaml @@ -353,6 +353,95 @@ # MAGI = 50_000 + (20_000 - 5_000) = 65_000 watca_alternative_tax_magi: 65_000 +- name: A dependent's Social Security stays out of the alternative tax MAGI + period: 2026 + reforms: policyengine_us.reforms.congress.watca.working_americans_tax_cut_act.watca_reform_object + input: + gov.contrib.congress.watca.in_effect: true + people: + parent: + age: 45 + employment_income: 50_000 + child: + age: 10 + is_tax_unit_dependent: true + social_security_survivors: 10_000 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + output: + # Section 1A(d) adds the taxpayer's own nontaxable benefits. The child's + # 10_000 is the child's, on the child's own return, so MAGI is the + # parent's AGI: 50_000, not 60_000. + tax_exempt_social_security: 10_000 + filer_tax_exempt_social_security: 0 + watca_alternative_tax_magi: 50_000 + +- name: A dependent's Social Security does not cost the filer eligibility + period: 2026 + reforms: policyengine_us.reforms.congress.watca.working_americans_tax_cut_act.watca_reform_object + input: + gov.contrib.congress.watca.in_effect: true + people: + parent: + age: 67 + employment_income: 100_000 + social_security_retirement: 12_000 + child: + age: 10 + is_tax_unit_dependent: true + social_security_dependents: 10_000 + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + output: + # Combined income 100_000 + 12_000 / 2 = 106_000 is above the $34,000 + # adjusted base amount, so the taxable part is the 85% cap: 10_200. + # AGI = 110_200 and the parent's nontaxable benefits are 1_800. + adjusted_gross_income: 110_200 + filer_tax_exempt_social_security: 1_800 + # MAGI = 110_200 + 1_800 = 112_000, below the 64_400 * 1.75 = 112_700 + # head of household limit. Adding the child's 10_000 would give 122_000. + watca_alternative_tax_magi: 112_000 + watca_alternative_tax_eligible: true + +- name: A dependent's Social Security from $0 to $1,000,000 leaves the MAGI unchanged + period: 2026 + reforms: policyengine_us.reforms.congress.watca.working_americans_tax_cut_act.watca_reform_object + input: + gov.contrib.congress.watca.in_effect: true + people: + parent: + age: 45 + employment_income: 100_000 + child: + age: 10 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [parent, child] + filing_status: HEAD_OF_HOUSEHOLD + axes: + - - name: social_security_survivors + # The child, the second person in each copy. + index: 1 + min: 0 + max: 1_000_000 + count: 11 + period: 2026 + output: + # The household amount carries the child's benefit in every copy. + tax_exempt_social_security: + [0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000, 900_000, 1_000_000] + # MAGI is the parent's AGI at every benefit amount, so the parent stays + # below the 64_400 * 1.75 = 112_700 limit, and the alternative maximum + # tax is (100_000 - 64_400) * 0.255 = 9_078. + watca_alternative_tax_magi: 100_000 + watca_alternative_tax_eligible: true + watca_alternative_max_tax: 9_078 + - name: Alternative tax MAGI includes specified possession income period: 2026 reforms: policyengine_us.reforms.congress.watca.working_americans_tax_cut_act.watca_reform_object diff --git a/policyengine_us/tests/test_state_sales_tax_table.py b/policyengine_us/tests/test_state_sales_tax_table.py index f23bdeacc93..4a20692f60b 100644 --- a/policyengine_us/tests/test_state_sales_tax_table.py +++ b/policyengine_us/tests/test_state_sales_tax_table.py @@ -101,7 +101,7 @@ "tax_exempt_interest_income", "veterans_benefits", "workers_compensation", - "tax_exempt_social_security", + "filer_tax_exempt_social_security", "tax_exempt_pension_income", "tax_exempt_retirement_distributions", "tanf", diff --git a/policyengine_us/variables/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.py b/policyengine_us/variables/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.py index 880c78fc7ee..49b8bfee9ab 100644 --- a/policyengine_us/variables/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.py +++ b/policyengine_us/variables/gov/irs/deductions/itemized/salt_and_real_estate/state_sales_tax_income_bracket.py @@ -6,10 +6,30 @@ class state_sales_tax_income_bracket(Variable): entity = TaxUnit definition_period = YEAR label = "State Sales Tax Income Bracket" + documentation = ( + "The Optional State Sales Tax Table income row for the filers' income: " + "their adjusted gross income plus their own nontaxable items. A tax " + "unit dependent's benefits and nontaxable income, such as a child's " + "Social Security or SSI, are the dependent's own and stay out. TANF is " + "an SPM unit amount, so every tax unit member's per-person share of it " + "counts, the dependents' included." + ) + reference = ( + # "Your 2025 income is the amount shown on your Form 1040 or 1040-SR, + # line 11b, plus any nontaxable items". + "https://www.irs.gov/pub/irs-prior/i1040sca--2025.pdf#page=5", + # IRS Pub. 915 (2025), "Who is taxed": benefits are income of "the + # person who has the legal right to receive the benefits". + "https://www.irs.gov/pub/irs-prior/p915--2025.pdf#page=5", + ) def formula(tax_unit, period, parameters): p = parameters( period ).gov.irs.deductions.itemized.salt_and_real_estate.state_sales_tax_table - income = add(tax_unit, period, p.income_sources) + # Person-level items are summed over the head and spouse. Tax-unit + # sources (adjusted gross income, the filers' nontaxable Social + # Security) are the filers' own already, and SPM-unit TANF is added + # as each member's per-person share. + income = tax_unit_non_dep_add(tax_unit, period, p.income_sources) return p.income_bracket.calc(income) diff --git a/policyengine_us/variables/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.py b/policyengine_us/variables/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.py index 7511a063e49..d6b8775fe2a 100644 --- a/policyengine_us/variables/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.py +++ b/policyengine_us/variables/gov/states/me/tax/income/credits/fairness/me_sales_and_property_tax_fairness_credit_income.py @@ -6,10 +6,24 @@ class me_sales_and_property_tax_fairness_credit_income(Variable): entity = TaxUnit unit = USD label = "Maine sales and property tax fairness credit total income" + documentation = ( + "The filers' income for the sales and property tax fairness credits: " + "their own income plus their own interest and Social Security left out " + "of federal adjusted gross income. A tax unit dependent's benefits and " + "interest are the dependent's own." + ) definition_period = YEAR reference = ( - "https://legislature.maine.gov/statutes/36/title36sec5219-KK.html" # 1. D. + "https://legislature.maine.gov/statutes/36/title36sec5219-KK.html", # 1. D. + "https://legislature.maine.gov/statutes/36/title36sec5213-A.html", # 1. B. + # Rule 813 .03: "The income of the taxpayer is equal to the + # taxpayer's federal adjusted gross income increased by" interest and + # Social Security left out of it. + "https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/Rule_813_May_2023.pdf#page=4", ) defined_for = StateCode.ME - adds = "gov.states.me.tax.income.credits.fairness.income_sources" + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.me.tax.income.credits.fairness + # Person-level sources are summed over the head and spouse. + return tax_unit_non_dep_add(tax_unit, period, p.income_sources) diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_combined_disposable_income.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_combined_disposable_income.py index 7c8d600c796..21e9ad484c6 100644 --- a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_combined_disposable_income.py +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_combined_disposable_income.py @@ -20,19 +20,22 @@ def formula(tax_unit, period, parameters): p = parameters( period ).gov.states.wa.dor.property_tax_exemption.senior_disabled.income - # RCW 84.36.383(2) requires combining the claimant's, spouse's, and - # each occupying cotenant's disposable income. AGI (and the other - # tax-unit-level sources) already excludes dependents because - # irs_gross_income masks them out at the person level. Non-tax-unit - # cotenants come in through wa_pte_cotenant_disposable_income. - # Person-level income add-backs (pension, military pay, veterans - # benefits) and medical deductions are summed across all tax-unit - # members. The statute (RCW 84.36.383(2) and (7)) restricts these - # to amounts of the claimant and spouse/domestic partner only, but - # we don't filter dependents at the moment. - own_income = add(tax_unit, period, p.sources) + # RCW 84.36.383(2) combines the disposable income of the claimant, + # the spouse or domestic partner, and each cotenant occupying the + # residence. WAC 458-16A-120(2)(b) adds each item left out of AGI to + # the AGI of the person who received it, so a tax unit dependent's + # benefits, pensions, military pay and tax-exempt interest are the + # dependent's own. Person-level sources are summed over the head and + # spouse; AGI and filer_tax_exempt_social_security already describe + # their return. Other cotenants, including a tax unit dependent who + # owns part of the residence, come in through + # wa_pte_cotenant_disposable_income. + own_income = tax_unit_non_dep_add(tax_unit, period, p.sources) cotenant_income = tax_unit("wa_pte_cotenant_disposable_income", period) income = own_income + cotenant_income + # The deductions are amounts the claimant or spouse paid (RCW + # 84.36.383(2)). Expense inputs record whose expense it is, not who + # paid it, so they are summed over every tax unit member. itemized = add(tax_unit, period, p.deductions.sources) # ESSB 6162 (RCW 84.36.383(14)) lets the claimant elect the standard # deduction in place of the itemized medical basket. The per-claimant diff --git a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_cotenant_disposable_income.py b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_cotenant_disposable_income.py index 99261c59857..8e7a63f6d41 100644 --- a/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_cotenant_disposable_income.py +++ b/policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/income/wa_pte_cotenant_disposable_income.py @@ -1,8 +1,9 @@ -# Disposable income of cotenants who occupy the residence but file -# outside this tax unit. Per RCW 84.36.383(2), combined disposable -# income includes each cotenant's disposable income. Default is zero; -# populate when the household has occupying co-owners filing separate -# federal returns. +# Disposable income of cotenants (residents with an ownership interest in +# the residence, RCW 84.36.383(3)) other than the tax unit head and spouse: +# co-owners who file their own federal returns, and a tax unit dependent +# who owns part of the residence. Per RCW 84.36.383(2), combined +# disposable income includes each cotenant's disposable income. Default is +# zero. from policyengine_us.model_api import *