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>
MaxGhenis
marked this pull request as ready for review
October 11, 2026 20:28
Contributor
Author
|
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. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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