Skip to content

Prorate income and expenses of SNAP-ineligible household members (7 CFR 273.11(c))#8892

Merged
hua7450 merged 13 commits into
PolicyEngine:mainfrom
hua7450:snap-ineligible-member-income
Jul 14, 2026
Merged

Prorate income and expenses of SNAP-ineligible household members (7 CFR 273.11(c))#8892
hua7450 merged 13 commits into
PolicyEngine:mainfrom
hua7450:snap-ineligible-member-income

Conversation

@hua7450

@hua7450 hua7450 commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements 7 CFR 273.11(c) and (d): the treatment of income, deductible expenses, and resources of household members who are ineligible for SNAP. Previously the model removed ineligible members from the household size but counted 100% of their income, and prorated only the employment income of work-requirement-failing members.

Addresses #6531; supersedes closed PR #6526.

Regulatory authority

What this implements

Member type Legal treatment How modeled
Ineligible alien, excepted categories of 273.11(c)(3)(i)(A)–(G) (post-OBBBA refugees, asylees, parolees, withholding) (c)(3)(ii): all 53 state agencies elect proration Income counted share = eligible members / household members
Ineligible alien, other statuses (undocumented, DACA, TPS, conditional entrant) (c)(3)(i): state option Prorate (40 states, default); count all (9 states: AZ GU ID IN KS ME MA TN UT); count all for gross test, prorate for net (4 states: AR HI KY NC)
Ineligible student 273.11(d) + 273.1(b)(7): nonhousehold member Income counted share = 0; excluded from proration denominator
Sanctioned under the general work requirements (§273.7) (c)(1): income and expenses count in their entirety Income counted share = 1; modeled noncompliance is treated as a state-imposed disqualification, consistent with exclusion from snap_unit_size (documented assumption)
ABAWD time-limit ineligible (§273.24; meets the general requirements) (c)(2) proration Income counted share = proration fraction
  • Proration fraction per (c)(2)(ii): divide the member's income evenly among household members (excluding ineligible students); count all but the ineligible members' shares (plural reading: sanctioned and count-all members' slices are also excluded).
  • The 20% earned income deduction automatically applies to the prorated earnings (deduction is computed from the prorated snap_earned_income).
  • Expenses per (c)(2)(iii): child support scales by the payer's counted share (payer is known); shelter and dependent care scale by a unit-level counted share equal to the mean of members' counted shares, under a stated per-capita payment assumption. Standard utility allowances are not prorated — they are not expenses "paid by or billed to" an ineligible member. Sanctioned members' expenses count in full per (c)(1); medical expenses of students and prorated members are excluded.
  • Self-employment: unit-level net SE income is attributed to members in proportion to their gross SE income, with each enterprise's loss floored at zero — 273.11(a)(2)(ii) offsets losses against other income only for farming operations, and the modeled SE sources are non-farm. The attribution ratio is bounded to [0, 1].
  • Excluded members do not confer household-wide elderly/disabled status: the gross-test exemption, the shelter deduction cap waiver, the BBCE HHEOD flag, and the elderly/disabled resource limit all key on the new has_snap_elderly_disabled_member (7 CFR 271.2 defines an elderly or disabled member as a member of a household).
  • Resources: ineligible members' resources continue to count in their entirety (273.11(c)(1)(i), (c)(2)(i), (c)(3)), but the members are excluded when comparing resources with the resource limits ((c)(1)(ii)(D), (c)(2)(iv)(D)). Nonhousehold members' (ineligible students') resources are not carved out because assets are modeled at the unit level.
  • Household size treatment (snap_unit_size) was already correct and is unchanged (exclusion mask extracted into is_snap_excluded_member).
  • CA's OBBBA delay (ACL 25-92, to 2026-04-01) carries through automatically via is_snap_immigration_status_eligible.

Structural changes

  • snap_earned_income_person becomes a true Person-level variable (was SPMUnit with a unit-level defined_for gate). This fixes a pre-existing bug: an excluded K-12 child earner's income was counted whenever any countable earner existed in the unit.
  • New snap_unearned_income_person; unearned sources split into sources/unearned.yaml (person-level) + sources/unearned_spm_unit.yaml (tanf stays fully counted at the unit level — cannot be attributed to a member). sources/earned.yaml now lists person-level employment income only; new snap_gross_self_employment_income_person (floored per enterprise) feeds both the SE expense deduction and the unit-net attribution in snap_earned_income/snap_gross_test_income.
  • New snap_gross_test_income mirrors snap_gross_income's composition with the full-count share substituted, and returns snap_gross_income exactly for households without full-count aliens. New snap_gross_test_income_fpg_ratio feeds both meets_snap_gross_income_test (ratio-form comparison) and the TANF non-cash (BBCE) gross screen, so the hybrid states' full-count election cannot be bypassed via categorical eligibility.
  • New is_snap_excluded_member (273.11(c)/(d) exclusion mask, shared by snap_unit_size, has_snap_elderly_disabled_member, and the asset test limit selection).
  • snap_work_requirement_income_proration_fraction removed; replaced by snap_prorated_income_fraction + snap_income_counted_share (only internal consumers).

Behavior changes (all intentional)

  1. Ineligible aliens' income is prorated (or fully counted / hybrid per state election) instead of 100% counted → higher benefits for mixed-status households in prorating states.
  2. Ineligible students' income is excluded entirely (was fully counted).
  3. Work-requirement failures split by regime: general-requirement failures now count income in full per (c)(1) (was prorated employment income); ABAWD-only failures are prorated across all income types per (c)(2).
  4. Excluded child earner leak fixed (see above).
  5. Deductible expenses are reduced by ineligible members' shares (was: full deductions), except standard utility allowances, which stay fully counted.
  6. Non-farm self-employment losses no longer offset other members' income (was: netted at the unit level).
  7. An excluded elderly/disabled member no longer exempts the household from the gross income test, uncaps the shelter deduction, raises the BBCE gross limit, or confers the elderly/disabled resource limit.

Not modeled (by design)

What Authority Why
IPV / felony / fleeing felon / SSN-refusal / child support disqualifications 273.11(c)(1)–(2) No model inputs for these statuses
Adjudicated-sanction distinction for work requirements 273.7 / 273.11(c)(1) Sanctions require state action; the model treats modeled noncompliance as a disqualification (pre-existing snap_unit_size convention, now documented in is_snap_prorated_income_member)
Count-none-with-benefit-cap option for excepted-category aliens 273.11(c)(3)(ii)(B) Zero state agencies elect it (State Options Report 16th ed.)
Sponsor deeming exclusion 273.11(c)(3)(v) Sponsor deeming is not modeled at all
ABAWD 3-months-in-36 clock 273.24 Existing instant-ineligibility approximation retained
Nonhousehold members' resource carve-out 273.11(d) Assets are modeled at the unit level; we do not track person-level assets

⚠️ Partner-facing impact — contract tests updated

The partner contract tests under tests/policy/baseline/partners/ are updated in this PR (team and partner notified). All changes raise SNAP for mixed-status households; LPR cases are unchanged, and signatures/, my_friend_ben, and impactica are unaffected (no mixed-status households). The headline for partners is the amplifi eligibility flip: that household was previously denied outright and now receives a benefit.

Case (annual SNAP) Old New
refugee head — TX (edge_cases/.../snap/federal.yaml) 2,546.82 4,147.92
undocumented head — TX (federal.yaml) 2,546.82 4,147.92
refugee CFAP transition — CA (ca.yaml) 999.36 2,162.22
undocumented + CalWORKs — CA (ca.yaml) 1,006.02 3,002.22
amplifi 2025 (undocumented parent, $48k, 2 citizen kids, CA) 0 / ineligible 2,114.10 / eligible
amplifi 2026 (same household) 0 / ineligible 2,360.52 / eligible
LPR head — all states unchanged

New partner edge cases pinning the state elections: MA count-all (3,815.82 — full counting yields less than TX's prorated 4,147.92 despite MA's SUA), NC hybrid gross-test denial at $48k (full income fails the gross and BBCE screens where prorated income would pass) and prorated benefit at $20k (4,147.92, matching TX), and an ineligible student whose excluded earnings are the only reason the household passes the gross test (287.68 minimum allotment).

Verification TODO

  • Verify state option elections for earlier years (15th edition backdating); current lists dated 2018-01-01 from the 16th edition (elections as of Oct 1, 2023)
  • Check whether enhanced CPS imputes non-citizen immigration_status (microsim aggregate impact) — default is CITIZEN
  • Decide conditional-entrant classification: this PR follows the literal 273.11(c)(3)(i)(A)–(G) list, which omits conditional entrants from the excepted categories
  • Decide whether has_all_usda_elderly_disabled (the AL/WV requires-all BBCE branch) should also exclude ineligible members

Test plan

  • Direct unit tests for every new formula variable: counted shares, proration fraction, gross-test income (incl. hybrid-state self-employment and mixed-sign loss cases), state-discretion alien statuses (UNDOCUMENTED, DACA, TPS, CONDITIONAL_ENTRANT), excluded-member mask, elderly/disabled unit membership, per-enterprise gross self-employment flooring, and countable child support
  • 17-case integration test: prorating/count-all/hybrid states, student exclusion, CA delay, expense and SUA treatment, SE attribution and loss flooring, excluded-elderly gross test, unearned and unit-level TANF counting, all-ineligible household
  • Behavior tests for the medical expense exclusion, the asset-test limit conferral, and the NC BBCE gross-screen divergence for full-count aliens
  • Boundary tests with real excluded members: shelter cap, asset limits, CA OBBBA-delay lapse (2027) and pre-OBBBA baseline (2025), combined student/prorated/sanctioned household, all-ineligible multi-member unit
  • SNAP + TANF non-cash folders pass locally (492 tests); partner SNAP edge cases, signatures, and fixtures pass locally (134 tests)
  • CI passes

🤖 Generated with Claude Code

…11(c)

Implements the treatment of income and deductible expenses of ineligible
household members: proration for ineligible aliens (with state count-all
and gross-test-only options), full exclusion of ineligible students'
income under 273.11(d), and person-level income counting that also fixes
the excluded child earner leak.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (f9e58e7) to head (6c16db0).
⚠️ Report is 49 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #8892    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            3        17    +14     
  Lines           55       258   +203     
==========================================
+ Hits            55       258   +203     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hua7450 and others added 10 commits July 4, 2026 19:54
…rence

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… unit level

person.spm_unit projections inside the person-level earned income formula
produced MicroSeries with mismatched weights under Microsimulation. Keep
snap_earned_income_person as a pure person-level adds variable and perform
the self-employment attribution inside the SPM unit formulas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… expense shares, and gross test

- Split 7 CFR 273.11(c)(1)/(c)(2): members sanctioned under the general
  work requirements have income and expenses counted in full; only ABAWD
  time-limit-ineligible members are prorated, and count-all state
  elections govern aliens who also fail work requirements.
- Attribute unit-level self-employment income by signed gross SE with
  the countable-earner mask in the numerator only, so excluded earners'
  SE income is dropped rather than reattributed and losses offset other
  income at the member's counted share.
- Prorate shared expenses as (n-i)(n+i)/(size*n) per the 273.11(c)(2)(iii)
  even-payment reading.
- Count full-count aliens' child support in full under the gross test in
  states deducting child support from gross income.
- Revert snap_gross_income_fpg_ratio to plain gross income so the TANF
  BBCE test is unaffected; the SNAP gross test reads snap_gross_test_income.
- Restore parameter paths gov.usda.snap.income.sources.earned/.unearned,
  add unit metadata to share variables, extract shared
  is_snap_state_discretion_ineligible_alien, and add self-employment and
  work-requirement-regime test coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…atus conferral, and gross-test consistency

- Floor non-farm self-employment losses at zero per 7 CFR
  273.11(a)(2)(iii) (only farm losses offset other income), bounding
  the unit-net SE attribution ratio to [0, 1] and preventing one
  member's loss from wiping out another's income.
- Rebuild snap_gross_test_income as a direct mirror of
  snap_gross_income with the full-count share substituted, returning
  snap_gross_income exactly for households without full-count aliens.
- Route both the SNAP gross income test and the BBCE/TANF non-cash
  gross screen through a new snap_gross_test_income_fpg_ratio so
  hybrid states' full-count election cannot be bypassed via
  categorical eligibility; restore the ratio-form comparison.
- Rewrite snap_expense_counted_share as the mean of members' income
  counted shares, applying one reading of 273.11(c)(2) across income,
  expense, and child support proration; stop prorating standard
  utility allowances, which are not expenses paid by or billed to an
  ineligible member.
- Add is_snap_excluded_member and has_snap_elderly_disabled_member so
  excluded members no longer confer household-wide elderly/disabled
  status for the gross test, shelter cap, and BBCE screens.
- Reuse snap_gross_self_employment_income_person in the SE expense
  deduction; document the 273.11(c)(1)/(c)(2) work-requirement split;
  fix USC-vs-CFR citation titles; add hybrid-state SE, sanctioned-
  member expense share, and elderly-status tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…into snap-ineligible-member-income

# Conflicts:
#	policyengine_us/variables/gov/usda/snap/income/deductions/snap_dependent_care_deduction.py
Compute the share as one minus the uncounted portions of actual
members' per capita payments, so a spm_unit_size input exceeding the
modeled member count leaves expenses fully counted. Give the second
member explicit work-requirement inputs in the counted-share tests,
since providing the variables for one member makes them input arrays
with false defaults for the rest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, and direct unit tests

- Correct the farm-loss-offset citation to 7 CFR 273.11(a)(2)(ii) in the
  gross self-employment variable, changelog, and test comments.
- Select the SNAP resource limit with has_snap_elderly_disabled_member:
  ineligible members' resources continue to count in their entirety
  (273.11(c)(1)(i), (c)(2)(i), (c)(3)) but the members are excluded when
  comparing resources with the resource limits ((c)(1)(ii)(D),
  (c)(2)(iv)(D)), so an excluded elderly or disabled member no longer
  confers the higher limit.
- Add direct unit tests for is_snap_state_discretion_ineligible_alien
  (covering DACA, TPS, and conditional entrants), is_snap_excluded_member,
  has_snap_elderly_disabled_member, snap_gross_self_employment_income_person
  (per-enterprise loss flooring), and snap_countable_child_support_expense.
- Add behavior tests: unprorated standard utility allowance, medical
  expense exclusion for prorated members, unearned income proration,
  unit-level TANF full counting, and the NC BBCE gross-screen divergence
  for full-count aliens.
- Read YEAR-defined booleans and counts with period.this_year in the new
  MONTH formulas; reground the elderly/disabled conferral on the 7 CFR
  271.2 member definition; replace the self-employment expense deduction
  blog reference with 273.9(c)(9) and 273.11(b); regroup unearned source
  comments under their 273.9(b)(2) subsections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hua7450 hua7450 marked this pull request as ready for review July 14, 2026 18:04
@hua7450 hua7450 requested a review from daphnehanse11 July 14, 2026 18:05
@daphnehanse11

Copy link
Copy Markdown
Collaborator

PR review — regulatory, reference, code-pattern, and test-coverage validation

Four-validator review of the full diff (56 files) from a clean checkout, with the regulation researched independently before reading the code. No critical issues found. The implementation is a faithful encoding of 7 CFR 273.11(c)/(d), including the subtle points: the plural-possessive proration reading of (c)(2)(ii) was verified against the verbatim CFR text, the state-election lists match the SNAP State Options Report 16th ed. p. 15 exactly (9 count-all, 4 hybrid, 40 prorate), the (c)(1) full-count vs (c)(2) prorate split for work requirements is correct, and the self-employment attribution ratio is genuinely bounded to [0, 1] with safe zero-denominator handling.

🔴 Critical (must fix)

None.

🟡 Should address

  1. Missing end-to-end test: shelter cap with a real excluded elderly member. snap_excess_shelter_expense_deduction.py now reads has_snap_elderly_disabled_member, and the PR claims excluded members no longer waive the shelter cap — but snap_excess_shelter_expense_deduction.yaml only renames the directly-set flag. Add a case with an excluded (e.g., undocumented) elderly member and shelter costs above the cap, asserting the deduction is now capped.
  2. Missing end-to-end test: asset limit with a real excluded elderly member. Same pattern in meets_snap_asset_test.yaml: every case sets has_snap_elderly_disabled_member directly. Add a case with a real excluded elderly member and assets between the standard and elderly/disabled limits, asserting the test now fails.
  3. CA OBBBA-delay boundary tested on one side only. Integration Case 8 tests CA at 2026-01 (before the ACL 25-92 delay date). Add a post-delay companion (e.g., period: 2027) showing the CA refugee becomes a prorated excluded member, matching the TX treatment.
  4. Stale test inputs referencing the retired flag. tests/policy/baseline/gov/usda/snap/snap_net_income.yaml (lines 21, 48) and snap_expected_contribution.yaml (lines 22, 53) still pass has_usda_elderly_disabled as an input; the deduction path now reads has_snap_elderly_disabled_member, so these inputs are dead (outputs unaffected only because the deduction is also supplied directly). Rename or remove.
  5. 2018-01-01 backdating of the state-election parameters is uncorroborated — the sole source (16th ed. State Options Report) documents elections as of Oct 1, 2023. The YAML comment already discloses this and it's in the PR's own Verification TODO; confirming it should be resolved (15th-edition check) before merge.

🟢 Suggestions

  1. Medical-expense exclusion citation: the treatment (full exclusion of prorated members' medical expenses) is correct, but 273.11(c)(2)(iii) doesn't list medical — the correct basis is 273.9(d)(3)/271.2 (deduction limited to elderly/disabled household members). Update the comment/test citation; no behavior change needed.
  2. SUA non-proration is textually defensible ((c)(2)(iii) prorates only expenses "paid by or billed to" the ineligible member) but not the only reading; the in-code documentation is good — flagging as a reviewed judgment call.
  3. snap_gross_income_fpg_ratio is now orphaned — both consumers switched to snap_gross_test_income_fpg_ratio; only its own test remains. Remove or confirm intentional retention as API-facing.
  4. snap_gross_test_income_fpg_ratio has no dedicated unit test (and no reference field); a small direct test would match the coverage given to every other new variable.
  5. Period-usage consistency: snap_excess_medical_expense_deduction.py reads is_usda_elderly/is_usda_disabled with period while the new has_snap_elderly_disabled_member uses period.this_year; since the PR touches this file, aligning them would remove the inconsistency (pre-existing, no behavior impact).
  6. Nice-to-have test cases: one household combining all three member types (ineligible student + prorated alien + sanctioned member) to exercise the proration numerator/denominator interaction; a student-only household (true zero-denominator branch of snap_prorated_income_fraction); a multi-person all-ineligible household; a pre-OBBBA (2025) refugee baseline case within this suite.

Validation summary

Check Result
Regulatory accuracy 0 critical, 0 should-fix, 3 documentation nuances
Reference quality 0 critical; state lists verified against State Options Report 16th ed. p. 15 (9/9 count-all, 4/4 hybrid); all CFR anchors correct
Code patterns 0 critical; no dropped income sources, no circular deps, no dangling references to the removed variable; latent snap_unit_size period bug fixed
Test coverage Strong (17-case integration + per-variable unit tests); 3 should-fix gaps above
CI 29 pass, 1 expected fail (partner contract tests, documented), 3 pending at review time

Verified correct (highlights)

  • Proration fraction eligible / (household − students) matches the plural "ineligible members' share" in (c)(2)(ii); hand-verified against integration Cases 2/3/11/16.
  • Three-way alien treatment: excepted categories always prorate per (c)(3)(ii); state-discretion statuses (UNDOCUMENTED/DACA/TPS/CONDITIONAL_ENTRANT) follow the (c)(3)(i) election; count-none option correctly omitted (zero electing states).
  • Hybrid-state gross/net split counts earnings, unearned, self-employment, and deductible child support in full on the gross side only, and snap_gross_test_income returns snap_gross_income identically when no full-count alien is present; BBCE screen wired to the same concept, closing the categorical-eligibility bypass.
  • Sanctioned (c)(1) full count vs ABAWD (c)(2) proration, including the count-all-state override.
  • Non-farm SE losses floored per enterprise per 273.11(a)(2)(ii); attribution drops (not reattributes) non-countable earners' shares, fixing the pre-existing excluded-child-earner leak.
  • Resources counted in full while excluded members don't confer the elderly/disabled limit, per (c)(1)(ii)(D)/(c)(2)(iv)(D).
  • adds-list split drops nothing: tanf moved to the new unit-level list (counted once, unprorated); survivor_benefits/financial_assistance merely reordered.
  • Reference fixes: mislabeled "USC Title 7" titles corrected to CFR; snapscreener.com blog link replaced with CFR citations.

Recommendation: no blocking issues — the should-address items are test hardening and cleanup, well within the scope of the PR's existing pre-merge TODO list.


🤖 Generated with Claude Code /review-pr

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

overall good, claude nits below

… citation

- Add end-to-end tests using real excluded members: shelter deduction
  cap with an excluded elderly member, asset limits on both sides of
  the elderly/disabled threshold, post-delay California refugee
  proration (2027) and pre-OBBBA baseline (2025), a household combining
  a student, prorated alien, and sanctioned member, a multi-member
  all-ineligible unit, and the student-only zero-denominator branch.
- Add a direct unit test for snap_gross_test_income_fpg_ratio; rename
  dead has_usda_elderly_disabled inputs in the net income and expected
  contribution tests.
- Reground the medical expense exclusion on 7 CFR 273.9(d)(3) and 271.2
  and read elderly/disabled status with period.this_year.
- Update partner contract expectations for 273.11(c) proration: TX
  refugee/undocumented cases rise to 4,147.92, CA CFAP and CalWORKs
  cases to 2,162.22 and 3,002.22, and the amplifi household flips from
  ineligible to a 2,114.10 (2025) / 2,360.52 (2026) benefit. Add count-all
  (MA), hybrid gross-test (NC), and student-income edge cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hua7450

hua7450 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review — all should-address items except the backdating research are resolved in b031fe8, and most suggestions are folded in too.

Should address

  1. Shelter cap with a real excluded elderly member — added integration Case 18: an excluded undocumented 70-year-old with $2,000/month housing costs; the deduction now stops at the $744 FY2026 cap ($804.50 uncapped would have applied under the old conferral).
  2. Asset limit with a real excluded elderly member — added two meets_snap_asset_test cases with $4,000 in assets (between the $3,000 standard and $4,500 elderly/disabled limits): an excluded undocumented grandparent fails the test, a citizen grandparent passes.
  3. CA OBBBA-delay boundary — added Case 19 (2027-01): the CA refugee becomes a prorated excluded member once ACL 25-92 lapses (unit size 2, counted shares [2/3, 1, 1], earned income $1,333.33), plus Case 22 as a pre-OBBBA (2025-01) TX baseline where the refugee counts fully.
  4. Stale flag inputs — renamed to has_snap_elderly_disabled_member in snap_net_income.yaml and snap_expected_contribution.yaml.
  5. State-election backdating — remains open in the PR's Verification TODO; the 15th-edition check is planned before merge.

Suggestions

  • Medical-expense citation: regrounded on 273.9(d)(3) + 271.2 in the formula comment and the test comment (agreed that (c)(2)(iii) does not list medical). The elderly/disabled reads in that formula now use period.this_year as well.
  • snap_gross_test_income_fpg_ratio: added a direct unit test mirroring the sibling ratio test.
  • snap_gross_income_fpg_ratio: retained deliberately as API-facing; no in-model callers is expected.
  • SUA non-proration: keeping the documented reading — (c)(2)(iii) prorates expenses "paid by or billed to" the ineligible member, which a standard allowance is not.
  • Nice-to-have cases: all four added — Case 20 combines a student, a prorated alien, and a sanctioned member in one household (fraction 2/4, shares [0, 0.5, 1, 1, 1], expense share 0.7); Case 21 covers a two-adult all-ineligible unit (size 0, fraction 0, snap 0); the student-only zero-denominator branch is pinned in snap_prorated_income_fraction.yaml Case 4; Case 22 covers the pre-OBBBA refugee baseline.

Partner contract tests

Also updated in the same push (team and partner notified): the TX refugee/undocumented cases rise to 4,147.92, the CA CFAP/CalWORKs cases to 2,162.22 and 3,002.22, and the amplifi household flips from ineligible to a 2,114.10 (2025) / 2,360.52 (2026) benefit — that eligibility flip is the headline for the partner notification. New edge cases pin the MA count-all election, the NC hybrid gross-test denial and prorated benefit, and the student-income exclusion. signatures/, my_friend_ben, and impactica are unaffected.

Local runs: SNAP + TANF non-cash folders 492/492; partner SNAP edge cases, signatures, and fixtures 134/134.

🤖 Generated with Claude Code

@daphnehanse11

Copy link
Copy Markdown
Collaborator

Re-review of b031fe8 ("Address review: boundary tests, partner contract updates, and medical citation")

Re-reviewed the new commit from a clean checkout, hand-verified the arithmetic in every new test case, and ran all 14 changed test files locally against the PR code: 106/106 pass (36 partner edge-case tests + 70 unit/integration/contract tests), so every committed expected value is confirmed to be what the model produces.

Findings from the previous review — status

Finding Status
Shelter cap with real excluded elderly member ✅ Integration Case 18 — math verified (counted shelter 0.75 × $2,000; uncapped $804.50 → capped at $744)
Asset limit with real excluded elderly member ✅ Two new meets_snap_asset_test cases bracketing the $3,000/$4,500 limits with a real undocumented elderly member
CA OBBBA-delay boundary (post-delay side) ✅ Case 19 (2027-01, share 0.6667, unit size 2)
Stale has_usda_elderly_disabled test inputs ✅ Renamed in snap_net_income.yaml and snap_expected_contribution.yaml
2018-01-01 backdating of state elections ⏳ Still open — remains on the PR's Verification TODO
Medical-expense citation (273.9(d)(3)/271.2) ✅ Fixed in formula comment and test
snap_gross_test_income_fpg_ratio unit test ✅ Added
Period alignment in medical deduction is_usda_elderly/is_usda_disabled now read with period.this_year
Mixed-type household (student + prorated + sanctioned) ✅ Case 20 — shares [0, 0.5, 1, 1, 1], fraction 2/4, expense share 0.7, all hand-verified
Student-only household (zero-denominator branch) snap_prorated_income_fraction Case 4
Multi-person all-ineligible household ✅ Case 21
Pre-OBBBA refugee baseline ✅ Case 22 (2025-01, full count, in-unit)
Orphaned snap_gross_income_fpg_ratio ⏳ Still orphaned (only its own test references it) — remove or confirm intentional retention

The partner contract updates (amplifi, analytics_coverage federal/CA/MA/NC) are also now in, including two well-constructed new NC hybrid-state cases (gross-test full-count denial vs. net-side proration benefit) and a new MA count-all case.

🟡 New should-address items (introduced by this commit)

  1. Stale calculation comments contradict the updated partner values. In tests/policy/baseline/partners/analytics_coverage/edge_cases/federal/nutrition/snap/federal.yaml, lines 805–810 and 872–875: the expected values were updated to 4_147.92, but the comments directly above still describe the pre-PR behavior — "their earnings still count in full (they meet work requirements, so no income proration) … annual = 9 x 208.80 + 3 x 222.54 = 2,546.82." These are the walkthroughs partners read to understand contract values; they now assert the opposite of what the value reflects (2/3 proration). The CA/MA/NC comments were properly rewritten — these two were missed.
  2. The PR body's partner-impact table no longer matches the committed values. Body table: federal/TX refugee & undocumented → 4,517.82; MA undocumented "unchanged at 2,912.22"; CA refugee 2,155.02; CA undocumented 2,608.02. Committed (and locally verified): 4,147.92; a new MA case at 3,815.82; 2,162.22; 3,002.22. The old values in the table (2,912.22) also don't match the files' prior values (2,546.82). The body already flags the table as needing re-confirmation — since partner notification is a stated pre-merge step, please refresh the table from the committed values before sending it. Worth highlighting in that notification: the amplifi CA case flips from ineligible/$0 to eligible ($2,114.10 in 2025, $2,360.52 in 2026), which is an eligibility flip, not just a value change.

Local verification

  • 36/36 pass: partners/analytics_coverage/edge_cases/federal/nutrition/snap/{federal,ca,ma,nc}.yaml
  • 70/70 pass: snap/income/ineligible_members/ (full suite incl. new Cases 18–22), meets_snap_asset_test.yaml, snap_gross_test_income_fpg_ratio.yaml, snap_net_income.yaml, snap_expected_contribution.yaml, partners/amplifi/{2025,2026}.yaml
  • CI on this commit was still running at review time; the previously-failing Household API Partners job should now pass given the contract updates.

Recommendation: unchanged — no blocking issues. Outstanding before merge: the two stale federal.yaml comments, the PR-body table refresh + partner notification, and the two carried-forward TODO items (state-election backdating check, orphaned snap_gross_income_fpg_ratio).


🤖 Generated with Claude Code /review-pr

The TX refugee and undocumented cases' calculation comments still
described full income counting with the pre-proration 2,546.82 math;
rewrite them to walk through the 2/3 prorated share arithmetic that
produces the committed 4,147.92 values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hua7450 hua7450 requested a review from daphnehanse11 July 14, 2026 19:59

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

all review comments addressed, lgtm

@hua7450 hua7450 merged commit 3665130 into PolicyEngine:main Jul 14, 2026
34 checks passed
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