Skip to content

Uprate poverty guidelines over the 9902(2) interval and fix the Trustees wage base - #10453

Merged
DTrim99 merged 1 commit into
mainfrom
uprating-review-followups
Oct 27, 2026
Merged

DTrim99 merged 1 commit into
mainfrom
uprating-review-followups

Conversation

@DTrim99

@DTrim99 DTrim99 commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

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.yaml uprated with gov.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:

    • 2022–2026 are BLS actuals for 2021–2025;
    • 2027–2037 are the 2025 actual (321.943) grown at CBO's February 2026 calendar-year rates;
    • 2038 on is extrapolated, after CBO's last point (calendar 2036, at the 2037 instant).

    It reproduces the published 2023–2026 four-person guideline increases within 0.12%: +0.10%, -0.11%, +0.09% and +0.01%.

  • fpg.yaml now uprates with it. gov.hhs.uprating keeps 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).

Contiguous US, four people 2026 2027 2028 2036
Before (main) 33,000 33,840.68 34,639.85 41,427.36
After 33,000 33,965.16 34,830.49 41,697.65

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_assumptions re-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 reruns extend_social_security_wage_indexed_parameters after 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.

Trustees scenario 2035 2036 2040 2100
Wage base, before 252,000 260,400 295,500 1,995,300
Wage base, after (= cap) 252,000 261,900 302,400 2,454,900
PIA bend point 1, before 1,756 1,813 2,059 13,899
PIA bend point 1, after 1,756 1,824 2,107 17,102

@MaxGhenis, the scenario's horizon is yours to confirm (#10452). NAWI start_year 2034 and the cap's last_projected_year=2035 now replace CBO's 2034 NAWI and 2036 cap. This PR leaves them as they are.

Smaller review items

  • G2: gov/hhs/uprating.yaml names 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.
  • G15: test_social_security_payroll_cap_rounds_150_ties_up covers the 430(b) $150 tie.
  • G16: the SSA proxy note now gives 2.27% a year, for the COLAs effective January 2029 to January 2036.
  • G17: test_extension_keeps_every_authored_value checks that no extension overwrites a value written in the YAML, for the nine extended series, the new index included.
  • G18: refresh notes in the CBO projection and IRS docstrings.
  • G19: Load CBO's February 2026 projections through 2036 into the upraters #10227's changelog fragment shipped in 2.65.0, so this PR adds a changed fragment noting that single-year datasets now extend through 2036 by default. END_YEAR_DEFAULT in the dataset-extension test fixtures is renamed END_YEAR_EXPLICIT.

Tests whose expected values move

Test Old New
states/or/delc/erdc/integration.yaml, Case 2: 2027 initial limit for 2 people, ceil(200% × FPG / 12) 3,699 3,713
contrib/states/ca/ab2591/ca_ab2591.yaml: 2027 deduction = FPG for 1, 2 and 4 people 16,367 / 22,191 / 33,841 16,427 / 22,273 / 33,965

The 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

  • Policy changes: the index's actuals and the guideline check use published BLS averages and HHS guidelines. The moved YAML values follow from them and are recomputed in each file's comment.
  • Source conflicts: not applicable. The statute and the HHS notices agree.
  • Formatted with ruff 0.15.5 (the uv.lock pin): ruff format and ruff check pass on the changed files.
  • Changelog fragments in changelog.d/.

Run locally on Python 3.11 with the uv.lock environment:

  • test_uprating_extensions.py, the new Trustees test and test_extend_single_year_dataset.py: 237 passed.
  • The changed YAML files, gov/hhs/head_start and 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

…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 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 #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

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.fpg in 30 files and 144 uses of spm_unit_fpg and tax_unit_fpg read 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. H values do not change, and the childcare partner files (36) and gov/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 == cap in 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 --check and ruff check pass. 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 _Trustees2025 fixture) and TC: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. But CountryTaxBenefitSystem applies a reform twice (policyengine_us/system.py:148 and :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 one Simulation(...).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. CountryTaxBenefitSystem and apply_trustees_2025_economic_assumptions are 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 == 261900 at 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"), year

Optional: 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 checks wage_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:739 already checks on the baseline.
  • Fix: replace TC:344-350 with 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"), name

G3. 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.yaml back on gov.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.65

Optional: 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_parameters starts 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 flat values: 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-38 and H:41-42 (the 2025, 2024 and 2026 poverty guideline notices); the label at H:31; U:932.
  • Evidence: after this PR, H serves 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 in H. They now belong to F, 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 at H:4-6 cites it. The docstring bullet at U:932 lists one HHS index, but there are now two.
  • Why a suggestion: every value in H keeps a corroborating reference. #10227 G2 asked for these references while the index still served the guidelines.
  • Fix: delete H:35-38 and H:41-42. Optional: label: Head Start and Early Head Start spending uprating at H:31. The path stays the same, so no partner pin moves. At U: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/CUUR0000SA0 opens 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-722 checks the 2023 increase, but F does 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-42 with 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 at H: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=true

G8. 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-5 states 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 at T:705 credits 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-5 already 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 of gov/bls/cpi/cpi_u.yaml (2036). This PR changes neither file, and the new 2037 point in F does 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-191 and policyengine_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=2037 at U: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. Its abs=5e-5 fails 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:704 says. 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:8 and salary_basis_threshold.yaml:8 uprate with gov.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:7 and H:9 truncate 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_u switches 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.

  1. 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.
  2. 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.
  3. If you change a file, run make format. Then run T, TC and the three changed YAML files again.
  4. When HHS publishes the 2027 guidelines (expected in January 2027), author 2027 in fpg.yaml, and replace the 2027 point in F with the BLS calendar-2026 average.
  5. Add the FLSA overtime threshold note to #10452 (see Out of scope).

@DTrim99
DTrim99 merged commit 1c6749c into main Oct 27, 2026
33 checks passed
@DTrim99
DTrim99 deleted the uprating-review-followups branch October 27, 2026 13:10
DTrim99 added a commit that referenced this pull request Oct 27, 2026
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
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