Skip to content

Pay California's SSI/SSP restaurant meals allowance only when the living arrangement prevents cooking - #10519

Merged
PavelMakarchuk merged 9 commits into
mainfrom
fix-10296-ca-ssp-meal-allowance-default
Oct 30, 2026
Merged

PavelMakarchuk merged 9 commits into
mainfrom
fix-10296-ca-ssp-meal-allowance-default

Conversation

@PavelMakarchuk

@PavelMakarchuk PavelMakarchuk commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

living_arrangements_allow_for_food_preparation had no default_value, so it was false for every household that did not set it. ca_state_supplement_food_allowance_eligible pays the restaurant meals allowance when the input is false, so every aged or disabled California SSI/SSP recipient got the no-cooking standard by default. In January 2025 that is $1,335.81 instead of $1,206.94 for an individual, and $2,315.57 instead of $2,057.83 for a couple (SSA POMS SI 01415.057, California codes A and C).

The input now defaults to true: a household can prepare meals at home unless the input says otherwise. The variable gets a documentation string and cites WIC 12200 and POMS SI SF01415.140. No formula or parameter changes. The allowance amounts ($128.87 individual, $257.74 couple) and the rule in ca_state_supplement_food_allowance_eligible are unchanged. The only reader of the input on main is ca_state_supplement_food_allowance_eligible.

Law

  • Welf. & Inst. Code 12200(e) gives the allowance to an aged or disabled individual under (c), or a married couple under (d), "whose living arrangement prevents preparation of" meals at home. The allowance is added "in addition to any other amount". The statute does not name blind recipients or children.
  • SSA POMS SI SF01415.140 (California OSS C, independent living without cooking facilities):
    • A: the recipient has no access to adequate cooking and food storage facilities and gets no meals as part of the living arrangement. Blind recipients and children under 18 are not eligible.
    • B.2: adequate means both cooking facilities (for example, two working burners, or a microwave plus one burner) and a working refrigerator.
    • C.1: eligibility rests on a California Application for Restaurant Meals Allowance that the individual or couple signs.
  • The allowance is therefore the exception. Without information on the living arrangement, the common case is independent living with cooking facilities.

PolicyEngine's other conditions for the allowance:

  • Aged or disabled only. ca_state_supplement_aged_disabled_count counts eligible members who are aged (65+) or SSI-disabled. A blind person who is neither does not count, which matches 12200(e) and POMS A.
  • Children. ca_state_supplement_eligible_person requires the tax-unit head or spouse, so dependent children never count, which matches the POMS exclusion of children under 18.
  • Couples. The married amount applies when both spouses are aged or disabled (12200(d)); otherwise the individual amount applies, which also matches POMS B.4 for a couple with one blind member.

Gaps that this PR does not change:

Changed expected values

spm_unit_benefits.yaml, "Benefits include California's SSI state supplement." A single aged Californian with no income in 2026. The case does not describe the living arrangement, so it now gets the regular standard: ca_state_supplement 4,425.72 → 2,879.28 ((1,233.94 − 994) × 12) and spm_unit_benefits 16,353.72 → 14,807.28. The comment now cites WIC 12200(e).

Partner contract tests: needs @hua7450's sign-off (policyengine_us/tests/policy/baseline/partners/AGENTS.md). Three cases in partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml change. None of them describes a household without a kitchen: they are aged people in ZIP 90001, and the file header attributes the food allowance to "the model default". Setting the input to false in the fixtures would keep them green but hide the change: an API call that does not send the input now gets the regular standard. So the proposal is to update the expected values, not to pin the input.

Case ca_state_supplement (2026, annual)
ca_state_supplement_aged_single_no_income_max (ca) 4,425.72 → 2,879.28 ((1,233.94 − 994) × 12)
ca_state_supplement_aged_couple_no_income (ca) 10,386.84 → 7,293.96 ((2,098.83 − 1,491) × 12)
ca_state_supplement_aged_single_earnings_partial (ca) 3,663.72 → 2,117.28 ((1,233.94 − 1,057.50) × 12)

