Plan: Program-Specific AU Composition Engine
On this page
Status
| Step | Description | Status |
|---|---|---|
1 |
Define AU composition types and traits in canopy-common |
Done (2026-04-09) — AuMemberStatus (7 variants), IncomeCountMethod, AuMember, AssistanceUnit with au_size/income_counted methods, 7 unit tests |
2 |
Implement SNAP AU composition rules (PAMMS 3205) |
Done (2026-04-09) — compose_snap_au() with IPV/sanction/student/ABAWD/felon/foster rules, 5 unit tests |
3 |
Implement TANF AU composition rules (PAMMS 1205) |
Done (2026-04-09) — compose_tanf_au() with SSI/IV-E/deeming/penalty/SFU rules, 5 unit tests |
4 |
Implement Medicaid MAGI budget group rules (PAMMS 2610) |
Done (2026-04-09) — compose_magi_budget_group() with tax filer/non-filer paths, SSI income exclusion, 6 unit tests |
5 |
Implement Medicaid non-MAGI budget group rules (PAMMS 2620) |
Done (2026-04-09) — compose_non_magi_budget_group() with Individual/Couple/Family types |
6 |
Wire AU composition into each program service’s determine handler |
Done (2026-04-09) — orchestrator passes MemberContext (person_id, relationship, age, disability_status) to program services via ApplicationContext.members field |
Dependency: Plans 2, 3, 4 (program services must exist)
Branch: feature/au-composition-engine
Context
PAMMS revealed that household composition for eligibility purposes differs significantly by program. Currently, canopy-persons manages physical household data (who lives together), but the legal Assistance Unit (AU) — who is included for eligibility purposes, whose income counts, and how — is determined differently by each program.
This is not an academic distinction. It directly affects benefit calculations: a person excluded from the SNAP AU but whose income is counted in full (IPV-disqualified per PAMMS 3625) produces a different result than a person whose income is pro-rated (enumeration-sanctioned per PAMMS 3620). TANF has six types of income deeming from non-AU members (PAMMS 1620-1632). Medicaid MAGI uses tax filing relationships rather than physical household composition (PAMMS 2610).
Design
AU Composition Types
/// A person's status within an Assistance Unit.
pub enum AuMemberStatus {
/// Full member — included in AU size, income and resources counted
Included,
/// Excluded — not in AU, income/resources NOT counted (e.g., SSI recipient in TANF)
Excluded,
/// Penalized — still SFU member, income counted, but needs excluded from AU size
/// (e.g., immunization failure in TANF per PAMMS 1345)
Penalized { reason: String },
/// Disqualified — IPV disqualified, income/resources counted IN FULL,
/// excluded from AU size (SNAP per PAMMS 3625)
Disqualified { income_treatment: IncomeCountMethod },
/// Sanctioned — enumeration/work sanctioned, income PRO-RATED,
/// excluded from AU size (SNAP per PAMMS 3620/3635)
Sanctioned { income_treatment: IncomeCountMethod },
/// Deemed — not in AU, but income is deemed to AU after surplus calculation
/// (TANF per PAMMS 1620-1632)
Deemed { deemer_type: String },
/// Optional — can be included or excluded at AU's election
/// (e.g., foster children in SNAP per PAMMS 3205)
Optional,
}
pub enum IncomeCountMethod {
/// Count income in full (IPV disqualified, work sanctioned in SNAP)
Full,
/// Pro-rate: divide income equally among all members, exclude sanctioned share
ProRata,
/// Do not count (SSI recipients in Medicaid MAGI BG per PAMMS 2610)
Excluded,
}
Per-Program Composition Rules
SNAP (PAMMS 3205)
Mandatory inclusion: Spouses (including pre-7/1/97 common-law) + parents and children under 22 (bio/adopted/step) + minor children under 18 under parental control.
Excluded: IPV disqualified (income counted in full), enumeration sanctioned (income pro-rated), work sanctioned (income counted in full), ineligible students, ineligible ABAWDs, fleeing felons, certain convicted felons.
Optional: Foster children.
TANF (PAMMS 1205)
Standard Filing Unit: Dependent child + biological/adoptive parents + minor siblings + dependent children of minor parents + pregnant women/minor pregnant women.
Ineligible: Child not deprived, wrong relationship degree, citizenship failure, lump sum period.
Penalized: Enumeration failure, felony conviction, drug felony, fleeing felon, parole violator, prenatal care failure, minor living arrangement failure, school attendance failure, immunization failure. Income/resources still counted.
Excluded: SSI recipients, IV-E foster care, child welfare foster care, relative care subsidy.
Medicaid MAGI (PAMMS 2610)
Tax filer BG: Filer + spouse (if filing jointly) + all claimed dependents + fetuses.
Non-tax filer BG: Individual + spouse + natural/adopted/step children under 19 + siblings under 19 + fetuses.
Special rules: SSI recipients included in BG but income NOT counted. Child tax dependent income excluded if below IRS exemption amount. NCP-claimed children stay in custodial parent’s BG.
Steps
Step 1: Define Types in canopy-common
File: crates/canopy-common/src/au_composition.rs (new)
Define AuMemberStatus, IncomeCountMethod, AuMember, and AssistanceUnit types. The AssistanceUnit struct holds: members with their statuses, AU size (count of included members only), and total household size.
Step 2: SNAP AU Composition
File: services/canopy-snap/src/au_composition.rs (new)
Implement compose_snap_au(household_members: &[HouseholdMember]) → AssistanceUnit. Apply PAMMS 3205 mandatory/excluded/optional rules. Handle edge cases: boarders (PAMMS 3205 — reasonable compensation test), disabled 60+ separate AU option (PAMMS 3205 — other members' income ⇐ 165% FPL).
Step 3: TANF AU Composition
File: services/canopy-tanf/src/au_composition.rs (new)
Implement compose_tanf_au(household_members: &[HouseholdMember]) → AssistanceUnit. Apply PAMMS 1205 SFU rules. Identify deeming relationships (stepparent, ineligible parent, etc.) and mark as AuMemberStatus::Deemed.
Step 4: Medicaid MAGI Budget Group
File: services/canopy-medicaid/src/au_composition.rs (new)
Implement compose_magi_bg(household_members: &[HouseholdMember], tax_filing_status: &TaxFilingStatus) → AssistanceUnit. Two paths: tax filer BG and non-tax filer BG per PAMMS 2610.
Verification
-
Unit tests for each composition function with edge cases (IPV member, sanctioned member, foster child election, two-parent TANF, tax filer vs non-filer Medicaid)
-
Integration tests: same household processed by SNAP, TANF, and Medicaid produces different AU sizes and income totals
-
Regression: existing SNAP/TANF determination tests continue to pass
PAMMS Source References
-
SNAP AU:
dfcs-snap/modules/snap/pages/3205.adoc -
SNAP excluded/sanctioned budgeting:
dfcs-snap/modules/snap/pages/3620.adoc,3625.adoc,3635.adoc -
TANF AU/SFU:
dfcs-tanf/modules/tanf/pages/1205.adoc -
TANF deeming:
dfcs-tanf/modules/tanf/pages/1620.adocthrough1632.adoc -
Medicaid MAGI BG:
dfcs-medicaid/modules/medicaid/pages/2610.adoc -
Medicaid non-MAGI BG:
dfcs-medicaid/modules/medicaid/pages/2620.adoc