Skip to content

Deem SSI parental income from the child's co-resident parents, not the tax unit - #10159

Open
MaxGhenis wants to merge 10 commits into
ssi-ineligible-child-allocation-scopefrom
ssi-parent-deeming-household
Open

MaxGhenis wants to merge 10 commits into
ssi-ineligible-child-allocation-scopefrom
ssi-parent-deeming-household

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

20 CFR 416.1165 deems an eligible child's ineligible parents' income to the child. 416.1160(d) defines an ineligible parent as "a natural or adoptive parent, or the spouse ... of a natural or adoptive parent, who lives with you and is not eligible for SSI benefits". The ineligible children allocated against that income are "the natural or adopted child of your parent or of your parent's spouse ... who lives in the same household with you".

Before this PR, PolicyEngine-US grouped all of this by the child's tax unit:

  • Parents. Every non-disabled tax-unit member flagged as a parent deemed to every disabled tax-unit child. That included grandparents and parents who live elsewhere. It left out stepparents and parents filed in another tax unit.
  • Ineligible children. Every tax-unit child was allocated, cousins and grandchildren included. Half-siblings claimed elsewhere were not.
  • Division. The tax unit's income was split among all its disabled children.
  • Status. No citizenship or qualified-noncitizen test applied to the child or the parent.

This PR resolves the child's parents, siblings and pool from relationships. #10146 did the same for the spouse-to-spouse side. This PR is stacked on #10146: its diff is only this change, and GitHub retargets it to main when #10146 merges.

What changes

Who deems (is_ssi_ineligible_parent, rows from resources/deemed/_ssi_parents.py):

  • With parent ids. The parents named among the child's household members, plus each one's co-resident spouse (the SSI spouse test).
  • Without ids. The documented tax-unit proxy of _parent_links.py: the unlinked parents in the child's tax unit who live with the child, and their spouses.
  • Shared with resources. This deemer-set logic is the one parental resource deeming already used. It moved unchanged into _ssi_parents.py, with a with_spouses switch added, and both sides now call it. Resource deeming results are unchanged: the reviewer compared 1,000 random households against the base.
  • Exclusions. A parent who meets the SSI status conditions (aged, blind or disabled, and a citizen or qualified noncitizen) is not an ineligible parent (416.1165(g)(1)). A person is never their own ineligible parent.
  • Stepparents. A stepparent deems only through a natural or adoptive parent who lives in the household (POMS SI 01320.500 A.1, SI 01320.550 B.8).

Eligible child (new is_ssi_income_deeming_child; POMS SI 01310.115 A.2, 416.1856): under 18, aged, blind or disabled, a citizen or qualified noncitizen, not married, not the head of a household, and living with at least one ineligible parent.

  • A child is married if the SSI spouse test finds a co-resident spouse, or if their two-person marital unit has a spouse in another household (416.1806).

Ineligible children (new ssi_parental_deeming_child_allocations; 416.1160(d), POMS SI 01310.115 A.3, SI 01310.140 A, SI 00501.010 B.2) are:

  • the child's own children;
  • the children of the child's co-resident parents or parents' spouses;
  • the children of a stepparent who has left the household and lives elsewhere (SI 00501.010 B.2.d).

Cousins and grandchildren are not allocated. Each child's 416.1163(b) amount still comes from ssi_ineligible_child_allocation (#10146).

Living allowance (new ssi_parental_deeming_parent_allocation, replacing the per-parent ssi_ineligible_parent_allocation): the individual rate for one ineligible parent, the couple rate for two, and both rates for two natural parents and a stepparent (416.1165(d)(3), POMS SI 01320.500 B.4 and Example F.5).

  • main gave the per-parent variable to each parent as a share of a tax-unit total. It cannot be defined per parent once one parent deems to children with different parent sets, so the allowance now lives on the child. Nothing outside the two deeming formulas read the old variable.

Division (416.1165(e)(2), SI 01320.500 C step 9): the remainder is divided among the eligible children who share the same ineligible parents.

  • The children of one pool share one set of allocations: every ineligible child of that deeming household. Their shares therefore add up to the parents' net income.
  • Two families in one home are deemed from their own parents only.

Student exclusion. The child's own student earned income exclusion (416.1112(c)(3)) is no longer subtracted from the parents' earnings. main did that; 416.1161(a) does not.

Medicaid copy (medicaid_optional_senior_or_disabled_unearned_income_deemed_from_ineligible_parent): the same rules with each state's disregards, except:

  • A disabled child need not meet SSI's immigration condition, since Medicaid applies its own.
  • A disabled child who shares the deemed income takes no allocation.
  • Missouri (DSS Manual 0805.020.15) deems only natural or adoptive parents ("Do not deem the income of any other persons in the home, including a stepparent"). It allocates for "each minor child (under age 18) who is living in the home and who is not applying for MA".