The header comment and the three arithmetic comments change to match. No other partner case changes: the Amplifi and signatures/ca.yaml cases already set the input to true. The partner file edit is in c0b77938e1, which updates the three expected values and the comments as above. The three gate questions were answered yes in the approving review on 2026-10-29 and by Pavel on 2026-10-30. The branch also merges main at 926ed24e69, which includes #10379. At the head, gov/states/ca/cdss (452) passes locally. With main at a14576f1b0 (also after #10379), the two SNAP files (30), spm_unit_benefits.yaml (6) and partners (623) pass.

Coordination

Tests

New cases in ca_state_supplement_food_allowance_eligible.yaml, all January 2025 (POMS SI 01415.057: federal SSI $967 / $1,450; independent living $1,206.94 / $2,057.83; no cooking $1,335.81 / $2,315.57):

Case Input Standard ca_state_supplement main branch
Unit: input not set — — eligible false fail pass
Aged individual not set 1,206.94 239.94 fail pass
Aged individual false 1,335.81 (1,206.94 + 128.87) 368.81 pass pass
Aged couple not set 2,057.83 607.83 fail pass
Aged couple false 2,315.57 (2,057.83 + 257.74) 865.57 pass pass

Local runs (policyengine-core YAML runner, one process per directory):

  • gov/states/ca/cdss/state_supplement, gov/states/ca/cdss/capi, household/income/spm_unit: 143 passed.
  • gov/ssa/ssi: 243 passed.
  • household/income/household: 53 passed.
  • partners/ (31 directories): 620 passed, 3 failed. The 3 failures are the CA partner cases in the table above. With the proposed partner edit, that file's 4 cases pass.
  • test_snap_child_support_treatment_invariants.py: 23 passed.
  • On main, the 3 new default cases and the spm_unit_benefits case fail; the other new cases pass.

Fixes #10296

axiom: n/a: changes only the value assumed when a household's living arrangement is not reported; the WIC 12200(e) amounts that rulespec-us encodes in us-ca/statutes/wic/12200.yaml and the eligibility rule are unchanged

🤖 Generated with Claude Code

The input had no default, so it was false for every household that did
not set it, and every aged or disabled California SSI/SSP recipient got
the restaurant meals allowance (no-cooking standard). WIC 12200(e) pays
the allowance only when the living arrangement prevents meal preparation
at home, and POMS SI SF01415.140 requires no adequate cooking and food
storage facilities and a signed application. Default the input to true
and cite both sources.

Add default and no-cooking cases for an aged individual and an aged
couple in January 2025, and update the spm_unit_benefits California case
to the regular standard (2,879.28 instead of 4,425.72).

The partner fixture analytics_coverage/edge_cases/state/ca/state_supplement.yaml
is not edited here: three of its cases change and need partner sign-off.

Fixes #10296

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

Copy link
Copy Markdown
Collaborator Author

@hua7450 — partner contract tests (per policyengine_us/tests/policy/baseline/partners/AGENTS.md). This PR changes three expected values in partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml. The head does not edit the file yet, so these three cases fail until you approve the edit.

Model change and law. living_arrangements_allow_for_food_preparation had no default, so an API call that does not send it gave every aged or disabled California SSI/SSP recipient the restaurant meals allowance. W&IC 12200(e) pays that allowance only when the living arrangement prevents meal preparation at home (POMS SI SF01415.140: no adequate cooking and food storage facilities, and a signed application). The input now defaults to true. None of the three cases describes a household without a kitchen (aged people in ZIP 90001; the file header attributes the food allowance to "the model default"), so the proposal is to update the values, not to set the input to false.

Case Old ca_state_supplement New Change
ca_state_supplement_aged_single_no_income_max (ca) 4,425.72 2,879.28 −1,546.44 (12 × 128.87)
ca_state_supplement_aged_couple_no_income (ca) 10,386.84 7,293.96 −3,092.88 (12 × 257.74)
ca_state_supplement_aged_single_earnings_partial (ca) 3,663.72 2,117.28 −1,546.44

Partner-facing impact: any partner that calls the API for an aged or disabled Californian without this input gets a lower California SSP from this PR on, by $128.87 a month for an individual and $257.74 for a couple.

Before the edit goes in:

  1. Are you sure you want to edit this test file?
  2. Have you notified a team member about this change?
  3. Have you notified the API partner about this change?

If you answer yes to all three, the edit below goes into this PR (the file's 4 cases pass with it). If you prefer, the fixtures can instead set the input to false and keep their values.

Proposed edit
diff --git a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml
index 4e95fb1..dea4de4 100644
--- a/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml
+++ b/policyengine_us/tests/policy/baseline/partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml
@@ -1,8 +1,9 @@
 # CA SSI State Supplementary Payment (SSP) partner edge cases.
 # 2026 payment standards (2026-01-01 params): aged/disabled single $1,233.94,
 # married (both aged/disabled) $2,098.83; food allowance single $128.87,
-# married $257.74 (applies when living arrangements do not allow food
-# preparation, the model default). 2026 SSI FBR: $994 single, $1,491 couple.
+# married $257.74 (applies only when living arrangements do not allow food
+# preparation, WIC 12200(e); the model default is that they allow it, so these
+# cases get no food allowance). 2026 SSI FBR: $994 single, $1,491 couple.
 # SSP = payment standard - SSI - SSI countable income.
 - name: ca_state_supplement_aged_single_no_income_max (ca)
   period: 2026
@@ -41,9 +42,9 @@
   output:
     spm_units:
       spm_unit:
-        # Standard: 1,233.94 + 128.87 food = 1,362.81; SSI = 994 FBR (no income).
-        # SSP: (1,362.81 - 994) x 12 = 368.81 x 12 = 4,425.72.
-        ca_state_supplement: 4_425.72
+        # Standard: 1,233.94 (no food allowance, WIC 12200(e)); SSI = 994 FBR
+        # (no income). SSP: (1,233.94 - 994) x 12 = 239.94 x 12 = 2,879.28.
+        ca_state_supplement: 2_879.28
 - name: ca_state_supplement_aged_couple_no_income (ca)
   period: 2026
   absolute_error_margin: 0.1
@@ -91,9 +92,9 @@
   output:
     spm_units:
       spm_unit:
-        # Both aged: married standard 2,098.83 + married food 257.74 = 2,356.57;
-        # SSI couple FBR 1,491. SSP: (2,356.57 - 1,491) x 12 = 865.57 x 12 = 10,386.84.
-        ca_state_supplement: 10_386.84
+        # Both aged: married standard 2,098.83 (no food allowance, WIC 12200(e));
+        # SSI couple FBR 1,491. SSP: (2,098.83 - 1,491) x 12 = 607.83 x 12 = 7,293.96.
+        ca_state_supplement: 7_293.96
 - name: ca_state_supplement_aged_single_earnings_partial (ca)
   period: 2026
   absolute_error_margin: 0.1
@@ -133,8 +134,9 @@
       spm_unit:
         # $2,200/mo earned: SSI countable = (2,200 - 20 - 65) / 2 = 1,057.50
         # > 994 FBR -> federal SSI = 0, but SSP standard is higher:
-        # SSP: (1,362.81 - 0 - 1,057.50) x 12 = 305.31 x 12 = 3,663.72.
-        ca_state_supplement: 3_663.72
+        # SSP: (1,233.94 - 0 - 1,057.50) x 12 = 176.44 x 12 = 2,117.28
+        # (no food allowance, WIC 12200(e)).
+        ca_state_supplement: 2_117.28
 - name: ca_state_supplement_resources_above_limit_ineligible (ca)
   period: 2026
   absolute_error_margin: 0.1

🤖 Posted by Claude Code

PavelMakarchuk and others added 2 commits October 27, 2026 18:06
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ance

With living_arrangements_allow_for_food_preparation defaulting to true,
an aged California SSI/SSP recipient who does not report a living
arrangement without cooking facilities gets the independent-living
standard, not the restaurant meals allowance (WIC 12200(e)). Three
non-partner tests relied on the old default.

- snap_unearned_income_state_ssi_supplements.yaml: the two California
  cases have no sign of a home without cooking facilities, so update
  ca_state_supplement to 239.94 (1,233.94 - 994), SNAP unearned income
  to 1,233.94 and SNAP to 35, with the calculation in comments.
- fy2027_cola.yaml: the California case tests the published FY2027
  minimum allotment. At $14,000 of Social Security the household got an
  SSP and, under the regular standard, SNAP of $26 and $38, above the
  minimum. Raise the income to $17,000, which is above both California
  aged standards plus the $20 disregard, so no SSI or SSP is paid and
  the case again gets the $24 and $25 minimums whatever the input says.
- test_social_security_current_law.py: the raw_core_dataset probe route
  set no state, so its 2026 household was in the default state (CA) and
  household_net_income@2026 included the California SSP. The
  differential compares with pinned pre-feature main 8986e05, so the
  default change showed as a $1,489.44 mismatch (SSP -$1,546.44, SNAP
  +$57). Put the raw dataset household in Texas in 2024 and 2026, as
  situation() does; state_code has a formula, so a 2024 input alone does
  not reach 2026.

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

Copy link
Copy Markdown
Collaborator Author

CI follow-up

The last run had three failures outside the partner fixtures. All three came from the new living_arrangements_allow_for_food_preparation = True default: each one passes on main and fails on this branch. The three partner cases in analytics_coverage/edge_cases/state/ca/state_supplement.yaml are still unchanged and still wait for partner approval.

gov/usda/snap/income/snap_unearned_income_state_ssi_supplements.yaml (2 cases). The two California cases expected the restaurant meals allowance (1,233.94 + 128.87 - 994). Nothing in either household points to a home without cooking facilities, so the expected values now follow WIC 12200(e):

  • ca_state_supplement is 239.94 (1,233.94 - 994).
  • snap_unearned_income is 1,233.94.
  • For the one-person case, snap is 35: 1,233.94 - 209 = 1,024.94; shelter deduction 663 - 512.47 = 150.53; net income 874.41, rounded to 874; 30% = 262.20, rounded up to 263; 298 - 263 = 35.

The supplement is still counted as SNAP unearned income, which is what these cases test.

gov/usda/snap/fy2027_cola.yaml, "Published FY2027 minimum determines California SNAP benefits from October through December". At $14,000 of Social Security, this household got a California SSP. Under the independent-living standard, its SNAP is $26 in September and $38 from October, so it no longer reaches the minimum allotment that the case tests. Updating the expected values would have kept the case but dropped what it checks. Setting the input to false would have claimed the household has no kitchen. The case now uses $17,000 instead. Less the $20 disregard, $1,396.67 a month is above both California aged standards ($1,233.94, and $1,362.81 with the allowance), so no SSI or SSP is paid. The result does not depend on the input, and SNAP is again $24 in September and $25 from October through December (the calculation is in the comments).

tests/microsimulation/test_social_security_current_law.py::test_legacy_public_ingress_matches_unmodified_main[raw_core_dataset]. This differential runs the same probe against this checkout and against the pinned pre-feature main 8986e05, and it requires every route to match exactly. Its only allowance for differences is the Social Security stale-cache routes in test_intended_difference_from_main_uses_fresh_live_value. The raw_core_dataset route built its household with no state. state_code falls back to CA, so the 70-year-old with $12,000 of Social Security got a California SSP in 2026. Under the new default, household_net_income@2026 is $16,045.28 instead of $17,534.72: the SSP falls by $1,546.44 (12 × 128.87) and SNAP rises by $57. These are the exact values in the CI log.

The fix puts the raw dataset household (the shared columns dict) in Texas for 2024 and 2026, as situation() already does for every other route. state_code has a formula, so a 2024 input alone leaves 2026 in CA. The same dict is also the base for the dataset-builder routes and the subsample route. Their 2026 households were also in the default state; they now match the Texas setting their 2024 inputs already used. No comparison was removed. Both probes still run the same code.

Local results (Python 3.11, Core 3.33.4):

  • Differential: 1 failed, 81 passed on the branch before the fix (the same route and values as CI); 82 passed on main; 82 passed with the fix (74 routes, 1,097 arrays).
  • Baseline YAML: gov/usda/snap 1,245 passed; gov/ssa 389 passed (YAML only, because revenue/test_tob_revenue.py needs hypothesis, which is not installed locally); gov/states/ca 955 passed; household 718 passed.

Head: 6f92ff7921 (with origin/main merged in 129b46e69d).

🤖 Posted by Claude Code

@PavelMakarchuk

Copy link
Copy Markdown
Collaborator Author

@hua7450 — when you have a moment: this PR needs your answers to the three partner-test questions in this comment before the three partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml cases can be edited (or kept by setting the input to false). Every other check is green after the CI follow-up. Two of your PRs, #10379 and #10240, have CAPI cases that rely on the old default; the PR body lists them.

🤖 Posted by Claude Code

@hua7450 hua7450 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.

Approving. I checked the change against WIC 12200(e), POMS SI SF01415.140 and the January 2025 California amounts in POMS SI 01415.057. A default of true matches the common case (code A: independent living with cooking facilities, or a living arrangement that provides meals).

Partner contract tests: yes to all three questions.

  1. Yes, I'm sure: please add your proposed edit to partners/analytics_coverage/edge_cases/state/ca/state_supplement.yaml, updating the three expected values rather than setting the input to false.
  2. Yes, a team member has been notified.
  3. Yes, the API partner has been notified.

Per the partner AGENTS.md, I'll approve again once the head contains that edit.

Nit (optional): the two new cases that set the input to false ("2025 aged individual whose living arrangement prevents food preparation gets the restaurant meals allowance" and the couple case) pass on main and cover the same classes as the 2026 "without cooking facilities" cases already in integration.yaml, so they could be dropped.

PavelMakarchuk and others added 6 commits October 30, 2026 08:54
…into fix-10296-ca-ssp-meal-allowance-default
…efault

The three aged California cases do not describe a household without a
kitchen, so they now get the regular SSI/SSP standard: 2,879.28,
7,293.96 and 2,117.28 for 2026. The partner gate was confirmed by
hua7450 (2026-10-29) and Pavel (2026-10-30).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR 10379 (now on main) added CAPI Case 5, which relied on the old default
of no food preparation and so expected the no-cooking food allowance.
With living arrangements now allowing food preparation by default, Case 5
gets the disabled individual standard alone: 1,233.94 x 12 = 14,807.28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The note from PR 10379 said the input had no default, so every aged or
disabled person got the no-cooking allowance. The input now defaults to
true, so the allowance applies only when the input is set to false.

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

Copy link
Copy Markdown
Collaborator Author

@hua7450, a heads-up on #10379, which merged first. Its ca_capi.yaml "Case 5, integration test, permanent resident without 40 SSI quarters" used the old default of no food preparation. On main with this PR, it gives 14,807.28 (1,233.94 × 12) instead of 16,353.72.

New head 30b0a6a7c2:

  • 83cc33f3db (with 8d8864a23f) merges main at 926ed24e69.
  • f4eeeed87a updates Case 5 to 14,807.28 and its comment.
  • 30b0a6a7c2 updates the NOTE in _ca_capi_ssi_ssp_standard.py. It said that the input had no default, so every aged or disabled person got the no-cooking allowance.

No other CAPI case changes; they set the input explicitly. Locally, gov/states/ca/cdss passes (452). The partner file is unchanged since c0b77938e1. I will merge when CI is green.

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.

California SSP: every aged or disabled recipient gets the restaurant-meal allowance by default

2 participants