PolicyEngine / PolicyEngine/policyengine-us
Medicaid MAGI household: 'living with both parents' proxy pools grandparent income in multigenerational households
- Dominant language
- Python
- Stars
- 162
- Forks
- 212
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 97
Description
## Summary
The Medicaid MAGI household rules infer "child living with both parents" from a family-level count of anyone with own children. In multigenerational households the grandparent counts as a second parent for every child, so every child is evaluated under non-filer rules with a household that pools every adult's income. Real parent links from the data fix it; this issue proposes the input variables and the variable changes.
## Where
- [medicaid_tax_dependent_exception_living_with_both_parents.py](https://github.com/PolicyEngine/policyengine-us/blob/main/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_tax_dependent_exception_living_with_both_parents.py): fires when `family.sum(is_parent) > 1` and `tax_unit.sum(is_parent) == 1`.
- [is_parent.py](https://github.com/PolicyEngine/policyengine-us/blob/main/policyengine_us/variables/household/demographic/person/is_parent.py): `own_children_in_household > 0`, so any adult with own children in the household is a "parent" of every child in the family.
- [medicaid_household_size.py](https://github.com/PolicyEngine/policyengine-us/blob/main/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_household_size.py) and [medicaid_household_income.py](https://github.com/PolicyEngine/policyengine-us/blob/main/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_household_income.py): the non-filer branch for a child sums *all* parents and *all* child-age persons in the family as the child's "parents and siblings" (42 CFR 435.603(f)(3)(iii)).
- [medicaid_claimed_by_parent_in_tax_unit.py](https://github.com/PolicyEngine/policyengine-us/blob/main/policyengine_us/variables/gov/hhs/medicaid/income/medicaid_claimed_by_parent_in_tax_unit.py), `is_mother`, `is_father`: same inference.
## Reproduction
Microcosm Build P (`populace_us_2024`, build `populace-us-2024-buildp-sparse-rmloss100-cae8640-20260728T011454Z`), policyengine-us 1.764.6, household 1009324: Ohio, 10 persons in one family, 3 tax units. A 56-year-old head ($108k wages) with dependents aged 17 ($13,774 wages) and 16; a 30-year-old head with four children (12, 10, 9, 7), $25k earned; a pregnant 27-year-old head with a 3-year-old, $24k wages.
`is_parent` is true for all three adults, so `medicaid_tax_dependent_exception_living_with_both_parents` is true for all seven children. Their non-filer household is size 10 with income $141,848 (211.46% of poverty against Ohio's 211% child limit). The 17-year-old's wages count because they exceed the TCJA-expiration dependent filing threshold. Raise the standard deduction to OBBBA's $16,100 and the teen is no longer required to file, the household income drops to $128,075 (190.9%), and all seven children become eligible: +$55,655 of Medicaid attributed to the standard deduction. Live: https://www.policyengine.org/us/obbba-household-explorer/?household=1009324&baseline=tcja-expiration.
Under 42 CFR 435.603(f)(2), the four children claimed by the 30-year-old take that parent's tax household (size 5, 60% of poverty), the 3-year-old the 27-year-old's (88%), and the 17- and 16-year-olds the 56-year-old's (about $81k for 3, far above 211%). Nothing moves at the standard-deduction step. The current code is identical on `main` as of 2026-09-07.
Regulation text (42 CFR 435.603): (f)(2)(ii) applies non-filer rules to "individuals under the age specified by the State ... who expect to be claimed by one parent as a tax dependent and are living with both parents but whose parents do not expect to file a joint tax return"; (f)(3)(iii) makes a child's non-filer household "the individual's parents and siblings" living with the individual.
## Proposed fix
1. Two new person input variables, `parent_1_id` and `parent_2_id` (int, default 0 meaning unknown or absent), holding the `person_id` of a co-resident parent. Populated by Microcosm from CPS `PEPAR1`/`PEPAR2` (https://github.com/PolicyEngine/microcosm/issues/884). Precedent for an id-valued person input: `medicaid_claiming_tax_unit_id`.
2. `medicaid_tax_dependent_exception_living_with_both_parents`: when both ids resolve to household members, "living with both parents" is true only if both parents are present and are not head and spouse of the same joint-filing tax unit. When ids are 0, keep today's proxy so results are unchanged on data without pointers.
3. `medicaid_household_size` and `medicaid_household_income`, non-filer branch: parents are the persons at `parent_1_id`/`parent_2_id`; siblings are child-age persons sharing at least one parent id. Fall back to the family sums when ids are 0.
4. `medicaid_claimed_by_parent_in_tax_unit`: true when the claiming head or spouse is one of the person's parent ids; fall back to the current inference when ids are 0.
5. `is_parent`, `is_mother`, `is_father`: derive from "some household member points at me" when any ids are present in the household; otherwise the current count test.
6. Tests: a YAML case encoding the household above with ids set, asserting each child's `medicaid_household_size`, `medicaid_household_income`, and eligibility follow the claiming parent's tax unit; a second case with ids at 0 asserting current outputs (regression guard); a two-unmarried-parents case where the exception should still fire.
## Scale
In the OBBBA paper frames the proxy is aggregate-negligible (2 records, weight ≈0.007). The standard-deduction Medicaid channel itself ($6.4B weighted) is mostly genuine law: dependents under 19, full-time students under 24, and disabled adult children whose earnings fall between the old and new dependent filing thresholds. This issue is about record-level correctness and about pe-us's role as the oracle baseline for the Axiom Medicaid encodings.
Contributor guide
Research direction
Start with medicaid_tax_dependent_exception_living_with_both_parents.py, medicaid_household_size.py, and medicaid_household_income.py, then inspect medicaid_claiming_tax_unit_id as the precedent for person IDs. Add YAML cases for the described linked-parent household, zero-ID regression, and two-unmarried-parents case, asserting household size, income, and eligibility. Done means the linked-parent outputs follow each child's claiming tax unit while zero IDs preserve current results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100