$npx -y skills add PolicyEngine/policyengine-claude --skill policyengine-healthcareUS healthcare domain knowledge (Medicaid, ACA premium tax credit, CHIP, Medicare) for analysts using the policyengine package. Load for: why ACA PTC and Medicaid changes show $0 in household_net_income (the include_health_benefits_in_net_income gotcha) and how to measure health i
| 1 | # PolicyEngine US healthcare domain knowledge |
| 2 | |
| 3 | Medicaid, the ACA marketplace (premium tax credit), CHIP, and Medicare are the hardest US programs |
| 4 | to analyze correctly, because they are modeled as **in-kind health benefits** rather than cash. |
| 5 | This skill is the domain layer for analysts using the `policyengine` package; for non-health US |
| 6 | programs use **policyengine-us**, for the shared calculation/reform mechanics use the |
| 7 | **policyengine** skill, and for building new health variables use **policyengine-model-development**. |
| 8 | |
| 9 | Verified against policyengine 4.21.0 / policyengine-us 1.764.6 (2026-07). Re-verify variable names |
| 10 | and parameter values before reporting. |
| 11 | |
| 12 | ## The one gotcha that dominates everything: health benefits are excluded from net income |
| 13 | |
| 14 | `gov.simulation.include_health_benefits_in_net_income` defaults to **False**. ACA PTC, Medicaid, |
| 15 | CHIP, and Medicare cost flow through `household_health_benefits`, which the default |
| 16 | `household_net_income` **does not include**. So a reform that changes `aca_ptc` or `medicaid` |
| 17 | produces a **$0 change in `household_net_income`** — the single biggest time-sink in health |
| 18 | analysis. If you score a PTC or Medicaid reform by net-income change and get zero, this is why. |
| 19 | |
| 20 | Measure health impact one of these ways instead: |
| 21 | |
| 22 | - **`household_net_income_including_health_benefits`** — the same net income *with* health benefits |
| 23 | folded in. Its difference from `household_net_income` is exactly the household's health-benefit |
| 24 | value. |
| 25 | - **The program variable directly** — `aca_ptc` (tax_unit), `medicaid` (person), summed or |
| 26 | differenced across baseline and reform. |
| 27 | - **Population cost: `pe.us.calculate_budgetary_impact`.** Its `total` already adds the |
| 28 | shared-funding health-program cost (Medicaid / CHIP / Medicare Savings Programs) on top of |
| 29 | Δtax − Δbenefits, so it captures the health split automatically — do not hand-roll it from |
| 30 | `household_net_income`. See the policyengine skill for the population flow. |
| 31 | |
| 32 | Verified end to end (single adult, $35k, Texas — ACA-eligible, not Medicaid-eligible): |
| 33 | |
| 34 | <!-- verify --> |
| 35 | ```python |
| 36 | import policyengine as pe |
| 37 | |
| 38 | r = pe.us.calculate_household( |
| 39 | people=[{"age": 45, "employment_income": 35_000}], |
| 40 | tax_unit={"filing_status": "SINGLE"}, |
| 41 | household={"state_code": "TX"}, |
| 42 | year=2026, |
| 43 | extra_variables=["aca_ptc", "household_net_income_including_health_benefits"], |
| 44 | ) |
| 45 | assert round(r.tax_unit.aca_ptc, 2) == 6_250.38 # a real PTC... |
| 46 | # ...but it is NOT in default net income; the gap is exactly the PTC: |
| 47 | gap = (r.household.household_net_income_including_health_benefits |
| 48 | - r.household.household_net_income) |
| 49 | assert round(gap, 2) == round(r.tax_unit.aca_ptc, 2) |
| 50 | ``` |
| 51 | |
| 52 | And the toggle itself: |
| 53 | |
| 54 | <!-- verify --> |
| 55 | ```python |
| 56 | from policyengine_us import CountryTaxBenefitSystem |
| 57 | p = CountryTaxBenefitSystem().parameters |
| 58 | assert p.gov.simulation.include_health_benefits_in_net_income("2026-01-01") == False |
| 59 | ``` |
| 60 | |
| 61 | ## Healthcare variables |
| 62 | |
| 63 | Entity and period are load-bearing (verified). Note `aca_ptc` and `slcsp` are **tax-unit**; |
| 64 | Medicaid/CHIP eligibility is **person**; `slcsp` is **monthly**. |
| 65 | |
| 66 | | Variable | Entity | Period | Meaning | |
| 67 | |---|---|---|---| |
| 68 | | `aca_ptc` | tax_unit | year | ACA premium tax credit (annual) | |
| 69 | | `is_aca_ptc_eligible` | person | year | PTC eligibility (income band, no disqualifying coverage) | |
| 70 | | `aca_magi` | tax_unit | year | MAGI for ACA — `adds` `medicaid_magi` | |
| 71 | | `aca_required_contribution_percentage` | tax_unit | year | required premium contribution rate | |
| 72 | | `slcsp` | tax_unit | **month** | second-lowest silver plan (benchmark) premium | |
| 73 | | `medicaid` | person | year | modeled Medicaid benefit value (per-capita cost when enrolled) | |
| 74 | | `is_medicaid_eligible` | person | year | overall Medicaid eligibility | |
| 75 | | `medicaid_enrolled` | person | year | eligibility × take-up | |
| 76 | | `medicaid_category` | person | year | enum (see precedence below) | |