Skip to content

Stamp the W-2 item facts with Tax Year 2020; the 2024 tips target moves from $28.28B to $34.29B - #1192

Open
MaxGhenis wants to merge 1 commit into
mainfrom
us-w2-items-tax-year-2020
Open

MaxGhenis wants to merge 1 commit into
mainfrom
us-w2-items-tax-year-2020

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The pinned US Chronicle feed stamped five cells of IRS SOI Table 4.B for Tax Year 2020 as ty2023. Target aging starts from a fact's period, so the 2024 W-2 Box 7 tips target aged one year where it needed four.

This PR re-pins the feed so those facts carry the year IRS published them for. The tips target moves from $28,280,884,269 to $34,287,530,779 (+21.2%). No other target changes.

Companion: PolicyEngine/chronicle#333 (tests at the source). The Chronicle package itself was already fixed on main by PolicyEngine/chronicle#292.

The finding, confirmed at the source

In the pinned feed (consumer_facts_us_c5e5bf8.jsonl, sha256 b8543739…f4839801) these facts had period.value 2023 and source.vintage tax_year_2023, while source.source_file is 20in04w2all.xlsx and source.source_table is "Table 4.B. Summary of Items for Taxpayers with Form W-2, by Return and Earner Type, Tax Year 2020":

Fact (as stamped) Value Workbook cell
irs_soi.ty2023.form_w2_social_security_tips…amount 26,786,522,000 D13
irs_soi.ty2023.form_w2_social_security_tips…return_count 6,038,613 B13
irs_soi.ty2023.form_w2_social_security_tips…taxpayer_count 6,105,713 C13
irs_soi.ty2023.form_w2_401k_elective_deferrals…amount 277,859,181,000 D22
irs_soi.ty2023.form_w2_designated_roth_401k_contributions…amount 32,302,509,000 D41

Checked on 10 October 2026:

  • IRS's Form W-2 statistics page (last reviewed 27 January 2026) links Table 4 for 2020 and 2019 only. 21in04w2all.xlsx to 24in04w2all.xlsx return 404. No TY2021, TY2022 or TY2023 Table 4.B exists. IRS's prior-releases page carries tax years 2008 to 2018 in one workbook (18inallw2.xls), so 2020 is the latest year published.
  • A fresh download of 20in04w2all.xlsx has the sha256 Chronicle pins (1178d776…cfc442f). Cell A1 of sheet "Table 4.B" is the title above. Rows 13, 22 and 41 hold the five values (money amounts in thousands).

So all five are Tax Year 2020 values. The three tips rows repeated the feed's correctly stamped irs_soi.ty2020 tips facts.

Why the feed stamped them 2023

At Chronicle c5e5bf8, soi-w2-statistics-2020 sets artifact_year: 2020, so every build reads that one workbook, but it rendered period, record ids, vintage and legal vintage from --year. us/chronicle_feed_scope.json built it at --year 2023 for three record sets.

Latest-vintage selection then took the ty2023 tips amount over its TY2020 twin. The ty2023 tips amount and return count arrived with the September re-pin (#955, merged 22 September). The July feed (b3c08356…) already carried the ty2023 401(k), Roth and tips taxpayer-count rows, none of which compiles to a target.

What changes

Feed pin

  • Chronicle commit f98acf4 (branch feed/us-c5e5bf8-w2-2020, tag microcosm-us-feed-w2-ty2020-v1): c5e5bf8 plus only the W-2 package file as chronicle#292 left it on main.
  • Scope: the three ty2023 W-2 pairs out, the TY2020 401(k) and Roth record sets in (the TY2020 tips pair was already there). 586 to 585 pairs, 62 to 61 package runs.
  • Feed: consumer_facts_us_f98acf4.jsonl, 39,155 rows, sha256 a81cbcc5…23df04c.
  • Against the old feed: 39,153 rows byte-identical; the five ty2023 ids gone; two ids new (the 401(k) and Roth amounts at ty2020, each with its twin's value and source cells).
  • tools/build_us_chronicle_feed.py built it from the new scope (10 runs, 61 packages). An independent splice of the old feed with one run of the W-2 package gives the same bytes.
  • The file is at ~/PolicyEngine/_buildh-runtime/inputs/consumer_facts_us_f98acf4.jsonl, beside the earlier pins.
  • Parity resources regenerated: 32 compiled families, 52 reviewed exclusions, 81 feed families, as before. The tips family's row count goes 6 to 3.
  • tools/route_a/route_a.sh and route_a.env.example restate the new digest and file name. The driver refuses a build commit whose pin is not its FEED_SHA.

Why not Chronicle main. At main (3dce46a6) seven more pairs of the pinned scope are no longer declared: the congressional-district file, the two IRA tables and the four state_2022 US rows. Moving those changes the year every district dollar target ages from. That is #1030's change and needs its own decisions.

Exclusion register (us_runtime/fiscal_targets.py)

A compile-time check

  • _check_w2_item_fact_tax_years runs at the start of compile_us_fiscal_target_registry and us_fiscal_target_exclusion_receipt.
  • For a fact of the three W-2 item families (irs_soi.form_w2_item layout) it requires:
    • the source table's title to name exactly one tax year;
    • that year to be the year target aging reads from the fact's period;
    • that year to be the one in the fact's tax_year_<year> vintage.
  • It refuses the old feed and names the five rows.
  • A title with no tax year, or with several, is refused too: the period could not be checked.

Effect on targets

Compiled as the release does (target period 2024, district crosswalk, aging on, Medicaid substitutions). "Before" is origin/main (7639ef8b0) compiling the old feed; "after" is this branch compiling the new one.

Before After
Compiled targets 32,842 32,842
national_state targets 5,694 5,694
national_state registry d315c75804ef 61a081ae55bb
W-2 Box 7 tips amount $28,280,884,269.41 $34,287,530,778.93
Its target name irs_soi.ty2023.form_w2_social_security_tips.box_7_social_security_tips.amount irs_soi.ty2020.form_w2_social_security_tips.box_7_social_security_tips.amount
Its aging factor 1.05578784246075: CBO wages 2024 / 2023 1.28002921689246: SOI Table 1.4 wages 2023 / 2020, then CBO wages 2024 / 2023
  • The tips target rises $6,006,646,510. That is the SOI wage growth from 2020 to 2023 that the ty2023 stamp skipped.
  • The other 32,841 targets keep their name, value and every metadata field (compared by a digest of all metadata).
  • The 401(k) and Roth amounts stay reviewed exclusions (input_side), so they move no target. SOI and CBO wage targets bind gross employment_income; the engine taxes irs_employment_income #1191 names the 401(k) amount as a candidate anchor: it is a Tax Year 2020 level.
  • The Route A release populace-us-2024-0fb05b6-4b57d15a287c-20260930T150401Z recorded the $28.28B target (tests/fixtures/us_route_a_target_loss_weights.json). This PR builds no release.

This agrees with #1030, which computed $34,287,530,779 for the same fact read at its data year.

Decisions checked

Invariants

  • Period matches the table. A W-2 item fact compiles only if its source table's title names exactly one tax year and that year is its period and its tax_year vintage (property test over generated feeds, with the verdict restated independently in the test).
  • Scope. Facts outside the W-2 item layout are never refused by this check (property; example with a Table 1.4 fact).
  • Order invariance. The list of mismatches does not depend on feed order (property).
  • Title reader. One named tax year reads back whatever surrounds it; a title naming two different years, or no tax year, never reads as one (properties, 400 examples each).
  • Differential. An honest TY2020 tips fact and its ty2023-stamped twin, compiled with the check lifted, differ by exactly the SOI wage growth from 2020 to 2023.
  • Pinned feed. The feed's W-2 item facts are exactly the five published TY2020 cells; the tips target equals $26,786,522,000 times a factor recomputed in the test from four feed facts.
  • Conservation. 32,841 targets are unchanged in name, value and metadata.

Tests

Run locally at this branch. CI has no feed and skips the pinned-feed tests; the compile-time check and the synthetic tests are what CI enforces.

  • test_us_w2_item_tax_year.py (new): 30 tests. 28 run in CI; 2 need the feed.
  • test_us_fiscal_targets.py, test_us_w2_item_tax_year.py, test_us_chronicle_feed.py and test_release_target_parity.py, with the new feed in place: 262 passed, none skipped.
  • The 8 feed-gated tests in test_us_acs_local_release_tool.py, test_us_acs_local_sparse_cd.py, test_us_release_gate_preflight.py and test_us_fiscal_refresh_builder.py pass on the new feed with MICROCOSM_US_CHRONICLE_FACTS set, so the ACS-local state and state_cd surface counts do not move.
  • test_us_chronicle_feed.py gains test_route_a_driver_restates_the_pin.
  • Mutation check on the new check: 10 mutants, all killed (check not called from the compile; not called from the receipt; period never compared; vintage never compared; a multi-year title read as its first year; check scoped to tips only; a year-less title waved through; check applied to every fact; abbreviated second year ignored; exclusion key left at ty2023).
  • python3 tools/ci_test_plan.py verify: ok. ruff check and ruff format --check on the touched files: clean.

Not changed here

axiom: n/a: calibration-target data correction; no policy rule changes.

🤖 Generated with Claude Code

…stamps them

The pinned US Chronicle feed carried five cells of IRS SOI Table 4.B for Tax
Year 2020 (20in04w2all.xlsx) with period 2023 and vintage tax_year_2023: the
Box 7 tips amount, return count and taxpayer count, the Box 12 D 401(k)
elective deferrals and the Box 12 AA designated Roth contributions. At
Chronicle c5e5bf8 the soi-w2-statistics-2020 package pins artifact_year 2020
but rendered its labels from --year, and the scope built it at --year 2023.
Tax Year 2020 is the latest Table 4.B IRS has published (checked 2026-10-10),
so no TY2023 table exists.

Latest-vintage selection took the ty2023 tips amount, so the 2024 target
aged one year on the CBO wages ratio: $28,280,884,269. Read at its tax year
it chains through SOI Table 1.4 wages from 2020: $34,287,530,779 (+21.2%).

- Re-pin the feed to Chronicle f98acf4 (c5e5bf8 plus the W-2 package file as
  chronicle#292 left it, tag microcosm-us-feed-w2-ty2020-v1). Scope 586 to
  585 pairs; feed 39,155 rows, a81cbcc5. Against the old feed 39,153 rows are
  byte-identical, the five ty2023 ids are gone and the 401(k) and Roth
  amounts return under their ty2020 ids. The builder's output is
  byte-identical to an independent splice of the old feed.
- Regenerate the target-parity resources: 32 compiled families, 52 reviewed
  exclusions, 81 feed families, as before.
- Key the #451 tips return-count exclusion to the ty2020 id. It still holds
  at every vintage (decision d179).
- Add _check_w2_item_fact_tax_years to the compile and the exclusion
  receipt: a W-2 item fact must name exactly one tax year in its source
  table title, and that year must be its period and its tax_year vintage.
- Restate the feed digest in tools/route_a/route_a.sh, with a test that
  fails if the driver falls behind the pin.

Compiled as the release does, the registry keeps 32,842 targets and
national_state 5,694 (d315c75804ef to 61a081ae55bb). The tips amount is the
only target that changes; the other 32,841 keep name, value and metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the us-w2-items-tax-year-2020 branch from 301a977 to 51a3f99 Compare October 10, 2026 20:40

This branch has not been deployed

No deployments
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