Repository navigation
Conversation
employer_sponsored_insurance_premiums uprated by CBO employment income (per capita after the per-capita conversion), and pre_tax_health_insurance_premiums by CMS out-of-pocket spending per capita, which by CMS's own definition excludes premiums. Both are shares of employer plan premiums, so both now follow CMS NHE Table 17's employer-sponsored insurance spending per enrollee (2013-2034, 2025-2034 projections release), extended past 2034 at the 2033-2034 growth rate. The per-capita classifier now treats per_enrollee paths as per-person rates, like per_capita ones, so they are neither divided by population nor rejected as unclassified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fier - Split the ESI tests: parameter and property checks stay in tests/core; the Simulation and dataset-extension checks move to tests/microsimulation (fewer Hypothesis examples, one vectorized simulation each). - Assert the 22 published Table 17 values exactly, keeping the spending-over-enrollment consistency check. - Per-person markers count only in a path's last segment, so a marker in an ancestor folder no longer hides a national total. - Cite the methodology paper's file page 29 in the href, the ZIP as the Table 17 source, and the 2035-2100 extension endpoint. - Describe the index as a premium-growth proxy at fixed coverage per policy and roughly constant employer share. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
health_insurance_premiums_without_medicare_part_b and other_health_insurance_premiums follow CMS ESI premium per enrollee, like pre_tax_health_insurance_premiums; health_insurance_premiums follows a new CMS direct purchase premium per enrollee series (NHE projections Table 17). CMS out-of-pocket spending excludes premiums by definition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rality Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No dataset fills long_term_health_insurance_premiums and no CMS series measures long-term care insurance premiums; 26 U.S.C. 213(d)(10)(B) indexes the deductible limits on them by the medical care CPI. Adds gov.bls.cpi.cpi_u_medical_care: BLS annual means to 2022, CBO's February 2026 calendar-year series for 2023-2036, extended at its 2035-2036 rate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds calibration.gov.hhs.cms.medicare_part_b_premium_per_enrollee: the standard monthly premium for 2013-2026 (2026 Trustees Report Table III.C2) and the Trustees' intermediate estimates for 2027-2035 (Table V.E2), extended at the 2034-2035 rate. A premium with any income-related adjustment is a fixed multiple of the standard premium (42 U.S.C. 1395r(i)(3)). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core tests cover transcription, the Part B statutory components, agreement with the model's Part B premium, Hypothesis bounds and extension rules for each index; the microsimulation test covers all five inputs. The SPM methodology page says which inputs follow which premium series. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uprating # Conflicts: # docs-quarto/methodology/spm-poverty.qmd # policyengine_us/parameters/uprating_extensions.py # policyengine_us/tests/core/test_per_capita_uprating.py # policyengine_us/tests/core/test_uprating_series.py # policyengine_us/tests/policy/baseline/parameters/test_uprating_extensions.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Long-term care: CPI-U medical care by calendar year is a proxy for the chained August index 26 U.S.C. 213(d)(10)(B) uses; CMS's projections have no long-term care premium series. - Part B: within an income tier, a premium is a fixed multiple of the standard premium before rounding; hold-harmless and Medicare Advantage reductions move some premiums differently. - Direct purchase is the closest CMS series for the self-employed slice, not a claim about how each premium was bought. - Move neutrality is conditional on a producer removing moved dollars. - Tests pin BLS means for 2015-2024 and the employee share in every year 2024-2034; one Trustees reference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 11, 2026 15:38
This was referenced Oct 11, 2026
…wording Keeps #10097's HSA sentence and series; the CMS out-of-pocket list now ends with prescription expenses. Long-term care: the statute's index is for August of the preceding year and CBO and CMS do not project it. Part B: a growth proxy, not each person's premium. Trustees reference title carries its file pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Hand-off to the US + core hub. Head
|
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.
Builds on #10083 (merged 2026-10-11 as
35f3c1f92a), which added the ESI premium per enrollee series.mainis merged in, and the diff againstmainis this PR's change alone.What changes
Five premium inputs uprated by
calibration.gov.hhs.cms.moop_per_capita, CMS's out-of-pocket health spending per capita. CMS defines that series to leave premiums out: "Premium payments for private insurance plans (including Medicare Advantage private plans) are not included in out-of-pocket spending" (NHEA methodology paper, 2024, file page 14). Each input now follows a premium series.health_insurance_premiums_without_medicare_part_bPHIP_VAL, the premiums the person reported payingother_health_insurance_premiumsPHIP_VALless modeled CHIP, Medicaid and Marketplace premiumshealth_insurance_premiumsPHIP_VAL, only for self-employed people under 65 without ESIlong_term_health_insurance_premiumsmedicare_part_b_premiums_reportedThe ratios are computed by the engine from each version's parameters (
scripts/per_person_ratios.py): base is #10083's head5b30a11f90; the PR's are at this branch's head.New parameters
calibration/gov/hhs/cms/direct_purchase_premium_per_enrollee.yaml: NHE projections Table 17, "Spending per Enrollee", "Direct Purchase" row, 2013–2034.gov/bls/cpi/cpi_u_medical_care.yaml: BLS annual means (CUUR0000SAM) for 2015–2022, then CBO's February 2026 calendar-year series ("CPI-U, medical care", sheet "2. Calendar Year", row 59) for 2023–2036.calibration/gov/hhs/cms/medicare_part_b_premium_per_enrollee.yaml: the standard monthly premium for 2013–2026 (2026 Trustees Report Table III.C2), then the Trustees' intermediate estimates for 2027–2035 (Table V.E2, file page 213).Extension.
uprating_extensions.pygrows each series at its last published one-year rate to 2100 and holds the 2100 value after that. This is the rulemoop_per_capitaand #10083's ESI series use.The per-capita classifier from #10083 already treats
per_enrolleepaths as per-person rates. The CPI series sits undergov.bls.cpi, like CPI-U, because a path undercalibration.gov.cbowould be divided by population.Docs.
spm-poverty.qmdno longer lists premiums among the inputs that follow out-of-pocket spending. It says which inputs follow each premium series and why.What the data put in each input
Microcosm (
packages/microcosm-build/src/microcosm/build/us/spec/sources.yaml, stageother_health_insurance_premiums, atorigin/main909586128):health_insurance_premiums_without_medicare_part_bis CPS ASECPHIP_VALon ASEC rows (us_runtime/cps_carried.py). On PUF-support rows it is imputed jointly with the next input by a QRF trained on CPS donors.other_health_insurance_premiumsismax(PHIP_VAL − chip_premium − marketplace_net_premium − medicaid_premium, 0)on ASEC rows, with the same QRF for PUF support.health_insurance_premiumsis a copy ofPHIP_VAL, made only where Schedule C income is positive, the person is under 65 with no Social Security disability income, and the person has no ESI (microcosm#451 item 2).long_term_health_insurance_premiumsandmedicare_part_b_premiums_reportedhave no producer. The certified file stores the retired namemedicare_part_b_premiums, which microcosm's own stored-input register (microcosm-data/.../stored_inputs.py) says the engine ignores. No formula readsmedicare_part_b_premiums_reported. The long-term care input feeds Ohio's medical deduction and Washington's senior property tax exemption.What
PHIP_VALholds (Census question HIPREM, identical in the 2023–2025 ASEC; cpsmar25.pdf file page 289):PEMCPREM. Medicare premiums paid by people without Social Security or SSDI are not addressed by the wording.Plan mix, measured on the certified dataset (
populace_us_2024.h5, sha2566496cc43…aee84, the model'sDEFAULT_DATASET). Dollars are 2024, weighted, and grouped by coverage at interview (scripts/plan_mix.py,plan_mix_certified.json):health_insurance_premiums_without_medicare_part_bother_health_insurance_premiumshealth_insurance_premiumsWhy each series
Reported and other premiums → ESI premium per enrollee. These inputs mix plan types, so one index has to stand for all of them.
esi-pre-tax-premiums-454, the follow-up to microcosm#1189) routes an eligible ESI policyholder'sPHIP_VAL, capped at wages, intopre_tax_health_insurance_premiums. Under the disjoint contract of Document disjoint health premium inputs and correct consumer treatment #10046, those dollars must then leave the reported inputs; that branch does not yet do this removal, so it is a contract the producer still has to meet. Uprate ESI premium inputs by CMS ESI premium per enrollee #10083 uprates the pre-tax input by the ESI index, so giving the reported inputs the same index means a move that does meet the contract leaves the dollars' growth unchanged. A test and a Hypothesis property check this on the engine side; they do not test the producer.Directly supplied premiums → direct purchase premium per enrollee. In the data this input holds only self-employed people under 65 without ESI. Direct purchase per enrollee is the closest CMS series for that group, but it is still a proxy. Census's premium question covers all of the payer's premiums for anyone in the household last year, and only 48.9% of these dollars sit on people with direct purchase coverage at interview. CMS's direct purchase category is premiums "for policies that are not available through an employer or a union-based plan", including Marketplace plans (methodology paper, file page 29).
health_insurance_premiums_without_medicare_part_b, which follows the ESI index. Those two equal each other in 2024 and differ afterwards by the ratio of the two indexes: 3.4% in 2026, 0.4% in 2034.other_health_insurance_premiumsis a different quantity, the residual after modeled program premiums and a floor at zero, so it already differs in 2024 for 413 of the 1,379 records.medical_expense_health_insurance_premiumsuses the direct input when it is nonzero. SPM MOOP addsother_health_insurance_premiumsto the current-year modeled program premiums (Marketplace, CHIP, Medicaid, Medicare), so its total is neither reported input alone.Long-term care premiums → CPI-U medical care, as a proxy. CMS's health expenditure projections have no long-term care insurance premium series, and the NHEA methodology paper never mentions long-term care insurance.
Reported Part B premiums → the Part B standard premium. Under 42 U.S.C. 1395r(i)(3), a premium with an income-related adjustment is the standard premium times 1.4, 2.0, 2.6, 3.2 or 3.4, before rounding to the dime. A reported premium at a fixed income tier therefore grows with the standard premium. The series is a growth proxy, not a forecast of each person's payment: hold-harmless limits (1395r(f)) and Medicare Advantage premium reductions move some people's premiums differently. A test checks the series against the model's own
gov.hhs.medicare.part_b.base_premiumfor 2021–2026.Sources, verified from the files
264f822618a5e1829138aea57cc6c8bf45bbaf072a72898fef5547f7ece6cd709c5755666847a78103016f04da937326744071a9a6736f4e77e91ce9e7af8629ce62fe2c236cc96ce287027784b141584ddf39e62c5fd8ddc3e771a014944817dee0ae96eb168277d63dd0c108d3097fc044d0c6cf9c8df99aa6e2b8f7150116ffa56b9137006872300b0346149eae1613d09a172b6ba118aad48e66dfc48fa8US-CBO/cbo-data@284a956)ae8f4920702fabf8fb3136bc94a42c53466cff5e890dec22396d8dc49dc2f7762f2d4026…(2017–2026),7ffc8b64…(2015–2016)Each transcription is checked against the source's own components:
Aggregate effect
Real microsimulation runs, one per year and side, on the model's default dataset (
populace_us_2024.h5@populace-us-2024-spm-20260909, sha2566496cc43…aee84). Base is currentmain(b2aaef3391), and the PR side is this head (2ebef84217). They ran as frozen snapshots in oneheavy_run.shjob under the shared heavy lock (impact2/inner.sh). Per-record arrays,compare.{2026,2034}.jsonandpoverty.*.jsonare inimpact2/in the evidence folder.health_insurance_premiums_without_medicare_part_bother_health_insurance_premiumshealth_insurance_premiumsAn earlier frozen pair, #10083's head
5b30a11f90against this PR's first commit9e6b734f12(impact/in the evidence folder), gave the same input and MOOP changes to within $1 million. Its poverty changes were +0.21 points in 2026 and +0.28 points in 2034.main's other changes since then move the base levels (SNAP, state tax) but not this PR's effect.Invariants and tests
tests/core/test_premium_input_uprating.py(155 tests) reads the parameter tree:gov.hhs.medicare.part_b.base_premiumfor 2021–2026.tests/microsimulation/test_premium_input_microsim_uprating.py(26 tests) runs the engine:Simulation, each of the five inputs and the pre-tax input equals its 2024 amount times its index ratio.extend_single_year_dataset, each person follows the ratio, and weighted totals grow by the ratio times population growth.Also updated:
test_uprating_series(expected series),test_per_capita_uprating(the new paths are per-person rates),test_uprating_extensions(each new series extends at its last rate and is flat after 2100).Mutation check: reverting
other_health_insurance_premiumsto out-of-pocket spending fails 9 tests, including the move-neutrality property.Test cost
Local macOS, each file run alone in its own process:
tests/core/test_premium_input_uprating.py(155 tests)tests/microsimulation/test_premium_input_microsim_uprating.py(26 tests)The ranges are runs at different host loads. Linux numbers will come from this PR's own CI artifacts.
The core file adds no memory over the system build that the Rest/core group already pays. The microsimulation file adds about 140 MB in isolation.
Coordination with #10046
#10046 (draft) adds
documentationstrings to the same premium variables, inserting them just above theuprating =line that this PR and #10083 change. A trial merge (git merge-tree) conflicts in four files: two from this PR (health_insurance_premiums_without_medicare_part_b.py,long_term_health_insurance_premiums.py) and two from #10083 (pre_tax_health_insurance_premiums.py,employer_sponsored_insurance_premiums.py). Each resolves by keeping both sides: #10046's documentation, then this PR's comment andupratingline. No content disagrees.#10097 (merged). HSA payroll contributions now follow the 223(b)(2) limit. The merge with
mainkeeps #10097's HSA sentence and series. As its session asked, the out-of-pocket list inspm-poverty.qmdnow ends "…lab and prescription expenses."#10084 (open) and #10119 (open).
moop_per_capita. A trial merge is clean.Other suites run locally
ruff formatandruff checkare clean.Independent review
Round 1 (GPT-6.1 Sol, at
caf654d7b5): APPROVE, with seven non-blocking findings. All are addressed in772c2ab338:other_health_insurance_premiumsis a residual and already differs in 2024.The reviewer independently re-derived all 67 parameter values from the source files and re-hashed every source. They recomputed every aggregate and both poverty rates from the per-record arrays, and ran 363 tests. Full text:
out_review_r1_full.mdin the evidence folder.Round 2 (GPT-6.1 Sol, at
772c2ab338): APPROVE. It found findings 3, 4 and 6 resolved and 1, 2, 5 and 7 partly resolved, all non-blocking, plus two new low findings:main.2ebef84217finishes them all:#page 89-90,213.mainagainst this head; see Aggregate effect.The reviewer also confirmed that the PR's 275 tests passed in CI at
772c2ab338. That run's Rest job failed only on main'stest_known_violations_only_shrink(the Illinois AABD entry #9902 removed), which is outside this diff. Full text:out_review_r2_full.md.Follow-ups, not in this PR (each queued as a separate task)
moop_per_capitais from CMS's February 2025 release. The current Table 03 has 2026 at $1,826, against $1,720 in the YAML. Update CMS out-of-pocket per-capita uprater to NHE projections 2025-2034 #10084 (open) refreshes it. If it merges first, the "before" column above rises: out-of-pocket spending grows faster in the new release. This PR's "after" factors don't depend on it.health_savings_account_payroll_contributionsfollowed out-of-pocket spending, which counts spending from HSAs rather than contributions into them. Uprate HSA payroll contributions by the 223(b)(2) contribution limit #10097 (merged) moved it to the 26 U.S.C. 223(b)(2) family limit, and this branch merges that change.gov.hhs.medicare.part_b.base_premiumstops at 2026, so the modeled standard base premium stays at $202.90 a month in later years. The new Trustees series makes a projection available.Evidence (sources with SHA256SUMS, research notes, scripts, run JSON):
~/reviews/premium-inputs-cms-uprating-2026-10/.axiom: n/a: microsim input uprating (data aging); no policy rule changes
🤖 Generated with Claude Code