Repository navigation
feat(clergy): file the housing allowance excess, ministerial SE earnings and Form 4361 boxes from sourced W-2 rows - #173
Merged
Conversation
…ngs and Form 4361 boxes from sourced W-2 rows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
#56 replaced the
clergynode with a stub that throws for every entry: itsinput named no W-2, employer, minister or advance designation, so it could not
tell an allowance already left out of W-2 box 1 from taxable excess, or check
Form 4361. A minister's return cannot be prepared at all today.
Evidence model
One strict row per church W-2 (
forms/f1040/nodes/inputs/income/wages/clergy),patterned on
f2106:minister:owner(taxpayer|spouse), name, SSN,credential(ordained, commissioned or licensed),
ordained_commissioned_or_licensed_confirmed: true,ministerial_services_confirmed: true,credential_reference.employer: church name, EIN,w2_reference(the entered W-2'ssource_document_reference);ministerial_wagesequals that W-2's box 1.housing_allowance(optional):included_in_w2_box1;designation(amount,
designated_onno later thaneffective_from, both by the end ofthe year,
designation_reference);paid(amount, record,paid_after_designation_confirmed: true);actual_housing_expenses(amount,record);
fair_rental_value(furnished plus utilities, confirmation, record);not_more_than_reasonable_pay_confirmed: true.parsonage(fair rental value plus utilities, record,not_more_than_reasonable_pay_confirmed: true),unreimbursed_ministerial_expenses(amount,not_reimbursed_confirmed: true,record),
form4361(approved: false, ortruewithapproved_onandapproval_reference),tax_year.Reasonable pay is attested, not computed. Pub 517 (2025) limits the rental
allowance exclusion to an amount that "isn't more than reasonable pay for your
services" and says of a parsonage that "the exclusion can't be more than the
reasonable pay for your services". The engine cannot judge that, so both
objects require
not_more_than_reasonable_pay_confirmed: true, in the sameliteral-attestation pattern as the other confirmations.
The start node passes the general filer identity and entered W-2s as context
fields, as it already passes
owner_identity,filing_statusandowner_birth_datesto other input nodes. The node fails closed unless eachrow matches the return's taxpayer or joint spouse and exactly one W-2 with the
same SSN, EIN, employer name, reference and box 1, no statutory-employee box
and no box 3 or box 5 wages (a minister's earnings are not covered under FICA:
Pub 517, Table 1), and unless all rows for one minister agree on Form 4361
approval. The minister's name is compared after ignoring case, periods,
commas, extra spaces, leading titles (Rev., Reverend, Pastor, Dr., Fr.) and
trailing suffixes (Jr., Sr., II, III, IV); every other word must match the
return's first, optional middle initial and last name. Doing this in the node
gives a calculation diagnostic for a mismatched W-2 and validates the owner
(taxpayer or spouse) before any Schedule SE row is created. At export,
domains/income/wages/clergy/clergy_source.tsreconciles the retained rowsagain against the retained general and W-2 sources, the finalized Schedule SE
rows and Schedule 2, as
form2106_staged.tsdoes for Form 2106. If you wouldrather keep reconciliation export-only, as Form 2106 does, say so and I will
move it.
Calculation and routing
value (IRC §107(2)). The excess goes to
f1040andagi_aggregatorline1h_other_earned(Pub 517: "Include this amount in the total on Form1040 or 1040-SR, line 1h. On the dotted line next to line 1h, enter 'Excess
allowance'"). A parsonage needs no income adjustment (§107(1)).
in full (Pub 517, "Figuring Net Earnings", "Allowable deductions" and
"Expenses Allocable to Tax-Free Income"; i1040sse 2025, Ministers) go to
schedule_se.ministerial_sources, one owned, referenced row per W-2; a bareamount is not taken (the existing "unsourced ministerial loss" test still
passes). Schedule SE adds them to line 2, per spouse on a joint return
(
kind: "ministerial"owner rows), and a loss reduces other line 2 earnings(i1040sse, More Than One Business). With an approved Form 4361,
unreimbursed expenses are ignored rather than rejected.
earnings, which are pay for services, not a trade or business. When
ministerial earnings sit beside Schedule C, Schedule F or partnership
earnings,
schedule_sesends those consumers the line 13 figured on thebusiness earnings alone (
businessLine13, andbusinessin the ownedbranch). That split is provisional and reachable only in tests, because
export refuses every such return (below). The part an exportable route needs
is narrower: with ministerial earnings only, nothing reaches QBI or
Schedule 1-A, and Form 7206 sees no SE deduction (test "sourced ministerial
earnings alone are Schedule SE line 2"). Dropping the split would send a
pastor's ministerial SE deduction to QBI on that route, so it stays, marked
provisional in the code.
IRS-instructed way to subtract it from reported wages, and the engine has no
negative line 8z route.
Filing
OtherEarnedIncomeAmt→WagesNotShownSchedule,OtherWagesNotShownTxtEXCESS ALLOWANCEf1_54)NetNonFarmProfitLossAmtincludes ministerial earningsf1_5AllowableSEExpenseExplnStmt, referenced from theIRS1040ScheduleSErootExemptForm4361Ind, first element afterSSNc1_1ExemptForm4361IndLine4_ReadOrder.c1_3ClergyMemberInd, betweenEarnedIncomeCreditAmtandDoNotClaimEICIndc2_12clergyleaves the attachment-coverage blocklist only for rows that parse,reconcile to their context and keep the allowance out of box 1.
Still fail-closed (named errors)
missing evidence, including the reasonable-pay attestation; rows for one
minister disagreeing on Form 4361; spouse minister on a non-joint return;
wrong-year row.
earnings on the return, including a spouse's. The joint Schedule SE
already keeps each spouse's earnings on their own schedule (tested at the
node, export-guard and end-to-end levels), but the export guards that replay
the owner Schedule SE sources for Form 8995 (joint owner), Form 8995-A,
Schedule 1-A and Form 7206 would see the ministerial rows as businesses and
are not ministerial-aware. A pastor whose spouse has a Schedule C is
therefore still refused.
beside another person's Schedule SE, such as a spouse's. The 2025 Schedule
SE instructions say to check box 1 "if you had no other income subject to SE
tax"; whether a joint return checks it beside the other spouse's SE tax was
not confirmed.
rules (EIC worksheet, Schedule 8812) are not modeled.
clergy_schedule_c(fees and honoraria).Planned follow-up
I plan a follow-up PR for the most common blocks above, which share the same plumbing:
Keeping it separate should make this PR easier to review.
Known limitations, not blocked
clergy earned-income rules: ministerial SE earnings are not added to their
earned income or compensation.
ministerial_sourcesreach onlyschedule_se, which passes Form 7206 the business earnings alone; Form 2441and the IRA/SEP limits never see them. How far that departs from the clergy
rules has not been worked out.
TY2026
Same shared nodes and builders, year from
ctx.taxYear. Tested: calculation,MeF build and local business rules for the excess/Schedule SE/explanation
return and the Form 4361 return; Form 1040 and Schedule SE PDF projections on
the 2026 drafts. Not verified: element names against the 2026v1.0 XSD.
Tests
clergy/index.test.ts(19): every evidence path fails when missing,including the reasonable-pay attestation on the allowance and the parsonage;
the designation date rule; each §107(2) limit; spending above the
designation; box-1 refusal; parsonage; full-allowance SE base; expenses to a
loss; 4361 (expenses ignored); two churches; Form 4361 disagreement across
one minister's W-2s (spouses may differ); names with titles and suffixes;
each W-2 mismatch; owner/spouse/year checks.
schedule_se/index.test.ts(+5): ministerial-only line 2, loss againstSchedule C, no QBI reduction, repeated reference, joint spouse instance.
clergy_source.test.ts(8): export facts, explanation only with expenses,refusals (drift, EIC/ACTC, clergy Schedule C, route support), and both
spouse cases refused with per-spouse Schedule SE amounts checked.
e2e/income/clergy/clergy_source_route.test.ts(12, plus 1 XSD test thatskips without
irs/):executeReturn→ MeF XML, business rules and PDFprojections for each route above, the explanation statement and its PDF page
only when expenses are subtracted, both spouse refusals, and TY2026.
Synthetic regression: single, church W-2 50,000, allowance designated and paid
24,000, used 20,000, fair rental value 22,000: line 1h 4,000; Schedule SE line
2 74,000, line 12 10,456; AGI 48,772 (base: clergy node threw). Fixture names
are synthetic ("Alex Example", "Example Community Church").
Verified
this branch: 11,446 → 11,490 passing (+44, all in the files above),
1,534 → 1,534 failing (the identical set), 303 → 304 skipped. No test that
passes on main fails or disappears here. The failures come from the
authoring environment: no network to irs.gov for fixtures that download IRS
PDFs, and
irs/not installed.irs/notinstalled):
bun run verify:changed 3add1ba7passed.test:unit --changedok;
test:forms --changed5,510 form tests, 30 failing, 0 outsideforms-failure-baseline.json;check:mef374 sample returns, 373 ready tofile, 0 problems;
check:cli18 returns, 0 problems; bench 87 failing(base 87).
check:ty20260 problems. The patch also applies cleanly tocurrent main (25884d9).
executeReturngive identicalpending output and diagnostics on main and here.
check:structure,check:cases,check:oracle,check:sandboxandcheck:irspass;oxlintreports 0 errors and the same 238 warnings asmain, none in the changed files.
.tsfiles. Whole-program
tsc --project tsconfig.jsonran out of heap at 8 GB onthe authoring machine (not compared against main there); the type check in
verify:changed's unit gate passed.schemas (Final Release, February 19, 2026):
IRS1040ScheduleSE.xsd(
ExemptForm4361Indfirst afterSSN; only the root carriesreferenceDocumentId/referenceDocumentName, fixed toAllowableSEExpenseExplanationStatement;NetNonFarmProfitLossAmthas noattributes),
IRS1040.xsd(ClergyMemberIndbetweenEarnedIncomeCreditAmtandDoNotClaimEICInd;OtherEarnedIncomeAmtreferences
WagesNotShownSchedule) andIRS1040Schedule2.xsd(
ExemptForm4361IndafterAdditionalTaxAmt).allowances and parsonage reasonable pay, Allowable deductions, Excess rental
allowance, Required statement); a reviewer also checked the 2025 edition.
The 2025 Schedule SE instructions' Form 4361 text was checked directly.
Not verified, and why
run the skipped test "E2E clergy returns validate against the TY2025 MeF
XSD" (
forms/f1040/e2e/income/clergy/clergy_source_route.test.ts) with yourteam copy of
irs/; it covers the excess/Schedule SE return, both Form 4361presentations and the explanation statement.
ReturnData1040.xsd,WagesNotShownSchedule.xsdor
AllowableSEExpenseExplanationStatement.xsdwas found.AllowableSEExpenseExplnStmtis placed afterPostponementCropInsDsstrStmtas in the TY2018
ReturnData1040.xsd(maxOccurs 2 there). The TY2018WagesNotShownSchedulerequiredWagesLiteralCd, whose list includedEXCESS ALLOWANCE; the IRS TY2025 stylesheet shows a choice ofWagesLiteralCdorOtherWagesNotShownTxt, so the free-text element isused. If the 2025 list still has
EXCESS ALLOWANCE, switching to the code isa one-line change in
foreign_employer_wages.ts.1040_Business_Rules_2025v3.0.csv, have 8 SSE rules, all implemented, andnone requires a Schedule C or K-1 when Schedule SE line 2 is nonzero; the
e2e returns pass them. Later rule releases were not available here and could
conflict, for example a rule tying a nonzero line 2 to Schedule C or K-1.
bun run test:unit/ whole-programtsc: the environment has 4 GB and thewhole program does not fit; see the per-file check above.
check:mef,check:ty2026,check:cli,bench: their fixtures fetch IRSPDFs, which this environment cannot reach.
TY2025 AcroForm field listings (Schedule SE
c1_1, Schedule 2Line4_ReadOrder[0].c1_3, Form 1040c2_12); the explanation page istested only for being appended.
Review notes
assertOwnedScheduleSEandform2106_staged, it recomputes in each builder, and a cache keyed on themutable pending object could hide in-place drift.
References