Repository navigation
Combine an SSI couple's income by each month's facility status - #10820
Conversation
ssi_marital_earned_income and ssi_marital_unearned_income were YEAR-defined and read the monthly ssi_couple_computation_applies for the year, which Core returns at December. ssi_countable_income and ky_ssp_countable_income split by the month's own status, so a part-year medical facility stay gave wrong SSI in the months whose status differs from December's (20 CFR 416.414(b)(3), 416.1802(b)(1), 416.420). Make both variables MONTH-defined through a shared helper, _ssi_couple_income. The annual Maryland PAA and Medicaid optional pathway formulas call the same helper for the year, so their results are unchanged; their Medicaid test inputs move from ssi_marital_* to the underlying SSI income inputs. Add cases for the months before and during a stay, including the POMS SI 02005.050 D.1 example. Fixes PolicyEngine#10818 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Requesting your review. This fixes #10818, which came up while clearing your reviews of #10633 and #10640.
All checks pass. It hasn't had a local review round, and no tests were run locally. |
PR Review: Combine an SSI couple's income by each month's facility statusReviewed at head SummaryThe fix is correct in law and in period handling. One item blocks approval under the mutation rule: the two annual readers were rewritten to keep pooling by the year's single status, and no test has a part-year stay for either, so reverting those hunks fails nothing. Open: 0 critical, 1 should, 5 suggestions. Law read independently before the code (eCFR as of 2026-10-30, POMS pages as published today):
So the month of entry is still a couple month, the first full calendar month is the first separate month, and each spouse's own income (with their own $20 exclusion, as D.1 shows: 400 - 20 and 200 - 20) is counted from then. The code matches this, given that the monthly facility input means "in the facility throughout the month". Critical (must fix)None. Should address1. The annual readers' part-year treatment is not pinned by any test. Fix: add one part-year case to
The same household in Maryland distinguishes the two for PAA. #10809 will then change the Maryland case on purpose when it makes PAA monthly. Suggestions1. Record the couple eligibility test deferral in the repository ("Not covered" 1). The model applies no such test, so the 2026 household's spouse A is paid 994 - 980 = 14 in each facility month although the couple's 2,480 exceeds the 1,491 couple rate. This predates the PR: It needs an intent-to-return input, so it is a reasonable deferral. It is recorded only in the PR body and rulespec-us#2191. Please open a policyengine-us issue and name it in the comment in 2. Say "first full calendar month" where the rule is stated.
3. Optional coverage for the other rows of the Results table. 4. Cost of the spouse test. 5. rulespec-us#2191 still describes the PR as a draft. Update it when the merged commit is recorded there. Verified correctPeriod handling:
Hand-checked expectations (all 16 new values):
Other checks:
Axiom line assessment
CI statusAll 37 checks pass at this head, including Baseline (ssa-usda), all four state shards, Household API Partners, Microsimulation and PR validation. Three workflow placeholders are skipped. No local run was needed; expectations were traced by hand. Branch status1 commit ahead of Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting one change, a test gap. The two annual readers (Maryland PAA and the Medicaid optional pathway) were rewritten to keep pooling by the year's single status, and no test has a part-year stay for either, so reverting those hunks to read ssi_marital_* passes every test while changing part-year results. One part-year case in each file closes it; the report above gives a worked example (Should Address 1).
The fix itself is right in law and in period handling: the month of entry is still a couple month, the first full calendar month is the first separate month, all 16 new expected values hold by hand, and the POMS SI 02005.050 D.1 example is reproduced. The five suggestions are optional. CI is green at 0ca225faa6.
…issue Add a part-year facility case to the Medicaid optional pathway and to Maryland PAA countable income: each applies December's status to the whole year, so reverting either to the monthly marital variables fails. Note in ssi_couple_computation_applies that the couple eligibility test during a temporary absence is not modeled (POMS SI 02005.050 B.3, issue 10851). Say "throughout" where 416.414(a)(1) defines a facility month, and cite it beside 416.414(b)(3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for another look at |
PR Review (round 2): Combine an SSI couple's income by each month's facility statusReviewed at head SummaryThe fix commit does what the reply says and nothing else. Each annual reader now has a part-year case, both expected values check by hand, and each case fails if its reader goes back to the monthly Open: 0 critical, 0 should, 4 suggestions (2 new, 2 carried over and optional). How each claim below was checked: expected values and the revert results by hand tracing of the head's formulas; wording, references, issues and the ratchet by reading; that the cases pass at this head by CI. No test was run locally for this round. Prior findings
New findingsCritical (must fix)None. Should addressNone. Suggestions1. Give one spouse earned income in the two part-year cases. One added input closes it in both files:
2. Two test names still date the change from entry. 3. Carried over, optional: a case whose stay ends before December, and a June assertion in 4. Carried over, optional: the spouse test runs on every monthly call of the two variables. VerifiedScope of the fix commit (reading the diff between the two heads, 102 added and 7 removed lines in 9 files):
Hand trace of the two new cases (the only new expectations):
Wording against the regulations (reading):
Other:
Axiom
CIAll 37 checks pass at Branch2 commits ahead of
Whichever of #10532 and #10809 merges after this will need a rebase. These are notes, not findings. Verdict: APPROVE |
DTrim99
left a comment
There was a problem hiding this comment.
Approving. Each annual reader now has a part-year case; both expected values (11,760 and 5,760) hold by hand, and each case gives 14,760 and 11,760 if its reader goes back to the monthly variable. The couple eligibility test is tracked in #10851 and named in the code, and the facility-month wording follows 20 CFR 416.414(a)(1). No formula changed in the fix commit.
Four optional suggestions are in the report above; the most useful is giving one spouse earned income in the two new cases, which would pin the earned line of each reader too. CI is green at 27687ea37f. #10532 and #10809 will need a rebase after this merges.
md_paa_countable_income became monthly on this branch, and #10820 made _ssi_couple_income combine a couple's income by each month's status. The formula still halved that income by December's status, so in a year with a part-year facility stay each spouse counted the couple's whole income in the months before it. both_eligible now reads the same month. Case 4 now expects 973.75 each in June, 1,447.50 and 480 in July, and 14,527.50 and 8,722.50 for 2025. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Combines an SSI couple's income by each month's facility status, so a part-year medical facility stay no longer changes SSI in the other months of the year.
Fixes #10818
Changes since review (2026-11-12)
medicaid_optional_senior_or_disabled_countable_income.yamlandmd_paa_countable_income.yaml(Case 4) each add a 2025 couple aged 72 and 70, with 12,000 and 6,000 of unearned income, in which the second spouse is in a Medicaid facility from July. Both annual formulas apply December's status to the whole year, so each spouse counts their own income in all twelve months: (1,000 - 20) x 12 = 11,760 and (500 - 20) x 12 = 5,760. Summing the monthlyssi_marital_unearned_incomeinstead would combine 1,500 a month through June and give 14,760 and 11,760, so reverting either formula to the monthly variables now fails its test.ssi_couple_computation_applies.py, after the comment that the model does not cover intent to return, says the model also omits SSI's couple eligibility test during a temporary absence (POMS SI 02005.050 B.3) and names Apply SSI's couple eligibility test when one spouse is temporarily absent in a facility #10851.What was wrong
ssi_marital_earned_incomeandssi_marital_unearned_incomewere YEAR-defined and read the monthlyssi_couple_computation_appliesfor the year, which Core returns at its last month.ssi_countable_incomeandky_ssp_countable_incomeare monthly and halve the pooled income by the month's own status. In a year with a part-year stay, the months whose status differs from December's got half of each spouse's own income, or each spouse got the couple's whole income.The pool and the split began to disagree when #10332 made
ssi_countable_incomemonthly. The two variables have read the status for the year since #8004, and the status has been monthly since #8375.Law
Regulation text is from the eCFR as of 2026-10-30.
Changes
ssi_marital_earned_incomeandssi_marital_unearned_incomeare MONTH-defined. Each calls a new helper,_ssi_couple_incomein_ssi_spouses.py, which reads the couple status and the income for the same period.md_paa_countable_incomeandmedicaid_optional_senior_or_disabled_countable_incomeare YEAR-defined and apply one couple status to the whole year. They now call the same helper for the year, so they pool annual income by that status, as before. Their results are unchanged in every one-household run below, and a part-year case in each test file now pins that: a stay from July gives each spouse their own income for the whole year, as onmain. A NOTE in each says they still treat a part-year stay as lasting all year or not at all.ssi_countable_incomeandky_ssp_countable_incomeare unchanged and now receive each month's pooled income.medicaid_optional_senior_or_disabled_countable_income.yamlsetssi_marital_*as inputs, which the annual formula no longer reads. They now setssi_unearned_incomeorssi_earned_income, with the same amounts and expected values.Results
One-household simulations on
main(23a7c9a) and on this branch. The 2026 household: spouse A, 68, with 1,000 a month of unearned income; spouse B, 62, disabled, with 1,500 a month, in a Medicaid facility from July.mainuncapped_ssiuncapped_ssississiky_ssp_countable_incomePOMS uses the 512 individual rate first set for 2000; SSA's rate table and the model have 513. Households with no stay, or a stay all year, are unchanged. So are the annual Medicaid and Maryland amounts in every run.
Tests
ssi_marital_unearned_income.yamlandssi_marital_earned_income.yaml: one case each, for June and July around a stay that runs through December.ssi_countable_income.yaml: the POMS SI 02005.050 D.1 example, June and July 2000, for countable income and SSI.medicaid_optional_senior_or_disabled_countable_income.yamlandmd_paa_countable_income.yaml(Case 4): one part-year case each, for the 2025 couple with a stay from July, expecting 11,760 and 5,760 for the year and the couple status for June and July.27687ea37f: 77 cases. Other suites were not run locally; CI validates.ruff format --checkandruff checkpass on the whole repository.Not covered
both_eligibleshould readperiod, and Case 4 inmd_paa_countable_income.yamlwill change with it.Overlap
ssi_marital_earned_income.py,md_paa_countable_income.py,ky_ssp_countable_income.py,ssi_marital_earned_income.yamlandmd_paa_countable_income.yaml, and Read monthly SSI support in Maryland and California benefits #10809 editsmd_paa_countable_income.pyandmd_paa_countable_income.yaml. Expect conflicts with whichever merges second.msp_fpg.yamlCase 4 can let its stay run through December again (it ends it before December in 64c82ef), and Apply each state's rule for a Medicaid applicant whose spouse is not aged, blind or disabled #10640's Case 44 can take back itsssi_countable_incomeassertion.Files
axiom: TheAxiomFoundation/rulespec-us#2191 queued
🤖 Generated with Claude Code