Repository navigation
Conversation
extend_parameter_values gains long_range_growth knots: after the last projected year, growth moves linearly from the measured short-range rate to the 2026 Medicare Trustees' 2050 and 2100 rates, as the Trustees interpolate years 11-25 of their projection. moop_per_capita and esi_premium_per_enrollee now glide to per capita health spending growth (4.3% in 2050, 4.1% in 2100); Medicare, Part B and Part D per-enrollee knots include the -0.1%/yr demographic mix from Table II.D1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The CI run on this pull request was cancelled at 23:27Z on 2026-10-11 to free the organization's shared GitHub runners for an urgent fix in another repository. The US + core hub will re-run it automatically (cancelled jobs only; jobs that had passed are kept). Nothing in this pull request changed. Please don't push or reopen just to restart CI. |
PR Review: Glide CMS health spending upraters to the Trustees' long-range growth ratesPR #10119 (author: MaxGhenis, head SummaryAfter a series' last projected year,
The method and inputs are right:
Two should-fixes, both caused by today's merges to
Three suggestions follow. Critical (must fix)None. Should address1. Merging
2. The PR body no longer describes the merge.
Suggestions1. Wire the series whose PRs have merged, or track them in an issue.
2. Cite the Trustees' own NHE extension, and the shape of their 2050–2100 path.
3. (Optional) Keep the knots in a calibration parameter.
Verified correct
Axiom line assessmentValid:
CI statusAll 26 checks pass (
Branch status
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Every cited Trustees Report page and quote checks out, the glide arithmetic is right with no step at the splice, and projected years are unchanged. Two should items (see the comment above): (1) merged with main (#10084 moved out-of-pocket to the 2025-2034 NHE release), two main tests fail because they assert the constant last-rate rule (test_cms_moop_uprating.py::test_extension_holds_the_last_projected_growth_rate, test_uprating_extensions.py::test_cms_moop_per_capita_extends_to_2100), and five descriptions go stale, including the WIRED_SERIES anchor, which should be 2034. (2) The PR body is outdated: #10107 and #10085 have merged, the wired out-of-pocket effect is +3.8% in 2100, not +41.9%, and the microsim section is still pending.
Summary
CMS's National Health Expenditure (NHE) projections stop in 2034, and the 2026 Medicare Trustees Report's detailed projections stop in 2035. After that,
extend_parameter_valuesrepeats a series' last projected growth rate every year to 2100. The Trustees' own long-range path does not do that. They interpolate from the short-range rate to a long-range rate over 2036–2050, then follow rates near GDP growth. Repeating the last rate puts every health series off that path by 2100: about 2.7 times too high for Medicare spending per enrollee (#10107), and 4% to 42% off for the out-of-pocket and private premium series.This PR adds optional
long_range_growthknots toextend_parameter_values. With knots, growth after the last projected year moves linearly from the measured short-range rate to the Trustees' 2050 rate, then to their 2100 rate. Without knots, every other series extends exactly as before.calibration.gov.hhs.cms.moop_per_capitaandcalibration.gov.hhs.cms.esi_premium_per_enrolleeglide to per capita health spending growth.medicare.per_capita_cost), the Part B premium (Uprate premium inputs by premium series, not CMS out-of-pocket spending #10085medicare_part_b_premium_per_enrollee) and Part D premiums (Subtract the expected Part D premium from medicare_cost #10111part_d.premiums_per_enrollee). The per capita knots also cover Uprate premium inputs by premium series, not CMS out-of-pocket spending #10085'sdirect_purchase_premium_per_enrollee. Each of those PRs keeps its reviewed head. Switching a series is a one-linelong_range_growth=argument, done in a follow-up as each one merges.What the Trustees report says
Source: 2026 Medicare Trustees Report, transmitted 2026-06-09, sha256
ffa56b9137006872300b0346149eae1613d09a172b6ba118aad48e66dfc48fa8. Page numbers are PDF file pages. Every statement below was read from the report this session.Transition method. The Trustees set detailed growth rates for 2026–2035. For each of Parts A, B and D, "the assumed cost growth rates for years 11 through 25 of the projection period" are set by interpolating between the rate at the end of the short-range period and the rate at the start of the last 50 years (pp. 24, 180). From 2050 the long-range rates decline gradually to 2100 (pp. 23, 173). Only the 2050 and 2100 rates are published, so the path between those two knots is linear here. That straight line is the one approximation this PR makes.
Per capita overall health spending: GDP plus 0.7 percent (4.3%) in 2050, declining gradually to GDP plus 0.4 percent (4.1%) by 2100. This comes from the factors model, which holds insurance coverage unchanged over the long range (pp. 173, 175).
Medicare cost growth, excluding demographic impacts:
Table II.C1's 2050–2100 averages are 3.7% total, 3.8% Part B and 4.0% Part D (p. 21).
How demographic effects enter a per-enrollee series. The cost growth rate is the increase in average expenditures per beneficiary before the effects of aging, the sex mix and proximity to death, "as the Trustees estimated these factors separately" (footnote 81, p. 172). These cost growth rates must then be modified for demographic impacts (pp. 23, 179). A series of spending per enrollee contains those effects. Table II.D1 (p. 29) puts the "beneficiary demographic mix" component at −0.1% a year in 2051–2100 for each of Parts A, B and D. So each Medicare per-enrollee knot is
(1 + cost growth) × (1 − 0.001) − 1, for example 3.696% in 2050 and 3.596% in 2100 for all of Medicare. For 2036–2050, Table II.D1's mix is +0.2 (A), −0.1 (B) and −0.2 (D). Weighted by 2035 spending shares (Table V.B2, p. 194) that is about zero, and the interpolation handles it.Private and out-of-pocket series. The Trustees publish no long-range private insurance rate: Table V.B5 (p. 200) leaves it blank after 2035. Those series use the per capita overall health spending rate. Two statements support that choice: the factors model holds coverage unchanged (p. 175), and the Trustees see "only a small likelihood that one part of the health sector could continue to grow indefinitely at significantly faster rates of growth than do other parts" (p. 177). Neither ESI nor out-of-pocket spending gets a demographic adjustment, because the Trustees publish none for them.
Premiums follow per-enrollee costs. The standard Part B premium "is set at the level of about 25 percent of average expenditures for beneficiaries aged 65 and over" (p. 97). From 2024, the Part D base beneficiary premium is the lesser of 25.5% of expected plan costs and the prior year's premium plus 6% (p. 113). With long-range cost growth near 4%, the 6% cap does not bind, so the premium grows with plan costs.
Check against the Trustees' own aggregates
The test below is independent of the knots' derivation. Take the Trustees' growth in incurred Medicare expenditures (Table V.B5, p. 200) and divide by their enrollment growth (Table V.B3, HI and/or SMI, p. 196). That implies per-enrollee growth for each long-range period. Starting the glide from Table V.D1's 2035 per-beneficiary growth (5.4%, p. 210), the knots reproduce it:
The Part B and Part D knots against Table II.D1 (total increase net of beneficiary growth):
All of these agree within the tables' rounding to a tenth of a point.
Size of the change
Levels in 2050 and 2100 under the current rule and under the glide (
scripts/quantify2.py, which imports the PR's helper and knots):moop_per_capita(main's values)moop_per_capita(#10084's values)esi_premium_per_enrolleedirect_purchase_premium_per_enrolleemedicare.per_capita_costmedicare_part_b_premium_per_enrollee(monthly)part_d.premiums_per_enrolleeMain's
moop_per_capitagrows only 3.59% after 2033 because its 2033–2035 values are themselves extrapolated at the 2031–2032 rate. #10084 replaces them with the 2025–2034 NHE release, which is why the glide's effect on that series shrinks after #10084.Long-run microsim
Pending: queued on the shared heavy lock. It runs base (main
065d0e9560) and this PR for 2050 and 2100 on the default dataset. Results will be added here.Invariants
Tested in
tests/core/test_long_range_health_growth.py: Hypothesis properties, a differential test against an independent numpy implementation, and published-table checks.1 + rate. This is checked againstnp.interpplusnp.cumprodfor random series and for the two wired CMS series.V_L (1 + g)^(y − L). Passing no knots leaves the old rule unchanged; it is the same code path.The existing ESI tests now assert the glide instead of a constant rate.
test_esi_premium_microsim_uprating.pyalready computes its expected factor from the parameter, so it needs no change.Not done here
axiom: n/a: uprating extension of calibration series only (no policy rule)
🤖 Generated with Claude Code