Skip to content

Count farm rent and leave out passive income that is also earned in the EITC investment income test (26 U.S.C. 32(i)(2)(E)) - #9889

Merged
MaxGhenis merged 13 commits into
mainfrom
eitc-passive-earned-overlap-farm-rent
Oct 12, 2026
Merged

MaxGhenis merged 13 commits into
mainfrom
eitc-passive-earned-overlap-farm-rent

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This fixes items 2 and 3 of #9635 in eitc_relevant_investment_income. Item 1, excluding dependents' amounts, landed in #9883.

  • Add farm_rent_income, including losses, to the passive-income basket.
  • Add a signed Person input, eitc_passive_income_also_in_earned_income, defaulting to zero. Subtract it from the head's and spouse's combined passive amounts before applying one zero floor.

The passive basket becomes:

max(0, filers' rental income + farm rent + passive partnership/S-corp income
       − eitc_passive_income_also_in_earned_income)

The portfolio and capital baskets retain main's filer-only calculation. Partnership self-employment earnings alone do not alter the passive basket. The overlap input classifies income already supplied elsewhere; it does not add income.

Law and input contract

26 U.S.C. 32(i)(2)(E) excludes amounts included in earned income from both passive income and passive losses. 2025 Publication 596, Worksheet 1, lines 11–13, applies that exclusion before flooring the combined passive basket. Lines 11 and 12 include Schedule E line 40, net farm rental income or loss from Form 4835.

26 U.S.C. 1402(a) includes a partner's distributive share of trade or business income in net earnings from self-employment. That inclusion is subject to the rental, investment-income, and gain exclusions in (a)(1)–(3); (a)(13) excludes a limited partner's distributive share except guaranteed payments for services actually rendered. A general partner who does not materially participate in a partnership's trade or business can therefore have a share that is both passive and earned.

The overlap amount must also be included in partnership_self_employment_net_earnings; the model does not validate that consistency. S corporation shares have no such overlap. Enter profits positively and losses negatively. Because these inputs aggregate several activities, the overlap can exceed either net aggregate or have the opposite sign. It is subtracted directly without a clamp. A dependent's overlap is ignored.

Modeling limits

Rental income retains the existing passive-basket convention. Nonbusiness rents can require a separate basket under §32(i)(2)(C); rental classification and routing remain deferred to rulespec-us#1416.

Form 4835 instructions recognize a real estate professional's nonpassive farm rental. The model lacks an input for that distinction and treats farm_rent_income as passive, as it already does rental_income. The public variable documentation discloses this limitation.

Household examples

Fresh 2025 calculations at the merged head 78a2ed87b99c441a8eccb9b8b61af914cfdbfeaa cover all 15 added YAML situations. These are household examples, not a population impact estimate.

Situation Investment income Investment test eligible EITC
Full positive overlap $5,000 Yes $6,291.74
Signed earned loss $13,000 No $0.00
Limited partner: no overlap $13,000 No $0.00
Partial overlap $8,000 Yes $6,247.10
Unrelated self-employment loss $13,000 No $0.00
Spouse earnings alone $13,000 No $0.00
S corporation: no overlap $13,000 No $0.00
Overlap exceeds net passive income $9,000 Yes $280.67
Earned loss exceeds net passive loss $14,000 No $0.00
Farm rental profit $13,000 No $0.00
Farm loss offsets rental profit $9,000 Yes $5,962.11
Farm rent at the 2025 limit $11,950 Yes $5,340.84
Farm rent $1 over the limit $11,951 No $0.00
Joint return: spouse overlap, two children $5,000 Yes $7,152.00
Dependent overlap ignored $13,000 No $0.00

Tests and invariants

Serial single-file validation passed at the merged head:

  • Investment-income YAML: 27 passed, including the 15 added cases.
  • Expanded invariant file: 3 passed.
  • Existing investment-income basket YAML: 3 passed.
  • Unchanged partner EITC contract: 15 passed; no expected values moved.
  • make format: passed Ruff formatting and checks.

Local macOS / Python 3.13.9 measurements for the same invariant file, including process setup: main snapshot 2839.29s wall time and 0.80 GiB peak RSS (854,966,272 bytes); merged head 217.87s wall time and 0.89 GiB peak RSS (956,268,544 bytes). These local measurements were collected on a busy shared host. Variable host load limits comparisons of incremental runtime; Linux CI measurements are reported separately below.

The test stays in the existing sequential core Rest CI group. Existing main CI evidence at fdd70629054a records 849 core tests, 16:01.65 process elapsed time and 12.66 GiB peak RSS; the three invariant case times sum to 8.480s, excluding shared setup. Historical PR CI at fa23f6fc807e also passed. Its smaller 667-test cohort prevents a controlled group-cost comparison and does not validate the new merge. No new Python test file, CI group, or runner is added.

The 15 added YAML cases cover signed overlap, unrelated earnings and S corporation guards, farm rent and losses, the 2025 $11,950 boundary, a spouse's overlap, and a dependent's overlap. The property test extends the existing file and checks, within its finite drawn ranges and numerical precision:

  1. Dependents' investment amounts never change filers' investment income, eligibility, EITC, filer capital-gain amount, or AGI.
  2. Investment income and eligibility match an independent numpy Worksheet 1 calculation over the head and spouse.
  3. Investment income is at least the nonnegative portfolio basket; adding $1,000 to the head's interest raises it by $1,000 while partnership self-employment earnings also change.
  4. Without dependents or negative capital-gain distributions, the result equals the same worksheet over every member.

The seeded population has 200 units and runs for 2021 and 2025. It separately asserts that farm rent alone and overlap alone each change eligibility for more than two units in each year. Partner expectations are unchanged.

Hub validation remaining

The hub will run matched 2025 and 2026 microsimulations at the final head against current main, then obtain a delta review and handle ready status, CI, and landing. Impact reporting will include income_tax and state_income_tax alongside investment income, eligibility, EITC, and household net income. It will also cover CO, DC, and IL credits that read investment income through calculate_eitc_like_amount, with state_income_tax providing an aggregate check of their effect. This PR remains a draft.

Hub microsimulation impact (current head)

A real microsimulation on the default dataset, main at the merge base 8b059f892d against this PR's head 78a2ed87b9, for 2025 and 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.

Output 2025 change 2026 change 2025 records changed (weighted) 2026 records changed (weighted)
eitc_relevant_investment_income +5.59bn +5.90bn 316 (477,948) 316 (481,361)
eitc -5 -4 1 (0) 1 (0)
eitc_eligible -52,347 -52,720 31 (76,598) 30 (77,145)
income_tax +5 +4 1 (0) 1 (0)
state_income_tax +1 +1 1 (0) 1 (0)
co_eitc +0 +0 0 (0) 0 (0)
dc_eitc +0 +0 0 (0) 0 (0)
il_eitc +0 +0 0 (0) 0 (0)
household_net_income -6 -5 1 (0) 1 (0)
household_benefits +0 +0 0 (0) 0 (0)

Comparison files are in fixes/9889-impact/ on the hub host.

Axiom

axiom: TheAxiomFoundation/rulespec-us#1416 queued

The existing overlap addendum and six hand-computed companion cases cover the earned-income exclusion. Farm rent shares the deferred rental-routing question. The signed-encoder dispatch, d439, is parked; parity follow-up remains with the hub.

MaxGhenis and others added 3 commits October 6, 2026 08:31
…come

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…line

Start from net_capital_gains, take out dependents' gains and losses, and add
the filers' floored capital gain distributions, so a tax unit amount supplied
for net_capital_gains still counts, as it did before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 6, 2026 10:00
… supplied

net_capital_gains is stored in float32, so subtracting a dependent's very large
gain from it could move the filers' capital gain line by a few dollars and flip
eligibility at the limit (independent review finding, reproduced in the model:
a child's 20,000,000 gain turned 11,951 into 11,950). Use the head's and
spouse's person-level gains, and read net_capital_gains only where it differs
from the members' own gains, that is, where a tax unit amount was supplied.

Also widen the property test to dependents' gains of 16 to 64 million, add the
two boundary cases, correct the Form 8814 explanation (an election also reaches
Worksheet 1 lines 3 and 5) and mention the distributions floor in the changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the eitc-passive-earned-overlap-farm-rent branch from 916bb02 to 9bc8fc0 Compare October 6, 2026 14:03
Comparing values alone read an abolished or stale net_capital_gains as a
supplied aggregate and subtracted dependents' gains from it (Opus delta
review S1; with gov.abolitions.net_capital_gains a child's 5,000 gain made the
parent eligible). Check core's input record (is_input, next to the existing
_input_keys in tools/period_branch.py) as well.

Add a test for that branch and a guard that the formula's gain list matches
net_capital_gains.adds; fix a stale test comment and a long YAML header line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the eitc-passive-earned-overlap-farm-rent branch from 9bc8fc0 to 1d98c79 Compare October 6, 2026 14:39
…ow invariant 4

A supplied net_capital_gains that equals the members' own gains and losses in
float32 adds nothing to them, so the filers' gains are summed exactly; two YAML
cases pin both rounding directions as intended (Sol delta review). Invariant 4
holds for filer gains in the drawn range; past about 16.8 million the previous
formula's float32 total could be off by a few dollars, which the direct sum
corrects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the eitc-passive-earned-overlap-farm-rent branch from 1d98c79 to ea6c681 Compare October 6, 2026 14:46
…ital_gains

Return to the capital gain line the task specified: the head's and spouse's
long- and short-term gains (tax_unit_non_dep_add) plus their floored capital
gain distributions. Reading a supplied tax unit net_capital_gains needs to
know which tax units supplied it, which core does not record, and every
value test for it let a dependent's gain move the filers' result somewhere
(four review rounds: float32 collisions, abolished, stale and default-filled
values). A supplied tax unit total is now not read, as in irs_gross_income and
the NIIT base; no PolicyEngine repo or the microdata supplies it. Drop the
is_input helper, the cases that pinned the aggregate reading and the
input-record test; pin instead that a supplied total is not read.

Add two downstream pins from a 504-household sweep (session bbf31ca6): a
dependent's income no longer removes MN child and working family credits or
the NM EITC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ad; clarify the capital gain comment