Living arrangement. ssi_federal_living_arrangement puts a child in a parental household when is_ssi_income_deeming_child holds, instead of when the tax unit has an "ineligible parent".

Worked cases

All amounts are annual. Base is #10146's head (9d14d23db3), which this PR is stacked on, with this PR's new variables removed from the expectations. Each row is a YAML case whose expectation is computed by hand from the cited source.

Case Base This PR Rule
SI 01320.500 F.5, Tommy: two natural parents and the mother's husband (2025) $3,060 $522 B.4 couple plus individual allowance; the Craig children allocated (416.1160(d))
SI 01320.550 D.7, Ben before his grandparents adopt him: only his mother Kay, 15, deems $9,192 $0 Kay is his parent, not his grandparents (416.1160(d))
Cousin in the mother's tax unit $0 $2,886 a cousin is not an ineligible child (416.1160(d))
Half-brother claimed by a co-resident grandmother; father and stepmother deem $6,090 $3,192 stepmother deems; the half-brother is allocated wherever he files
Stepfather, no ids, married to the child's mother $0 $6,090 "the spouse ... of a natural or adoptive parent" (416.1160(d))
Stepfather after the natural mother has left $5,886 $0 SI 01320.500 A.1, SI 01320.550 B.8
Father who claims the child but lives elsewhere $6,090 $0 "who lives with you" (416.1160(d))
Disabled mother without qualifying immigration status $0 $6,156 she is not eligible for SSI (416.1160(d))
Disabled sister without qualifying status: takes an allocation, no share (James's amount) $3,180 $6,360 416.1160(d), 416.1165(e)(2)
Married 17-year-old living with her husband and her parents $12,090 $0 416.1856(b), SI 01310.115 A.2
Married 17-year-old whose husband lives elsewhere; her brother's amount $5,943 $11,886 416.1856(b), 416.1806
Working 16-year-old student: his exclusion no longer cuts his mother's earnings $2,886 $5,886 416.1112(c)(3), 416.1161(a)
Two sisters sharing a home, each with a disabled son $7,185 each $5,886 and $2,556 416.1165(e)(2): each family's own parents
No ids: teen mother who deems is not also allocated as her son's sister $26,616 $17,670 the parent-link proxy; Kay is a parent, not a sibling
Mixed links: absent stepfather's son in his tax unit $0 $8,988 SI 00501.010 B.2.d
...with a cousin claimed by the mother $0 $8,988 the proxy reaches only the absent stepfather's tax unit
Medicaid Case 6, Missouri: SSI deeming (the stepfather included) $11,562 $65,598 416.1160(d); Missouri's own amount stays $11,562
Medicaid Case 7, DC: Medicaid and SSI $11,562 $65,598 the stepfather deems under SSI rules
Medicaid Case 8, Missouri: SSI deeming without the cousin's allocation $2,580 $5,562 416.1160(d); Missouri's own amount stays $2,580
Medicaid Case 9, DC: lawful permanent resident child, Medicaid / SSI $8,580 / $8,580 $11,562 / $0 SSI immigration gate on SSI only; the child is not allocated against her own parent's income
Medicaid Case 10, DC: immigrant teen mother $7,398 $8,580 she never deems her own income (416.1160(a))

The other source cases, whose relationships the tax unit already got right, give the same amounts on both. These are 416.1165(h) Examples 1, 2 and 4 (with and without parent ids), SI 01320.500 F.1–F.3, SI 01320.550 D.3 (both months), D.7 after the adoption, Missouri manual Examples 1 and 2, and the existing Medicaid Cases 1–3.

Invariants

policyengine_us/tests/core/test_ssi_parental_deeming_invariants.py runs three derandomized Hypothesis batches. Each has 30 random households plus 13 fixed ones:

  • blended families with three and four deemers;
  • a stepparent living elsewhere;
  • mixed immigration status;
  • an SSI-eligible father with another child.

Households contain a mother, a father (married, unmarried, away or absent), a stepparent (who may live elsewhere), a stepmother, an aunt and a grandparent. Children cover every relationship. Some are disabled, some lack qualifying immigration status, and some live elsewhere. They are filed in assorted tax units, with parent ids on everyone, no one or some people. Half the households are in Missouri and half in DC.

  1. Differential. Every person's is_ssi_income_deeming_child, is_ssi_ineligible_parent, child allocations, parent allowance and deemed income equal an oracle. The oracle is written from 416.1160(d), 416.1165, the POMS and the parent-link contract, without the model.
  2. Medicaid. The Medicaid copy equals the oracle's Medicaid variant, with Missouri rules in Missouri. In DC it equals SSI deeming wherever everyone at home is a citizen.
  3. Conservation. The shares deemed to one pool of eligible children add up to their ineligible parents' net income.
  4. Order. Listing people in reverse changes nothing.
  5. Monotonicity. More income for every child, or for every adult, never lowers deemed income.
  6. Bounds. Deemed income is never negative and never above the parents' gross income.

Mutation checks. 25 seeded bugs were run against the property test and YAML; every one that changes an output is caught:

  • dropping parents' spouses;
  • ignoring ids for siblings;
  • presuming without the contract;
  • the old allowance;
  • dividing across families;
  • dropping the immigration test;
  • Missouri keeping spouses or allocating only siblings;
  • ignoring co-residence;
  • letting eligible parents deem;
  • allocating from earned income first;
  • ignoring absent stepparents;
  • the Medicaid immigration gate and allocations;
  • self-deeming;
  • duplicate-id handling;
  • an absent spouse's proxy reach;
  • married minors;
  • the pool key;
  • pooled allocations.

The one survivor excluded a person's own spouse from their proxy set. It changes no output, since a deeming child is unmarried, and that exclusion was dropped to keep the shared helper identical to resource deeming.

Tests run locally

  • New YAML: 29 SSI cases in from_ineligible_parent/ssi_unearned_income_deemed_from_ineligible_parent.yaml, and 10 Medicaid cases (3 existing, 7 new).
  • The 222 YAML files under gov/ssa/ssi, gov/hhs/medicaid and the state supplement, OSS, MSA, PAA and NY HEAP folders, which read these variables: all 2,156 cases pass at c7fa16172c. They ran in batches of 20 under heavy_run.sh.
  • Property tests: the new module, test_ssi_resource_deeming_invariants.py, test_ssi_spousal_deeming_child_allocations.py, test_ssi_state_supplement_medicaid_dependency.py and test_ssi_disability_criteria_inputs.py pass.
  • Code health: these pass:
    • test_parameter_yaml_keys
    • test_reference_urls
    • test_known_dead_reference_urls
    • test_no_concatenated_reference_urls
    • test_no_builtin_sum_over_entity_calls
    • test_no_group_variables_in_person_adds
    • test_rest_python_groups
    • test_input_variable_definitions
    • test_org_input_variables
    • test_aggregate_list_integrity
  • test_formulas_do_not_write_into_cached_arrays is left to CI.

Impact

Run: one full-file 2026 run on each side.

Parental deemed income. 61 child records (132,175 weighted children) have parental deemed income at base.

  • 10 records change: 3 by under a cent (float noise) and 7 by more.
  • 6 of those 7 have weights under 1.
  • The seventh has a weight of 309 children. Their deemed income rises by $3,013 a year.
  • Total change: +$0.93 million a year.

Medicaid deemed component. The same +$0.93 million, across 8 records.

Benefits and taxes. Unchanged for every record:

  • SSI, medicaid, is_medicaid_eligible, federal and state income tax, household benefits and household net income all stay the same.
  • Every affected child's countable income was already above the federal benefit rate.
  • The SSI and household-benefits aggregates differ by $15 and $20, which is float summation noise: no record moves by more than half a cent.

These are the only numbers stated here, and they come from these two runs.

Independent review

Five rounds of GPT-6.1 Sol review (subfleet run --task review --tier hard). Rounds 1–4 found 9 defects, each fixed with the reviewer's reproduction added as a YAML case:

  • a teen parent splitting the sibling pool;
  • an absent stepparent's children;
  • the Medicaid immigration gate;
  • self-deeming;
  • a duplicate second parent id;
  • a mixed-link proxy;
  • an absent spouse's proxy reach;
  • married minors;
  • an eligible parent splitting the pool.

Round 5 approved c7fa16172c with no findings. Reports are in ~/reviews/ssi-parent-deeming-10159/.

Known limitations

  • 416.1166. An eligible parent living with an ineligible spouse and an eligible child. The spouse's income is deemed both to the parent (spousal deeming) and to the child (here). 416.1166 deems to the child only what remains after the parent's benefit reaches zero. Separate follow-up.
  • 416.1165(e)(3). The cap on a child's share and the redistribution. Separate follow-up, with SI 01320.500 F.4.
  • Parents receiving public income-maintenance payments (416.1165(d), 416.1161(a)(2)-(3)). Separate follow-up, together with the spousal side.
  • 416.1165(g)(6) and (i). The $30 medical-facility rate and the home-care waiver.
  • Parent ids name natural, adoptive or step parents alike. A stepparent named by an id deems even after the natural parent has left. Name only natural or adoptive parents and let the spouse test add the stepparent.
  • Data without parent ids. The tax-unit proxy cannot tell a grandparent or an older sibling who is a parent from the child's parent.
  • The same married-elsewhere gap in is_ssi_ineligible_child (Limit SSI spousal-deeming child allocations to the couple's co-resident children #10146) and is_ssi_resource_deeming_child. Separate follow-up.

axiom: TheAxiomFoundation/rulespec-us#1714 queued (20 CFR 416.1165 and the 416.1160(d) parent and child definitions; same corpus-release blocker as #1626 and #1706); TheAxiomFoundation/rulespec-us#1715 queued (Missouri MHABD Manual 0805.020.15)

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 12, 2026 14:20
…e tax unit

20 CFR 416.1165 deems an eligible child's ineligible parents' income: a
natural or adoptive parent, or the spouse of one, who lives with the child
(416.1160(d)). Resolve those parents with the deemor-set logic of parental
resource deeming (now shared in resources/deemed/_ssi_parents.py), drop
the ones who meet the SSI status conditions, allocate only for the child's
siblings, give the living allowance per POMS SI 01320.500 B.4, and divide
among the eligible children who share the same parents. Mirror in the
Medicaid copy with Missouri's natural-parent-only rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Differential against an oracle written from 416.1160(d), 416.1165 and the
parent-link contract, with Missouri's MHDC rules in the Medicaid copy;
conservation of each pool's deemed income, order independence,
monotonicity in children's and adults' income, and bounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… add README and source cases

Fixed blended households (two natural parents, the mother's husband and
the father's wife) join every Hypothesis batch, so the POMS SI 01320.500
B.4 allowance and split deemor pools are always tested. Add the
416.1165(h) examples with parent ids, a teen mother without ids, and make
two scope cases differ from the tax-unit rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 7 commits October 12, 2026 15:05
Excluding a person from their own tax-unit proxy set split a disabled
teen mother from her disabled brother, whose proxy set presumes her a
parent, so their parents' income was not divided between them. The old
resource code kept the person in their own set, which keeps such
siblings in one pool; income deeming drops the person anyway because a
deeming child meets the SSI status conditions. Add cases for the teen
mother and her brother and for a teen mother who deems in her parents'
tax unit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n gate from Medicaid deeming

Review round 1 (GPT-6.1 Sol). POMS SI 00501.010 B.2.d keeps the
ineligible-child allocation for the children of a stepparent who has
permanently left, so the spouse of a co-resident parent who lives
elsewhere (a two-person marital unit across households) now counts in
the sibling scope, by person_id for children with ids and by tax unit
for the proxy. The Medicaid copy no longer requires the SSI citizenship
or qualified-noncitizen condition of the child, as Medicaid applies its
own immigration rules, and a disabled child who shares the deemed income
takes no allocation there. The generator adds an absent stepparent and a
no-ids household with three deemors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riants

Seeded mutants that ignored an absent stepparent's children or allocated
for Medicaid deeming children survived the random batches; fixed
households now reach both, once in each state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…parent ids correctly

Review round 2 (GPT-6.1 Sol). A person is never their own ineligible
parent, which the Medicaid copy relied on SSI eligibility to ensure. A
second parent id that repeats the first is no second parent, so it is
not matched against an absent stepparent. The proxy may presume a child
is an absent stepparent's when that stepparent is an unlinked parent.
Add the three reproductions and update the docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ld married to a spouse elsewhere as married

Review round 3 (GPT-6.1 Sol). An unlinked absent stepparent now lends the
tax-unit proxy only his own tax unit, so a cousin claimed by the mother
is not allocated. A child in a two-person marital unit whose spouse lives
in another household is married (416.1856(b), 416.1806) and so is no
deeming child. Add both reproductions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le parents

Review round 4 (GPT-6.1 Sol). The division pool was keyed on all of a
child's parents, so half-siblings with the same ineligible mother were
each deemed her whole remainder when one also lived with an SSI-eligible
father. Pools are now keyed on the ineligible parents, whose income is
divided (416.1165(e)(2)), and the children of one pool share one set of
ineligible-child allocations, those of the deeming household, so their
shares add up to the parents' net income. Add the reproduction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seeded mutants keying pools on all parents or allocating per child
survived the random batches; a YAML case (an SSI-eligible father's
daughter allocated once for both boys who share the mother's income) and
a fixed household per state now catch both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 13, 2026 00:54
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Hand-off to the US + core hub.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant