Repository navigation
Count the gross section 911 exclusion toward the filing threshold - #10022
Conversation
Follow-ups from the r5 review of #9976: - 26 U.S.C. 6012(c): the filing add-back is Form 2555 line 43 (foreign_earned_income_exclusion_gross) when leaf inputs apply, with the legacy foreign_earned_income_exclusion fallback, floored at zero. - One Form 2555 leaf check (has_section_911_leaf_inputs) and one line 43 helper (section_911_gross_exclusion) replace hand-written leaf lists. - elects_section_911_exclusion docstring: the housing-deduction-only bar rests on the IRS instructions, not section 24(d)(3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Context from the session that opened this PR, for the US + core hub, which now owns it. I won't push to this branch. Head I last tested: Tests at
Why the per-leaf consumer test is built the way it is. My first version entered the legacy amount for the prior year only, and it missed 4 of 5 mutations. Every downstream fallback (
Review brief. A first-review prompt is ready at Impact. Not run at any head of this PR.
Out of scope, found in passing. Local state. I'm removing my worktree ( |
|
US + core hub merge audit, us#10022 at
|
Follows #9976. This fixes three findings from that PR's r5 review: P3-i (the filing threshold), P3-g (one leaf list) and P3-j (a docstring).
What changes
1. The filing threshold counts Form 2555 line 43 (P3-i)
Before.
tax_unit_is_required_to_fileaddedforeign_earned_income_exclusionto gross income. That variable is line 2c of the Foreign Earned Income Tax Worksheet:The law. The filing requirement needs gross income without the exclusion:
After. A new helper,
section_911_gross_exclusionintools/section_911.py, sets the add-back:foreign_earned_income_exclusion_gross(line 43).foreign_earned_income_exclusionfallback.The Massachusetts add-back already used exactly this rule. Its formula now calls the same helper, so the two cannot drift apart.
The review's failure case, a single filer in 2025:
employment_income(after the exclusion)foreign_housing_exclusion(line 36)foreign_earned_income_exclusion_allocable_deductions(line 44)2. One leaf list and one input check (P3-g)
Three formulas each wrote out the five leaf names and Core's input check by hand:
foreign_earned_income_exclusion;section_911_excluded_income, which imported the tuple but repeated the check;ma_foreign_earned_income_exclusion_addback.They now call
has_section_911_leaf_inputs(tax_unit, period), which iteratesSECTION_911_LEAF_INPUTS. The filing requirement reaches it throughsection_911_gross_exclusion.The only call to Core's private
_get_exportable_input_periodsis now inside that helper. The review's P3-b item (formulas relying on private Core helpers) is still open, but this call now lives in one place.3. The docstring of
elects_section_911_exclusion(P3-j)The docstring now says the bar on a filer who claims only the housing deduction rests on the IRS instructions, not the statute, and it cites both:
Behavior changes
These are intended:
foreign_earned_income_exclusion. That amount no longer lowers filing gross income, because an exclusion cannot be negative and the worksheet floors line 2c at zero. Main already floors the same amount in the main rates worksheet, the AMT, the NIIT and the Massachusetts add-back.Nothing else changes:
ma_foreign_earned_income_exclusion_addback,foreign_earned_income_exclusionandsection_911_excluded_incomekeep their formulas; the code only moved into the helpers.Not changed here: the filing variable's unearned-income test applies to every tax unit, not only to dependents. That is a separate, pre-existing issue and is tracked separately.
Invariants
These hold for every input:
foreign_earned_income_exclusion_gross, the add-back ismax(0, line 36 + line 42). Lines 44 and 50 and worksheet line 2b never change it. A directly enteredforeign_earned_income_exclusion_grossreplaces the sum, as an entered aggregate does elsewhere: entering 0 beside a $10,000 housing exclusion gives an add-back of 0.max(0, legacy amount). That equals main's add-back whenever the legacy amount is non-negative.SECTION_911_LEAF_INPUTS, entered alone (even as zero), switches every formula that chooses between leaf and legacy inputs to the leaf calculation.A Hypothesis property test covers invariants 1, 2 and 4. YAML cases cover 3. A test parametrized over the tuple covers 5. There is no second implementation of this rule to run a differential test against: Massachusetts and the filing requirement now share one.
Tests
Adoption work on 2026-10-11 merged main
a844fc1717e8632bc92a9b0d7c9d41dda5359fdcinto the PR branch with a plain, conflict-free merge, producing94f3dd7e42d1cb5f0b582fdea6b0b04f03a4a8b3. All eight original PR files are byte-identical to6974105681895e2cbafffdfea35b415bea89d53f; the diff against merged main still contains only those files. No additional model or test changes were needed.make formatpassed before the merge: 6,771 Python files were already formatted, and Ruff lint passed.Run by the hub at
94f3dd7e42d1cb5f0b582fdea6b0b04f03a4a8b3on 2026-10-11, one file per process:policyengine_us/tests/policy/baseline/gov/irs/tax_unit_is_required_to_file.yamlpolicyengine_us/tests/test_foreign_earned_income_exclusion_leaves.pytest_ma_foreign_earned_income_addback.py,test_section_911_batch_inputs.pyThe adoption build could not run tests in its sandbox, so the author's earlier 585 YAML and 51 Python passes predate the merge of main; the rows above are the current-head results.
Partner contract files were not edited. A scan found no section 911 aggregate/leaf inputs or direct references to
tax_unit_is_required_to_filein those files; no moving partner expected values were identified. The committed diff against main contains no partner files or lockfile changes.An independent review (GPT-6.1 Sol) approved this head on 2026-10-11 with no blocking findings; its three notes on this description are applied above.
Hub microsimulation impact (current head)
A real microsimulation on the default dataset, main at the merge base
a844fc1717against this PR's head94f3dd7e42, for 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.tax_unit_is_required_to_fileforeign_earned_income_exclusionincome_taxstate_income_taxhousehold_net_incomehousehold_benefitsComparison files are in
fixes/10022-impact/on the hub host.Axiom
axiom: TheAxiomFoundation/rulespec-us#1484 queued
foreign_earned_income_exclusion_adjustment_for_return_filing_gross_income, which is the section 911 exclusion itself, as an input amount. Axiom has no Form 2555 leaves, so this PR changes only how PolicyEngine derives that amount.main.Still open from the #9976 reviews
These are not in this PR:
foreign_earned_income_exclusionstill imports_uprating_index_value.