Skip to content

Load CBO's February 2026 projections through 2036 into the upraters - #10227

Open
DTrim99 wants to merge 6 commits into
mainfrom
cbo-2026-projections-2036
Open

DTrim99 wants to merge 6 commits into
mainfrom
cbo-2026-projections-2036

Conversation

@DTrim99

@DTrim99 DTrim99 commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Important

Do not merge yet. This PR is marked ready only so CI runs. Per the merge hold in PolicyEngine/policyengine-api#3926, none of the 2036 PRs merge until spm-calculator 1.1.0 (PolicyEngine/spm-calculator#51) is released. Reviews are welcome now.

Summary

Part of the US 2036 extension, tracked in PolicyEngine/policyengine-api#3926. CBO's February 2026 baseline runs through 2036, and its 10-year window is now 2027–2036. Several upraters still use older CBO vintages and stop in 2034 or 2035, so their 2036 values were extrapolations. This PR loads the February 2026 projections, so every refreshed series is CBO-based through 2036 and extrapolation starts in 2037.

It also extends the payroll cap after 2036 with the 42 U.S.C. 430(b) fixed-base formula, which the previous chained formula did not follow.

Based on main after #10225 merged, and merged with main again on 2026-10-23 (no conflicts). It grows from #10225's 2027 COLA and cap actuals and from SSA's published 2025 wage index.

How each series is refreshed

Each uprater grows from its latest actual at CBO's projected rate. Pasting CBO's levels after the actuals would understate the first projected year: actual 2026 inflation, and the official 2027 COLA and cap, came in above CBO's February path. With levels, the 2028 COLA would be 1.68% (CBO's 2027Q3 CPI-U 341.281 × 327.075 / 333.952 = 334.253, over the 2026Q3 CPI-W 328.746) against CBO's 2.49%, and the 2028 cap would rise 2.96% against 3.61%.

Series Anchor Growth Last CBO year
gov.ssa.uprating 2026Q3 CPI-W behind the 2027 COLA (328.746) CBO quarterly CPI-U, each Q3 over 2026Q3 (CBO publishes no CPI-W) 2036 (2035Q3)
gov.usda.snap.uprating June 2026 CPI-U (333.952) CBO quarterly CPI-U, each Q2 over 2026Q2 October 2036 (2036Q2)
gov.hhs.uprating the index's 2026 value (328.4), unchanged CBO calendar-year CPI-U over 2026 2036
gov.ssa.nawi SSA's published NAWI(2025) (72,800.33, from #10225) CBO's CBB over its 2027 CBB (191,100) 2034, which sets the 2036 cap
gov.irs.payroll.social_security.cap the official 2026 and 2027 bases, unchanged 42 U.S.C. 430(b) on the projected NAWI, rounded to $300 2036
gov.bls.cpi.cpi_w the series' existing method: CBO quarterly CPI-U × 327.075 / 333.952, the June 2026 not seasonally adjusted ratio from #10133 CBO quarterly CPI-U 2036Q4
gov.bls.cpi.cpi_u, gov.bls.cpi.c_cpi_u none: CBO's calendar-year levels, to one decimal, at each February instant CBO levels 2036
gov.irs.uprating chained CPI-U averaged from August to July (get_irs_cpi; #9105 tracks the one-month offset from the 12 months ending August in 26 U.S.C. 1(f)) CBO's chained CPI-U points through the 2035 instant 2036

HHS holds 2026. The 2026 poverty guidelines are explicit values, but Head Start spending is uprated from its 2023 values by this index. Partner contract tests under partners/analytics_coverage/.../head_start and .../early_head_start pin 2026 per-slot amounts derived from 328.4. Moving 2026 to CBO's February path (331.3) would change about 28 of those expected values by +0.89%. So 2026 keeps 328.4, and 2027–2036 grow from it at CBO's February 2026 rates. Poverty-guideline uprating from 2027 therefore follows CBO's growth exactly, and no partner test changes. The YAML also notes that gov/hhs/fpg.yaml grows guideline year Y by CPI-U CY(Y)/CY(Y-1), one year ahead of the CY(Y-1)/CY(Y-2) interval in 42 U.S.C. 9902(2) and the HHS notices. That mapping predates this PR (#5911), and aligning it changes a shared index, so it is left for a separate PR.

CPI-U and chained CPI-U keep CBO's 2035 point and add its 2036 point.

  • Each February instant holds CBO's calendar-year average for that year; the YAML's "# YYYY value" labels name the tax year it feeds. Both series already held CBO's February 2026 calendar-2035 value at the 2035 instant: 407.3 and 219.2.
  • extend_parameter_values(..., last_projected_year=2034) overwrote that instant with an extrapolation: 407.40 and 219.08.
  • IRS uprating read the YAML point only because it runs before the extension. Every parameter uprated directly by CPI-U saw the extrapolated value.
  • The 2036 instants now hold CBO's calendar-2036 values, 416.5 (416.542) and 223.5 (223.479), and last_projected_year is 2036, so extrapolation starts at the 2037 instant. HHS 2036 already uses 416.542, so the model now holds one 2036 CPI-U projection.
  • IRS uprating doesn't change: IRS 2036 averages August 2034 to July 2035, and IRS 2037 is still extrapolated at the 2035–2036 IRS growth (221.333; averaging the loaded points would give 221.35, +0.008%).
  • extend_single_year_dataset takes its default end year from the last authored CPI-U year, so single-year datasets now extend through 2036 by default, not 2035. test_extend_single_year_dataset.py pins that year and moves to 2036.

The payroll cap after 2036 follows 42 U.S.C. 430(b). The extension now computes the base for year Y as the larger of the base for Y-1 and $60,600 × NAWI(Y-2) / NAWI(1992), rounded to the nearest $300. The previous chained form, prior cap × NAWI(Y-2) / NAWI(Y-3), follows the wording of 20 CFR 404.1048(b)(2)(i), which Pub. L. 103-296 sec. 321(g)(1)(A) replaced for bases after 1994. On SSA's published series the fixed-base formula reproduces all 30 automatically adjusted bases from 1995 to 2027 (2010, 2011 and 2016 had no COLA, so no adjustment); the chained form reproduces 20. The 2028–2036 caps in the YAML already used 430(b), so this removes a seam at 2037: 2037–2100 now match 430(b) in all 64 years. The Trustees 2025 scenario calls the same function.

The data comes from CBO's February 2026 Economic Projections (quarterly and calendar-year cpiu and chained_cpiu) and Tax Parameters (tp_ss_max_earnings). I read them from the machine-readable US-CBO/cbo-data at 284a956, the same pinned commit spm-calculator uses. cbo.gov returns 403 to scripted downloads, so I checked each series' sheet and row against Wayback captures of the workbooks, and the YAML references cite the files with their sheet and row. Each YAML value has its formula in a comment.

Unchanged:

  • the CMS national health expenditure series, which have no projections past 2034;
  • Medicare Part B, which uses the 2035 Trustees projection.

Before and after

Values come from loading each tree's parameters (system.parameters) after the extensions run: the base is main (same uprating inputs as 3a5215d), the after is this branch. The 2037, 2050 and 2100 rows are extrapolated in both.

Long run. From 2037 each series grows at its last CBO growth rate. NAWI and the cap grow at 258,600 / 250,500 = 3.23% a year (CBO's 2036 and 2035 bases, which CBO rounds to $300), against 3.40% before. By 2100 NAWI is 11.0% lower than on main (804,774 against 904,606) and the cap 10.8% lower (1,995,300 against 2,235,900); the 2040 PIA bend points are $2,059 and $12,414 against $2,094 and $12,624. CBO's base growth for 2029–2036 ranges from 3.19% to 3.79%, so a multi-year rate would give a somewhat faster long-run path; that is a method change for a follow-up.

2036, before and after:

Series Before After Change
SSA uprating (January) 396.362 403.287 +1.75%
SNAP uprating (October) 409.084 419.448 +2.53%
HHS uprating (January) 410.297 412.265 +0.48%
IRS uprating (January) 217.031 217.050 +0.01%
NAWI 106420.49 104988.75 -1.35%
Payroll cap 263100 260400 -1.03%
CPI-U (February instant) 416.601 416.500 -0.02%
Chained CPI-U (February instant) 223.341 223.500 +0.07%
CPI-W (August instant) 404.548 409.096 +1.12%
SSA uprating (January), 2027–2037, 2050 and 2100
Year Before After Change
2027 328.746 328.746 +0.00%
2028 332.241 336.945 +1.42%
2029 339.431 344.854 +1.60%
2030 346.917 352.722 +1.67%
2031 354.600 360.699 +1.72%
2032 362.579 368.845 +1.73%
2033 370.656 377.171 +1.76%
2034 379.028 385.681 +1.76%
2035 387.598 394.385 +1.75%
2036 396.362 403.287 +1.75%
2037 405.324 412.390 +1.74%
2050 542.045 551.224 +1.69%
2100 1657.856 1682.750 +1.50%
SNAP uprating (October), 2027–2037, 2050 and 2100
Year Before After Change
2027 335.500 342.578 +2.11%
2028 342.700 350.710 +2.34%
2029 350.300 358.747 +2.41%
2030 358.100 366.868 +2.45%
2031 366.100 375.156 +2.47%
2032 374.300 383.625 +2.49%
2033 382.700 392.282 +2.50%
2034 391.300 401.134 +2.51%
2035 400.093 410.188 +2.52%
2036 409.084 419.448 +2.53%
2037 418.277 428.917 +2.54%
2050 558.383 573.338 +2.68%
2100 1696.295 1750.530 +3.20%
HHS uprating (January), 2027–2037, 2050 and 2100
Year Before After Change
2027 336.100 336.766 +0.20%
2028 343.600 344.719 +0.33%
2029 351.300 352.606 +0.37%
2030 359.200 360.587 +0.39%
2031 367.200 368.732 +0.42%
2032 375.500 377.055 +0.41%
2033 383.900 385.564 +0.43%
2034 392.500 394.265 +0.45%
2035 401.300 403.163 +0.46%
2036 410.297 412.265 +0.48%
2037 419.496 421.572 +0.49%
2050 559.644 563.531 +0.69%
2100 1695.847 1720.709 +1.47%
IRS uprating (January), 2027–2037, 2050 and 2100
Year Before After Change
2027 181.980 181.980 +0.00%
2028 186.096 186.096 +0.00%
2029 189.150 189.150 +0.00%
2030 193.000 193.000 +0.00%
2031 196.850 196.850 +0.00%
2032 200.750 200.750 +0.00%
2033 204.700 204.700 +0.00%
2034 208.750 208.750 +0.00%
2035 212.850 212.850 +0.00%
2036 217.031 217.050 +0.01%
2037 221.293 221.333 +0.02%
2050 284.958 285.342 +0.13%
2100 753.598 758.006 +0.58%
NAWI, 2027–2037, 2050 and 2100
Year Before After Change
2027 78124.71 78286.07 +0.21%
2028 81080.80 81028.94 -0.06%
2029 84149.34 83771.81 -0.45%
2030 87090.55 86514.68 -0.66%
2031 90031.76 89486.12 -0.61%
2032 93088.94 92343.28 -0.80%
2033 96258.56 95429.00 -0.86%
2034 99536.06 98514.73 -1.03%
2035 102920.73 101700.24 -1.19%
2036 106420.49 104988.75 -1.35%
2037 110039.27 108383.60 -1.50%
2050 169956.99 163920.76 -3.55%
2100 904606.38 804773.88 -11.04%
Payroll cap, 2027–2037, 2050 and 2100
Year Before After Change
2027 192300 192300 +0.00%
2028 198600 199200 +0.30%
2029 206400 206700 +0.15%
2030 214200 214200 +0.00%
2031 222300 221400 -0.40%
2032 230100 228600 -0.65%
2033 237900 236400 -0.63%
2034 246000 243900 -0.85%
2035 254400 252000 -0.94%
2036 263100 260400 -1.03%
2037 272100 268800 -1.21%
2050 420300 406500 -3.28%
2100 2235900 1995300 -10.76%
CPI-U (February instant), 2027–2037, 2050 and 2100
Year Before After Change
2027 340.300 340.300 +0.00%
2028 348.300 348.300 +0.00%
2029 356.300 356.300 +0.00%
2030 364.300 364.300 +0.00%
2031 372.600 372.600 +0.00%
2032 381.000 381.000 +0.00%
2033 389.600 389.600 +0.00%
2034 398.400 398.400 +0.00%
2035 407.399 407.300 -0.02%
2036 416.601 416.500 -0.02%
2037 426.011 425.908 -0.02%
2050 569.542 569.408 -0.02%
2100 1739.981 1739.615 -0.02%
Chained CPI-U (February instant), 2027–2037, 2050 and 2100
Year Before After Change
2027 187.200 187.200 +0.00%
2028 191.100 191.100 +0.00%
2029 194.900 194.900 +0.00%
2030 198.800 198.800 +0.00%
2031 202.700 202.700 +0.00%
2032 206.700 206.700 +0.00%
2033 210.800 210.800 +0.00%
2034 214.900 214.900 +0.00%
2035 219.080 219.200 +0.05%
2036 223.341 223.500 +0.07%
2037 227.685 227.884 +0.09%
2050 292.475 293.356 +0.30%
2100 766.266 774.897 +1.13%
CPI-W (August instant), 2027–2037, 2050 and 2100
Year Before After Change
2027 334.253 334.253 +0.00%
2028 342.098 342.098 +0.00%
2029 349.903 349.903 +0.00%
2030 357.817 357.817 +0.00%
2031 365.898 365.898 +0.00%
2032 374.157 374.157 +0.00%
2033 382.600 382.600 +0.00%
2034 391.234 391.234 +0.00%
2035 395.622 400.064 +1.12%
2036 404.548 409.096 +1.12%
2037 413.676 413.687 +0.00%
2050 552.884 552.957 +0.01%
2100 1687.127 1688.044 +0.05%

Tests

tests/policy/baseline/parameters/test_uprating_extensions.py:

  • test_upraters_encode_cbo_february_2026_projections (100 cases) checks every CBO-based value of the SSA, SNAP and HHS upraters, NAWI (through 2034), CPI-W, CPI-U and chained CPI-U against CBO's February 2026 data applied to its anchor, at the YAML's precision. The expected values come only from CBO's data and the named BLS and SSA actuals, never from a parameter. They include the last two CBO points of each series, which set its 2037–2100 growth, so an off-by-one end year or a wrong seam value fails.
  • test_projected_payroll_caps_follow_430b_through_2036 checks the 2028–2036 caps against 42 U.S.C. 430(b) and pins 2036 at 260,400.
  • test_irs_uprating_averages_cbo_chained_cpi_u_points checks IRS uprating for 2029–2036 against CBO's chained CPI-U points over the August–July window.
  • test_upraters_extrapolate_only_after_cbo_projections runs over the eight refreshed series and checks that each holds its final projected growth only after CBO's last year.
  • tests/microsimulation/data/test_extend_single_year_dataset.py now expects the CPI-U YAML to end in 2036.
  • The payroll-cap extension check now uses the 430(b) fixed-base formula at 2037, 2040, 2050, 2073 and 2100, as does the 2025 known-value check; the wage-indexed amounts check adds 2037, the first year that reads an extrapolated NAWI.

Run locally on Python 3.11 with policyengine-core 3.33.12: test_uprating_extensions.py, 141 passed; the ERDC integration, AB 2591 and basic_standard_deduction.yaml files, 42 passed.

CI on the full suites found three test files whose expectations move only because of the refreshed projections. c3d0880 and 493ec45 update them:

Test Old New Why it moves
states/or/delc/erdc/integration.yaml, Case 2: the 2027 ERDC initial income limit for 2 people 3,692 3,699 200% of the 2027 poverty guideline, rounded up. HHS uprating grows 2027 at CBO's rate: 336.766 / 328.4, not 336.1 / 328.4.
usda/snap/snap_max_allotment.yaml: FY2028 maximum allotment for 4 people 1,027.74 1,049.42 1,023 × 342.578 / 333.952. The old 335.5 was CBO's earlier 2027Q2 level, only 0.46% above the actual June 2026 CPI-U. Growing from June 2026 at CBO's 2027Q2/2026Q2 rate gives 2.58%.
contrib/states/ca/ab2591/ca_ab2591.yaml: the reform's 2027 standard deduction (six cases) 16,334 / 22,147 / 33,774 16,367 / 22,191 / 33,841 The deduction equals the 2027 poverty guideline for 1, 2 and 4 people. It moves with the same 2027 HHS growth as the Oregon case.

The ERDC case and the AB 2591 header now show their derivations. basic_standard_deduction.yaml's 2042 derivation comments now follow the chained CPI-U extension, which starts after the 2036 point (2041: 246.299); its expected values don't move. Every other suite passed at 493ec45, including the Contrib suites and Household API Partners, so the Head Start partner tests don't move. No partners/** file is edited.

axiom: n/a: projection data refresh, no change in law

🤖 Generated with Claude Code

https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

@DTrim99

DTrim99 commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Local check status:

  • test_uprating_extensions.py: 40 passed.
  • The targeted run of the 261 future-year YAML files was stopped by this machine's memory limits after 3 files, all of which passed. That is not enough to rule out churn.
  • CI covers the rest once this PR targets main, after Update Social Security and SSI parameters for the 2027 COLA #10225 merges, and is marked ready. pr.yaml skips drafts and non-main bases.
  • No partners/** file is edited.

@DTrim99
DTrim99 force-pushed the cbo-2026-projections-2036 branch from 69b39ee to 53c4fb3 Compare October 15, 2026 16:01
Base automatically changed from ssa-2027-cola to main October 19, 2026 15:11
@DTrim99
DTrim99 force-pushed the cbo-2026-projections-2036 branch from 53c4fb3 to b08acc7 Compare October 20, 2026 14:18
@DTrim99
DTrim99 marked this pull request as ready for review October 21, 2026 13:29
SSA and SNAP uprating and the national average wage index grow from
their latest actuals at CBO's February 2026 rates. The payroll cap
applies 42 U.S.C. 430(b) to that wage index, CPI-W extends to 2036Q4
at its existing ratio, and the HHS index grows from its 2026 value.

CPI-U and chained CPI-U keep CBO's 2035 projection point instead of
extrapolating over it, and IRS uprating reads it for 2036. Every
refreshed series extrapolates only from 2037.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@DTrim99
DTrim99 force-pushed the cbo-2026-projections-2036 branch from b08acc7 to 4510721 Compare October 21, 2026 14:55
DTrim99 and others added 2 commits October 21, 2026 14:11
Oregon ERDC's 2027 initial income limit is 200% of the projected 2027
poverty guideline. Growing HHS uprating at CBO's 2027 rate moves the
boundary from 3,692 to 3,699, so the strict-limit case now uses 3,699.

The FY2028 SNAP maximum allotment uprates the published FY2027 value.
Growing from June 2026 CPI-U at CBO's 2027Q2 rate gives 342.578, not
CBO's older 335.5 level, so the four-person allotment is 1,049.42.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The reform's 2027 standard deduction equals the projected poverty
guideline for the household's size. HHS uprating now grows 2027 at CBO's
rate (336.766 / 328.4), so the one-, two- and four-person values are
16,367, 22,191 and 33,841.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Program Review

PR #10227, "Load CBO's February 2026 projections through 2036 into the upraters" (DTrim99). Round 1, full review.

IDs: C = critical, SA = should address, G = suggestion.

Paths: U = policyengine_us/parameters/uprating_extensions.py, T = policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py. Parameter paths such as gov/ssa/uprating.yaml are under policyengine_us/parameters/. Line numbers refer to the reviewed head. PDF links use the file page number (file page = printed page + 8 in the CBO report).

Source Documents

Branch Status

  • The branch is 3 commits ahead and 47 behind main (237da945eb), and it is MERGEABLE. The staleness did not affect any finding.
  • Merge condition: the PR's own hold. Do not merge until spm-calculator 1.1.0 (PolicyEngine/spm-calculator#51) is released, per PolicyEngine/policyengine-api#3926. On 2026-10-23, PyPI has spm-calculator 1.0.1. This is a merge condition, not a finding about the code.

What is correct

All 198 changed values recompute from the cited CBO, SSA and BLS data with 0 mismatches, and every comment formula in the changed YAML gives its value. The anchors are right: SSA 2027 = 328.746 is the 2026Q3 CPI-W mean (327.104, 328.481, 330.654) and gives the published 3.6% COLA; SNAP October 2026 = 333.952 is June 2026 CPI-U; NAWI 2025 = 72,800.33 is SSA's published value; the 2026 and 2027 caps are SSA's 184,500 and 192,300. The anchor-and-grow method is sound. The NAWI back-out divides by CBO's own 2027 base (191,100), which keeps CBO's growth on one vintage. The 2028-2036 caps follow 42 U.S.C. 430(b) exactly, and no product is on a $150 tie. The 2027 wage-indexed amounts reproduce the SSA fact sheet (quarter of coverage $1,970, earnings test $25,560, SGA $1,770). The SSA CPI-U proxy agrees with CBO's own COLA path: CBO projects COLAs of 2.3% a year for 2029-2036 (#page=74), and the PR's implied COLAs average 2.27%. NAWI ends in 2034, the year behind CBO's last base (2036), and nothing reads NAWI 2035 as a CBO point. The CPI-U and chained CPI-U fix is right: CBO's 2035 points 407.3 and 219.2 now survive the extension (before: 407.40 and 219.08). The PR-body tables reproduce: 98 checkable rows of the nine 2027-2037 tables, the IRS 2027 row and all nine rows of the 2036 table. The three moved YAML tests are right: ERDC Case 2 is still exactly at the strict limit (ceil(2 x 22,191.28 / 12) = 3,699 and the rule is <), the SNAP FY2028 allotment is 1,023 x 342.578 / 333.952 = 1,049.42, and the six AB 2591 cases are within their $1 margin. No partner file is edited, all 623 partner tests pass in a local read-only run, and CI passes 27 of 27. The changelog fragment is top-level, typed changed and named after the branch. The PR body has the axiom line.

Critical (Must Fix)

C1. The SNAP uprater cites the wrong paragraph of 7 U.S.C. 2012(u).

  • Where: gov/usda/snap/uprating.yaml:29-30 (title: 7 U.S. Code § 2012(u)(4), href: ...2012#u_4).
  • What is wrong: Pub. L. 119-21 sec. 10101(a) (July 4, 2025) rewrote subsection (u). The October 1 adjustment "to reflect changes in the Consumer Price Index for All Urban Consumers ... for the most recent 12-month period ending in June" is now (u)(3)(C). Paragraph (u)(4) is now "Re-evaluation of market baskets". The enrolled law has the same structure (#page=11). The citation was right when #3976 added it in February 2024, because the former (u)(4) held the June adjustment. It became wrong in July 2025.
  • Why this PR: the two lines are unchanged context, but the PR rewrites the reference list of this block (it replaces the CBO 59710 entry). The citation is the only legal basis for the 10 values that the PR changes (October 2027 to October 2036), and the PR's method (June 2026 actual x CBO Q2 growth) uses the (u)(3)(C) text. An incorrect section citation is critical. main still has it, and no issue or PR tracks it. The fix changes metadata only. No value or test moves.
  • Fix: replace lines 29-30:
    - title: 7 U.S. Code § 2012(u)(3)(C)
      href: https://www.law.cornell.edu/uscode/text/7/2012#u_3_C

Optional, for the 2020-2024 actuals (former rule) and the link to the maximum allotments:

    - title: 7 U.S. Code § 2012(u)(4) (2023 edition, before Pub. L. 119-21)
      href: https://www.govinfo.gov/content/pkg/USCODE-2023-title7/html/USCODE-2023-title7-chap51-sec2012.htm
    - title: 7 CFR 273.10(e)(4)(ii)
      href: https://www.ecfr.gov/current/title-7/part-273/section-273.10#p-273.10(e)(4)(ii)

Should Address

SA1. The payroll cap extension after 2036 does not use the 42 U.S.C. 430(b) formula.

  • Where: U:774-810 (extend_social_security_payroll_cap, docstring at U:782-784), called at U:994-998 with the new start year. The test is T:313-318. The PR's own 430(b) loop is T:459-462.
  • What is wrong: the function chains the rounded prior-year cap: round300(cap(Y-1) x NAWI(Y-2) / NAWI(Y-3)). 42 U.S.C. 430(b) uses a fixed base: the larger of the base in effect and $60,600 x NAWI(Y-2) / NAWI(1992), rounded to the nearest $300 (a multiple of $150 rounds up). SSA's method page states the same fixed-base formula. The docstring says that the function "follows the statutory formula in 20 CFR 404.1048". 20 CFR 404.1048(b)(2)(i) still has the chained wording, but its last amendment is from 1992. Pub. L. 103-296 sec. 321(g)(1) replaced that formula for bases after 1994, so the statute controls.
  • Evidence: a probe shows that the fixed-base formula reproduces all 30 actual bases from 1995 to 2027. The chained wording reproduces only 20 of 30 (it misses by $300 in 1997-2000, 2009, 2013, 2014, 2017, 2018 and 2022). For 2037-2100 the head differs from 430(b) in 44 of 64 years: +$300 in 16 years from 2040 to 2061 (2040: 295,800 against 295,500) and -$300 to -$1,500 in all 28 years from 2073 to 2100 (2100: 1,993,800 against 1,995,300). The same values feed gov.ssa.social_security.wage_base. The PR now states and tests 430(b) for 2028-2036 (gov/irs/payroll/social_security/cap.yaml:64-76, T:459-462), so one parameter follows two methods with a seam at 2037, and one test file asserts two formulas for the same quantity. The function predates the PR (#7912). The PR moves its start year and edits the T:313 year list that pins the chained values. No issue tracks it.
  • Severity: the indexing structure is right and the rounding enters at the wrong place, so this is should-address, not critical. The largest gap is 0.10%. No test outcome and no partner pin moves.
  • Fix: a mutation test on a copy with this fix passes test_uprating_extensions.py, tests/policy/contrib/ssa/test_trustees_core_thresholds.py and tests/core/test_per_capita_uprating.py (99 passed) and the four YAML files with periods of 2036 or later. Then 0 of 64 years differ from 430(b). Replace U:774-810:
def extend_social_security_payroll_cap(
    parameters: ParameterNode,
    last_projected_year: int,
    end_year: int,
) -> None:
    """
    Extend the Social Security contribution and benefit base through `end_year`.

    Follows 42 U.S.C. 430(b) on the projected national average wage index
    (NAWI): the base for year Y is the larger of the base in effect for Y - 1
    and the 1994 base ($60,600) times NAWI(Y - 2) / NAWI(1992), rounded to the
    nearest $300 (a multiple of $150 rounds up). 20 CFR 404.1048(b)(2)(i)
    still states the pre-1995 chained formula, which Pub. L. 103-296,
    sec. 321(g)(1), replaced for bases after 1994.
    """
    cap = parameters.gov.irs.payroll.social_security.cap
    nawi = parameters.gov.ssa.nawi
    base_1994 = cap("1994-01-01")
    nawi_1992 = nawi("1992-01-01")

    for year in range(last_projected_year + 1, end_year + 1):
        current_cap = cap(f"{year - 1}-01-01")
        proposed_cap = round_social_security_payroll_cap(
            base_1994 * nawi(f"{year - 2}-01-01") / nawi_1992
        )
        cap.update(
            period=f"year:{year}-01-01:1",
            value=max(current_cap, proposed_cap),
        )

    final_value = cap(f"{end_year}-01-01")
    cap.update(start=instant(f"{end_year}-01-01"), value=final_value)

Replace T:313-318. The list adds 2073, the first year in which the old chain falls below the statute:

    # 42 U.S.C. 430(b): fixed 1994 base, never below the prior year's base.
    for year in [2037, 2040, 2050, 2073, 2100]:
        expected_cap = max(
            payroll_cap(f"{year - 1}-01-01"),
            round_social_security_payroll_cap(
                payroll_cap("1994-01-01")
                * nawi(f"{year - 2}-01-01")
                / nawi("1992-01-01")
            ),
        )
        assert payroll_cap(f"{year}-01-01") == expected_cap

The fix also covers the other caller, policyengine_us/reforms/ssa/trustees_2025.py:198-202. If you prefer to keep the function body out of this PR, correct the docstring here and open the follow-up issue "Extend the Social Security payroll cap with the 42 U.S.C. 430(b) fixed-base formula".

SA2. The new tests do not pin the CBO points that set the 2037-2100 path.

  • Where: T:430-474 (test_upraters_follow_cbo_february_2026_growth_through_2036) and T:477-502 (test_upraters_extrapolate_only_after_cbo_projections). extend_parameter_values (U:742-751) grows every year after the last CBO year L at p(L) / p(L-1).
  • Part 1, p(L-1) is not pinned. A mutation test multiplied one second-to-last point at a time by 1.01. All 40 tests pass for SSA 2035 (gov/ssa/uprating.yaml:19, 394.385 to 398.329), SNAP October 2035 (gov/usda/snap/uprating.yaml:21), HHS 2035 (gov/hhs/uprating.yaml:20), CPI-W 2035-02-01 and 2036-02-01 (gov/bls/cpi/cpi_w.yaml:1404, 1408) and CPI-U 2034-02-01 (gov/bls/cpi/cpi_u.yaml:1374, an older value that the new CPI-U end year makes the growth base). For SSA the long-run growth falls from 2.257% to 1.245% a year, and the 2100 index falls 47.1% (1,682.75 to 890.10). The CPI-W 2036-02-01 mutant raises CPI-W 2100 by 91%. test_uprating_growth_rates_are_reasonable accepts every mutant, because it allows any growth from 0.5% to 5%. NAWI 2033 is protected: the cap loop at T:459-462 catches it.
  • Part 2, the parametrized test misses an extension that starts one year early. If last_projected_year is L-1, the extension overwrites p(L) with p(L-1) x g, so p(L) / p(L-1) equals every later growth. A mutation test confirms that all 9 such mutants (one constant at a time) pass the parametrized test. This is the overwrite that the PR fixes for CPI-U and chained CPI-U. The 40-test suite catches each one only through one endpoint assertion in the other test. For SSA, SNAP and HHS that margin is 2.89x, 2.29x and 6.25x the abs=5e-4 tolerance, and it exists only because CBO's last two growth rates differ in the sixth digit. With a later CBO vintage whose final growth rates are flatter, these regressions pass silently. The parametrized test does catch all 8 "starts one year late" mutants.
  • Also: the IRS 2036 assertion (T:472-474) compares with get_irs_cpi(parameters, 2035), the same call as the code at U:954, so it pins no number. A mutation of chained CPI-U 2034-02-01 moves IRS 2036 by +0.48%, and that line still passes. IRS 2036 is 217.05 = (6 x 214.9 + 6 x 219.2) / 12 (see G3 for the window).
  • Fix: append after T:502. The expected values come only from CBO February 2026 data at 284a956 and from the anchors that T already pins. None reads a parameter. At the head the block passes 16 of 16, and the whole file passes 56 of 56. The block kills every mutant above except the cap "starts early" mutant, which T:463 already catches. ruff format makes no change.
# CBO February 2026 (US-CBO/cbo-data at 284a956; quarterly_2026-02.csv and
# calendar_2026-02.csv cpiu / chained_cpiu, annual_cy_2026-02.csv
# tp_ss_max_earnings): the last two CBO points of each series.
# extend_parameter_values grows every year after the last point at the ratio
# of these two points, so both must be CBO's values.
CBO_2026_02_SEAM_QUARTERLY_CPI_U = {
    "2026Q2": 330.708,
    "2026Q3": 332.976,
    "2034Q3": 399.460,
    "2035Q1": 403.943,
    "2035Q2": 406.203,
    "2035Q3": 408.476,
    "2036Q1": 413.061,
    "2036Q2": 415.373,
}
CBO_2026_02_SEAM_CALENDAR_CPI_U = {
    2026: 331.807,
    2034: 398.355,
    2035: 407.346,
    2036: 416.542,
}
CBO_2026_02_SEAM_CALENDAR_C_CPI_U = {2033: 210.759, 2034: 214.912, 2035: 219.152}
CBO_2026_02_SEAM_CBB = {2027: 191_100, 2035: 250_500, 2036: 258_600}
_Q = CBO_2026_02_SEAM_QUARTERLY_CPI_U
_CY = CBO_2026_02_SEAM_CALENDAR_CPI_U
_CC = CBO_2026_02_SEAM_CALENDAR_C_CPI_U
_CBB = CBO_2026_02_SEAM_CBB


@pytest.mark.parametrize(
    "path,date,expected,decimals",
    [
        # SSA: 2027 anchor 328.746 x CBO CPI-U Q3(Y-1) / 2026Q3.
        ("gov.ssa.uprating", "2035-01-01", 328.746 * _Q["2034Q3"] / _Q["2026Q3"], 3),
        ("gov.ssa.uprating", "2036-01-01", 328.746 * _Q["2035Q3"] / _Q["2026Q3"], 3),
        # SNAP: June 2026 CPI-U 333.952 x CBO CPI-U Q2(Y) / 2026Q2.
        (
            "gov.usda.snap.uprating",
            "2035-10-01",
            333.952 * _Q["2035Q2"] / _Q["2026Q2"],
            3,
        ),
        (
            "gov.usda.snap.uprating",
            "2036-10-01",
            333.952 * _Q["2036Q2"] / _Q["2026Q2"],
            3,
        ),
        # HHS: 2026 value 328.4 x CBO calendar CPI-U(Y) / calendar 2026.
        ("gov.hhs.uprating", "2035-01-01", 328.4 * _CY[2035] / _CY[2026], 3),
        ("gov.hhs.uprating", "2036-01-01", 328.4 * _CY[2036] / _CY[2026], 3),
        # CPI-W February points: CBO CPI-U Q1 x June 2026 CPI-W / CPI-U.
        (
            "gov.bls.cpi.cpi_w",
            "2035-02-01",
            _Q["2035Q1"] * 327.075 / 333.952,
            3,
        ),
        (
            "gov.bls.cpi.cpi_w",
            "2036-02-01",
            _Q["2036Q1"] * 327.075 / 333.952,
            3,
        ),
        # NAWI: SSA's 2025 AWI 72,800.33 x CBO CBB(Y+2) / CBB 2027.
        ("gov.ssa.nawi", "2033-01-01", 72_800.33 * _CBB[2035] / _CBB[2027], 2),
        ("gov.ssa.nawi", "2034-01-01", 72_800.33 * _CBB[2036] / _CBB[2027], 2),
        # CPI-U and chained CPI-U: CBO calendar year Y at the Y-02-01 instant,
        # one decimal. Chained 2033 feeds the IRS 2035 window.
        ("gov.bls.cpi.cpi_u", "2034-02-01", _CY[2034], 1),
        ("gov.bls.cpi.cpi_u", "2035-02-01", _CY[2035], 1),
        ("gov.bls.cpi.c_cpi_u", "2033-02-01", _CC[2033], 1),
        ("gov.bls.cpi.c_cpi_u", "2034-02-01", _CC[2034], 1),
        ("gov.bls.cpi.c_cpi_u", "2035-02-01", _CC[2035], 1),
    ],
)
def test_upraters_encode_the_cbo_points_behind_long_run_growth(
    path, date, expected, decimals
):
    """The last two CBO points of each series set its 2037-2100 growth."""
    assert PARAMETERS.get_child(path)(date) == round(expected, decimals)


def test_irs_uprating_averages_cbo_chained_cpi_u_points():
    """IRS(Y) = get_irs_cpi(Y - 1): chained CPI-U from August Y-2 to July Y-1.

    Six months read the February Y-2 point and six read February Y-1.
    """
    irs = PARAMETERS.gov.irs.uprating
    c_cpi_u = {year: round(value, 1) for year, value in _CC.items()}
    assert irs("2035-01-01") == pytest.approx(
        (6 * c_cpi_u[2033] + 6 * c_cpi_u[2034]) / 12, rel=1e-12
    )
    assert irs("2036-01-01") == pytest.approx(
        (6 * c_cpi_u[2034] + 6 * c_cpi_u[2035]) / 12, rel=1e-12
    )

If you also apply G1 option A, move the CPI-U and chained CPI-U rows one year later (CPI-U 2035 and 2036; chained 2034, 2035 and 2036, with _CY[2036] and a chained 2036 entry of 223.479). If #9105 changes the IRS window, the IRS test changes to a 5 and 7 month split.

SA3. The reference for the HHS 2026 anchor names the wrong CBO report.

  • Where: gov/hhs/uprating.yaml:34-36. The PR changed the comment on line 35. The title and the href are older (#6343).
  • What is wrong: 328.4 is CBO's January 2025 projection of calendar 2026 CPI-U (328.446, workbook for "The Budget and Economic Outlook: 2025 to 2035"). The title names the February 2024 report ("2024 to 2034"), whose calendar 2026 value is 327.896. The href https://www.cbo.gov/data/budget-economic-data#4 is an index of more than 20 vintages, not the file. "Row 51" is right only for the original January 2025 release. CBO's April 30, 2025 update inserted medical price rows, and CPI-U is now row 53 of "2. Calendar Year" (value unchanged). The PR uses 328.4 as the anchor of all 10 changed HHS values (gov/hhs/uprating.yaml:12-21).
  • Severity: the value is right, and the comment leads a careful reader to the right file, so the reference is not missing. But a reader who follows only the title and the href cannot corroborate 328.4.
  • Fix: replace lines 34-36:
    - title: CBO | Economic Projections | January 2025
      # 2026: Sheet 2. Calendar Year, Row 53, CPI-U 328.446 (Row 51 in the original January 2025 release, before CBO's April 30, 2025 update)
      href: https://www.cbo.gov/system/files/2025-01/51135-2025-01-Economic-Projections.xlsx

Optional, the pinned CSV (it exists at 284a956):

    - title: CBO | Economic Projections | January 2025, calendar-year CSV (variable cpiu)
      href: https://github.com/US-CBO/cbo-data/blob/284a95665f9f2f74ed1f482feb629b43fce323da/data/economic/economic_projections/calendar_2025-01.csv

SA4. The new Tax Parameters reference is a landing page, not the February 2026 file.

  • Where: gov/irs/payroll/social_security/cap.yaml:94-95 and gov/ssa/nawi.yaml:107-108. The PR added both entries.
  • What is wrong: the title says "February 2026", but https://www.cbo.gov/publication/53724 redirects (301) to https://www.cbo.gov/data/budget-economic-data#10, which lists 13 Tax Parameters vintages from 2018 to 2026. The target changes when CBO publishes a new vintage. In cap.yaml the PR replaced a direct file link with a row (January 2025 file, "Row 161") with this less specific link. The PR body says that cbo.gov blocks scripts, but the file URL is the link that the index page shows, so you can cite it without a download. The series is in sheet "1. Tax Parameters", row 155, "Maximum taxable earnings for the Social Security payroll tax" (2027 191,100 to 2036 258,600), and it equals the pinned CSV.
  • Severity: the pinned CSV in the same block corroborates every value, so this is a reference-format issue, not critical.
  • Fix: in both files, replace the two lines:
    - title: CBO | Tax Parameters and Effective Marginal Tax Rates | February 2026
      # Sheet: 1. Tax Parameters, Row 155: Maximum taxable earnings for the Social Security payroll tax
      href: https://www.cbo.gov/system/files/2026-02/53724-2026-02-Tax-Parameters.xlsx

Suggestions

G1. Load CBO's calendar-2036 CPI-U and chained CPI-U points, or state the scope limit. gov/bls/cpi/cpi_u.yaml:1375-1376, gov/bls/cpi/c_cpi_u.yaml:334-335, U:1014-1032, T:468-471, T:485-486.

  • Each February instant holds CBO's calendar-year average for the same year: 2035-02-01 = 407.3 = calendar 2035 (407.346). The "# 2036 value" label names the tax year that the point feeds, as the docstring of get_projected_cpi_u_for_month (U:410-421) says. The cited data has calendar 2036 (CPI-U 416.542, chained 223.479; workbook "2. Calendar Year" rows 53 and 57), but the 2036-02-01 instant is extrapolated: 416.399 (-0.034%) and 223.586 (+0.048%). HHS 2036 already uses 416.542, so the model holds two 2036 CPI-U projections.
  • A probe that loads the two points changes no value read on January 1, 2036, so the PR's design holds for tax year 2036. Readers inside calendar 2036 move by at most 0.37% (one cent in a school-meal rate; also 629 Arkansas tax-table cells and 51 WIC amounts). From 2037, 743 values move, for example the Louisiana standard deduction (+0.10%). The long-run growth after the last point rests on two one-decimal values (407.3 / 398.4 = 2.234% against CBO's 2.258%). The comments at U:1014-1016 and T:468 and the PR-body sentence "every refreshed series is CBO-based through 2036" are true only for tax years.
  • Fix, option A (preferred; a mutation test passes 40 of 40 when T:485-486 change to 2036). In cpi_u.yaml:
  2035-02-01: 407.3 # 2036 value.
  2036-02-01: 416.5 # 2037 value.
  # Values for 2037-2100 are set programmatically in uprating_extensions.py

In c_cpi_u.yaml, add 2036-02-01: 223.5 # 2037 value. and the same trailing comment. In U:1014-1032, set both last_projected_year=2036 and use this comment:

    # CPI-U (February values, last projection year 2036). Each February
    # instant holds CBO's February 2026 calendar-year average for that year
    # (the "# YYYY value" comments name the tax year it feeds), so CBO's last
    # point, calendar 2036, sits at the 2036 instant.

Change T:485-486 to 2036, and add assert parameters.gov.bls.cpi.cpi_u("2036-02-01") == 416.5 and assert parameters.gov.bls.cpi.c_cpi_u("2036-02-01") == 223.5 at T:470-471. Optional: IRS_LAST_PROJECTED_YEAR = 2037 with T:480 at 2037 (IRS 2037 moves +0.008%, and 6,355 IRS-uprated values move).

  • Fix, option B (comments only). At U:1014-1016:
    # CPI-U (February values, last projection year 2035). Each February
    # instant holds CBO's calendar-year average for that year; the 2035
    # instant (calendar 2035) feeds tax year 2036. CBO's calendar-2036 point
    # is not loaded, so the 2036 instant and later ones are extrapolated.

In the PR body, write "CBO-based for values read in 2036; CPI-U and chained CPI-U are extrapolated from the February 2036 instant".

G2. Say in the HHS index file that it runs one year ahead of 42 U.S.C. 9902(2). gov/hhs/uprating.yaml:3, :8-10; gov/hhs/fpg.yaml:132.

  • 42 U.S.C. 9902(2) uses the CPI-U change "during the annual or other interval immediately preceding the time at which the revision is made". The five HHS notices from 2022 to 2026 state that interval as calendar years Y-2 to Y-1 (2026: a 2.63% increase between calendar years 2024 and 2025, FR 2026-00755). The repo grows guideline year Y by CY(Y) / CY(Y-1).
  • A back-cast probe from the 2022 guidelines reproduces the published 2023-2026 4-person guidelines within 0.10% with the statutory lag. With the repo mapping it misses by -3.7% to -5.6%. With the lag, the 2027 4-person guideline is about $34,011, not $33,841 (-0.50%), and the ERDC 2027 limit is $3,718, not $3,699.
  • The mapping dates from #5911 (April 2025). The PR applies it correctly and narrows the gap (before the PR: -0.70%). The fix changes a shared index, so it belongs in its own PR (see Out of scope). In this PR, replace line 3:
  # Actuals: calendar-year average CPI-U for the labeled year.
  # NOTE: 42 U.S.C. 9902(2) and the HHS notices update guideline year Y by CPI-U
  # CY(Y-1)/CY(Y-2). gov/hhs/fpg.yaml uprates guideline year Y with this index by
  # CY(Y)/CY(Y-1), one year ahead of the statute (tracked in #<follow-up issue>).

Add to metadata.reference:

    - title: 42 U.S. Code § 9902(2)
      href: https://www.law.cornell.edu/uscode/text/42/9902#2
    - title: 2026 Annual Update of the HHS Poverty Guidelines
      href: https://www.federalregister.gov/documents/2026/01/15/2026-00755/annual-update-of-the-hhs-poverty-guidelines

Name the same issue in the 2026 hold comment at lines 8-10.

G3. Correct the IRS window in the new comment and in the PR body. U:939-940 says "2036 reads the 12 months ending August 2035". get_irs_cpi (U:25-33) averages August 2034 to July 2035, so IRS 2036 = 217.05 = (6 x 214.9 + 6 x 219.2) / 12. A September-August window gives 217.41. The growth still matches CBO's tax parameter for the legal window of 26 U.S.C. 1(f): the model's 2036/2035 ratio is 1.019732, and "1. Tax Parameters" row 153 gives 217.68 / 213.471 = 1.019717. The one-month offset is older than the PR and #9105 tracks it. Fix:

    # 2036 averages chained CPI-U from August 2034 to July 2035 (see #9105);
    # the 2035 instant holds CBO's February 2026 calendar-2035 point.

In the PR-body series table, correct "chained CPI-U, 12 months ending August" in the same way. The docstring at U:26 ("Sep to Aug") has the same error. It can go with #9105.

G4. Name the sheet and row in the three Economic Projections references. gov/hhs/uprating.yaml:37-38, gov/ssa/uprating.yaml:33-34, gov/usda/snap/uprating.yaml:33-34. The hrefs open the exact file, and the pinned CSVs name the variable, so every value is reproducible. The sibling files name the row (gov/bls/cpi/cpi_w.yaml:1428, cpi_u.yaml:1394, c_cpi_u.yaml:353), and the rows are confirmed in the workbook. Fix: put a comment line between title and href. In hhs/uprating.yaml: # Sheet: 2. Calendar Year, Row 53: CPI-U. In ssa/uprating.yaml and snap/uprating.yaml: # Sheet: 1. Quarterly, Row 53: CPI-U.

G5. Document the SSA CPI-U proxy and cite the COLA statute. gov/ssa/uprating.yaml:1, :10-11, :26-36. CBO publishes no CPI-W projection, so CBO CPI-U Q3/Q3 growth stands in for CPI-W. CBO's own COLA path agrees within about 0.03 percentage points (#page=74: "2.3 percent a year from 2029 to 2036"). The file has no statutory reference. Fix: add after line 11:

  # CBO's Economic Projections publish no CPI-W series, so CBO CPI-U Q3/Q3
  # growth stands in for CPI-W Q3/Q3. CBO's own COLA path (2.3% a year for
  # 2029-2036) agrees within about 0.03 percentage points.

and add to the references:

    - title: 42 U.S. Code § 415(i)
      href: https://www.law.cornell.edu/uscode/text/42/415#i
    - title: CBO | The Budget and Economic Outlook, 2026 to 2036 | February 2026, Chapter 3, Social Security (projected COLAs)
      href: https://www.cbo.gov/system/files/2026-02/61882-Outlook-2026.pdf#page=74

Optional: rename the title "Historical values" (line 27) to SSA | Cost-of-living adjustments, 1975-present. In gov/ssa/nawi.yaml:105-106, the 2027 fact sheet has no NAWI figure, and AWI.html#Series is the direct source.

G6. Say that the projected caps differ from CBO's levels by design. gov/irs/payroll/social_security/cap.yaml:64-67. The cited CSV holds CBO's own bases (2028 198,000; 2036 258,600), but the YAML holds 199,200 and 260,400, because NAWI grows from SSA's published 2025 value and CBO's 2027 base (191,100) is below the official 192,300. A reader can take this for a mismatch. Add to the comment:

  # The levels sit above CBO's tp_ss_max_earnings (2036: 260_400 against
  # 258_600), because NAWI grows from SSA's published 2025 value; only CBO's
  # growth is used.

G7. Report the long-run effect, and consider a multi-year NAWI growth rate. U:983-989, gov/ssa/nawi.yaml:94-95, PR body. From 2035, NAWI, the cap and the wage-indexed amounts grow at 258,600 / 250,500 = 3.234%, the ratio of two bases that CBO rounds to $300. CBO's year-to-year base growth for 2029-2036 moves between 3.19% and 3.79%, and the 4-year geometric mean is 3.30%. Against the merge base, NAWI in 2100 is 11.0% lower (804,774 against 904,606) and the cap 10.8% lower. The 2040 PIA bend points are 2,059 and 12,414 against 2,094 and 12,624. Before the PR the same one-step method gave 3.40%. No legal rule applies. Suggestion: add 2050 and 2100 rows to the PR-body tables. Optionally, use an annualized multi-year rate. extend_parameter_values takes one ratio today (U:742-745), so a multi-year rate needs a root.

G8. Derive the nine end years from the YAML. U:941, 964, 973, 985, 996, 1008, 1019, 1028, 1038. The CPI-U overwrite that this PR fixes came from an end year that fell behind the YAML. Other extenders in the same file take the boundary from the data (first_projected_year = 1 + max(...) at U:166-168). Suggestion: take last_projected_year from the last values_list instant at the series' month, and the IRS year from the last chained CPI-U February instant plus 1. Until then, the SA2 block catches a stale constant.

G9. Confirm the Trustees 2025 scenario horizon. policyengine_us/reforms/ssa/trustees_2025.py:19 and :121 (NAWI start_year 2034), :200 (cap last_projected_year=2035). The file is outside the diff, but the PR moves the CBO horizon under it. CBO-based NAWI now runs through 2034 and the cap through 2036, so the scenario now replaces CBO's 2034 NAWI (98,514.73) and the 2036 cap. The pair is consistent with itself. Confirm that this is the intent, or set start_year to 2035 at :19 and :121 and last_projected_year=2036 at :200 (the SOI projection at :151 already uses 2036).

G10. Tighten three test details.

  • T:511: add 2037, the first year that reads an extrapolated NAWI (2038 before the PR): for year in [2027, 2036, 2037, 2050, 2100]:.
  • T:466: name the June 2026 actuals, as the dicts at T:416-427 do, for example JUNE_2026_CPI_W = 327.075 # BLS CWUR0000SA0 and JUNE_2026_CPI_U = 333.952 # BLS CUUR0000SA0.
  • T:419-474: SSA, SNAP and HHS 2028-2034 and CPI-W 2035-05-01 to 2036-08-01 are not compared with CBO. A loop over the full CBO column covers them. The approx(abs=5e-4) checks mean "correctly rounded", and SNAP October 2036 (419.4475008) passes by 8e-7. Exact == round(expected, 3), as in SA2, states the intent.

G11. Add the derivation to ERDC Case 2. policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml:38-64. The case is still at the strict limit, but it only pins "limit <= 3,699". If a later refresh lowers HHS 2027, the case still passes, but no longer at the limit. Add above the case:

# 2027 2-person FPG = (15,960 + 5,680) x 336.766 / 328.4 = 22,191.28.
# Initial limit = ceil(22,191.28 / 12 x 2) = ceil(3,698.55) = 3,699. The rule
# is income < limit, so income of 3,699 is ineligible.

Optional: add a 2027-01 case at 3,698 (eligible) to or_erdc_income_eligible.yaml, which already pins the 2026 pair 3,606 / 3,607. Run it before you commit it. The output or_erdc_countable_income: 3_699 (line 61) echoes the input and checks nothing; that is older than the PR.

G12. Make the AB 2591 header add up. policyengine_us/tests/policy/contrib/states/ca/ab2591/ca_ab2591.yaml:5-10. 16,367 + 5,825 = 22,192, not 22,191, and 16,367 + 3 x 5,825 = 33,842, not 33,841. The model uses the unrounded parts (16,366.58 and 5,824.70), so the outputs are right. Fix:

# 2027 federal poverty guidelines (CONTIGUOUS_US), 2026 values x 336.766 / 328.4:
#   first person = $16,366.58
#   additional person = $5,824.70
#   1-person FPL  = $16,367 (rounded)
#   2-person FPL  = $22,191 (rounded)
#   4-person FPL  = $33,841 (rounded)

G13. Drop one trailing zero. gov/usda/snap/uprating.yaml:14: write 2028-10-01: 350.71 # 2028Q2: 333.952 * 347.303 / 330.708. The parameter rule says no trailing zeros. The sibling CPI-W file keeps fixed precision (376.250), so this is cosmetic. Keep 95_429.00 at gov/ssa/nawi.yaml:94: that file uses SSA's two-decimal form for every value (27_426.00 at line 49), and 95_429 would load as an integer.

G14. Correct one PR-body number. The sentence "With levels, the 2028 COLA would be 1.62% against CBO's 2.49%" does not reproduce. A probe over 6 CBO levels and 8 CPI-W/CPI-U ratios finds no 1.62%. The natural reading, CBO 2027Q3 CPI-U 341.281 x 327.075 / 333.952 = 334.253 over the 2026Q3 CPI-W 328.746, gives 1.68%. The 2.49%, 2.96% and 3.61% in the same paragraph reproduce. Fix: write "1.68% (CBO's 2027Q3 CPI-U 341.281 x 327.075 / 333.952 = 334.253, over the 2026Q3 CPI-W 328.746)", or give the formula behind 1.62%.

Investigated and cleared

  • SNAP description "approximates that uprating via CPI-U" (gov/usda/snap/uprating.yaml:1). It is accurate. USDA reprices the Thrifty Food Plan market basket with CPI-U food and item indexes (FNS monthly cost reports) and sets the maximum allotment at the June TFP cost, rounded down (7 CFR 273.10(e)(4)(ii)). FY2026 $994 and FY2027 $1,023 match the TFP cost. The all-items CPI-U would give $1,001 and $1,029. CBO projects only all-items CPI-U, so the index approximates in actual and projected years. A proposal to say that only the projections approximate was rejected. Optional: write the description as one sentence that spells out the program name.
  • HHS 2026 hold at 328.4. The YAML and the PR body document it. It keeps the Head Start and Early Head Start partner pins. FPG growth from 2027 does not change (it is a ratio to 2026). Only Head Start and Early Head Start spending from 2026 is about 1.0% low. No legal rule sets this level. It goes into the HHS follow-up issue.
  • NAWI vintage pairing. The back-out divides by CBO's own 2027 base (191,100), not the official 192,300. This keeps CBO's growth on one vintage. The $300 rounding moves each ratio by at most about 0.08% and does not compound.
  • NAWI 2035 removal. The cap, the wage-indexed amounts, the overtime thresholds and ss_aime read the extrapolated value after the NAWI extension runs. None treats it as a CBO point. The cap metadata uprating: gov.ssa.nawi (cap.yaml:81) has no effect, because the extension writes every year through 2100.
  • IRS 2036 value. It is 217.05, not 217.408. A value proposed during the review assumed a September-August window, and it fails on the real code.
  • CPI-W after 2036Q4. The annual February extension gives +1.12% from August 2036 to August 2037. The CPI-W level in 2027Q3 is 0.8% below the SSA uprater (334.253 against 336.945). The only reader, the Washington millionaires deduction, takes a 12-month ratio, and its 2028-2040 values are the same at the base and the head.
  • snap_max_allotment.yaml period 2027-11 (older, unchanged). The variable is MONTH-defined and the case needs FY2028. It passes in CI and locally.
  • ERDC Case 2 input moved with its output. This was necessary (3,692 would now be eligible), and the case is still at the strict limit.
  • Partner contract tests. No partners/** file is edited, and no partner test has a period after 2026. The HHS 2026 hold keeps the Head Start pins, and all 623 partner tests pass. This PR has no partner-facing change.
  • Severity disputes. The SNAP citation stays critical, because the PR edits that reference block and the fix is metadata only. The HHS lag is a pre-existing method issue: a note in this PR (G2) and a fix in a follow-up. The cap extension is should-address, not a suggestion: it contradicts a clear rule, and its docstring claims to follow the statute. The CPI-U 2036 instant is a suggestion, because no value read on January 1, 2036 changes. The missing sheet and row are a suggestion (the hrefs open the exact file), and the landing-page href is should-address. The test gaps in SA2 are should-address: the mutation tests show that a 1% error at the seam passes all 40 tests.

Out of scope / follow-up

  • "Federal poverty guideline projections lead the 42 U.S.C. 9902(2) CPI-U interval by one year" (pre-existing since #5911; include the 2026 hold). Designs: A, redefine gov.hhs.uprating so that instant Y holds CY(Y-1); B, a new FPG-only lagged index for gov/hhs/fpg.yaml:132; B', cadence metadata on fpg.yaml with 2026-2036 at CBO levels. Design B leaves the Head Start and Early Head Start partner pins unchanged. Designs A and B' move those partner pins (A: 2025 +1.46%, 2026 +2.07%). That is a partner-facing change, and it needs the partner gate before anyone edits a partner file. Under every design, the 2027 ERDC and AB 2591 expectations move.
  • "get_irs_cpi averages August-July, not the 12 months ending August": #9105 tracks it.
  • "CPI-U and chained CPI-U February points are calendar-year averages, not 12 months ending August": #9608 tracks it.
  • "Round projected SNAP maximum allotments down to the dollar (7 CFR 273.10(e)(4)(ii))": FY2028 is 1,049.42, and the rule gives 1,049.
  • "Round projected Social Security COLA steps to 0.1 percent (42 U.S.C. 415(i)(1)(D))": the 2028 step is 2.494%, and the statutory COLA is 2.5%.
  • "Index the SNAP standard deduction to CPI-U for items other than food (7 U.S.C. 2014(e)(1)(A)(ii)(II))": it uses the TFP-based SNAP index today, as do the shelter cap and the utility allowances.
  • "Remove the stale January 2025 CBO reference from cpi_w.yaml" (gov/bls/cpi/cpi_w.yaml:1424-1426): it supports no current value, and "Row 51" is stale since CBO's April 30, 2025 update.
  • "Fix CBO reference titles in cpi_u.yaml that name Tax Parameters but link Economic Projections files" (gov/bls/cpi/cpi_u.yaml:1384-1391).

Data Audit Summary

The PR cites no PDF for a value, so this table replaces the PDF audit. All values were recomputed from the cbo-data CSVs at 284a956, which equal the CBO workbook rows, and from the BLS and SSA series.

Group Checks Formula or source Result
Anchors 15 BLS CPI-W and CPI-U June and Q3 2026; SSA NAWI 2025 and 1992, CBB 1994, 2026 and 2027; CBO 2027 base and 2026 CPI-U bases; CBO January 2025 calendar 2026 (328.446) Match
SSA uprating 2028-2036 9 328.746 x CBO CPI-U Q3(Y-1) / 332.976 ("1. Quarterly", row 53) 9 of 9
SNAP uprating October 2027-2036 10 333.952 x CBO CPI-U Q2(Y) / 330.708 (row 53) 10 of 10
HHS uprating 2027-2036 10 328.4 x CBO calendar CPI-U(Y) / 331.807 ("2. Calendar Year", row 53) 10 of 10 (same-year mapping, G2)
NAWI 2026-2034 9 72,800.33 x CBO base(Y+2) / 191,100 ("1. Tax Parameters", row 155) 9 of 9
Payroll cap 2028-2036 9 430(b): 60,600 x NAWI(Y-2) / 22,935.42, nearest $300 9 of 9, no $150 tie
CPI-W 2035-05-01 to 2036-11-01 7 CBO CPI-U quarter x 327.075 / 333.952 7 of 7
Test constants 14 CSV values and literals in T 14 of 14
Moved YAML test values 7 ERDC Case 2, SNAP FY2028, AB 2591 1, 2 and 4 persons, and the two AB 2591 header components Match
PR-body tables 108 98 checkable rows of the nine 2027-2037 tables, the IRS 2027 row and the nine 2036 rows; parameter tree probe at the head and the merge base Match
CSV against workbook (not counted) 85 points 56 quarterly, 14 calendar, 15 tax-parameter 0 differences
PR-body narrative (not counted) 8 2.96%, 3.61%, 2.49%, 0.46%, 2.58%, 331.3 and +0.89% reproduce; "2028 COLA would be 1.62%" does not 7 match, 1 not reproduced (G14)

Tally: 198 checks match, 0 mismatch. Every comment formula in the changed YAML recomputes. Of 33 references checked, 24 are correct, 4 are wrong (C1, SA3, and SA4 in two files) and 5 were not checked (none supports a changed value). Three Economic Projections references name no sheet or row (G4).

Validation Summary

Check Result
CI 27 pass, 0 fail at 493ec45c8a
Local tests test_uprating_extensions.py 40/40; ERDC integration 14/14; snap_max_allotment.yaml 4/4; ca_ab2591.yaml 8/8
Partner contract tests No partner file touched. Read-only run of all partner tests: 623/623 pass
Regulatory 1 critical (C1, SNAP citation); 1 should-address (SA1, cap extension); HHS lag pre-existing (G2 and a follow-up)
References 33 checked: 24 correct, 4 wrong (C1, SA3, SA4 x2), 5 not checked
Code patterns No formula changed. End years match the YAML. Changelog fragment correct. One trailing zero (G13)
Tests 2 new tests and 1 changed check. The seam points and the "starts early" case are not pinned (SA2)
Mutation 26 mutants. 6 one-percent seam errors pass all 40 tests (SSA 2100 -47.1%). 9 of 9 "starts early" mutants pass the parametrized test. The SA2 block kills every survivor. The SA1 fix gives 0 of 64 years off 430(b)
Probes Full parameter tree at the head and the merge base; loading CBO's 2036 CPI points changes 0 values read on January 1, 2036; HHS back-cast 2023-2026
Branch 3 ahead / 47 behind main; MERGEABLE. Merge hold until spm-calculator 1.1.0
Other reviews Author comment only: a local run of the 261 future-year YAML files stopped after 3; CI covers the rest
Axiom line Present: "n/a: projection data refresh, no change in law"

Review Severity: REQUEST_CHANGES

One critical item (C1) and four should-address items (SA1, SA2, SA3, SA4) are open.

Next Steps

To auto-fix issues: run the fix-pr workflow for this PR.

  1. Apply C1: replace the SNAP citation at gov/usda/snap/uprating.yaml:29-30 with 2012(u)(3)(C).
  2. Apply SA1: replace extend_social_security_payroll_cap and the T:313-318 check. If you keep the function out of this PR, correct the docstring and open the follow-up issue.
  3. Apply SA2: append the test block after T:502. If you also take G1 option A, move the CPI-U and chained CPI-U rows one year later.
  4. Apply SA3 and SA4: replace the HHS 2026 reference and the two Tax Parameters references.
  5. Take the suggestions you agree with. G1, G2 and G3 remove the most reader confusion. G4, G5, G6, G12 and G13 are comment or reference edits. G14 and part of G1 and G3 are PR-body edits.
  6. Run make format, then test_uprating_extensions.py, the three moved YAML files and the partner tests (read-only).
  7. Open the follow-up issues in the list above. The HHS issue needs the partner gate if its design moves Head Start pins.
  8. Merge only after spm-calculator 1.1.0 is released.

DTrim99 and others added 2 commits October 23, 2026 15:57
- Cite 7 U.S.C. 2012(u)(3)(C) for the SNAP uprater, plus the pre-2025
  (u)(4) and 7 CFR 273.10(e)(4)(ii).
- Extend the payroll cap after 2036 with the 42 U.S.C. 430(b) fixed 1994
  base instead of the chained 20 CFR 404.1048 wording; it reproduces every
  automatically adjusted base from 1995 to 2027.
- Load CBO's calendar-2036 CPI-U (416.5) and chained CPI-U (223.5) points
  and start both extensions in 2037.
- Pin every CBO February 2026 projection point, including the two that set
  the 2037-2100 growth of each series, and the IRS August-July window.
- Cite the January 2025 Economic Projections file for the HHS 2026 anchor,
  the February 2026 Tax Parameters file for the cap and NAWI, and the sheet
  and row of each Economic Projections series.
- Document the HHS one-year lead over 42 U.S.C. 9902(2), the CPI-U proxy
  for CPI-W with 42 U.S.C. 415(i), and why projected caps sit above CBO's.
- Correct the IRS window comments, the ERDC, AB 2591 and 2042 dependent
  standard deduction derivations, and one trailing zero.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH
@DTrim99

DTrim99 commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator Author

Thanks, @PavelMakarchuk. All of this is in adf8982 and 241b029, after a merge of main (52 commits, no conflicts). I checked the new values and references against the cbo-data CSVs at 284a956, Wayback captures of the CBO workbooks, the Outlook PDF and SSA's AWI and CBB pages, and BLS. Locally, test_uprating_extensions.py passes 141 of 141, and the ERDC, AB 2591 and basic_standard_deduction.yaml files pass 42 of 42.

ID Status What changed Commit
C1 Fixed gov/usda/snap/uprating.yaml now cites 7 U.S.C. 2012(u)(3)(C). I also added the 2023-edition (u)(4) and 7 CFR 273.10(e)(4)(ii). adf8982
SA1 Fixed extend_social_security_payroll_cap now uses the 430(b) fixed 1994 base, with your code and docstring. I checked your claim against SSA's series. The fixed base reproduces all 30 automatically adjusted bases from 1995 to 2027; the only YAML entry it misses is 2016, a no-COLA year. The chained form reproduces 20 of 30. From 2037 to 2100, the cap now matches 430(b) in all 64 years (2100: 1,995,300). The extension check now uses 2037, 2040, 2050, 2073 and 2100. I also moved the 2025 known-value check to the fixed base, so the file asserts one formula. The fix also covers the Trustees 2025 caller. adf8982
SA2 Fixed (broader) test_upraters_encode_cbo_february_2026_projections covers every CBO-based value in 100 cases: SSA 2028–2036, SNAP October 2027–2036, HHS 2027–2036, CPI-W 2026Q3–2036Q4, NAWI 2026–2034, and CPI-U and chained CPI-U at February 2027–2036. Expected values come only from CBO data and named BLS/SSA actuals, compared with exact == round(expected, n). Your seam points are included, moved one year for G1. If a series' second-to-last point is wrong, or its extension starts a year early, a pinned point fails. test_irs_uprating_averages_cbo_chained_cpi_u_points checks IRS 2029–2036 with the 6/6 split. adf8982
SA3 Fixed The reference now points to the January 2025 Economic Projections file: sheet "2. Calendar Year", row 53, 328.446. It notes row 51 in the original release, before the April 30, 2025 update; I confirmed both rows in captures of the two versions. I added the pinned 2025-01 CSV. adf8982
SA4 Fixed cap.yaml and nawi.yaml now cite the February 2026 Tax Parameters file, sheet "1. Tax Parameters", row 155. adf8982
G1 Fixed (option A) The 2036 instants now hold 416.5 and 223.5. Both extensions start in 2037, and the extrapolation test uses 2036. I kept IRS_LAST_PROJECTED_YEAR = 2036 and declined the optional 2037: it changes IRS 2037 by only +0.008% and moves about 6,355 IRS-uprated values. The 2042 dependent standard deduction case still passes. Its derivation comment was already stale at the reviewed head, so I updated it (2041 chained CPI-U 246.299; outputs unchanged). One side effect: extend_single_year_dataset takes its default end year from the last authored CPI-U year, so single-year datasets now extend through 2036 by default, which fits the 2036 extension. 241b029 updates the test that pins that year. adf8982, 241b029
G2 Fixed (note) The note and the 9902(2) and FR 2026-00755 references are added. The YAML defers the fix to a separate PR instead of naming an issue number. Follow-up: "Federal poverty guideline projections lead the 42 U.S.C. 9902(2) CPI-U interval by one year" (including the 2026 hold, and the partner gate for designs A and B'). adf8982
G3 Fixed I corrected the comment and the PR-body series table. I also corrected the get_irs_cpi docstring (August to July, see #9105). The window itself stays with #9105. adf8982
G4 Fixed Sheet and row comments are in the HHS, SSA and SNAP references. adf8982
G5 Fixed I added the proxy note, 415(i) and the Outlook #page=74 reference, and renamed the COLA-series title. I also dropped the 2027 fact sheet from nawi.yaml, since it has no AWI figure. I measured the 2029–2036 proxy growth at 2.26% a year, so the comment says it matches CBO's 2.3% to the tenth of a percent that CBO publishes. adf8982
G6 Fixed The comment is added to cap.yaml. adf8982
G7 Partly The PR body now has a long-run paragraph and 2050 and 2100 rows in every table: NAWI 2100 is 804,774 against 904,606, the cap 1,995,300 against 2,235,900, and the 2040 bend points 2,059 and 12,414 against 2,094 and 12,624. A multi-year growth rate is deferred as a method change for a follow-up. PR body
G8 Deferred The full-column pins from SA2 now catch a stale end year. Deriving the end years from the YAML is a refactor for a follow-up. n/a
G9 Deferred No change. The Trustees scenario is consistent with itself: it uses Trustees NAWI from 2034 and the cap from 2036. Moving it to 2035 is a scenario-design question for #8220's owner, so it's a follow-up. n/a
G10 Fixed 2037 is added to the wage-indexed check. The June 2026 CPI-W and CPI-U (and the other anchors) are named constants. The full columns are compared with exact rounding (SA2). adf8982
G11 Fixed The derivation comment is above Case 2. I skipped the optional 3,698 case. adf8982
G12 Fixed The header now shows the unrounded parts and the rounded totals. adf8982
G13 Fixed The value is now 350.71. 95_429.00 stays, per your note. adf8982
G14 Fixed The PR body now gives 1.68%, with the formula. PR body

The merge hold still applies: no merge until spm-calculator 1.1.0 is released.

The test pins the last authored CPI-U year, which sets the default
dataset extension end year; CBO's calendar-2036 point now ends the YAML.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

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.

2 participants