Docs only, from the bafe4fe reviews: the changelog now says the test reads
the head's and spouse's long- and short-term gains and no longer a supplied
tax unit net_capital_gains; the variable documentation also says a
capital_gains amount set directly on a person is not read; the code comment
gives the actual reason the tax unit total is not read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 6, 2026 16:37
…he EITC investment income test (#9635 items 2 and 3)

Add the signed Person input eitc_passive_income_also_in_earned_income and
subtract it from the passive basket before the zero floor, as 26 U.S.C.
32(i)(2)(E) requires. Include farm_rent_income, income and losses, in the
passive basket (Pub. 596 Worksheet 1 lines 11-12, Schedule E line 40).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se and dependent overlap

From the #9889 reviews: the overlap input documentation now says it is a
partnership share that must also be in partnership_self_employment_net_earnings,
that S corporation shares have none, that it can exceed or oppose the net
passive and partnership SE amounts, and that a dependent's is not read. The
investment income documentation now describes the passive basket and the real
estate professional limitation. Two YAML cases cover a spouse's and a
dependent's overlap, and the seeded property test asserts that farm rent and
the overlap decide eligibility for some units.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the eitc-passive-earned-overlap-farm-rent branch from 419aa90 to d3f9e9d Compare October 6, 2026 20:43
…use case's credit; tidy wording

From the d3f9e9d review: the seeded test now asserts each new term decides
eligibility for some units on its own, the spouse overlap case pins its EITC
(7,152, under the joint phase-out start), the changelog no longer mentions S
corporations, and one sentence of the input documentation is reworded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Context from the original session (19896880) for the hub, which now owns this PR. I won't push to the branch.

  • Delta review at d3f9e9d415: APPROVE. An independent in-session Opus 5.5 review; Subfleet was held for low disk that day. It answered Opus r1 (REQUEST_CHANGES) and Sol r1 (APPROVE). Saved at ~/reviews/eitc-dependent-investment-income-2026-10-06/review-9889-delta-opus.md.
    • It confirmed B1 is a labelling problem. git diff 9bc8fc031c 4d9ea75300 leaves the overlap input file and the passive basket byte-identical; the amend only reworded a test comment. The pinned dataset has neither a tax-unit net_capital_gains nor an overlap column.
    • Its code nits are fixed in fa23f6fc80, which is in your branch: separate farm-rent and overlap eligibility assertions, eitc: 7_152 on the spouse case, no S corporations in the changelog, and reworded input documentation.
    • Its only open item was S3: the impact years, and saying that state_income_tax bounds the CO, DC and IL helper credits. Your 2025 and 2026 runs with those rows cover it.
  • The microsim I queued at d3f9e9d415 (eitcovl2-pr) never ran. It was still waiting for the heavy lock when the session stopped, and no output exists. So the only Count farm rent and leave out passive income that is also earned in the EITC investment income test (26 U.S.C. 32(i)(2)(E)) #9889 impact numbers are your new runs. The earlier 9bc8fc031c run is in impact-9889-2026.json, if you want a cross-check.
  • Follow-ups found in Count only the head's and spouse's income in the EITC investment income test (26 U.S.C. 32(i)) #9883's reviews, each queued as a session chip, outside this PR:
    • dependents' income in tax_unit_is_required_to_file, taxable_unemployment_insurance and tax_unit_social_security_for_taxability;
    • reading the person-level capital_gains in the EITC test and the NIIT base, so the capital-gains marginal rate sees the EITC cliff.
  • Axiom: Encode IRC §32(i)(2) disqualified income; replace the opaque eitc_relevant_investment_income input TheAxiomFoundation/rulespec-us#1416 has the E1–E6 overlap companion cases (comment). The dispatch is Max's d439, which is parked.

🤖 Generated with Claude Code

@MaxGhenis MaxGhenis closed this Oct 11, 2026
@MaxGhenis MaxGhenis reopened this Oct 11, 2026
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 11, 2026 23:22
@MaxGhenis
MaxGhenis merged commit eeff2f2 into main Oct 12, 2026
43 of 47 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#9889 at 78a2ed87b99c441a8eccb9b8b61af914cfdbfeaa (squash): Count farm rent and leave out passive income that is also earned in the EITC investment income test (26 U.S.C. 32(i)(2)(E)).

  • Review: independent GPT-6.1 Sol review APPROVE at this head (15 cases recomputed; Count only the head's and spouse's income in the EITC investment income test (26 U.S.C. 32(i)) #9883 intact). The approximation it discloses (all farm rent treated as passive; the real-estate-professional exception deferred to rulespec-us#1416) is stated in the description.
  • Gates checked live at merge:
    • gh pr checks exits 0;
    • the latest Pull request run at the head concluded success;
    • MERGEABLE;
    • not a draft;
    • no reviewer's latest review requests changes;
    • the semantic-overlap guard;
    • head pinned.
  • Impact (hub full-file microsimulation, merge base 8b059f892d against this head, in the description): 2025: eitc_relevant_investment_income +5.59bn (316 records); eitc -5 (1 records); eitc_eligible -52,347 (31 records); income_tax +5 (1 records); state_income_tax +1 (1 records); household_net_income -6 (1 records) | 2026: eitc_relevant_investment_income +5.90bn (316 records); eitc -4 (1 records); eitc_eligible -52,720 (30 records); income_tax +4 (1 records); state_income_tax +1 (1 records); household_net_income -5 (1 records).
  • Axiom: Encode IRC §32(i)(2) disqualified income; replace the opaque eitc_relevant_investment_income input TheAxiomFoundation/rulespec-us#1416 queued

@MaxGhenis
MaxGhenis deleted the eitc-passive-earned-overlap-farm-rent branch October 12, 2026 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant