Repository navigation
Uprate poverty guidelines over the 9902(2) interval and fix the Trustees wage base - #10453
Conversation
…ees wage base Projected federal poverty guidelines grew by CPI-U CY(Y)/CY(Y-1), one year ahead of 42 U.S.C. 9902(2) and the HHS notices, which use CY(Y-1)/CY(Y-2) (#10451). A new gov.hhs.fpg_uprating index holds the prior calendar year's CPI-U at each guideline year: BLS actuals through 2025, then the 2025 actual grown at CBO's February 2026 calendar-year rates. It reproduces the published 2023-2026 four-person increases within 0.12%. gov.hhs.uprating keeps its 2026 hold and now serves only Head Start and Early Head Start spending, so the partner pins do not move. The 2027 Oregon ERDC and California AB 2591 expectations move with the guidelines. The Trustees 2025 scenario re-extended the payroll cap from its NAWI but not the wage-indexed amounts, so its wage base kept CBO's cap from 2036 (#10452). It now reruns that extension. Also from the #10227 review: a 430(b) tie test, a guard that the extensions keep every authored YAML value, refresh notes in two docstrings, the SSA proxy note's 2.27%, and a rename of the mock end-year constant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PavelMakarchuk
left a comment
There was a problem hiding this comment.
Program Review
PR #10453, "Uprate poverty guidelines over the 9902(2) interval and fix the Trustees wage base" (DTrim99). Round 1, full review.
IDs: C = critical, SA = should address, G = suggestion. Items from the #10227 reviews are written "#10227 G2" and so on, so that they do not mix with the IDs of this review.
Paths: F = policyengine_us/parameters/gov/hhs/fpg_uprating.yaml, H = policyengine_us/parameters/gov/hhs/uprating.yaml, U = policyengine_us/parameters/uprating_extensions.py, R = policyengine_us/reforms/ssa/trustees_2025.py, T = policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py, TC = policyengine_us/tests/core/test_per_capita_uprating.py. Line numbers refer to the reviewed head.
Source Documents
- Reviewed head SHA: b449041
- Mode: full
- Scope: 15 files, 248 insertions and 37 deletions against the merge base
aa8596e3d8. No variable file changes. - Statutes and regulations: 42 U.S.C. 9902(2); the Head Start Act, 9832(19), 9835(a)(7)(B) and 9840(a)(1)(B)(i); 42 U.S.C. 430(b), 413(d)(2), 403(f)(8), 415(a)(1)(B) and 423(d)(4)(A); 20 CFR 404.1574(b)(2)(ii).
- Federal Register, HHS poverty guideline notices (full text): 2022 (87 FR 3315), 2023 (88 FR 3424), 2024 (89 FR 2961), 2025 (90 FR 5917) and 2026 (91 FR 1797). The ASPE page for the 2026 computations returns 404, and Wayback has no capture.
- BLS: CPI-U CUUR0000SA0 (not seasonally adjusted) and CUSR0000SA0 (seasonally adjusted), January 2020 to September 2026 and annual averages, through the BLS API and in a browser; the BLS FAQ on the 2025 shutdown (the 2025 average uses 11 months).
- CBO: Economic Projections, February 2026, sheet "2. Calendar Year", row 53 (read from a Wayback capture, because cbo.gov blocks scripts);
calendar_2026-02.csvat 284a956, equal to row 53 in all 14 years; The Budget and Economic Outlook: 2026 to 2036, page 74, for the COLA note. - Repository and process: issues #10451 and #10452; the round-1 and round-2 reviews of #10227;
CLAUDE.md(partner contract tests, changelog).
Branch Status
- The branch is 1 commit ahead and 4 behind
main(9ee14cdb43). The 4 commits (IA LIHEAP #10292, IN EITC #10249 and version bumps) change no file in this PR and add no YAML test with a 2027 or later period. They cannot conflict with the moved expectations. - CI passes 33 of 33 at the head.
- The PR body says that the merge waits for the decision on the 2036 hold (PolicyEngine/policyengine-api#3926). This review does not change that.
What the PR gets right
- The lagged index (
F). The five actuals (F:9-13) equal the BLS annual averages for 2021-2025, and the 11 projections (F:16-26) recompute exactly as 321.943 × CBO CPI-U(Y-1) / 322.378. - The 2026 entry, 321.943. BLS averages the 11 published months of 2025 (October was not collected). Only this base reproduces the 2.63% of the 2026 notice; a 12-month base gives about 2.70%.
- The interval. The notices from 2022 to 2026 each apply calendar Y-2 to calendar Y-1, and the BLS averages reproduce each percentage (4.7, 8.0, 4.1, 2.9, 2.63). The 2027 factor is now 331.359 / 321.943 (+2.92%), not 336.766 / 328.4 (+2.55%).
- Every guideline reader moves. 32 direct reads of
gov.hhs.fpgin 30 files and 144 uses ofspm_unit_fpgandtax_unit_fpgread the parameter; none keeps its own projection. The PR-body table (8 of 8) and the 2023-2026 fits reproduce. - The extension (
U:1014-1023). It runs before core uprating, and after 2037 it grows at CBO's last rate (1.0225764 against 1.0225754). Tests catch a removed extension, the wrong growth years and an end year of 2036. - The Head Start split.
Hvalues do not change, and the childcare partner files (36) andgov/hhs/head_start(57) pass. Ending the 2026 hold fails 28 partner cases, so the PR is right to leave it for the partner gate. - The Trustees fix (
R:204-206). An exact-fraction table from the statutes matches 9 series × 74 years on both paths (0 mismatches);wage_base == capin every year; 2027-2035 equal the baseline; the PR-body table reproduces (16 of 16). - Moved expectations. OR ERDC Case 2 ceil(2 × 22,272.91 / 12) = 3,713; CA AB 2591 16,427, 22,273 and 33,965; OH LIHEAP comment 120,961.27 (the tested value reads the 2026 guideline).
- Hygiene.
ruff format --checkandruff checkpass. Both changelog fragments are top-level and typed. No partner file is in the diff.
Follow-ups from #10227
| Item | Claim in the PR body | Status | Evidence |
|---|---|---|---|
| #10227 G2 | H names #10451 and says that the index serves only Head Start |
RESOLVED | The NOTE at H:4-6 and the hold comment at H:11-15 name #10451. The fix that G2 pointed to is done. G6 covers the references left behind |
| #10227 G9 | Scenario horizon left to @MaxGhenis | DEFERRED, as stated | R:20, R:122 (NAWI start_year 2034) and R:201 (last_projected_year=2035) are unchanged. #10452 keeps a checkbox for it |
| #10227 G9 follow-up | Rerun the wage-indexed extension in the Trustees scenario | RESOLVED | R:204-206, after the cap extension. Tested at TC:327-351 (see G1 and G2) |
| #10227 G15 | $150 tie test | RESOLVED | T:355-359 is the suggested code. Both rounding changes (a tie that rounds down, and round half to even) fail it |
| #10227 G16 | 2.27%, "January 2029 to January 2036" | RESOLVED | gov/ssa/uprating.yaml:12-15. (403.287 / 336.945)^(1/8) - 1 = 2.272% |
| #10227 G17 | Authored-value guard, 9 series | RESOLVED | T:668-691, now with gov.hhs.fpg_uprating. G4 suggests six more series |
| #10227 G18 | Refresh notes in two docstrings | RESOLVED | T:602-606 and T:626-627, the suggested text |
| #10227 G19 | changed fragment and rename |
RESOLVED | New fragment. END_YEAR_DEFAULT is renamed END_YEAR_EXPLICIT. G9 suggests clearer wording |
| #10451 | "Part of" | ACCURATE | Design B is done. Ending the Head Start 2026 hold (partner gate) stays open |
| #10452 | "Part of" | ACCURATE | The re-derivation is done and tested. The horizon checkbox stays open |
Critical (Must Fix)
None.
Should Address
None.
Suggestions
G1. Add a one-pass Trustees test, because the current fixture cannot see the call order.
- Where:
R:199-206(the cap extension, then the wage-indexed extension);TC:260-271(the_Trustees2025fixture) andTC:327-351(the new test). - Evidence: the wage-indexed extension copies the cap into
wage_base(U:832-835), so the cap must be re-derived first. The head has the correct order. ButCountryTaxBenefitSystemapplies a reform twice (policyengine_us/system.py:148and:168), so the second pass of the fixture reads the Trustees cap from the first pass. With the two calls swapped on a copy,T,TC(216 tests) and the 38 changed YAML cases still pass. One direct call in the swapped order, or oneSimulation(...).apply_reform(...), leaves the wage base below the cap in 65 years (2036: 260,400 against 261,900). - Why a suggestion: the head is correct on every route, and a code search of the PolicyEngine organization finds no other caller of
apply_trustees_2025_economic_assumptions. The test guards against a future reorder. - Fix: append to
TC.CountryTaxBenefitSystemandapply_trustees_2025_economic_assumptionsare already imported (TC:12,TC:22). The test passes at the head (52 of 52 in the file) and fails on the swapped order (assert 260400 == 261900at 2036). It adds about 16 seconds, for one extra system build.
def test_trustees_wage_base_follows_the_trustees_cap_in_one_pass():
"""System init applies a reform twice, so the fixture above would hide a
wage base derived before the cap. One direct call, as a caller outside a
Reform or a single Simulation.apply_reform makes it, must also set the
wage base to the scenario's own 430(b) cap (#10452)."""
parameters = CountryTaxBenefitSystem().parameters
apply_trustees_2025_economic_assumptions(parameters)
cap = parameters.gov.irs.payroll.social_security.cap
wage_base = parameters.gov.ssa.social_security.wage_base
for year in (2036, 2040, 2100):
assert wage_base(f"{year}-01-01") == cap(f"{year}-01-01"), yearOptional: at R:204-205, add to the comment that this call must come after the cap extension.
G2. Check all eight wage-indexed amounts after 2035 in the Trustees test.
- Where:
TC:344-350. After 2035 the test checkswage_base == cap, and bend point 1 at 2036, 2040 and 2100. It checks the quarter of coverage, both earnings-test amounts, bend point 2 and both SGA amounts only for 2027-2035. - Evidence: the PR body claims all eight amounts. An exact-arithmetic table finds 0 mismatches for all eight on the Trustees path, so the code is correct, but the test does not show it.
- Why a suggestion: the scenario reruns the same function that
T:739already checks on the baseline. - Fix: replace
TC:344-350with this block. It passes at the head.
nawi = parameters.gov.ssa.nawi
# (base amount, NAWI base year, rounding increment, months): 42 U.S.C.
# 413(d)(2), 403(f)(8)(B), 415(a)(1)(B), 423(d)(4)(A); 20 CFR
# 404.1574(b)(2)(ii). Bend points have no floor; the others keep the
# prior year's amount if it is larger.
formulas = {
"quarters_of_coverage_threshold": (250, 1976, 10, 1),
"exempt_amount_under_fra": (670, 1992, 10, 12),
"exempt_amount_year_of_fra": (2_500, 2000, 10, 12),
"bend_point_1": (180, 1977, 1, 1),
"bend_point_2": (1_085, 1977, 1, 1),
"sga_non_blind": (700, 1998, 10, 1),
"sga_blind": (930, 1992, 10, 1),
}
for name, (base, base_year, increment, months) in formulas.items():
for year in (2036, 2040, 2100):
computed = months * round_social_security_amount(
base * nawi(f"{year - 2}-01-01") / nawi(f"{base_year}-01-01"),
increment,
)
if not name.startswith("bend_point"):
computed = max(trustees[name](f"{year - 1}-01-01"), computed)
assert trustees[name](f"{year}-01-01") == computed, (name, year)
assert trustees[name]("2036-01-01") != baseline[name]("2036-01-01"), nameG3. Pin a projected guideline in dollars in a baseline test.
- Where:
policyengine_us/tests/policy/baseline/gov/hhs/spm_unit_fpg.yaml(its last period is 2021);policyengine_us/tests/policy/baseline/gov/states/or/delc/erdc/integration.yaml:38-68(Case 2). - Evidence: the only dollar pin of a projected guideline is the contrib CA AB 2591 test (margin $1). OR ERDC Case 2 asserts that income of 3,713 is ineligible, which is true for any 2027 limit at or below 3,713, so it still passes with
fpg.yamlback ongov.hhs.uprating(limit 3,699). A drift of 0.007 in the 2025 actual ($0.73 on the 2027 four-person guideline) passes every test of the PR. - Why a suggestion: the tests of the PR already catch the old mapping and a one-year shift of the index. These cases add a direct dollar check that does not depend on a contrib bill.
- Fix: append to
spm_unit_fpg.yaml. All three cases pass at the head. They fail on the old mapping, on a one-year shift in either direction, and on the 0.007 drift. Like the existing CBO pins, they will fail at the next CBO refresh, which is the intended signal.
- name: Four-person SPM unit in 2027 in contiguous US uses the projected guideline
period: 2027
absolute_error_margin: 0.01
input:
spm_unit_size: 4
state_group_str: CONTIGUOUS_US
output:
# 33,000 x 331.359 / 321.943 (CY2026 / CY2025, 42 U.S.C. 9902(2)) = 33,965.16
spm_unit_fpg: 33_965.16
- name: Two-person SPM unit in 2027 in Alaska uses the projected guideline
period: 2027
absolute_error_margin: 0.01
input:
spm_unit_size: 2
state_group_str: AK
output:
# (19,950 + 7,100) x 331.359 / 321.943 = 27,841.14
spm_unit_fpg: 27_841.14
- name: Four-person SPM unit in 2036 in contiguous US uses the last CBO-window guideline
period: 2036
absolute_error_margin: 0.01
input:
spm_unit_size: 4
state_group_str: CONTIGUOUS_US
output:
# 33,000 x 406.796 / 321.943 = 41,697.65
spm_unit_fpg: 41_697.65Optional: add an OR ERDC companion case at income 3,712 with or_erdc_income_eligible: true. It passes at the head and makes the 2027 boundary two-sided. But it will also fail at each refresh, and the Indiana CCDF tests keep a margin for that reason. It is also acceptable to leave Case 2 as it is.
G4. Add the six Social Security wage-indexed series to the authored-value guard.
- Where:
T:668-678(EXTENDED_SERIES);U:828(for year in range(2027, end_year + 1)). - Evidence:
extend_social_security_wage_indexed_parametersstarts at a fixed 2027, not after the last authored year. With this PR it also runs inside the Trustees scenario. If a refresher authors SSA's 2028 amounts, the extension overwrites them, and no test fails. #10227 G17 guards the other series against this class of bug. At the head, the six series with a flatvalues:key pass the guard (authored through 2026, 0 values overwritten). The PIA bend points are scale thresholds, so the["values"]read of the guard does not fit them. - Why a suggestion: #10227 G17 covered only the series with a
last_projected_year. The fixed start year is older than this PR (#8335). - Fix: append to
EXTENDED_SERIES. A value that SSA publishes and the formula reproduces still passes. Only a value that the extension would change fails.
"gov.ssa.social_security.wage_base",
"gov.ssa.social_security.quarters_of_coverage_threshold",
"gov.ssa.social_security.earnings_test.exempt_amount_under_fra",
"gov.ssa.social_security.earnings_test.exempt_amount_year_of_fra",
"gov.ssa.sga.non_blind",
"gov.ssa.sga.blind",G5. Say in F that the 2027 point is a forecast that the published 2026 months already exceed.
- Where:
F:14-16. - Evidence: the BLS average for January-September 2026 is 332.243. That is already 0.27% above the projected calendar-2026 average (331.359). If October-December stay at the September level (336.940), calendar 2026 is 333.417. HHS will divide that by the 11-month 2025 base. The 2027 increase is then about 3.56% to 3.60%, against 2.92% in the model, and the 2027 four-person guideline is about 34,176 to 34,189, against 33,965 (0.6% higher). Separately, the 11-month base alone makes CBO's 12-month growth understate the 2027 increase by about 0.07 percentage points. Every later year carries the same level gap.
- Why a suggestion: the statute sets the interval, not the forecast. The method is documented, follows the #10227 anchoring pattern, and the January 2027 notice replaces it. Until then, FPG-based limits for 2027 and later are slightly low.
- Fix (comment only; recommended for this PR): after
F:15, add:
# CY2026 is CBO's forecast. BLS January-September 2026 CPI-U averaged
# 332.243, above this point; the January 2027 HHS notice replaces the
# projected 2027 guideline.Alternative (value change): anchor 2027 on the observed months (333.417) and grow later years from it. This moves the OR ERDC and CA AB 2591 expectations again.
G6. Remove the poverty guideline notices from H, and update the module docstring.
- Where:
H:35-38andH:41-42(the 2025, 2024 and 2026 poverty guideline notices); the label atH:31;U:932. - Evidence: after this PR,
Hserves only Head Start and Early Head Start spending. The BLS reference (H:33-34) supports 2022-2025, and the CBO pairs (H:43-52) support 2026-2036. The three notices support no value or statement inH. They now belong toF, which cites them. A reader can think that Head Start spending follows the guidelines, but no statute ties them (the Act's CPI-U link is the base-grant increase in 9835(a)(7)(B)). Keep 42 U.S.C. 9902(2) (H:39-40), because the NOTE atH:4-6cites it. The docstring bullet atU:932lists one HHS index, but there are now two. - Why a suggestion: every value in
Hkeeps a corroborating reference. #10227 G2 asked for these references while the index still served the guidelines. - Fix: delete
H:35-38andH:41-42. Optional:label: Head Start and Early Head Start spending upratingatH:31. The path stays the same, so no partner pin moves. AtU:932:
- HHS uprating for Head Start and Early Head Start spending (January values)
- HHS poverty guideline uprating, one year behind (January values)G7. Make the BLS link show the annual averages, and complete the notice list in F.
- Where:
F:37-42. - Evidence: in a browser,
https://data.bls.gov/timeseries/CUUR0000SA0opens with the "include annual averages" box clear. The columns are the months, HALF1 and HALF2, with no Annual column, so 321.943 does not show. With the query string below, the Annual column shows all five cited values. The monthly values on the default page do reproduce the five averages, so the reference corroborates the values. But the title promises a column that the default view hides. Also,T:704-722checks the 2023 increase, butFdoes not cite the 2023 notice (88 FR 3424, "8.0 percent price increase between calendar years 2021 and 2022"). The 2025 entry uses a govinfo JavaScript page, and the other notices use federalregister.gov. - Why a suggestion: no value lacks support.
- Fix: replace
F:37-42with the block below. The fixed year range keeps the page correct after the default 10-year window of BLS moves past 2021. Optional: the same BLS link change atH:34, which is older than this PR.
- title: 2025 Annual Update of the HHS Poverty Guidelines
href: https://www.federalregister.gov/documents/2025/01/17/2025-01377/annual-update-of-the-hhs-poverty-guidelines
- title: 2024 Annual Update of the HHS Poverty Guidelines
href: https://www.federalregister.gov/documents/2024/01/17/2024-00796/annual-update-of-the-hhs-poverty-guidelines
- title: 2023 Annual Update of the HHS Poverty Guidelines
href: https://www.federalregister.gov/documents/2023/01/19/2023-00885/annual-update-of-the-hhs-poverty-guidelines
- title: BLS | CPI-U annual averages (CUUR0000SA0)
href: https://data.bls.gov/timeseries/CUUR0000SA0?from_year=2021&to_year=2025&annualAveragesRequested=trueG8. State the interval as one year in the description, the fixed fragment and a test docstring.
- Where:
F:1;changelog.d/uprating-review-followups.fixed.md:1;T:705. - Evidence: "the change in calendar-year average CPI-U over the two preceding calendar years" can be read as a two-year change. The interval is one year, from calendar Y-2 to calendar Y-1 (2026: +2.63%). The comment at
F:3-5states it correctly. The description also joins two clauses with a semicolon, while the sibling index files use one clause ("PolicyEngine uprates ... with this index"). The docstring atT:705credits the calendar-year interval to 9902(2) alone. The statute says "the annual or other interval immediately preceding", and the notices set the calendar years.F:4-5already says "42 U.S.C. 9902(2) and the HHS notices". - Fix: at
F:1:
description: PolicyEngine uprates the federal poverty guidelines with this index, which holds at each guideline year the calendar-year average CPI-U for the year before it.In the fragment, replace "by the CPI-U change over the two preceding calendar years" with "by the CPI-U change from the second preceding calendar year to the preceding calendar year". At T:705:
"""Guideline year Y uprates by CPI-U CY(Y-1)/CY(Y-2), the interval in
42 U.S.C. 9902(2) as the HHS notices apply it.Optional: add period: year to the metadata of F, as gov/ssa/nawi.yaml has.
G9. Reword the changed fragment, so that it does not read as a new change.
- Where:
changelog.d/uprating-review-followups.changed.md:1. - Evidence: the default end year comes from
_get_default_end_year(policyengine_us/data/economic_assumptions.py:75-78). It reads the last authored year ofgov/bls/cpi/cpi_u.yaml(2036). This PR changes neither file, and the new 2037 point inFdoes not move the default. The default became 2036 in 2.65.0. The sentence is true, but towncrier will list it under "Changed" for the next release, and a reader will take it as new. - Fix:
Note on 2.65.0: since that release loaded CBO's 2036 CPI-U point, single-year datasets extend through 2036 by default (the last authored CPI-U year); its changelog did not say so.
G10. Mention the statutory floor in the Trustees paragraph of the PR body.
- Where: the PR body, "That function sets each amount from a fixed base × NAWI(Y-2) / NAWI(base year)."
- Evidence: 430(b), 413(d)(2), 403(f)(8)(B) and 20 CFR 404.1574(b)(2)(ii) each keep the prior year's amount if it is larger. Only the PIA bend points have no floor. The code (
U:837-905) applies the floors correctly, and the wage base copies the cap. This is wording only. - Fix (body only): "That function sets each amount from a fixed base × NAWI(Y-2) / NAWI(base year), with the statutory rounding and, except for the PIA bend points, never below the prior year's amount. The wage base copies the cap."
G11. Update the stale 2027 guideline figures in two Indiana CCDF test comments.
- Where:
policyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/eligibility/in_ccdf_income_eligible.yaml:186-191andpolicyengine_us/tests/policy/baseline/gov/states/in/fssa/ccdf/copay/in_ccdf_copay.yaml:184-185. - Evidence: the comments give "2-person 2027 FPG = 22,147.39", "135% = 29,898.98", "1.5-era limit (33,221)" and "~1.026". At this head the figures are 22,272.91, 30,068.43, 33,409.37 and about 1.020. They were stale before #10227 too. No expected value changes, because the cases keep a margin on each side of the limit.
- Why a suggestion: outside the diff and older than the PR, but the PR updated the OH LIHEAP comment for the same reason.
- Fix: replace the four figures.
Investigated and cleared
- Rounding of projected guidelines. 9902(2) has no rounding rule; HHS rounds after the inflation step. The model leaves projections unrounded, and each program rounds. Older than the PR.
- Alaska, Hawaii and territories. AK and HI use the same factor, as HHS does (2027 four-person: AK 42,456.46, HI 39,059.94). GU, PR and VI stay 0.
- A separate index instead of
gov.bls.cpi.cpi_u. That series is seasonally adjusted from 2024 and holds CBO levels at one decimal. HHS uses the unadjusted BLS annual averages, so a separate index is correct. - Reforms that change CPI-U. Reforms apply after the parameter pipeline, so none re-uprates the guidelines, before or after this PR.
- Head Start eligibility. It reads
spm_unit_fpg, so it now uses the lagged path, which matches the "immediately preceding" interval of 9832(19). Spending has no statutory tie to the guidelines. - Partner contract tests. None is in the diff. The 623 partner cases use periods 2024-2026, and none reads a 2027 guideline.
- Trustees amounts. Each formula uses NAWI(Y-2), the correct base year, ties that round up and the prior-year floor (none for the bend points). The COLA conditions in 430(a) and 403(f)(8)(A) never bind. No other NAWI-indexed Social Security amount exists in the model. The closest product to a rounding tie ($0.0025 from a $5 tie, 2086) gives the same result in exact arithmetic.
last_projected_year=2037atU:1019. The same pattern as the sibling calls (#10227 G8, declined as defensible). The 2037 pin and the authored-value guard catch a wrong end year in both directions.- The 2.63% check at
T:719-722. Itsabs=5e-5fails a 12-month 2025 base, so it pins the 11-month choice. - Docstring and PR-body figures. The old mapping missed 2023-2026 by -3.67% to -5.62%, as
T:704says. The largest fit gap is 0.1118% (2024), inside "within 0.12%".
Out of scope / follow-up
- FLSA overtime thresholds in the Trustees scenario.
gov/irs/income/exemption/overtime/hce_salary_threshold.yaml:8andsalary_basis_threshold.yaml:8uprate withgov.ssa.nawi. Core uprating runs before the reform (policyengine_us/system.py:126, then:148), so in the Trustees tree they stay on CBO's NAWI (2040: 183,406.42 on both paths, while the Trustees NAWI is 3.2% higher). No current-law output reads them after 2028. Note it in #10452: either re-uprate these parameters in the scenario, or state that only the Social Security amounts follow the Trustees NAWI. H:7andH:9truncate 292.655 and 313.689 to 292.6 and 313.6 (rounded: 292.7 and 313.7). The Head Start effect is -0.03% in the years that read them. The 2026 partner pins do not move. Include it with the 2026 hold in #10451.- Hard-coded statutory bases in
extend_social_security_wage_indexed_parameters(U:842-901), from #8335. The cap extension reads its base from the tree. This PR adds a caller only. gov.bls.cpi.cpi_uswitches from unadjusted to seasonally adjusted values at 2024-01 (#9100), so twelve-month ratios across the switch mix two series. No open issue was found.- Trustees wage growth (
R:44-47, Table V.B1 covered-employment wages used as NAWI growth). Not checked; the PR does not touch it. - Open parts of #10451 and #10452. The Head Start 2026 hold (partner gate) and the scenario horizon (@MaxGhenis).
Validation Summary
| Check | Result |
|---|---|
| CI | 33/33 pass at b449041b5d |
| Local tests | 287 pytest (the four changed Python test files); 38 YAML (the three changed files); 9 contrib SSA; 4,461 of 4,461 YAML cases in the 331 files with a 2027 or later period, plus the Head Start and childcare partner files |
| Partner contract tests | None edited. Head Start and Early Head Start pins unchanged: childcare partner files 36/36, gov/hhs/head_start 57/57; values in H unchanged |
| Values | 5 BLS actuals and 11 CBO projections in F; 5 notice percentages; PR-body tables 8/8 and 16/16; the moved expectations; 1,332 statutory Trustees year-values. 0 mismatches |
| References | 16 entries checked: 14 correct, 2 correct with a suggested change (G6, G7). None wrong |
| Regulatory | The interval matches 9902(2) as HHS applies it. The Trustees amounts match 430(b), 413(d)(2), 403(f)(8)(B), 415(a)(1)(B), 423(d)(4)(A) and 20 CFR 404.1574(b)(2)(ii) |
| Code patterns | No variable change and no hard-coded legal value. ruff format --check and ruff check pass. Changelog fragments are top-level and typed |
| Mutation | 14 changes on copies of the package. 11 fail the tests of the PR. Ending the Head Start hold fails 28 partner cases. 2 survive: the swapped Trustees call order (caught by G1) and a 0.007 drift in the 2025 actual, worth $0.73 (caught by G3) |
| Effect | Projected guidelines rise: four-person +0.37% in 2027, +0.55% in 2028 and +0.65% from 2036. The Trustees wage base rises from 2036 (+23% in 2100) |
| Branch | 1 ahead / 4 behind main; no overlap |
| PR body | axiom: line present (n/a: projection method and scenario assumption, no change in current-law values). Process note only, not counted. Trustees wording (G10) |
| Other reviews | None on the PR |
Review Severity: APPROVE
No critical or should-address item is open, so the review criteria give APPROVE. Eleven suggestions are open (G1 to G11): test guards, comments, references and wording.
Next Steps
To auto-fix issues: run the fix-pr workflow for this PR.
- No change is required before merge. The merge timing still follows the decision on the 2036 hold (PolicyEngine/policyengine-api#3926), as the PR body says.
- Take the suggestions that you agree with. G1 to G4 add tests, and each one ran at the head. G5 to G9 are comment, reference and changelog edits. G10 changes the PR body only. G11 changes two test comments.
- If you change a file, run
make format. Then runT,TCand the three changed YAML files again. - When HHS publishes the 2027 guidelines (expected in January 2027), author 2027 in
fpg.yaml, and replace the 2027 point inFwith the BLS calendar-2026 average. - Add the FLSA overtime threshold note to #10452 (see Out of scope).
Brings in #10453 (poverty guideline uprating), which also edits test_uprating_extensions.py and programs.yaml in other places; both merged automatically. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH
Part of #10451 and #10452. Follow-ups from @PavelMakarchuk's round-2 review of #10227 (G2, G9 and G15–G19).
What and why
Poverty guidelines follow the 42 U.S.C. 9902(2) interval (#10451, design B)
42 U.S.C. 9902(2) and the HHS notices update guideline year Y by the CPI-U change from calendar Y-2 to Y-1. The 2026 notice applies 2.63%, from calendar 2024 to calendar 2025.
fpg.yamluprated withgov.hhs.uprating, which grows guideline year Y by CY(Y) / CY(Y-1), one year ahead of the statute.New index
gov.hhs.fpg_uprating. At each guideline year it holds the prior calendar year's average CPI-U:It reproduces the published 2023–2026 four-person guideline increases within 0.12%: +0.10%, -0.11%, +0.09% and +0.01%.
fpg.yamlnow uprates with it.gov.hhs.upratingkeeps its 2026 hold (328.4) and now serves only Head Start and Early Head Start spending. So the Head Start partner pins don't move, as the review expected for design B. Ending that hold still needs the partner gate (Federal poverty guideline projections lead the 42 U.S.C. 9902(2) CPI-U interval by one year #10451).main)2027 growth is 2.92% (CBO's calendar 2026 over calendar 2025, applied to the 2025 actual), against 2.55% before.
The Trustees 2025 scenario re-derives the wage-indexed amounts (#10452)
apply_trustees_2025_economic_assumptionsre-extended the payroll cap from the Trustees NAWI, but not the wage-indexed amounts. So its wage base kept CBO's cap from 2036. It now rerunsextend_social_security_wage_indexed_parametersafter the cap extension.That function sets each amount from a fixed base × NAWI(Y-2) / NAWI(base year). The Trustees NAWI first differs from CBO's in 2034, so 2027–2035 are unchanged; the new test checks this.
@MaxGhenis, the scenario's horizon is yours to confirm (#10452). NAWI
start_year2034 and the cap'slast_projected_year=2035now replace CBO's 2034 NAWI and 2036 cap. This PR leaves them as they are.Smaller review items
gov/hhs/uprating.yamlnames Federal poverty guideline projections lead the 42 U.S.C. 9902(2) CPI-U interval by one year #10451 and says the index now serves only Head Start.test_social_security_payroll_cap_rounds_150_ties_upcovers the 430(b) $150 tie.test_extension_keeps_every_authored_valuechecks that no extension overwrites a value written in the YAML, for the nine extended series, the new index included.changedfragment noting that single-year datasets now extend through 2036 by default.END_YEAR_DEFAULTin the dataset-extension test fixtures is renamedEND_YEAR_EXPLICIT.Tests whose expected values move
states/or/delc/erdc/integration.yaml, Case 2: 2027 initial limit for 2 people, ceil(200% × FPG / 12)contrib/states/ca/ab2591/ca_ab2591.yaml: 2027 deduction = FPG for 1, 2 and 4 peopleThe review expected both to move under any design. The Ohio LIHEAP Case 15 comment is updated too. Its value reads the lagged 2026 guideline and doesn't change.
Test plan
uv.lockpin):ruff formatandruff checkpass on the changed files.changelog.d/.Run locally on Python 3.11 with the
uv.lockenvironment:test_uprating_extensions.py, the new Trustees test andtest_extend_single_year_dataset.py: 237 passed.gov/hhs/head_startand the Head Start and Early Head Start partner files: 131 passed.CI runs the full suites.
Merge timing. This doesn't depend on spm-calculator 1.1.0. But it follows #10227, so it waits for whatever Pavel and @anth-volk decide about the 2036 hold (PolicyEngine/policyengine-api#3926).
axiom: n/a: projection method and scenario assumption, no change in current-law values
🤖 Generated with Claude Code