Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/tx-ceap-categorical-receipt.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Key categorical eligibility and receipt checks on calculated benefits: TX CEAP (42 USC 8624(b)(2)(A)), the Medicaid community engagement TANF pass-through, the SNAP work registration TANF exemption (7 CFR 273.7(b)(1)(iii)), and the Oklahoma sales tax relief credit TANF exclusion.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
spm_units:
spm_unit:
members: [person1]
is_tanf_enrolled: true
tanf: 100
meets_tanf_work_requirements: true
households:
household:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
spm_units:
spm_unit:
members: [head, child]
is_tanf_enrolled: true
tanf: 1_200
households:
household:
members: [head, child]
Expand All @@ -58,7 +58,7 @@
# Actual TANF recipients excluded (TANF includes sales tax relief)
ok_stc: 0

- name: OK STC - 2025 - modeled-TANF-eligible family still gets credit
- name: OK STC - 2025 - family not receiving TANF still gets credit
period: 2025
input:
people:
Expand All @@ -78,14 +78,15 @@
spm_units:
spm_unit:
members: [head, spouse, child1, child2, child3, child4]
# The family does not actually receive TANF; zero out the modeled
# amount, as an API user who knows actual receipt would.
tanf: 0
households:
household:
members: [head, spouse, child1, child2, child3, child4]
state_code: OK
output:
# Family is not enrolled in TANF (is_tanf_enrolled defaults to false),
# so the credit applies even though the model would impute TANF
# eligibility. 6 exemptions * $40 = $240. See policyengine-taxsim#988.
# 6 exemptions * $40 = $240. See policyengine-taxsim#988.
ok_stc: 240

# 2025 Sales Tax Credit Tests
Expand Down Expand Up @@ -219,3 +220,29 @@
# elderly $50,000 limit and restoring the $40-per-person credit.
ok_gross_income: 38_565.84
ok_stc: 80

- name: TANF recipients are excluded from the credit.
period: 2024
absolute_error_margin: 0.01
input:
people:
person1:
age: 30
employment_income: 15_000
person2:
age: 5
is_tax_unit_dependent: true
tax_units:
tax_unit:
members: [person1, person2]
spm_units:
spm_unit:
members: [person1, person2]
tanf: 1_200
households:
household:
members: [person1, person2]
state_code: OK
output:
# Income qualifies under Pathway 1, but TANF receipt excludes the unit.
ok_stc: 0
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
employment_income: 60_000
spm_unit_size: 4
state_code: TX
is_snap_eligible: false
# Isolate the income pathway: BBCE can make these incomes SNAP-positive.
snap: 0
output:
tx_ceap_eligible: false

Expand Down Expand Up @@ -60,17 +61,47 @@
employment_income: 50_000
spm_unit_size: 4
state_code: TX
is_snap_eligible: false
# Isolate the income pathway: BBCE makes this income SNAP-positive.
snap: 0
output:
tx_ceap_eligible: false

- name: Case 7, SNAP-eligible household above income limit is categorically eligible.
- name: Case 7, household receiving SNAP above the income limit is categorically eligible.
absolute_error_margin: 0.1
period: 2024
input:
employment_income: 80_000
spm_unit_size: 1
state_code: TX
is_snap_eligible: true
snap: 2_400
output:
tx_ceap_eligible: true

- name: Case 8, household receiving TANF above the income limit is categorically eligible.
period: 2024
input:
employment_income: 80_000
spm_unit_size: 1
state_code: TX
tanf: 1_200
output:
tx_ceap_eligible: true

- name: Case 9, household with a member receiving SSI above the income limit is categorically eligible.
period: 2024
input:
people:
person1:
employment_income: 80_000
ssi: 0
person2:
ssi: 9_000
spm_units:
spm_unit:
members: [person1, person2]
households:
household:
members: [person1, person2]
state_code: TX
output:
tx_ceap_eligible: true
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@

# --- (iii) Subject to and complying with TANF work requirements ---

- name: Case 9, TANF enrollee complying with TANF work requirements is exempt.
- name: Case 9, TANF recipient complying with TANF work requirements is exempt.
period: 2026-01
input:
people:
Expand All @@ -128,11 +128,11 @@
spm_units:
spm_unit:
members: [person1]
is_tanf_enrolled: true
tanf: 100
output:
is_snap_work_registration_exempt_non_age: true

- name: Case 10, complying with TANF work requirements but not enrolled in TANF is not exempt.
- name: Case 10, complying with TANF work requirements but not receiving TANF is not exempt.
period: 2026-01
input:
people:
Expand All @@ -143,11 +143,11 @@
spm_units:
spm_unit:
members: [person1]
is_tanf_enrolled: false
tanf: 0
output:
is_snap_work_registration_exempt_non_age: false

- name: Case 11, TANF enrollee not complying with TANF work requirements is not exempt.
- name: Case 11, TANF recipient not complying with TANF work requirements is not exempt.
period: 2026-01
input:
people:
Expand All @@ -158,7 +158,7 @@
spm_units:
spm_unit:
members: [person1]
is_tanf_enrolled: true
tanf: 100
output:
is_snap_work_registration_exempt_non_age: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class medicaid_community_engagement_pass_through_eligible(Variable):
def formula(person, period, parameters):
snap_work = parameters(period).gov.usda.snap.work_requirements
snap = person.spm_unit("snap", period) > 0
tanf = person.spm_unit("is_tanf_enrolled", period)
tanf = person.spm_unit("tanf", period) > 0

age = person("monthly_age", period)
# Cast to bool: single_amount bool brackets return int (0/1), which
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,9 @@ class ok_stc(Variable):
def formula(tax_unit, period, parameters):
# For details, see Form 538-S in the 511 packets referenced above
p = parameters(period).gov.states.ok.tax.income.credits.sales_tax
# Exclusion: TANF recipients are not eligible. Use actual enrollment
# (is_tanf_enrolled) rather than the modeled ok_tanf benefit, so that
# tax filers who are not receiving TANF still qualify even when the
# model would impute TANF eligibility for them.
tanf_ineligible = add(tax_unit, period, ["is_tanf_enrolled"]) > 0
# Exclusion: TANF recipients are not eligible, keyed on the
# calculated tanf benefit.
tanf_ineligible = add(tax_unit, period, ["tanf"]) > 0
# Get gross household income for eligibility tests
income = tax_unit("ok_gross_income", period)
# Pathway 1: Low income (gross income <= $20,000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ def formula(spm_unit, period, parameters):
income_limit = max_(fpg_limit, smi_limit)
income_eligible = income <= income_limit

# Categorical eligibility per 42 USC 8624(b)(2)(A)
# and FY 2024 State Plan Section 1.4
tanf = spm_unit("is_tanf_enrolled", period)
snap = spm_unit("is_snap_eligible", period)
person = spm_unit.members
ssi = spm_unit.any(person("is_ssi_eligible", period))
# Categorical eligibility per 42 USC 8624(b)(2)(A) and FY 2024
# State Plan Section 1.4: households where a member receives
# TANF, SNAP, or SSI.
tanf = spm_unit("tanf", period) > 0
snap = spm_unit("snap", period) > 0
ssi = add(spm_unit, period, ["ssi"]) > 0
categorically_eligible = tanf | snap | ssi

return income_eligible | categorically_eligible
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ def formula(person, period, parameters):
# (ii) Physically or mentally unfit for employment
is_disabled = person("is_disabled", period)
# (iii) Subject to and complying with TANF work requirements.
# TANF enrollment is an existing SPM-unit input; person-level
# compliance is a documented input the data layer may not yet
# populate (PolicyEngine/populace#244). We gate on enrollment
# because a person cannot be subject to TANF work requirements
# without receiving TANF.
complying_with_tanf_work_requirements = person.spm_unit(
"is_tanf_enrolled", period
# Person-level compliance is a documented input the data layer
# may not yet populate (PolicyEngine/populace#244). We gate on
# calculated TANF receipt because a person cannot be subject to
# TANF work requirements without receiving TANF.
complying_with_tanf_work_requirements = (
person.spm_unit("tanf", period) > 0
) & person("is_complying_with_tanf_work_requirements", period)
# (iv) Responsible for care of dependent child under 6
is_dependent = person("is_tax_unit_dependent", period)
Expand Down
Loading