Skip to content

Long-term CPS projections (2026–2100) have no populace replacement — decide rebuild / inherit / retire before #204 closes #333

Open

Description

@MaxGhenis

The populace#204 replacement audit (table on that issue) found one artifact family with no code-level populace replacement, not even pending: the long-term CPS projections (long_term/*, 75 single-year datasets 2026–2100) shipped by the archived policyengine-us-data. Two independent zero-match searches across populace confirm nothing addresses it — this is distinct from target-side aging (ledger cbo_growth_factor_aging), which ages the calibration surface, not the microdata records.

Decision needed before #204 can close: (a) rebuild long-term projections as a populace product (the populace-dynamics trajectory work is the natural eventual home — cf. populace-dynamics#45's design reservations), (b) explicit temporary inheritance from the archived artifacts with a documented sunset, or (c) declare out of scope with consumer migration notes. Consumers and evidence are in the #204 table.

Activity

  1. MaxGhenis commented on Jul 7, 2026

    @MaxGhenis
    ContributorAuthor

    Paused by Max (2026-07-07) — no rebuild/inherit/retire decision yet; revisit alongside the #204 archive decision after the next certified release.

  2. MaxGhenis commented on Sep 18, 2026

    @MaxGhenis
    ContributorAuthor

    New evidence for this decision, from an uprating review of policyengine-us on 2026-09-18, and a proposal for a smaller product than the 2026 to 2100 projections: a shared static-aging step for the budget window that both countries get.

    What the review measured

    Microsimulation takes the single-year Microcosm file and extends it in the country model (extend_single_year_dataset). Household weights grow with total population, and every dollar input on a national total (IRS SOI series, CBO income projections) grew by the full total as well. Weighted totals therefore overshot each national total by population growth: 0.9 percent in 2025, 3.5 percent by 2030, 5.1 percent by 2035 on populace_us_2024.h5 at populace-us-2024-spm-20260909. The archived policyengine-us-data pipeline divided totals by population growth, so this arrived with in-model extension of the single-year file.

    PolicyEngine/policyengine-us#9526 fixes the double count in the country model by uprating with each total divided by population. PolicyEngine/policyengine-us#9527 repairs several series mappings. Both are interim.

    What in-model extension cannot do

    It scales all weights by one factor, so age structure stays at the base year. The SSA projections the archived long-term build used (SSPopJul_TR2024.csv) have the 65 and over population up 2.8 percent in 2025, 15.5 percent by 2030 and 22.9 percent by 2035, against 0.7, 3.8 and 6.7 percent overall. With uniform scaling, recipient counts for age-linked income cannot move with demographics, so per-record amounts absorb it: each Social Security recipient's benefit grows 8.3 percent in 2025 because the aggregate does.

    Per-capita factors and age reweighting also cannot be mixed freely. A per-capita factor is only consistent with uniform weight scaling. Once weights follow age structure, the factor for each series has to be solved against the reweighted data.

    Proposal: static aging as a Microcosm step

    For each year in the budget window, from one base-year frame:

    1. Fit weights to the projected population by age, plus any projected totals the country's Chronicle surface carries for that year.
    2. For each dollar input that follows a national total, set the factor to the projected total divided by the reweighted base-year weighted total. Per-person rates and price indices pass through unchanged.
    3. Ship the years as one multi-year artifact. Country-model uprating becomes the fallback for household calculators and years outside the window.

    This is what the archived long-term build did in outline (policyengine-us uprating, then IPF to SSA single-year age, then entropy calibration to Social Security, taxable payroll and taxation-of-benefits totals), except that it corrected targeted totals by reweighting and left untargeted inputs with the double count. Solving the factor removes it for every series by construction.

    Nothing in the step is country-specific beyond the target source: SSA or CBO for the US, ONS and OBR for the UK. From the variable declarations on policyengine-uk main, most UK inputs already follow CPI, per-capita GDP or average earnings, with household_weight on ONS population, so the UK does not have the double count. It does share the uniform weight scaling. I did not check whether the UK build fits weights per year.

    The ruling this needs

    DESIGN.md says calibrating cross-sections independently destroys panels and is a kernel-level error, and places future years under the Dynamics operator (sequencing step 6). Static aging makes no panel claim: one base-year cross-section, reweighted per year, with no person identity across years. The question is whether that is admissible as a named cross-sectional operator now, with the trajectory work replacing it later, or whether future years wait for Dynamics. That choice also settles option (a) versus (b) above for the budget window.

    Evidence and scripts: the measurements above are reproducible from the PR bodies of PolicyEngine/policyengine-us#9525, #9526 and #9527.

  3. MaxGhenis commented on Sep 18, 2026

    @MaxGhenis
    ContributorAuthor

    Amendment to my comment above, after discussion: weights carry demographics only.

    The line "plus any projected totals the country's Chronicle surface carries for that year" was wrong. A program count is an output of rules, take-up and demographics; forcing weights to match a projected count means the model can no longer be wrong about it, so it can no longer be checked. Filers by AGI bin has the same problem in income form and double counts the factor step.

    The split is:

    1. Weights carry who exists: population by age, sex and marital status for the year, from SSA's projections for the US and ONS for the UK. Nothing else.
    2. Dollar factors carry the aggregates: for each input that follows a national total, the factor is the projected total divided by the reweighted base-year total. Per-person rates and price indices pass through. Social Security benefits per recipient then grow by what remains after the 65-and-over count has risen, not by the aggregate.
    3. Program counts and totals become predictions scored against CBO each year, not targets.

    One limitation stated rather than patched: employment status stays at its base-year distribution by age, so a projected downturn appears only as slower per-capita wage growth spread over everyone. Static aging cannot do better without labor-market transitions, which is the Dynamics work.

    Building this now as a Microcosm step; the ruling on cross-sectional reweighting versus Dynamics is still needed before it can merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions