Fix 2025 PDF export: correct AcroForm mappings, print-layer emissions, conditional-form gating#1
Open
temujin9 wants to merge 4 commits into
Open
Fix 2025 PDF export: correct AcroForm mappings, print-layer emissions, conditional-form gating#1temujin9 wants to merge 4 commits into
temujin9 wants to merge 4 commits into
Conversation
Line 37 (amount owed) and line 34 (overpayment) are the difference of two whole-dollar filed lines, but were computed from the cents-level difference and rounded afterward. The two disagree by $1 whenever the operands' cents round in opposite directions (e.g. 26,357.62 - 25,751.28: rounded-operand result 607 vs naive 606), which fails the printed form's own arithmetic (line 24 - line 33) and IRS cross-checks. Compute the balance from Math.round(line33) - Math.round(line24) and update the e2e expectations accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The PDF builder can only print keys present in a form's pending dict, but intermediate nodes (schedule3, schedule_b, schedule_d, form8606, form8880, form8889) computed their line values internally and routed only the results downstream — so their pending held raw inputs and the printed schedules came out blank or wrong. Each node now also emits its computed line values into its own pending dict under distinct print_* keys (the same self-emission pattern the f1040 output node already uses). Details: - schedule_d: splits covered/no-adjustment transactions (Parts A/D) onto the direct-report lines 1a/8a per Schedule D "Exception 1"; answers line 17 only when line 16 is a gain; line 20 from the 28%/1250 worksheet values. - form8889: emits the full Part I ladder (lines 2-13); only when contribution or distribution activity actually requires the form. - form8880: emits only when a nonzero credit exists, so ineligible returns (AGI above the phase-out) no longer produce a stray all-zero form. - form8606: emits lines 1/2/3/14 always, distribution/conversion lines when applicable. - schedule_b: emits per-payer rows and Part I/II totals. - general: forward taxpayer_middle_initial (accepted by the schema but previously dropped). - filer: derive firstNameWithInitial / fullName for PDF name fields. - form8889 tests: corrected two pre-existing expectations that treated employer HSA contributions as deductible on line 13. IRC §223(a) limits the deduction to the taxpayer's own contributions (min(line 2, line 12)); employer contributions are already excluded from W-2 box 1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…itional forms The 2025 descriptor field mappings did not match the actual IRS AcroForm layer, and the hasData check emitted every form whose pending held any defined value. Observable symptoms on a simple single-filer return: - Form 1040: "Filed pursuant to section 301.9100-2" wrongly checked (c1_1 is that header checkbox, not Single); filing status unchecked; digital assets question unanswered; occupation missing. - Schedule 3: foreign tax credit printed inside the name field (f1_01); line 8 unmapped. - Schedule D: capital gain distributions printed in row 8b's proceeds column; transaction totals, line 15/16 and the 17/20 checkboxes missing. - Form 8606: line 1 printed in the home-address field; lines 2/3/14 blank. - Form 8889: employer contributions printed on line 12; everything else blank. - Form 8880: rows off by one (deferrals on line 3) on a form that should not print at all above the AGI phase-out. - 14 pages of inapplicable $0 forms (Schedule A/EIC/SE, 6251, 8959, 8960, 8962, 8880) padded the export. Changes: - Rewrite the f1040, schedule3, schedule_b, schedule_d, f8606, f8880 and f8889 descriptors against AcroForm field dumps (name/type/rect) of the official 2025 PDFs; fill name/SSN headers on every schedule. - hasData now requires a meaningful value (nonzero number, true boolean, nonempty string) instead of merely-defined. - New includeWhen gate on descriptors (with access to the full normalized pending) encodes each conditional form's statutory filing trigger: Schedule A only when itemizing, Schedule B only above $1,500, Schedule SE /6251/8959/8960 only when the corresponding Schedule 2 tax exists, 8962 only with 1095-A data, 8880 only with a nonzero credit. - New printZero field option for lines where an explicit 0 is meaningful (8606 line 2, 8889 lines 2/13). - Year-pin every descriptor pdfUrl to pub/irs-prior/<form>--2025.pdf; the previous pub/irs-pdf URLs silently change revision every filing season. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…4-40 The MFJ_vs_single_1_child test asserted a credit derived from a $30,323 phase-out start, but the TY2025 MFJ threshold for one child is $30,470 (Rev. Proc. 2024-40 §3.11), which is what the engine config already uses and which is consistent with the published completed-phaseout amount ($57,554 = 30,470 + 4,328/0.1598). The test was failing against correct engine output: 0.1598 x (45,000 - 30,470) = 2,321.894; round(4,328 - 2,321.894) = 2,006. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
The 2025 PDF export produced returns that were not safe to file. Exercising it against a simple single-filer return (one W-2, 1099-DIV/INT/B, HSA, nondeductible IRA) surfaced four classes of defect:
hasDatatreated any defined value as content, padding the export with 14 pages of inapplicable forms (Schedule A/EIC/SE, 6251, 8959, 8960, 8962, and an off-by-one-row Form 8880 for a filer 4x over the Saver's Credit phase-out).Changes
print_*line values into their own pending (the pattern the f1040 output node already uses). Schedule D also splits covered/no-adjustment transactions onto direct-report lines 1a/8a per "Exception 1"; 8889 emits the full Part I ladder only when the form is required; 8880 emits only with a nonzero credit.generalacceptedtaxpayer_middle_initialbut dropped it).includeWhengate on descriptors (with access to the full normalized pending) encodes each conditional form's statutory trigger: Schedule A only when itemizing, Schedule B only above $1,500, SE/6251/8959/8960 only when the corresponding Schedule 2 tax exists, 8962 only with 1095-A data.printZerofield option for lines where an explicit 0 is meaningful (8606 line 2, 8889 lines 2/13).pub/irs-pdf/*.pdfsilently changes revision each season; the 2025 module now fetchespub/irs-prior/*--2025.pdf.Also corrects three pre-existing test expectations that failed against correct engine output:
min(line 2, line 12); employer contributions are already excluded from W-2 box 1);MFJ_vs_single_1_childtest used a $30,323 phase-out start where Rev. Proc. 2024-40 §3.11 (and the engine config) has $30,470.Test plan
deno task test: 6,070 passed, 0 failed (baseline on main: 72 failing).🤖 Generated with Claude Code