From bd5e958ade2404fbc8a92d1028f19678f730a3c9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 6 Jul 2026 09:02:28 -0400 Subject: [PATCH 1/4] Fix CA AMT double-add of disallowed itemized deductions (#8742) ca_pre_exemption_amti added the full ca_itemized_deductions_pre_limitation on top of ca_taxable_income + ca_amti_adjustments, double-counting property taxes (once in ca_amti_adjustments, once in the full itemized deductions) and incorrectly adding back AMT-allowed deductions like charity and acquisition mortgage interest. This made CA AMTI (and thus CA ordinary tax under the AMT floor) rise with property taxes. Per Schedule P (540) Part I, AMTI (line 19/21) = regular taxable income (line 15) + total adjustments and preferences (line 14) - restored itemized deductions limitation (line 18). Removed the erroneous full-deduction add and added ca_itemized_deductions_limitation (line 18 = pre - post limitation) as a subtraction. Added YAML tests including the issue's reported household. Co-Authored-By: Claude Fable 5 --- changelog.d/misc-accuracy.fixed.md | 1 + .../ca_itemized_deductions_limitation.yaml | 22 +++++++ .../amti/ca_pre_exemption_amti.yaml | 64 +++++++++++++++++++ .../amti/ca_itemized_deductions_limitation.py | 22 +++++++ .../amti/ca_pre_exemption_amti.py | 16 ++++- 5 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 changelog.d/misc-accuracy.fixed.md create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.yaml create mode 100644 policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.py diff --git a/changelog.d/misc-accuracy.fixed.md b/changelog.d/misc-accuracy.fixed.md new file mode 100644 index 00000000000..c893402662e --- /dev/null +++ b/changelog.d/misc-accuracy.fixed.md @@ -0,0 +1 @@ +- California AMT no longer double-adds disallowed itemized deductions; Schedule P (540) Part I now adds regular taxable income plus specific AMT adjustments minus the restored itemized deductions limitation (line 18), instead of adding the full pre-limitation itemized deductions. diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.yaml new file mode 100644 index 00000000000..4a44add7a13 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.yaml @@ -0,0 +1,22 @@ +# Schedule P (540) Part I, line 18: the amount of itemized deductions +# disallowed for regular tax under the California high-AGI limitation, which +# is restored for AMT. +# https://www.ftb.ca.gov/forms/2024/2024-540-p.pdf#page=1 + +- name: No limitation when pre and post limitation deductions are equal + period: 2026 + input: + state_code: CA + ca_itemized_deductions_pre_limitation: 45_000 + ca_itemized_deductions: 45_000 + output: + ca_itemized_deductions_limitation: 0 + +- name: Limitation equals the reduction in itemized deductions + period: 2026 + input: + state_code: CA + ca_itemized_deductions_pre_limitation: 58_000 + ca_itemized_deductions: 49_132.18 + output: + ca_itemized_deductions_limitation: 8_867.82 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.yaml b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.yaml new file mode 100644 index 00000000000..2af9d8adf5d --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.yaml @@ -0,0 +1,64 @@ +# Schedule P (540) Part I, line 19 / line 21. +# https://www.ftb.ca.gov/forms/2024/2024-540-p.pdf#page=1 +# AMTI = regular taxable income (line 15) + total adjustments/preferences +# (line 14) - restored itemized deductions limitation (line 18). +# Disallowed itemized deductions (property taxes, medical) are added back +# once via ca_amti_adjustments; the full pre-limitation itemized deductions +# must NOT be added again (issue #8742). + +- name: Property taxes are not double-added; AMTI equals AGI when no limitation applies + period: 2026 + input: + state_code: CA + ca_agi: 199_500 + ca_taxable_income: 154_500 + # Single filer, $45,000 real property tax deducted (below the CA high-AGI + # itemized-deduction limitation threshold, so pre = post limitation). + ca_amti_adjustments: 45_000 + ca_itemized_deductions_pre_limitation: 45_000 + ca_itemized_deductions: 45_000 + output: + # 154_500 + 45_000 - 0 = 199_500 (= AGI), flat regardless of property tax. + ca_pre_exemption_amti: 199_500 + +- name: Higher property taxes keep AMTI flat at AGI (issue 8742 reproduction) + period: 2026 + input: + state_code: CA + ca_agi: 199_500 + ca_taxable_income: 99_500 + ca_amti_adjustments: 100_000 + ca_itemized_deductions_pre_limitation: 100_000 + ca_itemized_deductions: 100_000 + output: + # 99_500 + 100_000 - 0 = 199_500; property tax does not inflate AMTI. + ca_pre_exemption_amti: 199_500 + +- name: High-AGI itemized-deduction limitation is restored for AMT (line 18) + period: 2026 + input: + state_code: CA + ca_agi: 400_000 + # Regular taxable income reflects post-limitation deductions. + ca_taxable_income: 350_867.81 + # Only real property taxes ($10,000) are disallowed for AMT. + ca_amti_adjustments: 10_000 + ca_itemized_deductions_pre_limitation: 58_000 + ca_itemized_deductions: 49_132.18 + output: + # 350_867.81 + 10_000 - (58_000 - 49_132.18) = 352_000. + ca_pre_exemption_amti: 352_000 + +- name: Non-itemizer AMTI equals AGI (standard deduction added back on line 1) + period: 2026 + input: + state_code: CA + ca_agi: 80_000 + # Taxable income = AGI - standard deduction ($5,706 single, 2026). + ca_taxable_income: 74_294 + # ca_amti_adjustments returns the standard deduction for non-itemizers. + ca_amti_adjustments: 5_706 + ca_itemized_deductions_pre_limitation: 0 + ca_itemized_deductions: 0 + output: + ca_pre_exemption_amti: 80_000 diff --git a/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.py b/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.py new file mode 100644 index 00000000000..ff1636da2c5 --- /dev/null +++ b/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_itemized_deductions_limitation.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ca_itemized_deductions_limitation(Variable): + value_type = float + entity = TaxUnit + label = "California itemized deductions limitation restored for AMT" + defined_for = StateCode.CA + unit = USD + definition_period = YEAR + reference = "https://www.ftb.ca.gov/forms/2024/2024-540-p.pdf#page=1" + + def formula(tax_unit, period, parameters): + # Schedule P (540) Part I, line 18. For regular tax, high-AGI filers + # have their itemized deductions reduced (California itemized + # deductions limitation). This limitation does not apply for AMT, so + # the amount of deductions disallowed for regular tax is restored + # (subtracted from AMTI, since it was excluded from regular taxable + # income on Form 540 line 19 / Schedule P line 15). + pre_limitation = tax_unit("ca_itemized_deductions_pre_limitation", period) + post_limitation = tax_unit("ca_itemized_deductions", period) + return max_(pre_limitation - post_limitation, 0) diff --git a/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.py b/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.py index 102de1be786..3995a7e53a6 100644 --- a/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.py +++ b/policyengine_us/variables/gov/states/ca/tax/income/alternative_minimum_tax/amti/ca_pre_exemption_amti.py @@ -8,11 +8,21 @@ class ca_pre_exemption_amti(Variable): defined_for = StateCode.CA unit = USD definition_period = YEAR - reference = "https://www.ftb.ca.gov/forms/2022/2022-540-p.pdf" + reference = "https://www.ftb.ca.gov/forms/2024/2024-540-p.pdf#page=1" - # Line 19 + # Schedule P (540) Part I, line 19: combine regular taxable income + # (line 15) with the total AMT adjustments and preferences (line 14) and + # subtract the restored itemized deductions limitation (line 18). + # + # ca_amti_adjustments (line 14) adds back only the specific AMT-disallowed + # itemized deductions (property taxes, medical, etc.), so the full + # pre-limitation itemized deductions must NOT be added on top; doing so + # double-counts disallowed items and adds back deductions (e.g. charity, + # acquisition mortgage interest) that AMT still allows. adds = [ "ca_amti_adjustments", "ca_taxable_income", - "ca_itemized_deductions_pre_limitation", + ] + subtracts = [ + "ca_itemized_deductions_limitation", ] From d578b53a5977b6f48fd0fcd00dc934670dafae10 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 6 Jul 2026 09:06:00 -0400 Subject: [PATCH 2/4] Fix AZ property tax credit table selection for non-spouse cohabitants (#8897) ARS 43-1072(A)(3)(b) applies the higher Table 2 (B)(2) credit schedule to any claimant who "lived with a spouse or one or more persons," while (A)(3)(a) applies Table 1 (B)(1) only to a claimant who "did not live with a spouse or any other persons." The previous logic keyed only off cohabitating_spouses and tax_unit_married, so a single or head-of-household claimant living with a non-spouse (adult child, sibling, roommate) was understated on Table 1. Broadened the Table 2 condition to also trigger when the claimant's household has more than one person. Added regression tests for a single claimant living with an adult child (Table 2, $323) versus living alone (Table 1, $78). Co-Authored-By: Claude Fable 5 --- changelog.d/misc-accuracy.fixed.md | 1 + .../credits/az_property_tax_credit.yaml | 31 +++++++++++++++++++ .../az_property_tax_credit.py | 18 +++++++---- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/changelog.d/misc-accuracy.fixed.md b/changelog.d/misc-accuracy.fixed.md index c893402662e..2e18a5cb635 100644 --- a/changelog.d/misc-accuracy.fixed.md +++ b/changelog.d/misc-accuracy.fixed.md @@ -1 +1,2 @@ - California AMT no longer double-adds disallowed itemized deductions; Schedule P (540) Part I now adds regular taxable income plus specific AMT adjustments minus the restored itemized deductions limitation (line 18), instead of adding the full pre-limitation itemized deductions. +- Arizona property tax credit now selects the higher Table 2 credit schedule for any claimant living with one or more other persons (including a non-spouse cohabitant), matching ARS 43-1072(A)(3)(b), rather than only for married couples and cohabitating spouses. diff --git a/policyengine_us/tests/policy/baseline/gov/states/az/tax/income/credits/az_property_tax_credit.yaml b/policyengine_us/tests/policy/baseline/gov/states/az/tax/income/credits/az_property_tax_credit.yaml index 2fae13c629d..2fa8487c45b 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/az/tax/income/credits/az_property_tax_credit.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/az/tax/income/credits/az_property_tax_credit.yaml @@ -80,3 +80,34 @@ households: {household: {members: [head, spouse], state_code: AZ}} output: az_property_tax_credit: 323 + +# ARS 43-1072(A)(3)(b): a single claimant who "lived with a spouse or one or +# more persons" uses the Table 2 (cohabitating) schedule. An elderly single +# filer living with a non-dependent adult child lives with another person. +- name: AZ property tax credit uses Table 2 for a single claimant living with an adult child + period: 2025 + input: + people: + head: {age: 75, taxable_interest_income: 3_637.87, rent: 9_059.32} + # Adult child living in the same household (not a tax dependent). + child: {age: 40, is_tax_unit_dependent: false} + tax_units: + claimant: {members: [head]} + child_unit: {members: [child]} + households: {household: {members: [head, child], state_code: AZ}} + output: + # At $3,637.87 income the Table 2 (cohabitating) credit is $323, whereas the + # Table 1 (living-alone) schedule would give only $78. The adult child's + # own tax unit is not credit-eligible (under age 65, no SSI). + az_property_tax_credit: [323, 0] + +# A truly solitary elderly filer at the same income uses the Table 1 schedule. +- name: AZ property tax credit uses Table 1 for a single claimant living alone + period: 2025 + input: + people: + head: {age: 75, taxable_interest_income: 3_637.87, rent: 9_059.32} + tax_units: {tax_unit: {members: [head]}} + households: {household: {members: [head], state_code: AZ}} + output: + az_property_tax_credit: 78 diff --git a/policyengine_us/variables/gov/states/az/tax/income/credits/property_tax_credit/az_property_tax_credit.py b/policyengine_us/variables/gov/states/az/tax/income/credits/property_tax_credit/az_property_tax_credit.py index f81ebbc735a..e77afe160ac 100644 --- a/policyengine_us/variables/gov/states/az/tax/income/credits/property_tax_credit/az_property_tax_credit.py +++ b/policyengine_us/variables/gov/states/az/tax/income/credits/property_tax_credit/az_property_tax_credit.py @@ -15,15 +15,21 @@ def formula(tax_unit, period, parameters): income = tax_unit("az_property_tax_credit_income", period) # ARS 43-1072(A)(3): a claimant who "lived with a spouse or one or - # more persons" uses the Table 2 (cohabitating) schedule. A married - # couple filing jointly lives together, so treat them as cohabitating - # regardless of the (default-False) cohabitating_spouses input. - cohabitating = tax_unit("cohabitating_spouses", period) | tax_unit( - "tax_unit_married", period + # more persons" uses the Table 2 (B)(2) schedule, while a claimant who + # "did not live with a spouse or any other persons" uses the Table 1 + # (B)(1) schedule. Any co-resident (spouse, adult child, sibling, + # roommate) triggers Table 2. Use the broadest available signal: + # explicit cohabitating-spouses input, a married couple filing jointly, + # or a household with more than one person. + household_size = tax_unit.household("household_size", period) + lives_with_others = ( + tax_unit("cohabitating_spouses", period) + | tax_unit("tax_unit_married", period) + | (household_size > 1) ) cap = where( - cohabitating, + lives_with_others, p.amount.cohabitating.calc(income), p.amount.living_alone.calc(income), ) From c5423f2785bc75d5f9f4231d9b0bfa718135764f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 6 Jul 2026 09:08:32 -0400 Subject: [PATCH 3/4] Fix LA FITAP deficit rounding and under-$10 payment suppression (#8770) Louisiana DCFS manual B-641-1-FITAP: "the deficit rounded down, if $10 or more, is the grant amount. If deficit is less than $10, the assistance unit is FITAP eligible but no grant is paid." The formula previously returned the unrounded deficit with no minimum-payment floor. Round the deficit down to a whole dollar and suppress payments below the new la.dcfs.fitap.minimum_payment parameter ($10). Eligibility (la_fitap_eligible) is unchanged; only the paid grant is suppressed. Added tests for the issue's reported households and the $10 boundary. Co-Authored-By: Claude Fable 5 --- changelog.d/misc-accuracy.fixed.md | 1 + .../states/la/dcfs/fitap/minimum_payment.yaml | 12 +++++ .../gov/states/la/dcfs/fitap/la_fitap.yaml | 44 +++++++++++++++++++ .../gov/states/la/dcfs/fitap/la_fitap.py | 12 +++-- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/la/dcfs/fitap/minimum_payment.yaml diff --git a/changelog.d/misc-accuracy.fixed.md b/changelog.d/misc-accuracy.fixed.md index 2e18a5cb635..2e75d4a6ee3 100644 --- a/changelog.d/misc-accuracy.fixed.md +++ b/changelog.d/misc-accuracy.fixed.md @@ -1,2 +1,3 @@ - California AMT no longer double-adds disallowed itemized deductions; Schedule P (540) Part I now adds regular taxable income plus specific AMT adjustments minus the restored itemized deductions limitation (line 18), instead of adding the full pre-limitation itemized deductions. - Arizona property tax credit now selects the higher Table 2 credit schedule for any claimant living with one or more other persons (including a non-spouse cohabitant), matching ARS 43-1072(A)(3)(b), rather than only for married couples and cohabitating spouses. +- Louisiana FITAP now rounds the grant deficit down to a whole dollar and pays no grant when the rounded deficit is below $10, per DCFS manual B-641-1-FITAP. diff --git a/policyengine_us/parameters/gov/states/la/dcfs/fitap/minimum_payment.yaml b/policyengine_us/parameters/gov/states/la/dcfs/fitap/minimum_payment.yaml new file mode 100644 index 00000000000..7f59898c215 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/dcfs/fitap/minimum_payment.yaml @@ -0,0 +1,12 @@ +description: Louisiana pays no Family Independence Temporary Assistance Program grant when the rounded-down deficit is below this amount, though the assistance unit remains FITAP eligible. +values: + 2023-01-01: 10 +metadata: + unit: currency-USD + period: month + label: Louisiana FITAP minimum payment + reference: + - title: Louisiana DCFS Economic Stability Manual B-640-FITAP Income Limits, B-641-1-FITAP (Determination of Eligibility and Grant Amount) + href: https://public.powerdms.com/LADCFS/documents/398921 + - title: Louisiana Administrative Code Title 67, Part III, Section 1229 + href: https://www.law.cornell.edu/regulations/louisiana/La-Admin-Code-tit-67-SS-III-1229 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/dcfs/fitap/la_fitap.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/dcfs/fitap/la_fitap.yaml index 2709c5441bf..3c86229bb2c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/la/dcfs/fitap/la_fitap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/la/dcfs/fitap/la_fitap.yaml @@ -28,3 +28,47 @@ la_fitap_countable_income: 0 output: la_fitap: 0 + +# DCFS manual B-641-1-FITAP: the deficit is rounded down; if it is less than +# $10 the unit is eligible but no grant is paid. +- name: Deficit under $10 pays no grant (issue 8770 example 1) + # $244 flat grant - $235.50 income = $8.50 deficit < $10, so no grant. + period: 2024-01 + input: + state_code: LA + la_fitap_eligible: true + la_fitap_flat_grant: 244 + la_fitap_countable_income: 235.50 + output: + la_fitap: 0 + +- name: Deficit of $10 or more is rounded down to the grant (issue 8770 example 2) + # $484 flat grant - $450.75 income = $33.25 deficit, rounded down to $33. + period: 2024-01 + input: + state_code: LA + la_fitap_eligible: true + la_fitap_flat_grant: 484 + la_fitap_countable_income: 450.75 + output: + la_fitap: 33 + +- name: Deficit of exactly $10 pays $10 + period: 2024-01 + input: + state_code: LA + la_fitap_eligible: true + la_fitap_flat_grant: 244 + la_fitap_countable_income: 234 + output: + la_fitap: 10 + +- name: Deficit of $9.99 pays no grant + period: 2024-01 + input: + state_code: LA + la_fitap_eligible: true + la_fitap_flat_grant: 244 + la_fitap_countable_income: 234.01 + output: + la_fitap: 0 diff --git a/policyengine_us/variables/gov/states/la/dcfs/fitap/la_fitap.py b/policyengine_us/variables/gov/states/la/dcfs/fitap/la_fitap.py index d412c6882f7..4d0dc9af7a5 100644 --- a/policyengine_us/variables/gov/states/la/dcfs/fitap/la_fitap.py +++ b/policyengine_us/variables/gov/states/la/dcfs/fitap/la_fitap.py @@ -11,9 +11,15 @@ class la_fitap(Variable): defined_for = "la_fitap_eligible" def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.dcfs.fitap flat_grant = spm_unit("la_fitap_flat_grant", period) countable_income = spm_unit("la_fitap_countable_income", period) - # Benefit = flat grant minus countable income - benefit = max_(flat_grant - countable_income, 0) - return min_(benefit, flat_grant) + # DCFS manual B-641-1-FITAP: the deficit between the flat grant and + # countable income, rounded down. If the rounded deficit is $10 or + # more it is the grant amount; if it is less than $10 the unit is + # FITAP-eligible but no grant is paid. + deficit = max_(flat_grant - countable_income, 0) + rounded_deficit = np.floor(deficit) + grant = min_(rounded_deficit, flat_grant) + return where(grant >= p.minimum_payment, grant, 0) From 792e4f3135fb98298622def1824f3bd5d05b6a30 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 6 Jul 2026 09:11:36 -0400 Subject: [PATCH 4/4] Apply NV TANF A-660.12 whole-dollar rounding and $10 minimum issuance (#8771) Nevada E&P Manual A-660.12: "A benefit is always a whole dollar amount. Round all amounts down to the nearest dollar. The minimum benefit amount is $10. Benefits of less than $10 are issued only for supplemental payments [or] payments made after an overpayment recoupment." The nv_tanf formula previously returned the unrounded deficit with no minimum-issuance floor. Round the benefit down to a whole dollar and suppress regular benefits below the new nv.dwss.tanf.minimum_payment parameter ($10). Added A-660.12 boundary tests. The A-660.12 Employment Retention Payment ($50/month for six months to households terminating for excess income with at least $1 of earned income) is out of scope here: it is a distinct six-month transitional benefit paid to households that are no longer TANF-eligible, requiring prior-eligibility and month-since-termination state that PolicyEngine's static monthly snapshot does not represent. It should be modeled as a new program, not folded into nv_tanf. Co-Authored-By: Claude Fable 5 --- changelog.d/misc-accuracy.fixed.md | 1 + .../states/nv/dwss/tanf/minimum_payment.yaml | 13 +++++ .../gov/states/nv/dwss/tanf/nv_tanf.yaml | 47 +++++++++++++++++++ .../gov/states/nv/dwss/tanf/nv_tanf.py | 13 ++++- 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 policyengine_us/parameters/gov/states/nv/dwss/tanf/minimum_payment.yaml diff --git a/changelog.d/misc-accuracy.fixed.md b/changelog.d/misc-accuracy.fixed.md index 2e75d4a6ee3..851154bb12c 100644 --- a/changelog.d/misc-accuracy.fixed.md +++ b/changelog.d/misc-accuracy.fixed.md @@ -1,3 +1,4 @@ - California AMT no longer double-adds disallowed itemized deductions; Schedule P (540) Part I now adds regular taxable income plus specific AMT adjustments minus the restored itemized deductions limitation (line 18), instead of adding the full pre-limitation itemized deductions. - Arizona property tax credit now selects the higher Table 2 credit schedule for any claimant living with one or more other persons (including a non-spouse cohabitant), matching ARS 43-1072(A)(3)(b), rather than only for married couples and cohabitating spouses. - Louisiana FITAP now rounds the grant deficit down to a whole dollar and pays no grant when the rounded deficit is below $10, per DCFS manual B-641-1-FITAP. +- Nevada TANF now rounds the monthly benefit down to a whole dollar and issues no regular benefit below $10, per Eligibility and Payments Manual A-660.12. diff --git a/policyengine_us/parameters/gov/states/nv/dwss/tanf/minimum_payment.yaml b/policyengine_us/parameters/gov/states/nv/dwss/tanf/minimum_payment.yaml new file mode 100644 index 00000000000..737fd765dc6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/nv/dwss/tanf/minimum_payment.yaml @@ -0,0 +1,13 @@ +description: Nevada pays no regular monthly TANF benefit below this amount; benefits under this floor are issued only as supplemental payments or after an overpayment recoupment. +# The $10 minimum issuance rule is a longstanding Nevada TANF benefit-issuance +# standard; it is dated to the start of the modeled NV TANF payment standard +# (2007) and sourced to the current Eligibility and Payments Manual A-660.12. +values: + 2007-07-01: 10 +metadata: + unit: currency-USD + period: month + label: Nevada TANF minimum payment + reference: + - title: Nevada DWSS Eligibility and Payments Manual, A-660.12 TANF Benefit Amount/SNAP Allotment + href: https://dwss.nv.gov/siteassets/dwss.nv.gov/ep-manual-section-a/chapter-a-600-budgeting-ada-8.2025.pdf#page=38 diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/tanf/nv_tanf.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/tanf/nv_tanf.yaml index 642195d714a..0977a9a27a1 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/tanf/nv_tanf.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/tanf/nv_tanf.yaml @@ -42,3 +42,50 @@ nv_tanf_countable_income: 0 output: nv_tanf: 0 + +# E&P Manual A-660.12: "A benefit is always a whole dollar amount. Round all +# amounts down to the nearest dollar." +- name: Benefit is rounded down to a whole dollar + period: 2025-01 + input: + state_code: NV + nv_tanf_eligible: true + nv_tanf_payment_standard: 386 + nv_tanf_countable_income: 100.75 + output: + # $386 - $100.75 = $285.25, rounded down to $285. + nv_tanf: 285 + +# A-660.12: "The minimum benefit amount is $10." Regular benefits below $10 +# are not issued. +- name: Benefit below the $10 minimum is not issued + period: 2025-01 + input: + state_code: NV + nv_tanf_eligible: true + nv_tanf_payment_standard: 386 + nv_tanf_countable_income: 379 + output: + # $386 - $379 = $7 < $10, so no benefit is issued. + nv_tanf: 0 + +- name: Benefit of exactly $10 is issued + period: 2025-01 + input: + state_code: NV + nv_tanf_eligible: true + nv_tanf_payment_standard: 386 + nv_tanf_countable_income: 376 + output: + nv_tanf: 10 + +- name: Deficit that rounds below $10 is not issued + period: 2025-01 + input: + state_code: NV + nv_tanf_eligible: true + nv_tanf_payment_standard: 386 + nv_tanf_countable_income: 376.50 + output: + # $386 - $376.50 = $9.50, rounds down to $9 < $10, so no benefit. + nv_tanf: 0 diff --git a/policyengine_us/variables/gov/states/nv/dwss/tanf/nv_tanf.py b/policyengine_us/variables/gov/states/nv/dwss/tanf/nv_tanf.py index d36b8db3abd..4157a49407d 100644 --- a/policyengine_us/variables/gov/states/nv/dwss/tanf/nv_tanf.py +++ b/policyengine_us/variables/gov/states/nv/dwss/tanf/nv_tanf.py @@ -7,14 +7,23 @@ class nv_tanf(Variable): label = "Nevada Temporary Assistance for Needy Families (TANF)" unit = USD definition_period = MONTH - reference = "https://dss.nv.gov/TANF/Financial_Help/" + reference = "https://dwss.nv.gov/siteassets/dwss.nv.gov/ep-manual-section-a/chapter-a-600-budgeting-ada-8.2025.pdf#page=38" defined_for = "nv_tanf_eligible" def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.nv.dwss.tanf payment_standard = spm_unit("nv_tanf_payment_standard", period) countable_income = spm_unit("nv_tanf_countable_income", period) # Benefit is payment standard minus countable income benefit = max_(payment_standard - countable_income, 0) # Cap benefit at payment standard to prevent negative income # from inflating benefits above the maximum. - return min_(benefit, payment_standard) + benefit = min_(benefit, payment_standard) + # E&P Manual A-660.12: "A benefit is always a whole dollar amount. + # Round all amounts down to the nearest dollar." + benefit = np.floor(benefit) + # A-660.12: "The minimum benefit amount is $10." Regular monthly + # benefits below $10 are not issued (only supplemental payments and + # post-overpayment-recoupment payments, which PolicyEngine does not + # model, may fall below $10). + return where(benefit >= p.minimum_payment, benefit, 0)