Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0ccaa0f
Limit SSI spousal-deeming child allocations to the couple's co-reside…
MaxGhenis Oct 12, 2026
892fcca
Cite POMS for spouse-to-spouse child allocations and add the SI 01320…
MaxGhenis Oct 12, 2026
fe68e0e
Floor each month's ineligible-child allocation and run the student ex…
MaxGhenis Oct 12, 2026
9d14d23
Treat a child's net loss as no income in the ineligible-child allocation
MaxGhenis Oct 12, 2026
ff19c9d
Merge main into SSI child allocation scope
MaxGhenis Oct 19, 2026
30fc588
Respect legal marriage and historical student limits in SSI deeming
MaxGhenis Oct 19, 2026
411fc28
Scope parental child allocations and align SSI and Medicaid recipients
MaxGhenis Oct 19, 2026
e90834c
Retain monthly SSI allocations through deeming thresholds and benefit…
MaxGhenis Oct 19, 2026
9e7a6b7
Preserve monthly deeming in Medicaid and MSP income consumers
MaxGhenis Oct 19, 2026
16418a7
Date historical student boundary fixtures at their annual input period
MaxGhenis Oct 19, 2026
a41437d
Cover monthly floors across both spouse income pools
MaxGhenis Oct 19, 2026
e5e449e
Keep pretax premium regressions distinct from student exclusions
MaxGhenis Oct 19, 2026
8256e51
Derive both spouse and student wages in monthly floor regression
MaxGhenis Oct 19, 2026
a4021ef
Preserve recipient pension income in the California married-screen fi…
MaxGhenis Oct 19, 2026
58e3613
Read annual student age in the monthly SSI allocation
MaxGhenis Oct 19, 2026
204532d
Specify SSI disability status in the derived California deeming case
MaxGhenis Oct 19, 2026
4e42c60
Preserve Missouri's under-18 parental allocation scope
MaxGhenis Oct 19, 2026
cb5e429
Apply sourced state limits to Medicaid child allocation scope
MaxGhenis Oct 19, 2026
e9794af
Retain Medicaid allocation scope for states without overrides
MaxGhenis Oct 19, 2026
9968f38
Fix Wisconsin dependent 18-year-old Medicaid allocations
MaxGhenis Oct 19, 2026
47f4a1a
Preserve K-12 evidence for Wisconsin allocation children
MaxGhenis Oct 19, 2026
9d5777d
Preserve annual SSI inputs while calculating monthly budgets
MaxGhenis Oct 19, 2026
9dabd07
Keep monthly cap witnesses on explicit monthly budgets
MaxGhenis Oct 19, 2026
e5d2604
Merge main and retain monthly Colorado and Texas couple budgets
MaxGhenis Oct 19, 2026
8573f6a
Use approved 2027 COLA for North Carolina supplement rates
MaxGhenis Oct 19, 2026
9852fb9
Remove the North Carolina 2027 rate update from this PR
MaxGhenis Oct 19, 2026
66bbf51
Merge main into ssi-ineligible-child-allocation-scope
MaxGhenis Oct 19, 2026
ee5640d
Merge main into ssi-ineligible-child-allocation-scope
MaxGhenis Oct 20, 2026
2e8084f
Merge main into ssi-ineligible-child-allocation-scope
MaxGhenis Oct 21, 2026
990c350
Merge current main into SSI child allocation branch
MaxGhenis Oct 23, 2026
7d8c624
Keep new state SSI supplement consumers on monthly budgets
MaxGhenis Oct 23, 2026
ce0054c
Make Oklahoma monthly regression fixtures explicit
MaxGhenis Oct 23, 2026
6559b7c
Use monthly parental deeming in new New Hampshire SSP reader
MaxGhenis Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/ssi-ineligible-child-allocation-scope.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Limit SSI spousal-deeming child allocations to the couple's co-resident children. Scope parental allocations to co-resident children, align SSI and Medicaid recipient immigration rules, preserve state Medicaid allocation age ceilings and child definitions, recognize marriage across households and historical student age limits, and retain monthly allocations through deeming thresholds, exclusions and benefit caps. Use full-time secondary-school attendance, including explicit K-12 enrollment at age 18, rather than tax dependency for Wisconsin's dependent 18-year-old allocation condition, with enrollment proxying expected completion before 19. Preserve annual SSI and Medicaid income inputs while applying allocations, exclusions, floors, and caps monthly. Keep Colorado and Texas couple-budget consumers, New York SSP, Virginia AG, Oklahoma SSP, Colorado OAP, and New Hampshire SSP on those monthly interfaces.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
description: States limit parental Medicaid income allocations to ineligible children below these ages. These overrides constrain the shared SSI allocation definition; states absent from this parameter retain the existing shared allocation behavior.
# The dates mark the shared Medicaid income model's 2015 coverage baseline,
# not an assertion that the states changed their allocation rules in 2015.
# Sources were checked for the current rules in October 2026.
metadata:
unit: year
period: year
label: Medicaid parental allocation ineligible child age limit
breakdown:
- state_code
reference:
- title: California Code of Regulations, title 22, section 50030 - Child
href: https://www.cdss.ca.gov/shd/res/pdf/50101.pdf
- title: Florida ESS Manual 2240.0606.03 - Dependent in Deeming
href: https://ffic.myflfamilies.com/manual/2200.pdf#page=40
- title: Florida ESS Manual 2640.0212.02 - Determine if Parent has Income to Deem
href: https://ffic.myflfamilies.com/manual/2600.pdf#page=61
- title: Idaho IDAPA 16.03.05.451.03 - Ineligible Child
href: https://adminrules.idaho.gov/rules/current/16/160305.pdf#page=37
- title: Louisiana Medicaid Eligibility Manual I-1400 - Ineligible Child
href: https://ldh.la.gov/assets/medicaid/MedicaidEligibilityPolicy/I-1400.pdf#page=4
- title: Michigan BEM 540 - Allocation to Non-SSI-Related Children
href: https://mdhhs-pres-prod.michigan.gov/olmweb/ex/BP/Public/BEM/540.pdf#page=2
- title: Missouri DSS 0805.020.15 - Deeming Parental Income, step 1
href: https://dssmanuals.mo.gov/mo-healthnet-for-the-aged-blind-and-disabled/0805-000-00/0805-020-00/0805-020-15/
- title: Montana Combined Medicaid Manual 603-1 - Ineligible Child Allocation
href: https://prod-dphhs.mt.gov/assets/hcsd/mamanual/CMA603.1.pdf
- title: North Carolina MA-2260 IV.A - Financial Eligibility Requirements
href: https://policies.ncdhhs.gov/wp-content/uploads/MA-2260-Financial-Elig-Requirements-PLA.pdf#page=4
- title: New Jersey Medicaid Only Manual 10:71-5.5 - Deeming of Income
href: https://nj.gov/humanservices/notices/documents/rules-and-regulations/NJAC%2010_71%20%20MEDICAID%20ONLY.PDF#page=247
- title: New York Medicaid Reference Guide - Allocation
href: https://www.health.ny.gov/health_care/medicaid/reference/mrg/income.pdf
- title: Ohio Administrative Code 5160:1-3-03.3(B)(2) and (8) - Medicaid deeming of income
href: https://codes.ohio.gov/ohio-administrative-code/rule-5160:1-3-03.3
- title: Texas MEPD G-2312 - Parent-to-Child Deeming, step 2
href: https://fhb.hhs.texas.gov/handbooks/medicaid-elderly-people-disabilities-handbook/g-2300-special-income-noninstitutional-budgets
- title: Virginia Medicaid Manual M0530.002 B.1-B.2 - Nonblind Nondisabled Child
href: https://www.dmas.virginia.gov/media/mghpujpo/m05-1-1-26.pdf#page=57
- title: Wisconsin Medicaid Eligibility Handbook 15.1.2 - Special Financial Tests
href: https://www.emhandbooks.wisconsin.gov/meh-ebd/policy_files/15/15.1.htm

CA:
2015-01-01: 21
FL:
2015-01-01: 21
ID:
2015-01-01: 21
LA:
2015-01-01: 21
MI:
2015-01-01: 18
MO:
2015-01-01: 18
MT:
2015-01-01: 21
NC:
2015-01-01: 21
NJ:
2015-01-01: 18
NY:
2015-01-01: 18
OH:
2015-01-01: 18
TX:
2015-01-01: 21
VA:
2015-01-01: 21
WI:
2015-01-01: 19
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description: The Social Security Administration treats a student regularly attending school as an ineligible child for deeming below this age.

values:
1974-01-01: 21
2008-06-16: 22
metadata:
label: SSI ineligible child deeming student age limit
unit: year
period: year
reference:
- title: POMS SI 01310.115 A.3 - Ineligible child for deeming purposes
href: https://secure.ssa.gov/poms.nsf/lnx/0501310115
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: The Social Security Administration treats a student regularly attending school as a child under the Supplemental Security Income program below this age.

values:
1974-01-01: 22
metadata:
label: SSI child student age limit
unit: year
period: year
reference:
- title: 42 U.S.C. § 1382c(c) - Definition of child
href: https://www.law.cornell.edu/uscode/text/42/1382c#c
- title: 20 CFR § 416.1856(a)(2) - Who is considered a child
href: https://www.ecfr.gov/current/title-20/section-416.1856#p-416.1856(a)(2)
142 changes: 142 additions & 0 deletions policyengine_us/tests/core/test_ssi_annual_income_inputs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"""SSI monthly budgets must preserve existing annual input overrides.

Policy examples and monthly allocation caps are covered in YAML. These tests
exercise Core's period conversion, supplied-input detection and branch caches,
which require the Python API. One small Core system uses the production
variable classes and the imported country's read-only parameters; it never
constructs or copies another country model. This belongs to Rest/core.
"""

import numpy as np
import pytest
from policyengine_core.simulations import Simulation
from policyengine_core.taxbenefitsystems import TaxBenefitSystem

from policyengine_us.entities import MaritalUnit, Person
from policyengine_us.system import system as country_system
from policyengine_us.tools.period_branch import get_override_branch

YEAR = 2026
MONTH = "2026-01"
ANNUAL_CURRENCY_VARIABLES = (
"ssi_countable_income",
"ssi_unearned_income_deemed_from_ineligible_parent",
"ssi_earned_income_deemed_from_ineligible_spouse",
"ssi_unearned_income_deemed_from_ineligible_spouse",
"ssi_income_deemed_from_ineligible_spouse",
"ssi_ineligible_child_allocation",
"ssi_in_kind_support_and_maintenance",
"ssi_pmv_amount",
"medicaid_optional_senior_or_disabled_countable_income",
"medicaid_optional_senior_or_disabled_unearned_income_deemed_from_ineligible_parent",
"medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse",
)

ANNUAL_INPUT_VARIABLES = (*ANNUAL_CURRENCY_VARIABLES, "is_ssi_spousal_deeming_applies")


@pytest.fixture(scope="module")
def small_system():
result = TaxBenefitSystem(entities=[Person, MaritalUnit])
names = (
"is_ssi_eligible_individual",
"is_ssi_ineligible_spouse",
"ssi_earned_income",
"ssi_unearned_income",
"ssi_spousal_deeming_child_allocations",
*ANNUAL_INPUT_VARIABLES,
*(f"{name}_monthly" for name in ANNUAL_INPUT_VARIABLES),
)
result.add_variables(*(type(country_system.variables[name]) for name in names))
result.parameters = country_system.parameters
return result


@pytest.mark.parametrize("input_period", [YEAR, MONTH])
@pytest.mark.parametrize("name", ANNUAL_INPUT_VARIABLES)
def test_annual_input_overrides_reach_monthly_budgets(small_system, name, input_period):
amount = 1_200 if name in ANNUAL_CURRENCY_VARIABLES else True
monthly = 100 if name in ANNUAL_CURRENCY_VARIABLES else True
changed = 2_400 if name in ANNUAL_CURRENCY_VARIABLES else False
changed_monthly = 200 if name in ANNUAL_CURRENCY_VARIABLES else False
simulation = Simulation(
tax_benefit_system=small_system,
situation={
"people": {
"claimant": {
name: {input_period: amount},
# Supplied inputs bypass the formula's eligibility gate.
"is_ssi_eligible_individual": {YEAR: False},
}
},
"marital_units": {"unit": {"members": ["claimant"]}},
},
)
assert small_system.variables[name].definition_period == "year"
np.testing.assert_array_equal(simulation.calculate(name, YEAR), [amount])
np.testing.assert_array_equal(simulation.calculate(name, MONTH), [monthly])
np.testing.assert_array_equal(
simulation.calculate(f"{name}_monthly", MONTH), [monthly]
)

branch = get_override_branch(
simulation, "annual_override", YEAR, {name: np.array([changed])}
)
np.testing.assert_array_equal(
branch.calculate(f"{name}_monthly", MONTH), [changed_monthly]
)
np.testing.assert_array_equal(
simulation.calculate(f"{name}_monthly", MONTH), [monthly]
)


def test_computed_annual_cache_does_not_replace_monthly_budgets(small_system):
name = "ssi_earned_income_deemed_from_ineligible_spouse"
allocations = {
f"2026-{month:02d}": 0 if month <= 6 else 200 for month in range(1, 13)
}
simulation = Simulation(
tax_benefit_system=small_system,
situation={
"people": {
"claimant": {
"is_ssi_ineligible_spouse": {YEAR: False},
"ssi_earned_income": {YEAR: 0},
"ssi_unearned_income": {YEAR: 0},
"ssi_spousal_deeming_child_allocations": allocations,
},
"spouse": {
"is_ssi_ineligible_spouse": {YEAR: True},
"ssi_earned_income": {YEAR: 12_000},
"ssi_unearned_income": {YEAR: 0},
"ssi_spousal_deeming_child_allocations": {
month: 0 for month in allocations
},
},
},
"marital_units": {"couple": {"members": ["claimant", "spouse"]}},
},
)
# Six months of $1,000 and six of $800 are not $900 in every month.
np.testing.assert_array_equal(simulation.calculate(name, YEAR), [10_800, 0])
np.testing.assert_array_equal(
simulation.calculate(f"{name}_monthly", MONTH), [1_000, 0]
)
np.testing.assert_array_equal(
simulation.calculate(f"{name}_monthly", "2026-07"), [800, 0]
)

if hasattr(simulation, "_get_store_history"):
# Core 3.33+ invalidates inherited calculations on direct set_input.
branch = simulation.get_branch("first_annual_override")
branch.set_input(name, YEAR, [24_000, 0])
else:
branch = get_override_branch(
simulation, "first_annual_override", YEAR, {name: np.array([24_000, 0])}
)
np.testing.assert_array_equal(
branch.calculate(f"{name}_monthly", MONTH), [2_000, 0]
)
np.testing.assert_array_equal(
simulation.calculate(f"{name}_monthly", MONTH), [1_000, 0]
)
Loading
Loading