Add KFF eligible-uninsured moments and Medicaid 100% take-up reform rows - #69
Open
MaxGhenis wants to merge 14 commits into
Open
Add KFF eligible-uninsured moments and Medicaid 100% take-up reform rows#69MaxGhenis wants to merge 14 commits into
MaxGhenis wants to merge 14 commits into
Conversation
…ct probe The reported Medicaid-at-interview input sums to 24.6M under-65 on the sparse Build P artifact versus roughly 60M survey-reported Medicaid, leaving an 80.9M reported-uninsured denominator against roughly 27M ACS-reported nonelderly uninsured. Named on the joined rows so the 43.15% primary share reads with that context; modeled-uninsured and eligible-not-enrolled rows flagged as the informative counterparts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI runs pytest without pandas; the builder now reads extracts with csv/gzip and computes masks as boolean lists, matching the other pipeline modules. Rerunning it on the full-file extracts reproduces all 208 committed staged rows (worst relative value difference 1.7e-9, every non-numeric field identical). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolves the three blockers from the merge audit: - Blank or non-finite values in age/person_weight/medicaid now raise at parse (the denominator column keeps NaN, used only in the paired retention check); identity/anchor/bridge gates use NaN-proof inverted comparisons; JSON writes set allow_nan=False. - The full path requires the exact certified provenance triple via a shared require_certified_provenance (engine 1.764.6 / us-5.0.2 / Build P id) instead of trusting any self-consistent sidecar; the extractor calls the same pin. - The extractor validates provenance before any computation or write, and publishes CSV + metadata sidecar together via temp-and-rename, so a rejected rerun can no longer leave a fresh CSV beside a stale certified sidecar. New tests cover blank-cell rejection, denominator NaN tolerance, the anchor-passing full path, and rejection of a wrong-but-self-consistent triple (179 -> 183). Committed artifacts are unaffected: they are all finite, and under the previous lenient parser any blank in a strict column would have propagated NaN into them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vahid-ahmadi
left a comment
Contributor
There was a problem hiding this comment.
Review — KFF eligible-uninsured moments + 100% take-up rows
Ran the branch locally (179 passed / 4 skipped, ruff clean, CI green) and verified the external side against the live source:
Verified:
- KFF values re-fetched from the live indicator page: US 24.9 / AL 9.5 / CA 32.5 / AK 40.8 / MD 23.3 all match
raw/state_indicator_2024acs_2025levels.mdexactly, vintage confirmed (2024 ACS, 2025 eligibility levels). Bonus: the page's own column header reads "Medicaid/Other Public Eligible" — matching the stagedSTATE_SOURCE_COLUMN, so thekff-column-label-verbatimcaution (annotations.json:47,source.jsondiagnosis_upstream) can be retired. - Take-up vocabulary is the engine's real input:
takes_up_medicaid_if_eligible(compute_kff_medicaid_extract.py:30) is incompute_counterparts.py's proven fulltakeup set (line 60), not a guessed name. - Arithmetic identities hold: 77.325 − 72.336 = 4.989M enrollment change; bridge 2.792 + 2.196 = 4.988 ≈ Δ within fp.
- reform_ref exhibit route is fail-loud: mutual exclusion with
external_claim_match, framework pin,reform_keycross-check all raise (ingest_campaign.py:176-199); idempotency stays exact-run_id, no prefix sweep. - The 80.9M reported-uninsured denominator anomaly is measured and honestly diagnosed (
annotations.jsonkff-medicaid-reported-denominator-sanity: thinned Medicaid-at-interview input, 24.6M vs ~60M survey).
Should consider:
- Primary/alternative designation contradicts the lane's own sanity annotation. The denominator annotation concludes the reported-uninsured share "is not a survey-faithful uninsured measure on this artifact" and names the modeled variant + eligible-and-not-enrolled counts as "the informative PolicyEngine rows for this join" — yet reported-uninsured (43.15%) is the primary construct and modeled (5.71%) the annotated alternative. A consumer surfacing primary rows shows exactly the comparison the lane says is uninformative. Either swap primacy, or carry the annotation's verdict onto the primary rows' display status so the 43.15%-vs-24.9% pairing can't render unqualified.
- Minor:
meta["note"](ingest_campaign.py:205,240) raises a bare KeyError on a note-less exhibit row rather than the labeled ValueError every sibling contract violation gets.
Solid lane overall — the construct-difference annotations are the most complete of any source in the repo.
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
policyengine_us_inputsReformRef route and stage the reform that forces annual Medicaid take-up to 100%, including enrollment, spending, and marginal-enrollee bridge rows for the US and every state.different_model,held_out, and eitherconcept_mismatchfor 2024 ornot_computedwith a dated 2024 reference for the 2022 claims.Results
The national eligible and enrolled estimates differ from the lane anchors by 0.03% and 0.05%, respectively. Enrollment change equals eligible minus enrolled, and the two bridge components sum to the enrollment change within floating-point precision.
The three largest absolute state differences in the primary eligible-share comparison are California (+31.99 percentage points PE minus KFF), Connecticut (+31.74), and Maryland (+28.25). These rows carry named construct differences rather than accuracy labels.
Construct annotations
has_esi, Marketplace-at-interview, non-Marketplace direct-purchase-at-interview, Medicaid-at-interview, TRICARE, VA, CHAMPVA, other-means-tested, or IHS coverage, plus not modeledmedicare_enrolled. The under-65 restriction is applied during moment aggregation.medicaid_enrolled, including anchor-and-fill enrollees presumed to have survey underreporting. KFF states no analogous underreporting correction.years_since_us_entry, so the engine's five-year-bar leg uses that variable's default.Staging and ingest
app/public/data/moments.json: 603 total rows, including 52 KFFconcept_mismatchrows and five KFFnot_computedrows with 2024 references.data/pe/.sources/campaign-20260818/us/, covering four components across the US plus 50 states and DC.data/scorecard.dbas 208 exhibits under canonical ReformRef key849973669b6526d6; offline re-ingest is idempotent./private/tmp.Ready-to-run ingest command:
Validation
pe.us.managed_microsimulation()on policyengine-us 1.764.6 and certified bundlepopulace-us-2024-buildp-sparse-rmloss100-cae8640-20260728T011454Z(us-5.0.2).uv run --offline --no-project --active pytest tests/ -q: 179 successful tests.app/node_modules; network access was prohibited, so no dependency install was attempted.Review findings (main session)
A post-lane probe of the certified artifact's person inputs found the
reported-uninsured denominator is not survey-faithful: 80.9M people under 65
carry none of the nine reported-coverage inputs, versus roughly 27M
ACS-reported nonelderly uninsured in 2024. Employer (146.9M under 65) and
Marketplace (21.4M) inputs sit near survey levels, but the reported
Medicaid-at-interview input sums to 24.6M under 65 against roughly 60M
survey-reported Medicaid — the sparse build thins it, and CMS-calibrated
modeled enrollment does not backfill the reported flag. Consequences, now
annotated on the joined rows:
denominator context; the modeled-uninsured variant (5.71%) and the
eligible-and-not-enrolled counts (2.79M uninsured marginal enrollees) are the
informative PE rows for this join.
denominator effect with a genuine construct difference: PE's eligibility
formula includes state coverage regardless of immigration status (e.g.
CA's
is_ca_medicaid_immigration_status_eligibleleg), while KFF's ACA-lenscategories class those people as ineligible due to immigration status.
thinning in the sparse build (adjacent to the untargeted-input zeroing class,
microcosm#361).
Follow-ups
Medicaid/Other Publicto a more specific metric label.🤖 Generated with Claude Code