Skip to content

Declare point-in-time (average-month) semantics for enrollment take-up flags and snapshot-month provenance #332

Description

@daphnehanse11

Context

policyengine-us is an annual-period engine, but health program enrollment is monthly administrative reality. The build currently resolves this implicitly: the CPS anchor columns are point-in-time at interview (has_*_health_coverage_at_interview), and the cms_medicaid ledger facts are month-tagged state snapshots (e.g. month2024_12, per #321). Nothing declares what an annual *_enrolled flag means against those inputs, which invites concept drift — e.g. someone later calibrating to T-MSIS ever-enrolled-in-year counts (~10M+ higher post-unwinding) against a point-in-time anchor.

There is strong precedent for resolving this deliberately. Urban's HIPSM methodology (2020): "For Medicaid enrollment, we generally use the June enrollment report from CMS… We chose to use a point-in-time snapshot for all states compatible with our Marketplace targets, rather than an annual average." HIPSM models coverage as average-monthly/point-in-time throughout — survey anchor, admin target, and model concept all at the same instant — and handles within-year churn in separate machinery (TRIM3), not in the coverage model.

The point-in-time convention is also what keeps spending coherent: average-monthly enrollment approximates the full-year-equivalent count that CMS per-enrollee cost denominators use; ever-enrolled semantics would overstate spending unless durations were modeled.

Goal

Make the convention explicit doctrine rather than emergent behavior, so every enrollment take-up stage (#331, the ACA stage, future Medicare/BHP work) and every enrollment target shares one declared concept.

Suggested implementation

  • Add a doctrine paragraph to take_up_contract.json: enrollment take-up flags represent enrollment at a representative point in time (average month), anchored on interview-point survey coverage and calibrated to month-tagged administrative snapshots; annual-flow (ever-enrolled) semantics are explicitly out of scope, deferred to the longitudinal frame direction (DESIGN.md, time-as-a-dimension).
  • Require enrollment-count target facts to carry their snapshot month (already true for cms_medicaid month2024_12 rows — make it a checked convention, not an accident), and surface the month in release diagnostics/target registry output.
  • Record the concept decision per target family: point-in-time snapshot vs annual average vs ever-enrolled, with the chosen concept asserted where targets are compiled.
  • Feeds Add coverage-universe targets for uninsured and private coverage #230's open decision ("person-level annual coverage, interview/current coverage, or both") — coverage-universe targets should adopt the same current-coverage concept where source support allows.

Acceptance criteria

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions