Skip to content

Add Ohio state supplementation for 2026 - #10164

Merged
hua7450 merged 14 commits into
mainfrom
oh-ssp-2026
Oct 22, 2026
Merged

hua7450 merged 14 commits into
mainfrom
oh-ssp-2026

Conversation

@hua7450

@hua7450 hua7450 commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

Ohio's Residential State Supplement (RSS) was missing from PolicyEngine-US. Add oh_rss for 2026 under ORC 5119.41, OAC 5160:1-5-01 and OAC Chapter 5122-36. RSS is a monthly cash payment to Medicaid-eligible aged, blind or disabled adults who need a protective level of care and live in an approved residential care setting (5160:1-5-01(A), (C)).

  • Who administers it: Ohio. The Department of Behavioral Health runs the program and decides the non-financial criteria; the rules still call it OhioMHAS (ORC 5119.41(A); 5122-36-01(A); 5160:1-5-01(I)(1)). The county department of job and family services or the Department of Medicaid decides income and resources (ORC 5119.41(D)). The program is paid from the General Assembly's appropriation (ORC 5119.41(C); 5122-36-03(F)(2)). SSA doesn't pay RSS, so the shared helper for SSA-administered supplements (SSA rounding and its $1 minimum) isn't used. The folder is oh/dbh because ORC 5119.41, as amended by HB 96 (effective September 30, 2025), names the Department of Behavioral Health.

  • 2026 levels, unchanged since July 1, 2023 (5122-36-05(B)-(C); 5160:1-5-01(B)(2); MEPL 175):

    Component Monthly amount
    Allowable fee (what the recipient pays the living arrangement) $1,600
    Personal needs allowance $200
    Income standard (fee plus allowance) $1,800

    The model derives the $1,800 from the two parameters rather than storing it separately.

  • Payment: the $1,800 income standard less countable income (5160:1-5-01(G)(1)). Countable income equal to or above the standard makes the person ineligible ((E)(4)(b)). There is no federal $1 minimum.

  • Countable income: income is treated as for aged, blind or disabled Medicaid, except that SSI counts as income and there is no deeming (5160:1-5-01(E)(4)(a), (c)).

    • The exclusions follow 5160:1-3-03.2. Interest and dividends are excluded ((D)(2)(v)). The $20 general exclusion doesn't apply to SSI ((D)(2)(l)). The student earned income exclusion applies ((E)(3)).
    • Ohio's $20 general, $65 earned and one-half exclusions and its $2,000 / $3,000 resource limits equal SSI's (5160:1-3-03.2(D)(2)(l), (E)(5), (E)(7); 5160:1-3-05.1(B)(9)). The model reads the SSI parameters for them, with comments citing Ohio's adoption.
  • First month: a placement that starts after the first day is prorated. The daily amount and the prorated total are each rounded up to the next cent (5160:1-5-01(G)(5)-(6)).

  • Couples (5160:1-5-01(E)(2)-(3)):

    • Both spouses have a level of care and live in the same RSS home: their countable income is pooled, with one $20 and one $65 exclusion (5160:1-3-03.2(H)). Each spouse gets $1,800 less half the pooled income, and their combined resources are tested against $3,000.
    • Only one spouse has a level of care: that spouse is budgeted alone on their own income, with no deeming, and their own resources are tested against $2,000.
    • Spouses living apart: enter them as separate marital units from the month after they stop living together (documented on oh_rss_certified; 5160:1-3-05.20(E)(4)).
  • COLA: none. The rules fix the dollar amounts, so a rise in SSI lowers RSS by the same amount. A 2027 case shows $771 = $1,800 − $1,029.

  • Who qualifies, each month. oh_rss_eligible holds the first three rows, and oh_rss applies the income and resource tests:

    Requirement Source How modeled
    Eligible for Ohio Medicaid 5160:1-5-01(C)(1)(a); 42 CFR 435.232 and Ohio SPA 15-015, Attachment 2.2-A pp. 15-16 medicaid_enrolled_for_ssi_state_supplement (computed Medicaid eligibility and take-up; a yearly value), or Ohio's group for people who receive only a state supplement and "would be eligible for SSI except for the level of their income": is_ssi_eligible with uncapped_ssi at or below 0
    Aged, blind or disabled, and at least 18 5160:1-5-01(A); 5122-36-02(A)(1) is_ssi_aged_blind_disabled and minimum_age (18 from July 15, 2017)
    Protective level of care, an approved RSS living arrangement and the other non-financial criteria (no more than 120 days of skilled nursing a year; no waiver, PACE or hospice; not related to the operator) 5160:1-5-01(C)(1)(d)-(f); 5122-36-02(A)(2)-(11) Input oh_rss_certified, which also covers a state-approved temporary institutional stay under 5160:1-5-01(H)
    Countable income below $1,800 5160:1-5-01(E)(4)(b), (E)(6) oh_rss_countable_income; a payment of $0 at or above the standard
    Countable resources within $2,000, or $3,000 for an eligible couple 5160:1-5-01(F); 5160:1-3-05.1(B)(9) ssi_countable_resources
    Receives SSI or Social Security Not a condition ORC 5119.41(A) describes RSS as supplementing SSI or Social Security, but under 5119.41(B) the rules set eligibility, and neither 5160:1-5-01(C) nor 5122-36-02(A) requires receiving either. Ohio's general Medicaid conditions (5160:1-2-10(B)) don't require applying for SSI. A code NOTE records this, so the model doesn't require SSI take-up.
    Lives in Ohio State program defined_for = StateCode.OH
  • Source conflicts (each has a code NOTE and is listed in the Axiom conflicts comment):

    • The couple income standard. (E)(2) cites "the appropriate couple income standard as defined in rule 5160:1-3-03.5", and that rule defines it as the SSI couple rate ($1,491). Read literally, a couple whose only income is SSI would be ineligible. The model follows (B)(2): it compares pooled income with twice the $1,800 standard (NOTE in oh_rss_countable_income; integration Cases 1 and 8).
    • One eligible spouse's resources. (E)(3) budgets that spouse as an individual, while 5160:1-3-05.1(B)(9)(b) and 5160:1-3-05.20(E)(1)-(2) combine a couple's resources against $3,000. The model follows the RSS rule (NOTE in oh_rss; integration Case 13). The reading decides the result only when Medicaid is entered: computed Medicaid and the SSI resource test both combine the couple's resources (integration Case 14).
    • One eligible spouse's income standard. (E)(3) points to "the appropriate individual income standard as defined in rule 5160:1-3-03.5", the SSI individual rate ($994). The model compares that spouse's own countable income with the $1,800 RSS standard (NOTE in oh_rss_countable_income; integration Case 15).
    • ORC 5119.41(A)'s description of recipients, as above (NOTE in oh_rss; integration Cases 3 and 13).
  • Inputs:

    • oh_rss_certified (monthly, default false) records Ohio's approval of the placement and level of care.
    • oh_rss_partial_month_days (monthly, default 0) records the days from the move-in day through the end of a first month. At 0 the month is paid in full. The variable has a formula returning 0, so an entry for one month doesn't carry into later months (integration Case 11).
    • Entering either for one person leaves other household members unchanged (integration Case 10).
    • Medicaid enrollment is computed. A candidate in the state-supplement-only group meets the Medicaid condition even when medicaid_enrolled is entered as false. If you enter medicaid_enrolled, enter it for every person: an entry for one person sets everyone else to false. This is documented on oh_rss_eligible.

RSS is added to household_state_benefits (all four year blocks), spm_unit_benefits and SNAP unearned income. It isn't counted as HUD income. RSS is paid to the person (5122-36-04(A)(7)), but recipients live in licensed residential care (5122-36-02(A)(5)), and counting it would make its Medicaid condition circular through rent-related tax deductions (NOTE on oh_rss). No other Ohio program is wired. Ohio CCAP is the only other Ohio program on main that reads SSI, and it excludes SSI (5180:2-16-03(I)(1)).

Files:

policyengine_us/parameters/gov/states/oh/dbh/rss/              allowable_fee.yaml, personal_needs_allowance.yaml, minimum_age.yaml
policyengine_us/variables/gov/states/oh/dbh/rss/               oh_rss.py, oh_rss_eligible.py, oh_rss_countable_income.py, oh_rss_certified.py, oh_rss_partial_month_days.py
policyengine_us/tests/policy/baseline/gov/states/oh/dbh/rss/   oh_rss.yaml, integration.yaml

Shared files:

  • household_state_benefits.yaml gains one Ohio entry per year block.
  • SNAP income/sources/unearned.yaml, spm_unit_benefits.py and programs.yaml each gain one Ohio entry.
  • medicaid_enrolled_for_ssi_state_supplement.py keeps main's code; only its docstring changes, from naming Indiana and Kansas to "state supplements that require Medicaid enrollment". The text is the same as in Add Utah state supplementation for 2026 #10170.
  • The shared state supplement helper and minimum_payment.yaml are unchanged.

References

Additional section and page citations are included alongside the parameters and formulas.

Coverage limits

The registry marks Ohio as partial, verified for 2026. The $1,600, $200 and $1,800 were checked against 5122-36-05 and MEPL 175 in October 2026.

Not modeled:

  • Enrollment depends on available funds: Ohio offers enrollment only when "RSS program funds are sufficient to provide cash assistance to all enrollees" (5122-36-03(F)(2)). The model pays every eligible person.
  • Repayment after a mid-month move out (5160:1-5-01(G)(3); 5122-36-04(A)(11)), and the rule against a second payment after a move between homes ((G)(4)).
  • Exclusions absent from the federal SSI model: plans to achieve self-support (5160:1-3-03.2(D)(2)(m), (E)(9)), impairment-related and blind work expenses ((E)(6), (E)(8)), and infrequent or irregular earnings ((E)(2)).
  • A personal needs allowance above $200. 5122-36-05(C) says "at least" $200; the model uses the $200 that MEPL 175 prints.
  • The non-financial determinations themselves, including the November 15, 1990 living-arrangement grandfathering (5160:1-5-01(C)(2); 5122-36-02(B)(2)). Users enter the outcome through oh_rss_certified.

Microsimulation and model limits:

The amounts start July 1, 2023. Earlier years use parameter backfilling and are unverified historical estimates (MEPL 175 lists a $1,100 fee before then); no historical coverage is claimed.

Related: #10226 tracks the reform copies of spm_unit_benefits (such as the Texas rebate's), which this PR leaves unchanged.

Test plan

  • 37 Ohio RSS YAML cases (22 in oh_rss.yaml, 15 in integration.yaml) pass locally on this branch merged with main at 1f678c7. They cover:
    • SSI-only, Social Security-only and earnings budgets; countable income at and $1 below the standard (set directly); interest and dividend exclusions; and the student earned income exclusion;
    • care certification, Medicaid (entered and computed, including the state-supplement-only group for a candidate without SSI), the minimum age, aged, blind or disabled status, resources at and above the limit, and another state;
    • first-month proration in 31- and 30-day months, a whole-cent daily amount (including one from float32 monthly income), zero days as a full month, and a one-month entry that doesn't carry into the next month;
    • couples: both approved, one approved, an ineligible spouse's wages not deemed, combined resources at and above $3,000, pooled income with one exclusion, one spouse's partial month, spouses in separate homes, one approved spouse tested on own resources (with Medicaid entered and computed), and one approved spouse compared with the RSS standard;
    • the annual total with household_state_benefits, spm_unit_benefits, SNAP and HUD income, and the 2027 SSI rate.
  • The aggregate list integrity and program registry tests pass locally (728 passed, 10 skipped).
  • ruff format and ruff check on the Ohio RSS files, and git diff --check.
  • Changelog fragment in changelog.d/.
  • CI passes.

axiom: ORC 5119.41; OAC 5160:1-5-01, 5122-36-02(A), 5122-36-05(B)-(C), 5160:1-3-03.2, 5160:1-3-05.1(B)(9); MEPL 175 TheAxiomFoundation/rulespec-us#1836 queued

hua7450 and others added 3 commits October 12, 2026 14:24
- Registry placement and comments, SNAP reference title, shorter programs.yaml note
- Rule-level OAC references; document the one-spouse resource-standard reading
- Guard the daily-rate ceiling against float error on exact-cent amounts
- State-neutral wording in the shared Medicaid helper documentation (same as UT)
- Add interest/dividend, couple pooling and exact-cent partial-month cases; realistic Case 3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hua7450
hua7450 marked this pull request as ready for review October 13, 2026 08:14
@hua7450
hua7450 marked this pull request as draft October 13, 2026 19:04
hua7450 and others added 2 commits October 13, 2026 15:05
Counting oh_rss as HUD income made Medicaid enrollment, rent-related tax
deductions and HUD income circular, so the shared SSP Medicaid helper had
to run a full-population branch in every year and the microsimulation job
ran out of time and memory. RSS recipients live in licensed residential
care, so RSS stays out of HUD income, and the helper and its core test
return to main's version (only the docstring wording differs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hua7450 and others added 3 commits October 20, 2026 00:29
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the days-of-placement formula input with a zero-default partial-month input, cite ORC 5119.41 and document that the rules pay non-recipients, add NOTEs for the couple standard, resources, federal SSI gaps and the Medicaid gate, update parameter metadata and the registry entry, and pin the readings with new cases.

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

DTrim99 commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Add Ohio state supplementation for 2026

PR #10164 (author: hua7450, head 0ca3daf9af, merge-base f19877374a). 16 files (+950/−1), 8 commits.

Summary

The PR adds Ohio's Residential State Supplement (RSS):

  • Eligibility. oh_rss_eligible (Person, MONTH, defined_for = StateCode.OH) requires four things:
    • the input oh_rss_certified (level of care, an approved living arrangement and the other 5122-36-02 criteria);
    • age 18 or over;
    • aged, blind or disabled status;
    • Medicaid, through the shared medicaid_enrolled_for_ssi_state_supplement.
  • Countable income. oh_rss_countable_income applies SSI's $20 / $65 / one-half exclusions to non-SSI income, excludes interest and dividends and the student earned income exclusion, then adds SSI in full. An (E)(2) couple's income is pooled and halved.
  • Payment. oh_rss pays the $1,600 fee plus the $200 allowance, less countable income. It applies the $2,000 / $3,000 resource test and prorates a first month that starts after day 1, with (G)(6)'s round-up to the cent.
  • Aggregates.
    • oh_rss goes into household_state_benefits (all four year blocks), spm_unit_benefits and SNAP unearned income.
    • It is left out of HUD income, with a documented reason.
    • There is a programs.yaml entry (partial, verified_years: "2026") and 33 YAML cases.

The 2026 policy content is right:

  • Amounts and rules. Every amount, rule and date matches the sources: 5122-36-05 (effective July 1, 2023), MEPL 175, 5160:1-5-01 (August 1, 2025), 5122-36-02 (September 3, 2022), 5160:1-3-03.2 (April 15, 2026), 5160:1-3-05.1 and ORC 5119.41 (September 30, 2025).
  • Administration. Ohio pays RSS from state funds and administers it itself; POMS SI 01415.058 doesn't list Ohio. So skipping the shared SSA helper is right.
  • Source conflicts. The author found three, documented them in code and in rulespec-us#1836, and pinned each with a test. I agree with two outright. The third is genuinely ambiguous (Suggestion 3).
  • Axiom. The line is valid: Update Maryland tax rules for 2022 #1836 is open, labelled pe-parity, dispatch-ready and consistent with the head.
  • Batch checks.
    • The New Hampshire bug pattern doesn't occur.
    • A probe shows the Medicaid dependency gives the same results in either calculation order.
    • The Utah over-count doesn't recur. Microsimulation gives $0, an under-count that is documented.
    • I checked 24 expectations by hand.
  • CI and branch. All 27 checks pass on the head, and the branch merges cleanly with main.

No critical items remain. One should-fix item remains:

  • The Medicaid condition misses the Medicaid group Ohio uses for RSS recipients who get no SSI. So RSS computes to $0 for every such candidate unless medicaid_enrolled is entered.

Four suggestions:

  • Encode the $1,100 fee in force before July 2023.
  • The first-month proration can round the daily amount up one cent too many.
  • Two couple readings.
  • Polish.

Critical (must fix)

None.

Should address

1. The Medicaid condition misses Ohio's group for people who receive only the state supplement, so RSS is $0 for candidates with no SSI unless Medicaid is entered.

  • Where.

    • oh_rss_eligible.py:26 requires medicaid_enrolled_for_ssi_state_supplement.
    • The NOTE at lines 15-18 says PolicyEngine's Ohio aged, blind or disabled Medicaid limit is the SSI rate and "has no group for people who receive only an optional state supplement. A person whose income is above that rate therefore needs medicaid_enrolled entered."
    • The user-facing documentation only says to enter medicaid_enrolled for every person if you enter it at all.
  • The law.

    • 5160:1-5-01(C)(1)(a) requires that the individual "Be determined eligible for medical assistance in accordance with Chapter 5160:1-3".
    • 5160:1-3-03.5(B)(3) sets the general aged, blind or disabled limit at "the current supplemental security income (SSI) benefit rate for an individual".
    • But Ohio's state plan also covers RSS recipients through a separate group. Ohio SPA 15-015 (the 1634 conversion, "Effective Date: 08/01/2016"), Attachment 2.2-A:
      • Page 15 (PDF page 17), item 10, checked, under 42 CFR 435.232: "The following groups of individuals who receive only a State supplementary payment (but no SSI payment) under an approved optional State supplementary payment program that meets the following conditions. The supplement is— a. Based on need and paid in cash on a regular basis. b. Equal to the difference between the individuals' countable income and the income standard used to determine eligibility for the supplement. ... d. Paid to one or more of the classifications of individuals listed below, who would be eligible for SSI except for the level of their income."
      • Page 16 (PDF page 18): "X (4) Aged individuals in domiciliary facilities or other group living arrangements as defined under SSI." Items (5) blind and (6) disabled are also marked X.
    • RSS fits each condition. Its payment is "the difference between the individual's income ... and the income standard" ((G)(1)). It is paid in cash to the person (5122-36-04(A)(7)), and recipients live in licensed group residential settings (5122-36-02(A)(5)).
    • So an RSS candidate who gets no SSI but meets SSI's other criteria has Medicaid through this group.
  • Probe at the head (policyengine-core 3.32.29; January 2026; age 65, certified; medicaid_enrolled not entered):

    Income SSI Computed medicaid_enrolled oh_rss oh_rss with Medicaid entered
    Social Security disability $1,635.90 (the input of oh_rss.yaml Case 2) 0 false 0 184.10 (Case 2's expectation)
    Social Security $1,100 0 false 0 720

    SSI recipients are unaffected: Case 19 computes Medicaid through SSI and pays 806.

  • Reach.

    • Every certified candidate whose countable income lies between the SSI rate ($994) and the $1,800 standard gets no SSI. For unearned income alone, that is Social Security of about $1,014 to $1,820 a month.
    • The SSA average disabled-worker benefit the PR itself uses ($1,635.90) sits inside that band.
    • For these households the default household calculation pays $0 where Ohio pays $1,800 less income.
  • Why should, not critical.

    • The PR documents the gap in the code NOTE, the PR body and Update Maryland tax rules for 2022 #1836, and gives a workaround.
    • The missing group belongs to the shared Medicaid model.
    • But the default result is wrong in the claimed year for the program's main non-SSI population, and a local fix is available.
  • Remedies (either):

    • (a) Model the 435.232 path in oh_rss_eligible. Treat (C)(1)(a) as met for a certified candidate who meets SSI's non-income criteria and gets no SSI, alongside the existing Medicaid variable.
      • is_ssi_eligible (MONTH) already tests aged, blind or disabled status, the resource test and immigration status "without income test". That matches "would be eligible for SSI except for the level of their income".
      • Cite SPA 15-015 in the NOTE and reference.
      • Add a case with Case 2's inputs and computed Medicaid (184.10).
      • Case 8 (Medicaid entered false) would then need to fail this path too, or the documentation should say that entering medicaid_enrolled: false no longer zeroes RSS for this group.
    • (b) At minimum, surface the limit where users see it. Put it in the oh_rss_eligible documentation and the programs.yaml notes. Correct the NOTE so it says Ohio does cover these people (SPA 15-015) and PolicyEngine doesn't model the group, then update Update Maryland tax rules for 2022 #1836's "Medicaid" gap to match.

Suggestions

1. Encode the $1,100 fee in force before July 2023 (deferral documented in the PR body).

  • The leak. allowable_fee.yaml:3 has only 2023-07-01: 1_600, so backdating gives $1,600 to every earlier period.
    • RSS is $500 a month too high from at least 2016 to June 2023.
    • The 2023 household_state_benefits block includes oh_rss, so January–June 2023 totals carry that.
    • The $200 allowance is right throughout.
  • The law.
    • 5122-36-05 effective January 1, 2016:
      • (C): "The allowable fee is the amount a resident pays to a living arrangement, and is one thousand one hundred dollars per month."
      • (D): "The personal needs allowance is two hundred dollars per month."
    • 5122-36-05 effective September 3, 2022 (B): "... and is one thousand one hundred dollars per month."
    • MEPL 175 prints "$1,300 / $1,100 / $200" under "Current Value, Ends June 30, 2023".
  • Why it's a suggestion.
  • Fix.
    • Add 2016-01-01: 1_100 with the two authenticated rule PDFs as references.
    • One caution if earlier years are encoded. The 2016 version's (A) computed the payment differently: "This payment calculation includes the twenty dollars that is disregarded for eligibility purposes in paragraph (E)(6) of rule 5160:1-5-01". Check when today's (G)(1) wording took effect before claiming those years.

2. A prorated first month can round the daily amount up one cent too many.

  • Where. oh_rss.py:55-58 divides the float32 payment by the days and applies ceil(x * 100 - 1e-8).

  • Probe at the head (Medicaid entered; moves in January 16, so 16 days):

    Pension a year Countable income Full-month oh_rss (Feb) January, model January, law
    17,249.52 1,417.46 382.54 197.60 382.54 / 31 = 12.34 exactly; × 16 = 197.44
    17,621.52 1,448.46 351.54 181.60 11.34 × 16 = 181.44
  • Why. Countable income is stored as float32 (1,417.4599609), so the payment is 382.5400391. On the cents scale, 382.5400391 / 31 × 100 = 1,234.000126, which is above the 1e-8 epsilon, so the ceiling gives 12.35.

    • In a numpy check with float32 storage, about half the exact-cent daily amounts in a 31-day month round up this way.
    • The error is at most $0.01 × days, so $0.31 a month.
    • Case 9 covers only 241.50, which float32 represents exactly.
  • Fix.

    • Widen the epsilon to about 1e-3 of a cent: np.ceil(payment / period.days * 100 - 1e-3) / 100. That is safe, because a true daily amount's fraction of a cent is a multiple of 1/(2 × days), at least 0.016 of a cent.
    • Add the first row above as a case.

3. Two couple readings.

  • (a) Case 13's result depends on Medicaid being entered. Integration Case 13 (lines 359-393) pins $1,800 for the approved spouse under the (E)(3) own-resources reading (NOTE at oh_rss.py:36-40; conflict 3 on Update Maryland tax rules for 2022 #1836).
    • Probe at the head. The same couple without medicaid_enrolled computes medicaid_enrolled [false, false] and oh_rss [0, 0]. PolicyEngine's Medicaid test applies SSI's combined $3,000 couple resource test.
    • The rule. That matches 5160:1-3-05.20(E)(1): "When an eligible spouse and an ineligible spouse live together, all resources are combined". It also matches (C)(1)(a)'s requirement of Medicaid eligibility under Chapter 5160:1-3.
    • So the reading only bites with entered Medicaid. It decides the result only when Medicaid is entered, and Ohio's general rules would deny Medicaid to that couple, unless (E)(3)'s sentence that the other spouse's Medicaid is "determined as an individual" carries over to the RSS spouse.
    • My view. I agree the (E)(3)/(F) question is genuinely ambiguous, and the PR's reading is defensible.
    • Fix. Add one sentence to the NOTE and to conflict 3 saying this. Pin the computed-Medicaid variant (0) beside Case 13. With Should 1's remedy (a), meets_ssi_resource_test also applies the combined test, so the result stays 0.
  • (b) The (E)(3) individual income standard isn't pinned.
    • The cross-reference. (E)(3) points the one-approved-spouse case to "the appropriate individual income standard as defined in rule 5160:1-3-03.5", which is $994.
    • No case reaches it. The conflicts comment rightly says it changes no current case: the approved spouse's own countable income is 745.50 in Case 2 and 0 in Cases 3 and 13.
    • The NOTE. oh_rss_countable_income.py:57-66 mentions only (E)(2).
    • Fix.
      • Add a one-approved-spouse case with own countable income between $994 and $1,800. For example, Social Security disability of $1,200 gives countable income of 1,180. The PR's reading pays 620; the literal reading makes the spouse ineligible.
      • Extend the NOTE to (E)(3).

4. Polish.

  • programs.yaml notes.
    • Say that RSS is 0 in microsimulation, because certification is an input only (see the microsimulation check under Verified).
    • Unless Should 1's remedy (a) lands, say that candidates without SSI need Medicaid entered.
  • minimum_age.yaml.
    • The July 15, 2017 version of 5122-36-02 already reads "(A) The individual is at least eighteen years of age." So 2017-07-15 is a better start date than 2022-09-03.
    • This is harmless either way, since backdating gives 18.
  • Update Maryland tax rules for 2022 #1836. Update it for whichever items land:
    • the Medicaid gap and Case 19's "modelling device" note (Should 1);
    • the earlier fee (Suggestion 1);
    • conflict 3's sentence and the new cases (Suggestion 3).

Verified correct

  • Batch cross-cutting checks:

    # Check Verdict
    1 Axiom line Valid: TheAxiomFoundation/rulespec-us#1836 queued; see the Axiom line assessment
    2 House-template descriptions All three follow it, each one sentence ending "under the Residential State Supplement program": "Ohio sets this amount as the monthly allowable fee ...", "Ohio provides this amount as the monthly personal needs allowance ...", "Ohio sets this age as the minimum age ...". The program's own name is used, as Utah's DWS files used 205-10's title
    3 Backdating The fee leaks $1,600 back to 2015, where Ohio paid $1,100 until June 30, 2023. This is a documented deferral (Suggestion 1). The $200 allowance and the age of 18 are right in earlier years
    4 tx_rebate.py copy Omits oh_rss (and nc_sa). The PR body defers this to Keep one spm_unit_benefits list so reforms that add a benefit stop dropping baseline programs #10226 (open), as the siblings did; accepted
    5 Aggregate wiring Complete, with HUD left out by design and no double count (details below)
    6 Income attribution The single, both-approved, one-approved, ineligible-spouse and apart readings are documented and pinned: integration Cases 1-5, 8, 10, 12 and 13. Two readings need a sentence or a case (Suggestion 3)
    7 Sibling conflicts Branch note only (see Branch status)
    8 CI All green on the head
    9 State law Verified (below)
  • Amounts.

    • 5122-36-05 ("Effective: July 1, 2023"):
      • "(B) The allowable fee is the amount an individual receiving RSS payments pays to a living arrangement and is one thousand six hundred dollars per month."
      • "(C) The personal needs allowance is at least two hundred dollars per month."
    • MEPL 175, page 1 ("Effective Date: July 1, 2023"): "increasing the income standard for the Residential State Supplement (RSS) program to $1,800/month ... The allowable fee will increase from $1,100/month to $1,600/month ... The RSS Personal Needs Allowance (PNA) will remain at $200/month."
    • Both parameters and their #page=1 anchor match. Using $200 for an "at least" floor is documented in the body.
  • Payment rules, from 5160:1-5-01 ("Effective: August 1, 2025"):

    • The income standard. (B)(2): "the aggregate of the allowable fee standard and the personal needs allowance". The model derives this as the sum.
    • Income treatment. (E)(4) gives three exceptions to Medicaid's: "(a) Supplemental security income (SSI) is countable income in the RSS program. (b) When an individual has countable income equal to or in excess of the income standard, the individual is ineligible for RSS. (c) The RSS program has no deeming provision."
    • The payment. (G)(1): "equal to the difference between the individual's income after all allowable deductions and disregards and the income standard."
    • Proration. (G)(5) pays a full month for a move on the first day. (G)(6)(b)-(c): "Round amounts up to the next whole cent", for both the daily amount and the product, counting "the day that the individual moves into the RSS living arrangement through the last day of the month".
  • Eligibility.

    • (C)(1)(a)-(f) of 5160:1-5-01.
    • 5122-36-02(A) ("Effective: September 3, 2022") lists eleven criteria, from "(1) The individual is at least eighteen years of age" to the waiver, PACE, hospice and release-of-information conditions.
    • oh_rss_certified's documentation covers (A)(2)-(11), including the supervision criterion (A)(4), and 5160:1-5-01(H)'s temporary institutional stay.
    • The funding cap (5122-36-03(F)(2): "RSS program funds are sufficient to provide cash assistance to all enrollees") is listed as not modeled.
  • Who administers and pays.

    • ORC 5119.41 ("Effective: September 30, 2025", HB 96) names "the department of behavioral health". (D) assigns income and resources to the county department of job and family services or the Department of Medicaid. That supports the oh/dbh folder.
    • POMS SI 01415.058 (January 2026 edition, effective 08/28/2026) doesn't mention Ohio.
    • SSA's January 2011 Ohio summary describes state administration with state funds, and says "A standard is established by the state for the total SSI payment. The federal SSI payment and any countable income are deducted from the state standard." SSA's site blocks automated fetches, so I confirmed this through SSA-domain search results.
    • So the PR rightly doesn't use the shared SSA-administered helper (SSA rounding, $1 minimum).
  • Exclusions, from 5160:1-3-03.2 ("Effective: April 15, 2026"):

    • The $20 exclusion. (D)(2)(l): it "does not apply to income/assistance based on need that uses income as a factor of eligibility and is wholly or partially funded by the federal government". So adding SSI after the exclusions is right.
    • Interest and dividends. (D)(2)(v): "Interest and dividend income from a countable resource or from a resource excluded under a federal statute other than section 1613(a)". The SSI unearned list contains exactly interest_income and dividend_income, so the subtraction matches. The federal over-count is documented (SSI counts interest and dividends from countable resources, which 42 USC 1382a(b)(23) excludes #10079).
    • Earned income. (E)(3)(a) is the student earned income exclusion, and (E)(4), (E)(5) and (E)(7) are the $20 remainder, $65 and one-half.
    • Couples. (H): "applied only once to an eligible couple". This is implemented by pooling before the exclusions.
    • RSS and Medicaid income. (D)(2)(b) excludes RSS itself from Medicaid income ("Residential state supplement (RSS) payments are included in this category"), so RSS can't feed back into Medicaid.
  • Resources. 5160:1-3-05.1(B)(9): "(a) For an individual, the resource limit is two thousand dollars. (b) For a married couple, whether both are eligible or one is ineligible, the resource limit is three thousand dollars." These match SSI's parameters.

  • The Oklahoma lesson (Add Oklahoma state supplementation for 2026 #10165). ssi_earned_income now subtracts pre-tax premiums (Document disjoint health premium inputs and correct consumer treatment #10046), and RSS inherits that. Ohio's rules don't override it, unlike Oklahoma's:

    • 5160:1-3-03.1(B)(1)(a) says "Gross income, prior to any deductions or exclusions ... is considered available", and 5160:1-1-01(B)(19) defines earned income as including "wages, salary, or commissions".
    • Neither names cafeteria plans. Oklahoma's 317:35-5-42(b)(9)(A) does name them.
    • 5160:1-3-03.1(D) adopts 20 CFR 416.1103, and Ohio has applied SSI methodology as a 1634 state since August 1, 2016 (SPA 15-015; 42 CFR 435.601(b)).
    • So inheriting SSI's treatment is right, and no case sets the premium.
    • Integrate modeled state unemployment insurance into income flows #9558. ssi_unearned_income reads total_unemployment_compensation, so it is satisfied.
  • Source conflicts.

    • (1) The couple standard. I agree with twice the (B)(2) standard. Read literally, (E)(2) with 5160:1-3-03.5(B)(2)'s $1,491 would deny RSS to any couple living only on SSI.
    • (2) ORC 5119.41(A)'s description of recipients. I agree. (B) leaves eligibility to the rules, and neither 5160:1-5-01(C) nor 5122-36-02(A) requires receiving SSI or Social Security.
    • (3) Resources. See Suggestion 3(a).
  • The New Hampshire bug pattern doesn't occur here.

    • The variables. The Ohio-gated variables are a bool (oh_rss_eligible), two floats and an int input with a formula (oh_rss_partial_month_days). The int is used only in (days > 0) & (days < period.days), never as a parameter or breakdown key.
    • The parameters are read by attribute.
    • The tests. oh_rss.yaml Case 14 (Indiana) gives 0. test_future_poverty_in_all_states, which calculates spm_unit_benefits for every state in one simulation, passes in CI's Rest jobs, as do Microsimulation and both Rest (Python) jobs.
  • Medicaid dependency and calculation order.

    • oh_rss_eligible is the fourth consumer of medicaid_enrolled_for_ssi_state_supplement, after Indiana, Kansas and Utah (Add Utah state supplementation for 2026 #10170).
    • Probe at the head (2027). A certified Ohio SSI recipient and a 40-year-old SNAP workfare adult, calculating oh_rss, snap and medicaid_enrolled in both orders, give identical results:
      • oh_rss [9,252, 0] (771 × 12);
      • snap [300, 3,256.26];
      • medicaid_enrolled [true, true];
      • no ssi_state_supplement_medicaid branch is left behind.
    • Cost. The variable is cached per year and already computed for Indiana and Kansas, so Ohio adds no microsimulation cost.
    • The shared docstring. Its one-line change is the same as Add Utah state supplementation for 2026 #10170's.
  • Microsimulation (the Utah check). The Utah over-count doesn't recur here; the bias runs the other way.

    • Direction: downward. oh_rss_certified defaults to false and no dataset sets it, so RSS is $0 in microsimulation.
    • Magnitude: the whole program.
      • OhioMHAS's 2020 RSS database solicitation says "The RSS program has an annual budget of $16 million and currently serves approximately 2,400 Ohioans statewide".
      • The FY2024–25 budget "increased from $16M per year to $24M per year".
      • So the model understates by roughly $24 million a year, which is small in Ohio's state-benefit totals.
    • Documentation. The code NOTE on oh_rss_certified and the PR body say so. The programs.yaml notes say only "Care certification is an input" (Suggestion 4).
    • Precedent. This is the same pattern as Pennsylvania's care-home input (Add Pennsylvania state supplementation for 2026 #10167, approved). No take-up issue arises, since nothing reaches the data.
  • Aggregate wiring at the head:

    • household_state_benefits.yaml (lines 76, 177, 289, 402);
    • spm_unit_benefits.py:29;
    • SNAP income/sources/unearned.yaml:53;
    • programs.yaml:1151, whose parameter_prefix resolves, as the registry test confirms.

    ssi is the federal payment only, and oh_rss isn't an SSI income source, so nothing is counted twice.

    • HUD. Leaving RSS out of HUD income, with the NOTE at oh_rss.py:16-18, matches ks_sspp and Utah's ut_dhhs_ssp, which are also kept off the list for the Medicaid cycle. RSS recipients live in licensed residential care (5122-36-02(A)(5)), so HUD assistance rarely applies.
    • Other Ohio programs. Ohio CCAP, the only other Ohio program on main that reads SSI, excludes it.
  • Code:

    • There are no hard-coded policy values. The SSI exclusion and resource parameters are reused with comments citing Ohio's adoption.
    • MONTH variables read YEAR inputs through period.this_year or core's division.
    • References give one entry per document, and the variable tuples have no titles.
    • The oh_rss_partial_month_days formula correctly stops a one-month input from carrying forward (Case 11).
  • Hand checks (2026 FBR $994 individual, $1,491 couple; 2027 $1,029):

    • oh_rss.yaml:
      • Case 1: 1,800 − 994 = 806.
      • Case 2: 19,630.80 / 12 = 1,635.90; − 20 = 1,615.90 > 994, so SSI 0; 1,800 − 1,615.90 = 184.10.
      • Case 3: countable 1,800 equals the standard, so 0.
      • Case 4: 1,800 − 1,799 = 1.
      • Case 5: 2,087.52 − 20 = 2,067.52 ≥ 1,800, so 0.
      • Case 6: 2,860 / 12 = 238.33; (238.33 − 85) / 2 = 76.67; SSI 917.33; countable 994; 806.
      • Case 13: resources 2,001 > 2,000, so 0.
      • Case 15: 806 / 31 = 26.00 exactly; × 16 = 416.
      • Case 17: 1,636 + 4 + 1 = 1,641 for SSI; RSS 1,641 − 5 − 20 = 1,616; 184. Resources 1,600 ≤ 2,000.
      • Case 18: wages 715 are within the 2026 student limits ($2,410 a month, $9,730 a year); unearned 1,181 − 20 = 1,161; 639. Without the exclusion, (715 − 65) / 2 = 325 more, so 314.
      • Case 20: 1,800 − 1,029 = 771.
    • integration.yaml:
      • Case 1: pooled 1,491; (3,600 − 1,491) / 2 = 1,054.50 each.
      • Case 2: own SSI 745.50; 1,054.50 and 0.
      • Case 3: 49,380 / 12 = 4,115; SSI deems (4,115 − 85) / 2 = 2,015, so SSI 0; RSS 1,800 and 0.
      • Case 4: 3,000 ≤ 3,000, so 1,054.50 each.
      • Case 5: 3,001 > 3,000, so 0.
      • Case 6: SSI 11,928; RSS 806 × 12 = 9,672; SNAP unearned and spm_unit_benefits 21,600; HUD 11,928.
      • Case 7: 806 / 30 = 26.8667, rounded up to 26.87; × 15 = 403.05.
      • Case 8: (2,087.52 + 986.70 − 20) / 2 = 1,527.11; 1,800 − 1,527.11 = 272.89 each.
      • Case 9: 241.50 / 30 = 8.05; × 15 = 120.75.
      • Case 10: 1,054.50 / 30 = 35.15; × 15 = 527.25, and 1,054.50 for the other spouse.
      • Case 11: March 0; April 403.05; May 806.
      • Case 12: separate units, so 994 SSI and 806 each.
      • Case 13: own 1,500 ≤ 2,000, so 1,800 and 0.
  • Changelog: changelog.d/oh-ssp-2026.added.md is top-level, typed added, and accurate.

  • PR body:

    • The case count is right: 33 = 20 + 13, matching CI.
    • The shared files it lists match the diff.
    • Its claims about HB 96, the exclusions and the resource limits check out against the sources above.
  • Partner tests: the PR touches none, and Household API Partners passes.

Axiom line assessment

Valid: axiom: ORC 5119.41; OAC 5160:1-5-01, 5122-36-02(A), 5122-36-05(B)-(C), 5160:1-3-03.2, 5160:1-3-05.1(B)(9); MEPL 175 TheAxiomFoundation/rulespec-us#1836 queued.

  • Issue state.
    • The PR author filed Update Maryland tax rules for 2022 #1836 on 2026-10-20. It is open, labelled pe-parity, and the only rulespec-us issue a search for "Ohio Residential State Supplement" finds.
    • rulespec-us main (5796861e58) still has no module: us-oh/ holds only policies/cms, policies/income_tax and statutes/5747. So queued is the right form.
  • Dispatch-ready on the Add AMT parameters for 2020-2023 #1467 model:
    • Module paths: 5160:1-5-01, 5122-36-05 and -02, and ORC 5119.41, with 5160:1-3-03.2, 5160:1-3-05.1 and MEPL 175 co-cited.
    • Corpus citations. I confirmed each against axiom-corpus main (393127f8b2). manifests/us-oh-medicaid-eligibility-manual.yaml holds us-oh/manual/odm/medicaid/5160-1-5-01, 5160-1-3-03-2 and 5160-1-3-05-1, each with source_as_of: '2026-09-10'.
    • The recorded blocker. ORC 5119.41 and MEPL 175 are "Needs ingest".
    • Verbatim law. I checked these quotes against the live sources:
      • (B)(2), (C)(1), (E)(2)-(4), (F), (G)(1) and (G)(6);
      • 5122-36-02(A)(1);
      • 5122-36-05(B)-(C);
      • MEPL 175;
      • 5160:1-3-03.2 (D)(2)(l), (v), (E)(3)(a), (4), (5), (7) and (H);
      • 5160:1-3-05.1(B)(9).
    • Required outputs. Five rows: the parameters, the income standard, non-income eligibility, countable income and the payment.
    • Companion tests A–U come from the rules, with SSA Snapshot, BLS and Ohio minimum-wage inputs rather than PolicyEngine output. Each maps to a PolicyEngine case by number.
    • The conflicts comment covers the three conflicts, each with the reading taken and the pinning case.
  • Matches the head:
    • the variable and parameter names and dates;
    • the 20 / 13 case counts;
    • the couple, Medicaid and SSI-interest readings.
  • If Should 1 or the suggestions land: update Update Maryland tax rules for 2022 #1836 as Suggestion 4 lists.

CI status

All 27 checks pass (gh pr checks 10164, rechecked at the end of the review). The three "skipping" entries belong to the superseded run 39387842563.

  • The run. Run 39388133783 (pull_request) on head 0ca3daf9af, created 2026-10-20 07:41 UTC and completed 11:42 UTC.
  • Quick Feedback ran both Ohio files: integration.yaml 13 passed and oh_rss.yaml 20 passed.
  • The rest. All 11 Baseline shards, the nine Contrib shards, Microsimulation, both Rest (Python) jobs, Package and compatibility, PR validation and Household API Partners pass.
  • Main since then. main's two newer commits (Encode the published 2027 state paid leave premiums (CO, WA, NY, NJ) and cite the unchanged 2027 rates #10295, 2027 paid leave premiums, and a version bump) touch none of the files this PR reads or edits.
  • Local runs. Because CI is green, I ran only two small probes at the head (policyengine-core 3.32.29), for Should 1, Suggestions 2 and 3(a), and the calculation order.

Branch status

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for 1 should item; details in the report above. The 2026 amounts ($1,600 fee + $200 PNA = $1,800), the (E)(4) income rules, exclusions, resources and (G)(6) proration check out against OAC 5122-36-05, MEPL 175 and ORC 5119.41. rulespec-us#1836 is valid, the NH-sibling bug doesn't occur here, and CI is green. Should 1: the Medicaid gate misses Ohio's 42 CFR 435.232 group, people who receive only the state supplement (SPA 15-015, Att. 2.2-A pp. 15–16). With Medicaid computed, a candidate with SSDI of $1,635.90 or Social Security of $1,100 gets RSS 0, though they get $184.10 or $720 when Medicaid is entered. Fix: accept is_ssi_eligible for certified non-SSI candidates, or document the limit where users will see it. Four suggestions are in the report: the pre-7/2023 $1,100 fee, a one-cent float32 proration rounding, pinning the Case 13 reading, and programs.yaml notes.

hua7450 and others added 2 commits October 20, 2026 16:04
…ounding

- Meet the RSS Medicaid condition through the 42 CFR 435.232 group (SPA 15-015)
  for candidates who meet SSI's other criteria but whose income is too high.
- Allow a thousandth of a cent before rounding the daily amount up.
- Pin the one-spouse income standard and the computed-Medicaid couple.
- Start the minimum age on 2017-07-15 and note microsimulation in programs.yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DTrim99 DTrim99 mentioned this pull request Oct 20, 2026
3 tasks done
hua7450 and others added 2 commits October 20, 2026 18:24
The new source-conflict guard (#10287) registers statute conflicts only; this
NOTE compares a regulation with another regulation or a handbook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hua7450
hua7450 requested a review from DTrim99 October 21, 2026 15:56
@hua7450

hua7450 commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, David. This round's changes are in dc0950b, with main merged.

Should 1, the Medicaid group for people who receive only RSS: fixed with remedy (a).

  • oh_rss_eligible now meets the Medicaid condition through medicaid_enrolled_for_ssi_state_supplement, or through Ohio's 42 CFR 435.232 group: is_ssi_eligible with uncapped_ssi at or below 0, so SSI's criteria other than income, with income too high for SSI.
  • A comment in the formula quotes SPA 15-015, Attachment 2.2-A pages 15-16 (I checked the archived PDF, pages 17-18), and the PDF is a new reference. The documentation says that entering medicaid_enrolled: false doesn't remove this group.
  • New oh_rss.yaml Case 21 (Case 2's inputs, Medicaid computed) gives 184.10. Case 8 still gives 0: with no income the person is income-eligible for SSI, so only the entered Medicaid applies.
  • The shared Medicaid helper is unchanged.

Suggestion 1, the $1,100 fee before July 2023: not taken. The batch keeps earlier years out of scope, and the body notes the $1,100 fee.

Suggestion 2, float32 proration: fixed. The daily amount now allows a thousandth of a cent before rounding up. New Case 22 (Social Security of 17,249.52 a year, 16 days) gives 197.44. With the old 1e-8 it gives 197.60 and fails.

Suggestion 3:

Suggestion 4: the programs.yaml notes say microsimulation pays no RSS. minimum_age starts on 2017-07-15, with the July 15, 2017 rule as a second reference (I checked (A) on its page 1). TheAxiomFoundation/rulespec-us#1836 and its conflicts comment are updated for all of these.

Branch note, main's statute-first rule (#10287): the oh_rss NOTE on one eligible spouse's resources no longer uses the words "Source conflict" (30b5c8d). It weighs 5160:1-5-01(E)(3) against Ohio's Medicaid resource rules, 5160:1-3-05.1(B)(9)(b) and 5160:1-3-05.20(E)(1)-(2). No statute sits on either side, so it needs no register entry, and the new wording keeps the #10287 ratchet test from counting it. The model's reading and integration Cases 13 and 14 don't change, and the conflicts comment on TheAxiomFoundation/rulespec-us#1836 still lists it as conflict 3.

CI: both red jobs come from one test, test_conflict_sounding_comments_do_not_grow; Rest (Python + variables) passes its own shard and fails only on shard 1's result. The test flags main's Florida and South Dakota LIHEAP files, none of this PR's. Main fixed it in #10334, so I'll merge main again after your review.

37 Ohio RSS cases pass locally (22 in oh_rss.yaml, 15 in integration.yaml).

@DTrim99

DTrim99 commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

PR Review (round 2): Add Ohio state supplementation for 2026

PR #10164 (author: hua7450). This round reviews head dc0950b4ec; round 1 reviewed 0ca3daf9af. The branch is 12 commits ahead of main and 4 behind. Four commits landed since round 1:

  • 801e0c0693, "Cover Ohio's state-supplement-only Medicaid group and fix proration rounding" (7 files, +139/−13). It does the following:
    • lets oh_rss_eligible meet the Medicaid condition through the 42 CFR 435.232 group, is_ssi_eligible & (uncapped_ssi <= 0), alongside medicaid_enrolled_for_ssi_state_supplement. It moves the NOTE into the formula, quotes SPA 15-015, adds the SPA as a third reference and rewrites the documentation;
    • widens the epsilon on the daily amount from 1e-8 to 1e-3 of a cent;
    • adds NOTE sentences on the (E)(3) resource reading (it decides the result only when Medicaid is entered) and on the (E)(3) individual income standard;
    • starts minimum_age on 2017-07-15, with the 2017 rule PDF as a second reference;
    • says in the programs.yaml notes that microsimulation pays no RSS;
    • adds oh_rss.yaml Cases 21 and 22 and integration Cases 14 and 15.
  • 74b373d62b, a merge of main at 07eba1aeea with three hand-resolved blocks: SNAP unearned, programs.yaml and spm_unit_benefits.py.
  • 30b5c8dde5, "Reword a source NOTE that involves no statute". The oh_rss.py resource NOTE no longer starts "Source conflict:"; it now says "Ohio's Medicaid resource rules ... would instead combine". The meaning is unchanged.
  • dc0950b4ec, a clean merge of main at 1f678c72cd. It brings in Tie source-conflict markers to the register shared with Axiom #10287 (the source-conflict guard) and Ohio HEAP (Add Ohio HEAP regular heating assistance #9975).

Summary

Ziming fixed the round-1 should item with remedy (a) as I proposed it. He also fixed every suggestion except one documented deferral, which I accept.

  • Should 1 (Medicaid). A certified candidate who meets SSI's criteria other than income, and whose income is too high for SSI, now meets 5160:1-5-01(C)(1)(a) through Ohio's 42 CFR 435.232 group.
    • My round-1 probe household (Social Security disability of $1,635.90, Medicaid not entered) got 0 at the old head. oh_rss.yaml Case 21 now pins 184.10.
    • The documentation now says that entering medicaid_enrolled: false doesn't zero RSS for this group.
  • Suggestion 2 (proration). The epsilon is widened, and Case 22 pins my probe row: 197.44, where the old head gave 197.60.
  • Suggestion 3. Both couple readings are now pinned and noted, and Update Maryland tax rules for 2022 #1836 records them as conflicts 3 and 4:
    • integration Case 14, with Medicaid computed, gives 0;
    • integration Case 15, the one-spouse income standard, gives 620.
  • Suggestion 4. The programs.yaml notes, the 2017 start date and Update Maryland tax rules for 2022 #1836 are all updated.
  • Suggestion 1 (the $1,100 fee before July 2023) stays out of scope. The PR body documents it and programs.yaml claims only 2026, as the sibling PRs do. I accept it.

Merge resolutions. All three hand-resolved blocks keep both sides.

  • Against the merge base, each shared list gains only Ohio's line, once.
  • No sibling line is dropped. New Jersey, Pennsylvania, Wyoming, North Carolina, Nevada, Montana, Oklahoma, New York, Rhode Island, South Dakota and Virginia are all present.
  • The HUD unearned list is untouched, by design.

The wage lesson (NH #10156 round 3, OK #10165) finds nothing here.

  • RSS is state-administered, and its non-SSI budget reads ssi_earned_income, which nets out pre-tax premiums since Document disjoint health premium inputs and correct consumer treatment #10046.
  • Ohio's rule says "Gross income, prior to any deductions", but RSS income is treated as for aged, blind or disabled Medicaid. As a 1634 state since 2016, Ohio may not be more restrictive than SSI methodology there (42 CFR 435.601(b)(2), (d)(2)).
  • The phrase is SSI's own (20 CFR 416.1110(a)(1)), and SSA reads it together with the cafeteria-plan exclusion.
  • Optional Suggestion 1 asks for that reading to be recorded, as in Virginia.

Other checks.

Every new expectation checks by hand (4 cases, 12 outputs).

CI and branch.

Prior findings status

Finding Status Evidence
Should 1: the Medicaid condition missed Ohio's group for people who receive only the state supplement, so RSS was $0 for candidates with no SSI unless medicaid_enrolled was entered Fixed (remedy (a)) The code. oh_rss_eligible.py:30-40 returns ... & (medicaid | state_supplement_only), where state_supplement_only = is_ssi_eligible & (uncapped_ssi <= 0). is_ssi_eligible tests aged, blind or disabled status, the SSI resource test and immigration status "without income test". That matches the SPA's "would be eligible for SSI except for the level of their income". The NOTE at lines 20-29 quotes that phrase and cites 435.232, SPA 15-015 Attachment 2.2-A pages 15-16 and 5160:1-3-03.5(B)(3). The reference is the SPA at #page=17, under a # PDF pages 17-18 comment, as CLAUDE.md asks. The documentation says the group qualifies "even when medicaid_enrolled is entered as false", so Case 8 (an SSI recipient with Medicaid entered false; uncapped_ssi 994) still gives 0. The tests. oh_rss.yaml Case 21 uses Case 2's inputs with no Medicaid input and gives SSI 0, eligible true and 184.10. My round-1 probe gave 0 for that household at the old head, so the case exercises the new branch. Integration Case 15 also reaches it, and Case 14 shows it fails when the couple's combined resources exceed $3,000. The body and #1836 both describe the group.
Suggestion 1: encode the $1,100 fee in force before July 2023 Deferred (accepted) allowable_fee.yaml still starts at 2023-07-01: 1_600. The body says "Earlier years use parameter backfilling and are unverified historical estimates (MEPL 175 lists a $1,100 fee before then); no historical coverage is claimed". programs.yaml gives verified_years: "2026", and #1836 lists "years before July 2023" as out of scope. This matches #10170, #10172 and #10174.
Suggestion 2: a prorated first month could round the daily amount up one cent too many Fixed The code. oh_rss.py:59-61 is now np.ceil(payment.astype(np.float64) / period.days * 100 - 1e-3) / 100, with a NOTE on float32 storage. The product keeps 1e-8, which is safe in float64. The test. oh_rss.yaml Case 22 is my first probe row: pension 17,249.52, 16 days, countable 1,417.46 and 197.44. The arithmetic. The float32 payment 382.5400391 gives 1,234.000126 cents a day; less 0.001 that is 1,233.999126, which rounds up to 1,234, so 12.34 × 16 = 197.44. Existing cases are unchanged. 806 / 31 = 26.00 (Case 15), 806 / 30 = 26.87 (integration Case 7), 241.50 / 30 = 8.05 (Case 9) and 1,054.50 / 30 = 35.15 (Case 10). A true daily amount from a whole-cent payment exceeds a whole cent by at least 1/31 of a cent, far above 0.001.
Suggestion 3(a): Case 13's result depends on Medicaid being entered Fixed The NOTE at oh_rss.py:36-43 now adds: "The reading decides the result only when medicaid_enrolled is entered: computed Medicaid and the SSI resource test both combine the couple's resources, so a couple above $3,000 fails the Medicaid condition." The test. Integration Case 14 is Case 13 without the Medicaid input: SSI [0, 0], eligible [false, false], oh_rss [0, 0]. #1836's conflict 3 gains the same sentence and cites Case 14. The body's conflict list says the same.
Suggestion 3(b): the (E)(3) individual income standard wasn't pinned Fixed The NOTE at oh_rss_countable_income.py:66-69 quotes (E)(3)'s "the appropriate individual income standard as defined in rule 5160:1-3-03.5" and says the model uses the RSS standard. The test. Integration Case 15 is my example: Social Security disability $1,200, countable 1,180, RSS 620 and 0. #1836 adds it as conflict 4 (companion test W) and the body lists it as a source conflict.
Suggestion 4: polish Fixed programs.yaml notes: "Care certification is an input, so microsimulation pays no RSS". The note about entering Medicaid became moot once remedy (a) landed. minimum_age.yaml: it starts on 2017-07-15, and the second reference is the July 15, 2017 rule PDF. Page 1 reads "Effective: July 15, 2017" and "(A) The individual is at least eighteen years of age." #1836 was updated 2026-10-21 04:58 UTC with the SPA 15-015 row and quote, the 435.232 Medicaid interpretation, the 2017 date, companion tests V (Case 22) and W (Case 15), conflict 3's sentence with Case 14, conflict 4, and the 22 / 15 case counts.

New findings

Critical (must fix)

None.

Should address

None.

Suggestions

1. Record why RSS may use SSI's wage count, so the batch's wage finding isn't applied here by mistake (optional).

  • Where. oh_rss_countable_income.py:23-27 reads ssi_earned_income. Since Document disjoint health premium inputs and correct consumer treatment #10046, that returns wages less min_(wages, pre_tax_health_insurance_premiums).
  • Why it looks like the New Hampshire pattern.
  • Why it's right for Ohio.
    • The cross-reference to Medicaid. 5160:1-5-01(E)(4) treats RSS income as for aged, blind or disabled Medicaid. Ohio has used SSI's criteria as a 1634 state since August 1, 2016 (SPA 15-015).
      • 42 CFR 435.601(b)(2): "the agency must apply the financial methodologies and requirements of the cash assistance program that is most closely categorically related to the individual's status".
      • (d)(2): such methodologies "may be less restrictive, but no more restrictive (except in States using more restrictive requirements than SSI), than: (i) For groups of aged, blind, and disabled individuals, the SSI methodologies".
      • Counting salary reductions that SSI excludes would be more restrictive.
    • The same phrase in SSI's own rule. 20 CFR 416.1110(a)(1): "Wages are what you receive (before any deductions) for working as someone else's employee. Wages are the same for SSI purposes as for the social security retirement program's earnings test."
    • Ohio's own definition points the same way. 5160:1-1-01(B)(19): "Earned income includes but is not limited to wages, salary, or commissions from which state or federal income taxes are paid or withheld." No income tax is withheld from a salary-reduction premium.
    • No Oklahoma-style clause. Oklahoma's 317:35-5-42(b)(9)(A) lists "cafeteria plans" among the deductions that stay in wages; no Ohio rule does. 5160:1-3-03.1(C), which lists deductions that "are not subtracted", names only court orders, overpayment recovery and garnishments.
  • Worked by hand, with no local run. Take an aged, certified Ohio resident with Social Security of $1,200, wages of $600 and pre-tax premiums of $100 a month.
    • SSI countable income is 1,180 + (500 − 65) / 2 = 1,397.50, above $994, so there is no SSI.
    • The 435.232 path applies, so RSS = 1,800 − 1,397.50 = 402.50.
    • Counting wages gross would give 1,447.50 and 352.50. The model's 402.50 is the right figure.
  • Fix (optional).

2. Ohio HEAP, which arrived with the latest merge, counts SSI but not RSS. Record the choice and refresh the PR body (optional).

  • Where. oh/odjfs/liheap/income/sources/unearned.yaml (Add Ohio HEAP regular heating assistance #9975, brought in by dc0950b4ec) lists ssi and general_assistance, but not oh_rss.
  • The body is out of date. It still says "No other Ohio program is wired. Ohio CCAP is the only other Ohio program on main that reads SSI." At this head the HEAP list reads ssi too.
  • The rule. The 2022-2023 Energy Assistance Programs Guidelines define gross income as including "public assistance, SSI". That definition would reach RSS for an RSS recipient who is a HEAP household.
  • The precedent. Florida's LIHEAP list leaves out fl_oss, with a NOTE: its recipients live in assisted living and similar residential settings, and the Florida manual excludes those residents from LIHEAP households.
    • RSS recipients also live in licensed residential care and pay the $1,600 allowable fee to the living arrangement.
    • So the same reasoning probably applies here. Either way, few households are affected.
  • Fix (optional).
    • Add a one-line NOTE like Florida's, in the HEAP list or on oh_rss. Or add oh_rss to the list with a case, checking the SNAP–HEAP–Medicaid order with the existing dependency test.
    • Update the body sentence either way.

Verified

  • Merge resolutions (74b373d62b). There are three hand-resolved blocks; each keeps both sides.
    • SNAP income/sources/unearned.yaml. ny_ssp, oh_rss, ok_ssp, in alphabetical order. At the head, oh_rss appears once (line 55).
    • programs.yaml. Main's Montana, Oklahoma, New York, Rhode Island, South Dakota and Virginia entries are kept, and Ohio follows Virginia in merge order. Ohio appears once (line 1260), with the round-2 notes. The registry tests pass in CI.
    • spm_unit_benefits.py. mt_ssp, ok_ssp, ny_ssp, ri_ssp, sd_ssp and va_ag are kept, and "oh_rss" comes after va_ag, once (line 35).
    • The rest. The second merge (dc0950b4ec) had no conflicts.
      • Against the merge base 1f678c72cd, every shared file shows additions only: one Ohio line in each list, and one in each of the four household_state_benefits.yaml year blocks (lines 78, 187, 307, 428).
      • The HUD unearned list is identical to main's.
      • The Medicaid helper's docstring change is the same one-line edit as before.
  • The NH Add New Hampshire state supplementation for 2026 #10156 check: nothing found.
    • The variables. The Ohio-gated variables are still a bool, two floats and the oh_rss_partial_month_days int, which is used only in comparisons. The new code reads two federal, ungated variables (is_ssi_eligible, uncapped_ssi).
    • The parameters are read by attribute. No parameter or breakdown is keyed by a variable.
    • Multi-state coverage. oh_rss.yaml Case 14 (Indiana) gives 0, and the aggregate-list integrity tests pass in CI's Rest shards.
  • Microsimulation (the default rule for population effects).
    • The 435.232 path sits inside the oh_rss_certified & conjunction. oh_rss_certified defaults to false and no dataset sets it, so RSS remains $0 in microsimulation.
    • Ohio's roughly $24 million a year is still understated, as round 1 found. That is now documented in programs.yaml, the code NOTE and the body.
    • The new reads are cached SSI variables, so the change adds no cost.
  • The new path against the rule.
    • SPA 15-015 item 10 (435.232) covers people who "receive only a State supplementary payment (but no SSI payment)" and "would be eligible for SSI except for the level of their income". uncapped_ssi <= 0 captures "except for income". is_ssi_eligible captures the other SSI criteria, including deemed resources, which 5160:1-3-05.20(E)(1) also combines.
    • An SSI-eligible person who doesn't take up SSI (uncapped_ssi > 0) still goes through the Medicaid variable. Their income is below the SSI rate, so the aged, blind or disabled limit computes Medicaid for them.
    • Requiring eligibility rather than enrollment matches (C)(1)(a)'s "Be determined eligible for medical assistance".
  • The source-conflict guard (Tie source-conflict markers to the register shared with Axiom #10287).
    • No Ohio RSS file, code or test, matches the guard's conflict regex. The one near miss, "Read literally" in oh_rss_countable_income.py:61, isn't a pattern.
    • CI's guard run on this head lists no Ohio file. So the rewording in 30b5c8dde5 keeps the PR clean, and the merged tree adds nothing.
  • Hand checks of every new expectation (2026 FBR $994):
    • oh_rss.yaml Case 21:
      • 19,630.80 / 12 = 1,635.90, and 1,635.90 − 20 = 1,615.90 > 994, so SSI 0;
      • aged, no resources and a citizen, so oh_rss_eligible true;
      • 1,800 − 1,615.90 = 184.10.
    • oh_rss.yaml Case 22:
      • 17,249.52 / 12 = 1,437.46, and 1,437.46 − 20 = 1,417.46 > 994, so countable 1,417.46;
      • 1,800 − 1,417.46 = 382.54, and 382.54 / 31 = 12.34 exactly;
      • × 16 days = 197.44.
    • Integration Case 14:
      • both spouses are aged, and 1,500 + 1,600 = 3,100 > 3,000, so SSI [0, 0];
      • the SSI resource test and computed Medicaid both fail, and person2 isn't certified, so eligible [false, false];
      • oh_rss [0, 0].
    • Integration Case 15:
      • person2 is 58, not aged, blind or disabled, and has no income to deem;
      • 14,400 / 12 = 1,200, and 1,200 − 20 = 1,180 > 994, so SSI [0, 0];
      • the 435.232 path makes eligible [true, false];
      • only one spouse is eligible, so own countable income [1,180, 0];
      • 1,800 − 1,180 = 620, so oh_rss [620, 0].
  • The PR body.
    • It claims "37 Ohio RSS YAML cases (22 in oh_rss.yaml, 15 in integration.yaml)", which matches CI's 22 + 15.
    • The Medicaid row and the source-conflict list match the code.
    • Its axiom line is unchanged. The one stale sentence is in Suggestion 2.
  • Unchanged since round 1 and still correct:
    • the amounts ($1,600 + $200 = $1,800; 5122-36-05; MEPL 175);
    • the (E)(4) income rules, exclusions and resource limits;
    • the (G)(5)-(6) proration;
    • the HUD exclusion and its NOTE;
    • the changelog fragment changelog.d/oh-ssp-2026.added.md.
    • The PR touches no partner test files, and Household API Partners passes.
  • The Texas rebate copy. It is still deferred to Keep one spm_unit_benefits list so reforms that add a benefit stop dropping baseline programs #10226 (open), as for the siblings.

Axiom line assessment

Valid: axiom: ORC 5119.41; OAC 5160:1-5-01, 5122-36-02(A), 5122-36-05(B)-(C), 5160:1-3-03.2, 5160:1-3-05.1(B)(9); MEPL 175 TheAxiomFoundation/rulespec-us#1836 queued.

  • Issue state.
    • Update Maryland tax rules for 2022 #1836 is open and labelled pe-parity. It was last updated on 2026-10-21 at 04:58 UTC, after 801e0c0693.
    • rulespec-us main (5796861e58) still has no Ohio RSS module: us-oh/ holds only .axiom, policies and statutes. So queued is still the right form.
  • Dispatch-ready.
    • Module paths and corpus status, as round 1 confirmed. The new row is "Co-cited for Medicaid eligibility: Ohio SPA 15-015, Attachment 2.2-A", marked "Needs ingest", with the #page=17 link.
    • Verbatim law. The SPA quote is added, and so is the 2017 edition of 5122-36-02(A)(1).
    • Required outputs. The non-income eligibility row now includes "eligible for Ohio Medicaid, including through the 42 CFR 435.232 group".
    • Companion tests now run to W. They add V (197.44, Case 22) and W (620, Case 15), and note that Cases 19 and 21 and integration Case 14 compute Medicaid in PolicyEngine-US.
  • Matches the head:
    • the 22 / 15 case counts;
    • the minimum age from 2017-07-15;
    • the Medicaid interpretation;
    • conflict 3's sentence with Case 14, and conflict 4 with Case 15.
  • If Suggestion 1 lands, add the "Wages" interpretation.

CI status

25 pass, 2 fail, 0 pending (gh pr checks 10164, rechecked at the end of the review). The run is 39545661732 (pull_request) on head dc0950b4ec; it started 2026-10-21 04:44 UTC and finished 08:14 UTC.

  • The two failures are the known main-caused ratchet failure, not a finding.
    • "Full Suite - Rest (Python, shard-1 + variables)" fails one test of 2,500: test_source_conflicts.py::test_conflict_sounding_comments_do_not_grow.
    • Its grown set lists only Florida and South Dakota LIHEAP files: fl_liheap_eligible.py, fl_liheap_income_limit.py, fl_liheap.py, fl/.../payment/base_amount.yaml and sd/.../limits/table/in_effect.yaml. No Ohio file is among them.
    • "Full Suite - Rest (Python + variables)" passes all its own tests (60, 55, 1,767 and 980). It fails only because it aggregates the shards: "Rest shards did not all succeed: shard-1=failure, shard-2=success".
    • Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334 (fec98b87c8) fixed the baseline on main at 13:24 UTC, after this run began. Merge main and re-run.
  • Passed.
    • Quick Feedback ran both Ohio files: integration.yaml 15 passed and oh_rss.yaml 22 passed.
    • The rest. All 11 Baseline shards, all 9 Contrib shards, Microsimulation, Household API Partners, Package and compatibility, and PR validation pass.
    • Ohio-relevant tests in the Rest shards pass: test_ssi_state_supplement_medicaid_dependency.py, the aggregate-list integrity tests and the program registry tests.
  • Local runs: none. CI covers every touched file, and the wage example above is worked by hand.

Branch status

Verdict: APPROVE

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2: Should 1 is fixed. RSS now meets the Medicaid condition through the 42 CFR 435.232 group (Case 21 gives 184.10), and suggestions 2-4 are fixed too. All three hand-resolved merge blocks keep every sibling's line and add Ohio's once. The two red checks are the known FL/SD LIHEAP ratchet failure from before #10334, so merge main and re-run. Two optional suggestions. Full report in the comment above.

hua7450 and others added 2 commits October 21, 2026 21:18
Each sibling SSP PR adds its line to the same unsorted lists, so the
entries now sit at different anchors and the PRs merge without conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hua7450
hua7450 merged commit 1d6acb9 into main Oct 22, 2026
27 checks passed
@hua7450
hua7450 deleted the oh-ssp-2026 branch October 22, 2026 04:49
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.

2 participants