diff --git a/changelog.d/statute-first-federal-income-tax.fixed.md b/changelog.d/statute-first-federal-income-tax.fixed.md new file mode 100644 index 00000000000..cc2887ac6d6 --- /dev/null +++ b/changelog.d/statute-first-federal-income-tax.fixed.md @@ -0,0 +1 @@ +Follow the statute where IRS forms differ: the refundable child tax credit bar applies only to a section 911 exclusion, not the housing deduction alone (with Form 2555 leaf inputs; a positive legacy aggregate still counts as an exclusion); a claimable spouse aged 65 or blind on a 2018-2025 joint return must file with income other than earned income over the section 63(c)(5)(A) amount; estate and trust royalties count as EITC investment income; and through 2020 former section 32(c)(1)(F) denies the EITC to a filer whose qualifying children all lack identification. diff --git a/policyengine_us/parameters/gov/irs/credits/eitc/eligibility/qualifying_child_without_identification_bar.yaml b/policyengine_us/parameters/gov/irs/credits/eitc/eligibility/qualifying_child_without_identification_bar.yaml new file mode 100644 index 00000000000..a39cef744a7 --- /dev/null +++ b/policyengine_us/parameters/gov/irs/credits/eitc/eligibility/qualifying_child_without_identification_bar.yaml @@ -0,0 +1,20 @@ +description: The Internal Revenue Service denies the earned income tax credit to a filer who has qualifying children none of whom meets the identification requirement, when this is true. +values: + # Former 26 U.S.C. 32(c)(1)(F). P.L. 105-206 section 6021(b)(2) added it + # as section 32(c)(1)(G), effective under section 6021(c)(2) as if included + # in section 11111 of the Revenue Reconciliation Act of 1990; P.L. 108-311 + # section 205(b)(1) redesignated it (F). So it applies to every year the + # model computes before 2021. + 0000-01-01: true + # American Rescue Plan Act section 9622 struck subparagraph (F) for + # taxable years beginning after December 31, 2020. + 2021-01-01: false +metadata: + unit: bool + period: year + label: EITC bar on filers whose qualifying children all lack identification + reference: + - title: 26 U.S.C. 32(c)(1)(F) (2015 edition) + href: https://www.govinfo.gov/content/pkg/USCODE-2015-title26/html/USCODE-2015-title26-subtitleA-chap1-subchapA-partIV-subpartC-sec32.htm + - title: Public Law 117-2, section 9622 + href: https://www.congress.gov/117/plaws/publ2/PLAW-117publ2.pdf#page=151 diff --git a/policyengine_us/tests/code_health/test_source_conflicts.py b/policyengine_us/tests/code_health/test_source_conflicts.py index 5cb01c89cf6..690aa04a9ed 100644 --- a/policyengine_us/tests/code_health/test_source_conflicts.py +++ b/policyengine_us/tests/code_health/test_source_conflicts.py @@ -150,6 +150,10 @@ "policyengine_us/parameters/gov/usda/snap/eligibility/waiting_period/subject_immigration_statuses.yaml": 1, "policyengine_us/reforms/states/az/dependent_credit/az_dependent_credit_reform.py": 1, "policyengine_us/reforms/states/mn/walz/mn_walz_hf1938.py": 1, + "policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py": 1, + "policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py": 1, + "policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py": 1, + "policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py": 1, "policyengine_us/variables/gov/local/ca/cc/ga/ca_cc_general_assistance_maximum_grant.py": 1, "policyengine_us/variables/gov/local/ca/cc/ga/eligibility/ca_cc_general_assistance_eligible.py": 1, "policyengine_us/variables/gov/states/ar/ade/oec/sra/rates/ar_sra_daily_copay.py": 1, diff --git a/policyengine_us/tests/core/test_dependent_eitc_investment_income_invariants.py b/policyengine_us/tests/core/test_dependent_eitc_investment_income_invariants.py index 3899de9e039..b5767164c07 100644 --- a/policyengine_us/tests/core/test_dependent_eitc_investment_income_invariants.py +++ b/policyengine_us/tests/core/test_dependent_eitc_investment_income_invariants.py @@ -13,7 +13,11 @@ Worksheet 1 lines 11 and 12 name (Schedule E lines 40, 34a column (d) and 34b column (c)). `passive_estate_income`, the passive subset of `estate_income`, defaults to zero; the draws leave it unset, or set it to all, half or none of -`estate_income`, or to an unrelated signed amount. +`estate_income`, or to an unrelated signed amount. Royalties received through +an estate or trust and not derived in a trade or business +(`estate_royalty_income`, Schedule K-1 (Form 1041) box 5) are their own +basket under 32(i)(2)(C), floored at zero, which Worksheet 1 line 8 leaves out +and the model counts under the statute. Hypothesis draws batches of tax units (single, head of household with dependents, joint with and without dependents), and a seeded population of 200 @@ -32,7 +36,8 @@ interest and dividends, plus their Schedule D gain with capital gain distributions floored at zero (line 7), plus their net rental, farm rental, passive partnership and passive estate and trust income less the signed part - also in earned income, floored at zero (line 13). + also in earned income, floored at zero (line 13), plus the estate and trust + royalty basket floored at zero (section 32(i)(2)(C)). 3. Bounds: it is at least the filers' interest and dividends (drawn nonnegative), so never negative, and at least that plus their capital gains floored at zero, so no passive loss (an estate or trust loss included) @@ -81,6 +86,9 @@ ESTATE = "estate_income" PASSIVE_ESTATE = "passive_estate_income" OVERLAP = "eitc_passive_income_also_in_earned_income" +# Section 32(i)(2)(C) royalties received through an estate or trust: a basket +# of their own, floored at zero. +ROYALTY = "estate_royalty_income" SE_EARNINGS = "partnership_self_employment_net_earnings" # The filer's amounts, which a dependent's income must not change. FILER_OUTPUTS = [ @@ -129,6 +137,7 @@ def investment_amounts(draw, dependent=False): ) ), SE_EARNINGS: draw(signed), + ROYALTY: draw(signed), **draw(estate_amounts()), } @@ -240,6 +249,19 @@ def _seeded_units(n=200): ], } ) + # Royalties come from their own stream, so the draws above stay as they + # were before the royalty basket existed. The stream and the 30% rate + # leave every basket deciding eligibility for some units (the coverage + # assertions in test_seeded_population). + royalty_rng = np.random.default_rng(SEED + 5) + for unit in units: + for amounts in [unit["head"], unit["spouse"], *unit["dependents"]]: + if amounts is not None: + amounts[ROYALTY] = ( + float(round(royalty_rng.uniform(-12_000, 12_000))) + if royalty_rng.random() < 0.3 + else 0.0 + ) return units @@ -355,29 +377,36 @@ def filer_sum(names): ) capital = np.maximum(0, filer_sum(CAPITAL_INPUTS) + distributions) passive = np.maximum(0, filer_sum(PASSIVE_INPUTS) - filer_sum([OVERLAP])) - expected = portfolio + capital + passive + royalties = np.maximum(0, filer_sum([ROYALTY])) + expected = portfolio + capital + passive + royalties # Units whose eligibility turns on farm rent alone, or on the overlap input # alone, so the seeded population shows each term is exercised. eligible = expected <= run["limit"] without_farm_rent = ( portfolio + capital + + royalties + np.maximum( 0, filer_sum([n for n in PASSIVE_INPUTS if n != "farm_rent_income"]) - filer_sum([OVERLAP]), ) ) - without_overlap = portfolio + capital + np.maximum(0, filer_sum(PASSIVE_INPUTS)) + without_overlap = ( + portfolio + capital + royalties + np.maximum(0, filer_sum(PASSIVE_INPUTS)) + ) without_estate = ( portfolio + capital + + royalties + np.maximum( 0, filer_sum([n for n in PASSIVE_INPUTS if n != PASSIVE_ESTATE]) - filer_sum([OVERLAP]), ) ) + without_royalties = portfolio + capital + passive + royalty_decides = eligible != (without_royalties <= run["limit"]) farm_rent_decides = eligible != (without_farm_rent <= run["limit"]) overlap_decides = eligible != (without_overlap <= run["limit"]) estate_decides = eligible != (without_estate <= run["limit"]) @@ -422,11 +451,19 @@ def filer_sum(names): - _by_person(units, OVERLAP), ), ) + + np.maximum(0, _unit_sum(run, _by_person(units, ROYALTY))) ) np.testing.assert_allclose( investment_income[unchanged], all_member[unchanged], atol=TOLERANCE ) - return has_dependent, unchanged, farm_rent_decides, overlap_decides, estate_decides + return ( + has_dependent, + unchanged, + farm_rent_decides, + overlap_decides, + estate_decides, + royalty_decides, + ) # A batch's cost is mostly per-variable overhead, so each example is a large @@ -453,6 +490,7 @@ def test_seeded_population(year): farm_rent_decides, overlap_decides, estate_decides, + royalty_decides, ) = _check(_seeded_units(), year) # The population exercises both branches of each property. assert has_dependent.sum() > 50 @@ -460,3 +498,4 @@ def test_seeded_population(year): assert farm_rent_decides.sum() > 2 assert overlap_decides.sum() > 2 assert estate_decides.sum() > 2 + assert royalty_decides.sum() > 2 diff --git a/policyengine_us/tests/core/test_filing_requirement_dependent_invariants.py b/policyengine_us/tests/core/test_filing_requirement_dependent_invariants.py index 9b895cdd293..3fd639bdc12 100644 --- a/policyengine_us/tests/core/test_filing_requirement_dependent_invariants.py +++ b/policyengine_us/tests/core/test_filing_requirement_dependent_invariants.py @@ -9,8 +9,11 @@ unearned income test. YAML cases pin the published amounts one case at a time; these tests check what must hold for every input, which YAML cannot state. -Where the statute and the IRS charts differ (decision d1395: the age and -blindness addition in the 2018-2025 joint test, a dependent filing +On a 2018-2025 joint return, section 6012(f)(2)(D) tests a claimable +spouse's income other than earned income against the section 63(c)(5)(A) +amount alone, while Table 2 adds the additional standard deduction for age or +blindness; the model follows the statute, and property 10 states it. Where +the statute and the IRS charts differ otherwise (a dependent filing separately, and in 2026 blindness and the exact dollar), the tests below assert nothing that depends on the difference. @@ -29,10 +32,11 @@ 3. For a filer nobody can claim, the result depends on gross income alone: it is the same however that income is split between wages and interest. 4. On a 2025 joint return with no other income, where the spouse who can be - claimed is under 65 and not blind, the result is the unearned income test - (over $1,350), whatever the other spouse's age and blindness. (For a - claimed spouse who is 65 or older or blind, section 6012(f)(2)(D) and - Table 2 differ; that is d1395.) + claimed has only interest, the result is section 6012(f)(2)(D)'s unearned + income test (over $1,350), whatever either spouse's age and blindness. + Table 2 would add $1,600 for each of the claimed spouse's age 65 and + blindness; the grid's amounts between $1,350 and those sums tell the two + apart. `test_filing_requirement_properties` draws batches of tax units with Hypothesis (single, head of household, surviving spouse, separate and joint; @@ -54,11 +58,11 @@ income belongs on the dependent's own return. 9. Table 2 and the Medicaid implementation, as in 1 and 2, on the drawn single filers who can be claimed and have no self-employment income. -10. Lower bound (2025): on a single, separate or joint return, a head or - spouse who can be claimed and whose interest and dividends are over - Table 2's unearned income amount for them always makes the return - required. Table 2's amount is never below the statute's, so this holds - under either reading of d1395. +10. Lower bound (2025): on a single or separate return, a head or spouse + who can be claimed and whose interest and dividends are over Table 2's + unearned income amount for them always makes the return required. On a + joint return the amount is section 6012(f)(2)(D)'s: the section + 63(c)(5)(A) amount, $1,350, with no addition for age or blindness. `test_earned_income_sources_are_gross_income_sources`: @@ -215,16 +219,18 @@ def head_medicaid_requirement(simulation, units, year): def unearned_test_met(units): - """Whether Table 2's unearned income test is met by a head or spouse who - can be claimed, for single, separate and joint returns (2025 amounts).""" + """Whether the unearned income test is met by a head or spouse who can be + claimed (2025 amounts): Table 2's for single and separate returns, and + section 6012(f)(2)(D)'s, with no addition for age or blindness, for joint + returns.""" met = [] for unit in units: - married = unit["filing_status"] in ("SEPARATE", "JOINT") - per_condition = ( - TABLE_2_MARRIED_AGED_OR_BLIND_ADDITION - if married - else TABLE_2_AGED_OR_BLIND_ADDITION - ) + if unit["filing_status"] == "JOINT": + per_condition = 0 + elif unit["filing_status"] == "SEPARATE": + per_condition = TABLE_2_MARRIED_AGED_OR_BLIND_ADDITION + else: + per_condition = TABLE_2_AGED_OR_BLIND_ADDITION met.append( unit["filing_status"] in ("SINGLE", "SEPARATE", "JOINT") and any( @@ -292,8 +298,9 @@ def test_table_2_boundary_grid(): single_filer(age, blind, False, wages, gross - wages) for age, blind, gross, wages in splits ] - # Joint returns whose younger spouse, under 65 and not blind, can be - # claimed and has only interest. + # Joint returns whose spouse can be claimed and has only interest, with + # and without age 65 and blindness: section 6012(f)(2)(D) tests every + # such spouse at the section 63(c)(5)(A) amount alone. joint = [ { "filing_status": "JOINT", @@ -305,8 +312,8 @@ def test_table_2_boundary_grid(): "taxable_interest_income": 0, }, { - "age": 40, - "is_blind": False, + "age": spouse_age, + "is_blind": spouse_blind, "claimed_as_dependent_on_another_return": True, "taxable_interest_income": interest, }, @@ -315,6 +322,8 @@ def test_table_2_boundary_grid(): } for head_age in (45, 70, 80) for head_blind in (False, True) + for spouse_age in (40, 65) + for spouse_blind in (False, True) for interest in UNEARNED_GRID ] units = claimable + unclaimable + joint diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.yaml index 44f9e6f5b7f..b552338a9bc 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.yaml @@ -30,7 +30,12 @@ foreign_earned_income_exclusion: 0 ctc_credit_limit_worksheet_b_applies: false -- name: Housing deduction filer cannot use Worksheet B when worksheet deductions offset the stacking amount. +- name: A filer claiming only the housing deduction is not barred, so Worksheet B applies. + # Section 24(d)(3) bars a taxpayer who "elects to exclude any amount from + # gross income under section 911"; the section 911(c)(4)(A) housing + # deduction is a deduction, not an exclusion. The Schedule 8812 + # instructions would bar every Form 2555 filer; the model follows the + # statute, and Worksheet B reads the statutory bar. period: 2025 input: ctc_qualifying_children: 2 @@ -38,7 +43,8 @@ foreign_earned_income_exclusion_disallowed_deductions: 500 output: foreign_earned_income_exclusion: 0 - ctc_credit_limit_worksheet_b_applies: false + refundable_ctc_barred_by_section_911_exclusion: false + ctc_credit_limit_worksheet_b_applies: true - name: Does not apply in 2021, when the CTC was fully refundable. period: 2021 diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc.yaml index 4b6ca135f18..90d903f4452 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc.yaml @@ -206,3 +206,44 @@ section_911_excluded_income: 0 # Without the section 911 bar, the same phase-in gives a $3,400 refund. refundable_ctc: 0 + +- name: A filer claiming only the foreign housing deduction gets the refundable credit + # Section 24(d)(3) bars only an election to exclude an amount under section + # 911; the section 911(c)(4)(A) housing deduction is not an exclusion. + # Phase-in: 15% x ($12,500 - $2,500) = $1,500, below the $1,700 refundable + # maximum and the $2,200 credit, with no tax to absorb the credit. + period: 2025 + input: + foreign_earned_income_exclusion_amount: 0 + foreign_housing_exclusion: 0 + foreign_housing_deduction: 1_000 + ctc: 2_200 + ctc_refundable_maximum: 1_700 + ctc_phase_in: 1_500 + ctc_limiting_tax_liability: 0 + output: + refundable_ctc: 1_500 + +- name: A filer claiming only the housing deduction completes Worksheet B with a residential clean energy credit + # Not barred by section 24(d)(3), so Credit Limit Worksheet B applies and + # the residential clean energy credit uses the liability first. + # Worksheet A line 5: max(0, 2,000 - 1,500) = 500. + # Increase in the credit: min(4,400, 500 + 3,000) - min(4,400, 500) = 3,000. + # Refundable: min(3,400 maximum, 3,000) = 3,000. Under the Schedule 8812 + # instructions, which bar every Form 2555 filer, it would be 0. + period: 2025 + input: + foreign_earned_income_exclusion_amount: 0 + foreign_housing_exclusion: 0 + foreign_housing_deduction: 1_000 + ctc_qualifying_children: 2 + ctc: 4_400 + ctc_refundable_maximum: 3_400 + ctc_phase_in: 3_000 + ctc_tax_liability_after_preceding_credits: 2_000 + residential_clean_energy_credit: 1_500 + output: + refundable_ctc_barred_by_section_911_exclusion: false + ctc_credit_limit_worksheet_b_applies: true + ctc_limiting_tax_liability: 500 + refundable_ctc: 3_000 diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.yaml index 4a1f10bf6fa..8f172b3ac4d 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.yaml @@ -92,3 +92,45 @@ output: foreign_earned_income_exclusion: 0 refundable_ctc_barred_by_section_911_exclusion: true + +# Section 911(c)(4)(A) treats the housing amount of a filer without +# employer-provided housing as "a deduction allowable in computing adjusted +# gross income". A filer who claims only that deduction (Form 2555 line 50) +# excludes nothing, so section 24(d)(3) does not bar the refundable credit, +# although the Schedule 8812 instructions bar every Form 2555 filer. The model +# follows the statute. +- name: A housing deduction alone does not bar the refundable credit + period: 2025 + input: + foreign_earned_income_exclusion_amount: 0 + foreign_housing_exclusion: 0 + foreign_housing_deduction: 1_000 + output: + refundable_ctc_barred_by_section_911_exclusion: false + +- name: A housing deduction alone did not bar the credit in 2015 either + period: 2015 + input: + foreign_earned_income_exclusion_amount: 0 + foreign_housing_exclusion: 0 + foreign_housing_deduction: 1_000 + output: + refundable_ctc_barred_by_section_911_exclusion: false + +- name: A housing exclusion with a housing deduction is still barred + period: 2025 + input: + foreign_earned_income_exclusion_amount: 0 + foreign_housing_exclusion: 2_000 + foreign_housing_deduction: 1_000 + output: + refundable_ctc_barred_by_section_911_exclusion: true + +# The legacy aggregates include the housing deduction, so without Form 2555 +# leaves a positive aggregate is treated as an exclusion. +- name: A positive legacy aggregate is still treated as an exclusion + period: 2025 + input: + foreign_earned_income_exclusion: 1_000 + output: + refundable_ctc_barred_by_section_911_exclusion: true diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_eligible.yaml index b8de8659af6..22e8f12508f 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_eligible.yaml @@ -134,3 +134,107 @@ output: foreign_earned_income_exclusion: 0 eitc_eligible: false + +# Former 26 U.S.C. 32(c)(1)(F), through 2020: "No credit shall be allowed +# under this section to any eligible individual who has one or more qualifying +# children if no qualifying child of such individual is taken into account +# under subsection (b) by reason of paragraph (3)(D)." The 2018-2020 Form 1040 +# instructions send such a filer to the credit without a qualifying child; the +# model follows the statute. ARPA section 9622 struck the bar from 2021. +- name: 2020 filer whose only qualifying child lacks an SSN gets no EITC + period: 2020 + input: + people: + head: + age: 30 + employment_income: 6_000 + ssn_card_type: CITIZEN + child: + age: 5 + ssn_card_type: NONE + tax_units: + tax_unit: + members: [head, child] + tax_unit_is_filer: true + households: + household: + members: [head, child] + state_code: TX + output: + eitc_child_count: 0 + eitc_eligible: false + # The instructions' route would give the childless credit: + # min(7.65% x $6,000, $538) = $459. + eitc: 0 + +- name: 2021 the same filer can claim the credit without a qualifying child + period: 2021 + input: + people: + head: + age: 30 + employment_income: 6_000 + ssn_card_type: CITIZEN + child: + age: 5 + ssn_card_type: NONE + tax_units: + tax_unit: + members: [head, child] + tax_unit_is_filer: true + households: + household: + members: [head, child] + state_code: TX + output: + eitc_child_count: 0 + eitc_eligible: true + +- name: 2020 filer with one child with an SSN and one without keeps the credit + period: 2020 + input: + people: + head: + age: 30 + employment_income: 6_000 + ssn_card_type: CITIZEN + child1: + age: 5 + ssn_card_type: CITIZEN + child2: + age: 3 + ssn_card_type: NONE + tax_units: + tax_unit: + members: [head, child1, child2] + households: + household: + members: [head, child1, child2] + state_code: TX + output: + eitc_child_count: 1 + eitc_eligible: true + +- name: 2020 filer with no qualifying child at all keeps the childless credit + # Control for former section 32(c)(1)(F): the bar needs at least one + # qualifying child, so a genuinely childless filer is unaffected. + # min(7.65% x $6,000, $538) = $459. + period: 2020 + input: + people: + head: + age: 30 + employment_income: 6_000 + ssn_card_type: CITIZEN + tax_units: + tax_unit: + members: [head] + tax_unit_is_filer: true + households: + household: + members: [head] + state_code: TX + output: + eitc_child_count: 0 + eitc_eligible: true + eitc: 459 diff --git a/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_investment_income_estate_trust.yaml b/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_investment_income_estate_trust.yaml index 8f667559a0c..627bf39d5f7 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_investment_income_estate_trust.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/credits/earned_income/eitc_investment_income_estate_trust.yaml @@ -358,3 +358,150 @@ adjusted_gross_income: 31_601 # 4,213 - 15.98% x (31,601 - 22,720) = 4,213 - 1,419.1838. eitc: 2_793.8162 + +# Royalties received through an estate or trust. Section 32(i)(2)(C) counts +# "gross income from rents or royalties not derived in the ordinary course of +# a trade or business" over the deductions and interest allocable to it, and +# section 662(b) keeps the trust's character for the beneficiary. A +# beneficiary reports these Schedule K-1 (Form 1041) box 5 royalties in +# Schedule E Part III column (f). Publication 596 (2025) Worksheet 1 line 8 +# takes royalties only from Schedule E line 23b, so it leaves them out; the +# model follows the statute. The 2025 limit is 11,950 (Rev. Proc. 2024-40, +# section 2.06(2)). + +- name: Trust royalties alone exceed the 2025 investment income limit + period: 2025 + absolute_error_margin: 0.01 + input: + age: 30 + estate_income: 12_000 + estate_royalty_income: 12_000 + output: + eitc_relevant_investment_income: 12_000 + eitc_investment_income_eligible: false + # Worksheet 1 would count none of it, so the test would pass. + +- name: Trust royalties at the 2025 limit pass + period: 2025 + absolute_error_margin: 0.01 + input: + age: 30 + taxable_interest_income: 950 + estate_income: 11_000 + estate_royalty_income: 11_000 + output: + eitc_relevant_investment_income: 11_950 + eitc_investment_income_eligible: true + +- name: A net royalty loss floors its basket at zero and never offsets interest + period: 2025 + absolute_error_margin: 0.01 + input: + age: 30 + taxable_interest_income: 11_950 + estate_income: -2_000 + estate_royalty_income: -2_000 + output: + eitc_relevant_investment_income: 11_950 + eitc_investment_income_eligible: true + +- name: Royalties and passive estate income are separate baskets + period: 2025 + absolute_error_margin: 0.01 + input: + age: 30 + estate_income: 1_000 + estate_royalty_income: 3_000 + passive_estate_income: -2_000 + output: + # max(0, 3,000) royalties + max(0, -2,000) passive: the passive loss + # cannot reduce the royalty basket. + eitc_relevant_investment_income: 3_000 + +- name: Trust royalties end the credit for an otherwise eligible couple with one child + period: 2025 + absolute_error_margin: 1 + input: + people: + head: + age: 35 + employment_income: 15_000 + estate_income: 12_000 + estate_royalty_income: 12_000 + spouse: + age: 35 + child: + age: 5 + tax_units: + tax_unit: + members: [head, spouse, child] + households: + household: + members: [head, spouse, child] + state_code: TX + output: + # AGI is below the 2025 joint phase-out start of 30,470, so with + # estate_royalty_income of zero the model gives the one-child maximum, + # 4,328. + eitc_relevant_investment_income: 12_000 + eitc: 0 + +# Where rental real estate goes. Section 32(i)(2)(C) counts rents and +# royalties "not derived in the ordinary course of a trade or business", and +# (E) counts passive activity income. The statute does not say whether +# rental real estate is a (C) rent or an (E) passive activity, so the model +# takes the IRS's reading: Publication 596 Worksheet 1 lines 8-10 (the (C) +# basket) take Schedule E line 23b royalties and Schedule 1 line 8l personal +# property rents, while lines 11-12 (the (E) basket) take Schedule E line 26 +# rental real estate, which section 469(c)(2) treats as passive. Trust +# royalties stay in the (C) basket under sections 652(b) and 662(b). So a +# rental real estate loss offsets other passive income, not trust royalties. + +- name: A rental real estate loss does not offset trust royalties, so the couple loses the credit + # If the rental were a (C) rent, the basket would net to 12,000 - 5,000 = + # 7,000, under the 11,950 limit, and the couple would keep the one-child + # maximum of 4,328 (AGI 15,000 + 12,000 - 5,000 = 22,000 is below the 2025 + # joint phase-out start of 30,470). + period: 2025 + absolute_error_margin: 1 + input: + people: + head: + age: 35 + employment_income: 15_000 + estate_income: 12_000 + estate_royalty_income: 12_000 + rental_income: -5_000 + spouse: + age: 35 + child: + age: 5 + tax_units: + tax_unit: + members: [head, spouse, child] + households: + household: + members: [head, spouse, child] + state_code: TX + output: + # max(0, 12,000) royalties + max(0, -5,000) passive = 12,000 > 11,950. + eitc_relevant_investment_income: 12_000 + eitc_investment_income_eligible: false + eitc_eligible: false + eitc: 0 + +- name: A rental real estate loss with interest and trust royalties stays in the passive basket + period: 2025 + absolute_error_margin: 0.01 + input: + age: 30 + taxable_interest_income: 9_000 + estate_income: 3_000 + estate_royalty_income: 3_000 + rental_income: -2_000 + output: + # 9,000 interest + max(0, 3,000) royalties + max(0, -2,000) passive = + # 12,000 > 11,950. Netting the rental against the royalties as a (C) rent + # would give 9,000 + 1,000 = 10,000. + eitc_relevant_investment_income: 12_000 + eitc_investment_income_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/irs/tax_unit_is_required_to_file_dependents.yaml b/policyengine_us/tests/policy/baseline/gov/irs/tax_unit_is_required_to_file_dependents.yaml index f7ba92e3c6d..b557341e25a 100644 --- a/policyengine_us/tests/policy/baseline/gov/irs/tax_unit_is_required_to_file_dependents.yaml +++ b/policyengine_us/tests/policy/baseline/gov/irs/tax_unit_is_required_to_file_dependents.yaml @@ -5,10 +5,13 @@ # Chart B of the Form 1040 instructions (Tables 1 and 2 of Publication 501). # Section 6012(f) governs 2018 to 2025 and section 6012(a)(1) governs 2026. # For an unmarried filer who can be claimed, section 6012(f)(1) gives Chart -# B's result. Where the statute and the charts differ (decision d1395: the -# age and blindness addition in the 2018-2025 joint test, a dependent filing -# separately, and in 2026 blindness and the exact dollar), the cases stay -# clear of the difference. +# B's result. On a 2018-2025 joint return the statute and Chart B differ on +# the unearned income test of a claimable spouse aged 65 or blind: section +# 6012(f)(2)(D) names the section 63(c)(5)(A) amount alone, Chart B adds the +# additional standard deduction, and the model follows the statute (cases +# below). Where they differ otherwise (a dependent filing separately, and in +# 2026 blindness and the exact dollar), the cases stay clear of the +# difference. # 2025 amounts (Chart B, page 10 of # https://www.irs.gov/pub/irs-prior/i1040gi--2025.pdf): # Single dependents, under 65 and not blind, must file if @@ -19,8 +22,9 @@ # 65 or older or blind: $3,350, $17,750, and the larger of $3,350 or earned # income (up to $15,300) plus $2,450. 65 or older and blind: $5,350, # $19,750, and the larger of $5,350 or earned income plus $4,450. -# Married dependents, 65 or older or blind: unearned income over $2,950 -# (section 6012(f)(2)(D): over $1,350, with no addition). +# Married dependents, 65 or older or blind: Chart B says unearned income +# over $2,950; section 6012(f)(2)(D), which the model follows, says over +# $1,350, with no addition. # Filers nobody can claim: gross income only. The cases stay a dollar away # from the threshold itself, where Chart A ("at least") and section 6012(f)(1) @@ -402,7 +406,8 @@ - name: 2025, joint return whose spouse aged 65 can be claimed, unearned income over $2,950 # Required under both readings: over $1,350 + $1,600 (Chart B) and over - # $1,350 (section 6012(f)(2)(D)). At $2,950 or less they differ (d1395). + # $1,350 (section 6012(f)(2)(D)). At $2,950 or less they differ; the next + # case follows the statute. period: 2025 input: people: @@ -422,6 +427,127 @@ output: tax_unit_is_required_to_file: true +- name: 2025, joint return whose claimable spouse is aged 65 must file with $2,000 of interest + # Section 6012(f)(2)(D) excuses a joint return only if neither spouse is an + # individual described in section 63(c)(5) "who has income (other than + # earned income) in excess of the amount in effect under section + # 63(c)(5)(A)": $1,350 for 2025, with no addition for age or blindness. + # $2,000 is over $1,350, so a return is required. Chart B would add $1,600 + # (over $2,950) and excuse it. Gross income of $2,000 is under the joint + # standard deduction, so only this test makes the return required. + period: 2025 + input: + people: + head: + age: 40 + spouse: + age: 65 + claimed_as_dependent_on_another_return: true + taxable_interest_income: 2_000 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: TX + output: + tax_unit_is_required_to_file: true + +- name: 2025, a blind claimable spouse is tested at $1,350 too + period: 2025 + input: + people: + head: + age: 40 + spouse: + age: 30 + is_blind: true + claimed_as_dependent_on_another_return: true + taxable_interest_income: 1_351 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: TX + output: + # Over $1,350 by a dollar; Chart B would require over $2,950. + tax_unit_is_required_to_file: true + +- name: 2025, a claimable spouse aged 65 and blind must file with $2,000 of interest + # Section 6012(f)(2)(D) tests the claimable spouse's income other than + # earned income against the section 63(c)(5)(A) amount alone, $1,350 for + # 2025, with nothing added for age or blindness. $2,000 is over $1,350, so a + # return is required. Chart B would add two additional amounts (over + # $4,550) and excuse it. Gross income of $2,000 is under the joint standard + # deduction, so only this test makes the return required. + period: 2025 + input: + people: + head: + age: 40 + spouse: + age: 65 + is_blind: true + claimed_as_dependent_on_another_return: true + taxable_interest_income: 2_000 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: TX + output: + tax_unit_is_required_to_file: true + +- name: 2025, a claimable spouse aged 65 with $1,350 of interest need not file + period: 2025 + input: + people: + head: + age: 40 + spouse: + age: 65 + claimed_as_dependent_on_another_return: true + taxable_interest_income: 1_350 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: TX + output: + # "In excess of" $1,350: equal is not over. + tax_unit_is_required_to_file: false + +- name: 2026, section 6012(a)(1)(C)(i)(I) adds the additional standard deduction + # From 2026 the test is income other than earned income "in excess of the + # sum of the amount in effect under section 63(c)(5)(A) plus the additional + # standard deduction (if any) to which the individual is entitled", so the + # same $2,000 of interest does not require a return for the aged spouse. + period: 2026 + input: + people: + head: + age: 40 + spouse: + age: 65 + claimed_as_dependent_on_another_return: true + taxable_interest_income: 2_000 + tax_units: + tax_unit: + members: [head, spouse] + households: + household: + members: [head, spouse] + state_code: TX + output: + tax_unit_is_required_to_file: false + - name: 2025, a claimed spouse's farm profit is earned income, not unearned income # Farm income (Schedule 1 line 6) is earned income on the IRS dependent # worksheet, so the unearned income test does not apply to it. Gross income diff --git a/policyengine_us/tools/section_911.py b/policyengine_us/tools/section_911.py index 9a6b1f26f9a..9ecca435b7b 100644 --- a/policyengine_us/tools/section_911.py +++ b/policyengine_us/tools/section_911.py @@ -63,28 +63,21 @@ def elects_section_911_exclusion(tax_unit, period): exclusion elections, so housing-only filers also elect section 911. Positive Form 2555 amounts identify the election even when deductions or an explicit aggregate override reduce the federal stacking amount to zero. - Schedule 8812 (Line 13 and Part II-A) and Publication 596 (Rule 5) bar - Form 2555 filers from Worksheet B, refundable CTC, and EITC. - - A filer who claims only the section 911(c)(4) housing deduction (Form - 2555 line 50) is also barred. That case rests on the IRS instructions, - not on the statute. Section 24(d)(3) applies to a taxpayer who "elects - to exclude any amount from gross income under section 911", and section - 911(c)(4)(A) treats the housing amount as "a deduction allowable in - computing adjusted gross income", not an exclusion. The Schedule 8812 - instructions bar every Form 2555 filer: Part II-A says "If you file Form - 2555, you cannot claim the additional child tax credit", and Credit - Limit Worksheet B applies only if "You are not filing Form 2555". - Publication 596 Rule 5 denies the EITC to anyone who files Form 2555 "to - deduct or exclude a foreign housing amount"; section 32(c)(1)(C) excludes - an individual who "claims the benefits of section 911". + + This is the broad test: whether the filer claims the benefits of section + 911 at all, including a filer who claims only the section 911(c)(4) + housing deduction (Form 2555 line 50). Section 32(c)(1)(C) ("claims the + benefits of section 911") bars such a filer from the EITC, as Publication + 596 Rule 5 says ("to deduct or exclude a foreign housing amount"). The + EITC, the state EITC helpers, the New Jersey childless EITC and the + filing propensity in tax_unit_is_filer read it. The refundable child tax + credit and Credit Limit Worksheet B use the narrower section 24(d)(3) + test in `excludes_amount_under_section_911`. References: https://www.law.cornell.edu/uscode/text/26/911#a https://www.law.cornell.edu/uscode/text/26/911#c_4 - https://www.law.cornell.edu/uscode/text/26/24#d_3 https://www.law.cornell.edu/uscode/text/26/32#c_1_C - https://www.irs.gov/instructions/i1040s8 https://www.irs.gov/publications/p596 """ return np.logical_or.reduce( @@ -99,6 +92,42 @@ def elects_section_911_exclusion(tax_unit, period): ) +def excludes_amount_under_section_911(tax_unit, period): + """Whether the filer elects to exclude an amount under section 911(a). + + Section 24(d)(3) denies the refundable child tax credit to a taxpayer who + "elects to exclude any amount from gross income under section 911". + Section 911(c)(4)(A) treats the housing amount of a filer without + employer-provided housing as "a deduction allowable in computing adjusted + gross income", not an exclusion, so claiming only that deduction (Form + 2555 line 50) does not trigger the bar. The Schedule 8812 instructions + bar every Form 2555 filer ("If you file Form 2555, you cannot claim the + additional child tax credit"); the model follows the statute. + + With Form 2555 leaf inputs, the exclusions are the line 42 foreign earned + income exclusion and the line 36 housing exclusion, tested before the + line 44 allocable deductions so that deductions offsetting the stacking + amount cannot hide an exclusion. The legacy aggregates + (foreign_earned_income_exclusion and section_911_excluded_income) include + the housing deduction, so they cannot tell a deduction-only filer apart; + a positive aggregate is treated as an exclusion. Supply the leaves to + model a filer who claims only the deduction. + + References: + https://www.law.cornell.edu/uscode/text/26/24#d_3 + https://www.law.cornell.edu/uscode/text/26/911#a + https://www.law.cornell.edu/uscode/text/26/911#c_4 + https://www.irs.gov/pub/irs-prior/f2555--2025.pdf#page=3 + """ + if has_section_911_leaf_inputs(tax_unit, period): + return (tax_unit("foreign_earned_income_exclusion_amount", period) > 0) | ( + tax_unit("foreign_housing_exclusion", period) > 0 + ) + return (tax_unit("foreign_earned_income_exclusion", period) > 0) | ( + tax_unit("section_911_excluded_income", period) > 0 + ) + + def validate_section_911_batch_inputs(situation, default_period): """Reject ambiguous JSON batches before Core fills omitted inputs with zeros. diff --git a/policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py b/policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py index 533956cea34..f5a971dd8cd 100644 --- a/policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py +++ b/policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py @@ -31,7 +31,10 @@ def formula(tax_unit, period, parameters): # whose CTC was not fully refundable. return np.zeros(tax_unit.count, dtype=bool) has_qualifying_child = tax_unit("ctc_qualifying_children", period) > 0 - # Form 2555 filers skip Worksheet B in the years section 24(d)(3) - # denies them the refundable CTC (from 2015). + # Filers barred by section 24(d)(3) skip Worksheet B in the years the + # bar is in force (from 2015). A filer who claims only the section + # 911(c)(4) housing deduction is not barred, so completes Worksheet B. + # The instructions' condition "You are not filing Form 2555" + # conflicts with the statute here; the model follows the statute. barred = tax_unit("refundable_ctc_barred_by_section_911_exclusion", period) return has_qualifying_child & ~barred diff --git a/policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py b/policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py index ea457d74439..74b8549b8b3 100644 --- a/policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py +++ b/policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py @@ -1,5 +1,5 @@ from policyengine_us.model_api import * -from policyengine_us.tools.section_911 import elects_section_911_exclusion +from policyengine_us.tools.section_911 import excludes_amount_under_section_911 class refundable_ctc_barred_by_section_911_exclusion(Variable): @@ -10,26 +10,40 @@ class refundable_ctc_barred_by_section_911_exclusion(Variable): "Whether section 24(d)(3) denies the refundable Child Tax Credit " "because the filer elects to exclude foreign earned income or housing " "amounts from gross income under section 911 (Form 2555). These " - "filers also skip Schedule 8812 Credit Limit Worksheet B." + "filers also skip Schedule 8812 Credit Limit Worksheet B. Claiming " + "only the section 911(c)(4) housing deduction is not an exclusion and " + "does not bar the credit, although the Schedule 8812 instructions bar " + "every Form 2555 filer; the model follows the statute. In 2021 the " + "bar is off for every filer: ARPA's section 24(i)(1) switched off " + "subsection (d) only for a filer whose principal place of abode was " + "in the United States for more than half the year, or a bona fide " + "resident of Puerto Rico, and the model has no input for that test, " + "so it applies the exemption to everyone. Most section 911 claimants, " + "who need a foreign tax home, cannot meet it, so the model can " + "overstate their 2021 refundable credit." ) definition_period = YEAR reference = ( "https://www.law.cornell.edu/uscode/text/26/24#d_3", # 2025 Instructions for Schedule 8812, Part II-A. "https://www.irs.gov/pub/irs-prior/i1040s8--2025.pdf#page=3", + # Section 911(c)(4)(A): the housing deduction is a deduction, not an + # exclusion. + "https://www.law.cornell.edu/uscode/text/26/911#c_4", # 2021 Schedule 8812: Part I-B has no Form 2555 condition. "https://www.irs.gov/pub/irs-prior/f1040s8--2021.pdf#page=1", ) def formula(tax_unit, period, parameters): p = parameters(period).gov.irs.credits.ctc.refundable - claims_section_911 = elects_section_911_exclusion(tax_unit, period) - # Section 24(i)(1)(A) (2021) switched off all of subsection (d), - # including this bar, for filers whose principal place of abode was in - # the United States for more than half the year and for bona fide - # residents of Puerto Rico. The model assumes every filer meets that - # test in a fully refundable year. + excludes_section_911 = excludes_amount_under_section_911(tax_unit, period) + # Former section 24(i)(1)(A) (2021, added by ARPA section 9611) + # switched off all of subsection (d), including this bar, for filers + # whose principal place of abode was in the United States for more + # than half the year and for bona fide residents of Puerto Rico. The + # model assumes every filer meets that test in a fully refundable + # year, although most section 911 claimants cannot. bar_in_force = ( p.foreign_earned_income_exclusion_bar_applies and not p.fully_refundable ) - return claims_section_911 & bar_in_force + return excludes_section_911 & bar_in_force diff --git a/policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py b/policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py index 6399554581b..df9f96a393e 100644 --- a/policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py +++ b/policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py @@ -31,12 +31,39 @@ class eitc_relevant_investment_income(Variable): "defaults to zero; nonpassive estate and trust income (Schedule E " "Part III columns (e) and (f), such as Schedule K-1 (Form 1041) box 5 " "annuities and income in respect of a decedent) is not on lines 11 " - "and 12." + "and 12. Box 5 royalties not derived in the ordinary course of a trade " + "or business (estate_royalty_income) go in the 26 USC 32(i)(2)(C) " + "basket, net of their allocable deductions and floored at zero, " + "because sections 652(b) and 662(b) keep their character as " + "royalties. Worksheet 1 line 8 takes royalties only from Schedule E " + "line 23b, so it leaves these out; here the model follows the " + "statute. Section 32(i)(2)(C) also counts rents not derived in the " + "ordinary course of a trade or business, and the statute does not say " + "whether rental real estate belongs there or, as a passive activity, " + "in 32(i)(2)(E). The model follows the IRS's reading in Worksheet 1 " + "(lines 8-13): the (C) basket on lines 8-10 takes Schedule E line 23b " + "royalties and the personal property rents on Schedule 1 line 8l, " + "and the (E) basket on lines 11-12 takes the rental real estate on " + "Schedule E line 26, which section 469(c)(2) treats as a passive " + "activity. The model reads rental_income as that Schedule E rental " + "real estate, so it is in the passive basket: a rental real estate " + "loss offsets other passive income but not estate and trust " + "royalties. The model has no input for personal property rents, " + "which belong in the (C) basket, or for rental real estate that is " + "not a passive activity (marked NPA on Worksheet 1), which is not " + "investment income at all. The model has no input for royalties " + "received directly (Schedule E Part I), so the (C) basket holds only " + "estate and trust royalties." ) unit = USD definition_period = YEAR reference = ( "https://www.law.cornell.edu/uscode/text/26/32#i_2", + "https://www.law.cornell.edu/uscode/text/26/652#b", + "https://www.law.cornell.edu/uscode/text/26/662#b", + # Rental activity is a passive activity. + "https://www.law.cornell.edu/uscode/text/26/469#c_2", + # Publication 596 (2025) Worksheet 1, lines 8-13. "https://www.irs.gov/pub/irs-prior/p596--2025.pdf#page=7", "https://www.irs.gov/pub/irs-prior/f8814--2025.pdf#page=1", "https://www.irs.gov/pub/irs-prior/i8814--2025.pdf#page=4", @@ -114,4 +141,27 @@ def formula(tax_unit, period, parameters): ) - tax_unit_non_dep_add( tax_unit, period, ["eitc_passive_income_also_in_earned_income"] ) - return portfolio_income + max_(0, capital_gains) + max_(0, passive_income) + # Section 32(i)(2)(C): rents and royalties not derived in the ordinary + # course of a trade or business, net of their allocable deductions. + # A beneficiary's box 5 royalties keep that character (sections + # 652(b) and 662(b)) and are nonpassive, so they go here and not in + # the passive basket. Worksheet 1 line 8 conflicts with the statute + # by taking royalties only from Schedule E line 23b; the model follows + # the statute. Rents: the statute does not settle whether rental real + # estate is a (C) rent or an (E) passive activity, so the model takes + # the IRS's reading. Worksheet 1 puts personal property rents + # (Schedule 1 line 8l) on lines 8-10 with royalties, and Schedule E + # line 26 rental real estate on the passive lines 11-12 (section + # 469(c)(2)). rental_income is that rental real estate and stays in + # the passive basket above. The model has no input for personal + # property rents or for nonpassive (NPA) rental real estate, which + # Worksheet 1 leaves out, or for royalties received directly. + nonbusiness_royalties = tax_unit_non_dep_add( + tax_unit, period, ["estate_royalty_income"] + ) + return ( + portfolio_income + + max_(0, capital_gains) + + max_(0, nonbusiness_royalties) + + max_(0, passive_income) + ) diff --git a/policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py b/policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py index f4be2784cbf..e01f084154b 100644 --- a/policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py +++ b/policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py @@ -11,6 +11,8 @@ class eitc_eligible(Variable): "https://www.law.cornell.edu/uscode/text/26/32#c_1_A", # No EITC for an individual who claims the benefits of section 911. "https://www.law.cornell.edu/uscode/text/26/32#c_1_C", + # Former section 32(c)(1)(F), struck from 2021. + "https://www.govinfo.gov/content/pkg/USCODE-2015-title26/html/USCODE-2015-title26-subtitleA-chap1-subchapA-partIV-subpartC-sec32.htm", ) def formula(tax_unit, period, parameters): @@ -31,6 +33,21 @@ def formula(tax_unit, period, parameters): & filers_has_ssn & ~claims_section_911 ) + # Former section 32(c)(1)(F), through 2020: "No credit shall be + # allowed under this section to any eligible individual who has one or + # more qualifying children if no qualifying child of such individual + # is taken into account under subsection (b) by reason of paragraph + # (3)(D)", the identification requirement. The 2018-2020 Form 1040 + # instructions conflict with this: EIC Step 3 sends such a filer to + # the credit without a qualifying child. The model follows the + # statute. + if eitc.eligibility.qualifying_child_without_identification_bar: + person = tax_unit.members + has_qualifying_child = tax_unit.any( + person("is_eitc_qualifying_child", period) + ) + no_child_counted = tax_unit("eitc_child_count", period) == 0 + eligible = eligible & ~(has_qualifying_child & no_child_counted) # This parameter is true if separate filers are eligible. if eitc.eligibility.separate_filer: return eligible diff --git a/policyengine_us/variables/gov/irs/tax_unit_is_filer.py b/policyengine_us/variables/gov/irs/tax_unit_is_filer.py index d67b3372a6b..914c7002bd6 100644 --- a/policyengine_us/variables/gov/irs/tax_unit_is_filer.py +++ b/policyengine_us/variables/gov/irs/tax_unit_is_filer.py @@ -50,9 +50,11 @@ def formula(tax_unit, period, parameters): files_voluntarily = tax_unit("would_file_taxes_voluntarily", period) # A section 911 exclusion is claimed on Form 2555 attached to a - # return (Treas. Reg. 1.911-7(a)(1) and 1.6012-1(a)(3)). Sections - # 24(d)(3) and 32(c)(1)(C) deny the claimant the refundable credits, - # so those credits cannot be its reason to file. A claimant under the + # return (Treas. Reg. 1.911-7(a)(1) and 1.6012-1(a)(3)). Section + # 32(c)(1)(C) denies every claimant the EITC, and section 24(d)(3) + # denies the refundable CTC to one who elects an exclusion (not one + # who claims only the housing deduction); eligible_for_refundable_credits + # handles which credit can be a reason to file. A claimant under the # filing threshold need not file in a later year of a continuing # election, so the propensity to file for a tax benefit decides. claims_section_911 = elects_section_911_exclusion(tax_unit, period) diff --git a/policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py b/policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py index d63cc80d891..a50add6845e 100644 --- a/policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py +++ b/policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py @@ -123,10 +123,17 @@ def formula(tax_unit, period, parameters): # amount plus their own additional standard deduction for age or # blindness: section 6012(a)(1)(C)(i)(I) and Publication 501, Table 2. # On a joint return the test applies to each spouse who can be claimed. - # Section 6012(f)(2)(D), which governs joint returns for 2018 to 2025, - # names the section 63(c)(5)(A) amount alone; Table 2 adds the - # additional standard deduction, and this follows Table 2 (open as - # decision d1395). Nobody else has an unearned income test. + # For 2018 to 2025, section 6012(f)(2)(D) sets the joint return test + # at "the amount in effect under section 63(c)(5)(A)" alone, with no + # addition for age or blindness, so a claimable spouse aged 65 or + # blind must file with more than that amount of income other than + # earned income. Chart B conflicts with the statute: it adds the + # additional standard deduction ($2,950 rather than $1,350 for 2025). + # The model follows the statute. + # For an unmarried filer, section 6012(f)(1) has no separate unearned + # income test, and Table 2's test with the addition is already implied + # by the gross income test against the limited standard deduction. + # Nobody else has an unearned income test. # # Table 2's other two tests need no code here. The standard deduction # in the threshold above is already the limited one for these filers @@ -168,8 +175,14 @@ def formula(tax_unit, period, parameters): additional_standard_deduction = aged_or_blind_count * tax_unit.project( p_standard.aged_or_blind.amount[filing_status] ) - unearned_income_threshold = ( - p_standard.dependent.amount + additional_standard_deduction + joint = filing_status == filing_status.possible_values.JOINT + statutory_joint_test = ( + joint & p.income.filing_requirement.standard_deduction_rule.applies + ) + unearned_income_threshold = p_standard.dependent.amount + where( + tax_unit.project(statutory_joint_test), + 0, + additional_standard_deduction, ) unearned_income_over_threshold = tax_unit.any( can_be_claimed & (unearned_income > unearned_income_threshold) diff --git a/policyengine_us/variables/household/income/person/estate/estate_royalty_income.py b/policyengine_us/variables/household/income/person/estate/estate_royalty_income.py new file mode 100644 index 00000000000..888844167c3 --- /dev/null +++ b/policyengine_us/variables/household/income/person/estate/estate_royalty_income.py @@ -0,0 +1,35 @@ +from policyengine_us.model_api import * + + +class estate_royalty_income(Variable): + value_type = float + entity = Person + label = "Estate and trust royalties" + unit = USD + documentation = ( + "Royalties included in estate_income that are not derived in the " + "ordinary course of a trade or business, net of the deductions and " + "interest clearly and directly allocable to them: Schedule K-1 (Form " + "1041) box 5 royalties, reported in Schedule E Part III column (f). " + "Sections 652(b) and 662(b) give a beneficiary's share of trust income " + "the character it had in the trust, so 26 USC 32(i)(2)(C) counts these " + "royalties as disqualified income for the EITC. Publication 596 " + "Worksheet 1 line 8 takes royalties only from Schedule E line 23b " + "(Part I) and so leaves them out; the model follows the statute. " + "Enter income as a positive amount and a net loss as a negative " + "amount. The default is zero. This classifies income already counted " + "in estate_income and does not represent additional income; box 5 " + "also holds annuities and income in respect of a decedent, which are " + "not royalties and are not included here. The input is not checked " + "against estate_income or passive_estate_income." + ) + definition_period = YEAR + default_value = 0 + reference = ( + "https://www.law.cornell.edu/uscode/text/26/32#i_2_C", + "https://www.law.cornell.edu/uscode/text/26/652#b", + "https://www.law.cornell.edu/uscode/text/26/662#b", + "https://www.irs.gov/pub/irs-prior/p596--2025.pdf#page=7", + "https://www.irs.gov/pub/irs-prior/f1041sk1--2025.pdf#page=2", + "https://www.irs.gov/pub/irs-prior/i1041sk1--2025.pdf#page=2", + ) diff --git a/source_conflicts/candidates.yaml b/source_conflicts/candidates.yaml index 3af4376ef07..02d04ed6e37 100644 --- a/source_conflicts/candidates.yaml +++ b/source_conflicts/candidates.yaml @@ -10125,6 +10125,40 @@ candidates: unearned_sources.yaml) and for categorical eligibility (wy_lieap_eligible.py). It follows rule 8(a)(ii)(L) over the plan in excluding lump sums and has no lottery-winnings input. It deducts child support paid only from the payer's own earnings (wy_lieap_countable_income.py), since rule 8(a)(iii) does not say whose earnings. +- id: us:additional-child-credit-2021-abode-section-911 + program: income-tax + years: + from: 2021 + to: 2021 + type: tax + question: In 2021, does a section 911 exclusion claimant who fails ARPA's United States abode test lose the refundable + child tax credit under section 24(d)(3), when the model applies the 2021 exemption from subsection (d) to every + filer? + sources: + - kind: statute + citation: 26 U.S.C. 24(i)(1) as added by P.L. 117-2 section 9611; 24(d)(3) + url: https://www.congress.gov/117/plaws/publ2/PLAW-117publ2.pdf + - kind: form + citation: 2021 Schedule 8812, Part I-B + url: https://www.irs.gov/pub/irs-prior/f1040s8--2021.pdf#page=1 + readings: + statute: Subsection (d), including the (d)(3) bar, is switched off in 2021 only for a taxpayer whose principal + place of abode was in the United States for more than half the year, or a bona fide resident of Puerto Rico. + other: The model has no abode input and treats every 2021 filer as meeting the test, so no section 911 claimant + is barred. + example: In 2021, a filer abroad all year with $30,000 of wages, all excluded under section 911(a), and two + qualifying children aged 7 and 9 gets $6,000 of refundable child tax credit in the model; under the statute + subsection (d) applies, and the (d)(3) bar denies the refundable part. + pe_us: + follows: not-modelled + code: + - policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10297 + state: unreviewed + note: The variable's documentation states the assumption. Most section 911 claimants need a foreign tax home and + cannot meet the abode test. A fix needs an abode input, defaulting to the current behavior for filers without + a section 911 exclusion. The model gives the $6,000 figure. - id: us:additional-child-credit-housing-deduction-bar program: income-tax years: @@ -10140,25 +10174,28 @@ candidates: citation: Schedule 8812 Part II-A; Credit Limit Worksheet B; Pub. 596 Rule 5 url: null readings: - statute: A housing deduction alone arguably does not trigger the section 24(d)(3) exclusion bar. + statute: Section 24(d)(3) bars only a taxpayer who elects to exclude an amount under section 911; the section + 911(c)(4)(A) housing deduction is a deduction, claimed without an election (Treas. Reg. 1.911-7(a)(3)), so it + alone does not trigger the bar. other: The instructions bar a Form 2555 filer even when the form claims only the housing deduction. pe_us: - follows: conflicting-source + follows: statute code: - policyengine_us/tools/section_911.py - policyengine_us/variables/gov/irs/credits/ctc/refundable/refundable_ctc_barred_by_section_911_exclusion.py + - policyengine_us/variables/gov/irs/credits/ctc/refundable/ctc_credit_limit_worksheet_b_applies.py - policyengine_us/parameters/gov/irs/credits/ctc/refundable/fully_refundable.yaml - policyengine_us/parameters/gov/irs/credits/ctc/refundable/foreign_earned_income_exclusion_bar_applies.yaml prs: - https://github.com/PolicyEngine/policyengine-us/pull/10022 - state: unreviewed - note: 'PE-US follows the instructions: elects_section_911_exclusion treats a filer who claims only the section - 911(c)(4) housing deduction as electing section 911, so refundable_ctc_barred_by_section_911_exclusion denies - the additional child tax credit from 2015 except in 2021, when the credit is fully refundable and the bar does - not apply; the helper''s docstring says this case rests on the IRS instructions, not the statute (tools/section_911.py, - refundable/fully_refundable.yaml, refundable/foreign_earned_income_exclusion_bar_applies.yaml). The statute-first - rule requires revising the deduction-only ACTC bar; verify that interpretation separately from EITC, whose statutory - wording differs.' + - https://github.com/PolicyEngine/policyengine-us/pull/10297 + state: unreviewed + note: PE-US follows the statute. refundable_ctc_barred_by_section_911_exclusion reads excludes_amount_under_section_911 + (tools/section_911.py), which tests only the Form 2555 line 42 and line 36 exclusions when leaf inputs are supplied, + so a filer who claims only the section 911(c)(4) housing deduction (line 50) keeps the refundable credit and completes + Credit Limit Worksheet B (ctc_credit_limit_worksheet_b_applies.py). The legacy aggregates still count as an exclusion. + The EITC keeps the broader section 32(c)(1)(C) test in elects_section_911_exclusion. Register the entry and add + the marker once #10297 is on main. - id: us:charitable-non-itemizer-2020-separate-cap program: income-tax years: @@ -10275,6 +10312,74 @@ candidates: education credits (is_barred_from_education_credits_by_dependency.py). Ruled October 2026; the statute-first rule now requires changing the whole-return bar; verify the education-credit page anchor because the supplied URL is for student loan interest.' +- id: us:eitc-qualifying-child-identification-bar + program: income-tax + years: + from: 2018 + to: 2020 + type: tax + question: Before 2021, does a filer whose qualifying children all fail the identification requirement get no EITC, + or the credit for a filer without a qualifying child? + sources: + - kind: statute + citation: Former 26 U.S.C. 32(c)(1)(F); P.L. 117-2 section 9622 + url: https://www.govinfo.gov/content/pkg/USCODE-2015-title26/html/USCODE-2015-title26-subtitleA-chap1-subchapA-partIV-subpartC-sec32.htm + - kind: instructions + citation: 2018-2020 Form 1040 instructions, EIC Step 3, question 1 + url: https://www.irs.gov/pub/irs-prior/i1040gi--2020.pdf#page=42 + readings: + statute: No credit is allowed to a filer with one or more qualifying children if no qualifying child is taken into + account because of the identification requirement. + other: The instructions send such a filer to Step 4, the credit for a filer without a qualifying child. + example: 'In 2020, a filer with $6,000 of wages and one qualifying child without an SSN gets $0 under the statute + and $459 (7.65% of $6,000, under the $538 maximum) under the instructions; the model gives these with the bar on + and off.' + pe_us: + follows: statute + code: + - policyengine_us/variables/gov/irs/credits/earned_income/eligibility/eitc_eligible.py + - policyengine_us/parameters/gov/irs/credits/eitc/eligibility/qualifying_child_without_identification_bar.yaml + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10297 + state: unreviewed + note: PE-US follows the statute through 2020; the parameter turns the bar off from 2021, when ARPA section 9622 struck + the subparagraph. P.L. 105-206 section 6021(b)(2) added the bar as (c)(1)(G), effective as if included in section + 11111 of the Revenue Reconciliation Act of 1990, and P.L. 108-311 redesignated it (F). Register the entry and add + the marker once #10297 is on main. +- id: us:eitc-rental-real-estate-basket + program: income-tax + years: + from: 2018 + type: tax + question: Is rental real estate a section 32(i)(2)(C) rent, netted with nonbusiness royalties, or a section 32(i)(2)(E) + passive activity for the EITC investment income limit? + sources: + - kind: statute + citation: 26 U.S.C. 32(i)(2)(C) and (E); 469(c)(2) + url: https://www.law.cornell.edu/uscode/text/26/32#i_2 + - kind: worksheet + citation: Publication 596 (2025) Worksheet 1, lines 8-13 + url: https://www.irs.gov/pub/irs-prior/p596--2025.pdf#page=7 + readings: + statute: Section 32(i)(2)(C) counts rents and royalties not derived in the ordinary course of a trade or business, + net of their allocable deductions; (E) counts passive activity income, without amounts described in (C). The + text does not say which basket rental real estate is in. + other: Worksheet 1 puts Schedule E line 23b royalties and Schedule 1 line 8l personal property rents on lines 8-10, + and Schedule E line 26 rental real estate on the passive lines 11-12; nonpassive rental real estate is left out. + example: In 2025, $12,000 of trust royalties and a $5,000 rental real estate loss give $12,000 of investment income + with rentals in the passive basket (over the $11,950 limit, so a joint couple with one child and $15,000 of wages + gets no EITC) and $7,000 if the rental is a (C) rent (the couple gets $4,328); the model gives these figures. + pe_us: + follows: gap-fill + code: + - policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py + prs: + - https://github.com/PolicyEngine/policyengine-us/pull/10297 + state: ruled + note: Where the text and the canons do not settle a reading, the model follows the administering agency's reading, + here Worksheet 1. rental_income, read as Schedule E rental real estate, stays in the passive basket, so a rental + real estate loss offsets other passive income but not trust royalties. The model has no input for personal property + rents ((C) basket) or nonpassive rental real estate (not investment income). - id: us:eitc-trust-royalties-investment-income program: income-tax years: @@ -10293,17 +10398,20 @@ candidates: statute: Box 5 royalties count toward the investment-income limit. other: Only Schedule E Part I royalties enter line 8. pe_us: - follows: conflicting-source + follows: statute code: - policyengine_us/variables/gov/irs/credits/earned_income/eitc_relevant_investment_income.py + - policyengine_us/variables/household/income/person/estate/estate_royalty_income.py - policyengine_us/variables/household/income/person/estate/passive_estate_income.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10194 + - https://github.com/PolicyEngine/policyengine-us/pull/10297 state: unreviewed - note: 'PE-US follows the worksheet: the passive basket counts passive_estate_income, Schedule E Part III column - (d), and leaves out the box 5 royalties, annuities and income in respect of a decedent that go in nonpassive - column (f) (eitc_relevant_investment_income.py, passive_estate_income.py). The statute-first rule requires including - qualifying Part III royalties; obtain the worksheet version and verify the omitted income basket.' + note: PE-US follows the statute. The estate_royalty_income input (Schedule K-1 (Form 1041) box 5 royalties, net of + their allocable deductions) forms the section 32(i)(2)(C) basket in eitc_relevant_investment_income, floored at + zero and kept apart from the passive basket, so these royalties count although Worksheet 1 line 8 reads only Schedule + E line 23b. Where rental real estate goes is a separate reading (us:eitc-rental-real-estate-basket). Register the + entry and add the marker once #10297 is on main. - id: us:filing-chart-a-blindness-and-equality program: income-tax years: @@ -10388,18 +10496,18 @@ candidates: other: Chart B and Publication 501 add age or blindness amounts, giving $2,950 or $4,550 in the supplied 2025 reading. pe_us: - follows: conflicting-source + follows: statute code: - policyengine_us/variables/gov/irs/tax_unit_is_required_to_file.py prs: - https://github.com/PolicyEngine/policyengine-us/pull/10135 - https://github.com/PolicyEngine/policyengine-us/pull/10137 + - https://github.com/PolicyEngine/policyengine-us/pull/10297 state: open - note: 'PE-US follows Chart B and Publication 501 Table 2: the unearned income threshold for a filer who can be - claimed is the section 63(c)(5)(A) amount plus their own additional standard deduction for age or blindness, - on joint returns too, and the comment records that section 6012(f)(2)(D) names the 63(c)(5)(A) amount alone - (tax_unit_is_required_to_file.py). The statute-first rule requires removing the extra amounts from this statutory - test.' + note: PE-US follows the statute. For 2018 to 2025, a joint return's unearned income test for a claimable spouse is + the section 63(c)(5)(A) amount alone, with no addition for age or blindness (tax_unit_is_required_to_file.py, + statutory_joint_test). Other filing statuses, and every return from 2026, keep Table 2's addition. Register the + entry and add the marker once #10297 is on main. - id: us:hsa-limit-indexing-windows program: income-tax years: