diff --git a/changelog.d/codex-remove-reported-value-shortcuts.fixed.md b/changelog.d/codex-remove-reported-value-shortcuts.fixed.md new file mode 100644 index 00000000000..867de088d93 --- /dev/null +++ b/changelog.d/codex-remove-reported-value-shortcuts.fixed.md @@ -0,0 +1 @@ +Remove reported-value fallback shortcuts from modeled SNAP, broadband subsidy, and state income tax calculations. diff --git a/policyengine_us/parameters/gov/simulation/reported_broadband_subsidy.yaml b/policyengine_us/parameters/gov/simulation/reported_broadband_subsidy.yaml deleted file mode 100644 index d60f606ccff..00000000000 --- a/policyengine_us/parameters/gov/simulation/reported_broadband_subsidy.yaml +++ /dev/null @@ -1,6 +0,0 @@ -description: Broadband subsidies are taken as reported in the CPS ASEC. -values: - 2000-01-01: true -metadata: - unit: bool - label: Use reported broadband subsidies diff --git a/policyengine_us/parameters/gov/simulation/reported_snap.yaml b/policyengine_us/parameters/gov/simulation/reported_snap.yaml deleted file mode 100644 index 2d45e647e5b..00000000000 --- a/policyengine_us/parameters/gov/simulation/reported_snap.yaml +++ /dev/null @@ -1,6 +0,0 @@ -description: SNAP benefits are taken as reported in the CPS ASEC. -values: - 2000-01-01: false -metadata: - unit: bool - label: Use reported SNAP benefits diff --git a/policyengine_us/parameters/simulation/reported_state_income_tax.yaml b/policyengine_us/parameters/simulation/reported_state_income_tax.yaml deleted file mode 100644 index d8366e09ddd..00000000000 --- a/policyengine_us/parameters/simulation/reported_state_income_tax.yaml +++ /dev/null @@ -1,6 +0,0 @@ -description: Whether to take State income tax liabilities as reported. -values: - 0000-01-01: false -metadata: - unit: bool - label: Use reported State income tax diff --git a/policyengine_us/reforms/federal/__init__.py b/policyengine_us/reforms/federal/__init__.py index 818d777f5bf..a19e1941be5 100644 --- a/policyengine_us/reforms/federal/__init__.py +++ b/policyengine_us/reforms/federal/__init__.py @@ -2,4 +2,3 @@ create_abolish_federal_income_tax_reform, ) from .abolish_payroll_tax import create_abolish_payroll_tax_reform -from .reported_state_income_tax import create_reported_state_income_tax_reform diff --git a/policyengine_us/reforms/federal/reported_state_income_tax.py b/policyengine_us/reforms/federal/reported_state_income_tax.py deleted file mode 100644 index cde109b414d..00000000000 --- a/policyengine_us/reforms/federal/reported_state_income_tax.py +++ /dev/null @@ -1,69 +0,0 @@ -from policyengine_us.model_api import * - - -def create_reported_state_income_tax() -> Reform: - class household_tax_before_refundable_credits(Variable): - value_type = float - entity = Household - label = "total tax before refundable credits" - documentation = "Total tax liability before refundable credits." - unit = USD - definition_period = YEAR - - def formula(household, period, parameters): - p = parameters(period) - added_components = p.gov.household.household_tax_before_refundable_credits - flat_tax = p.gov.contrib.ubi_center.flat_tax - if p.simulation.reported_state_income_tax: - added_components = [ - "employee_payroll_tax", - "self_employment_tax", - "income_tax_before_refundable_credits", # Federal. - "flat_tax", - # State tax reported in ASEC includes refundable credits. - "spm_unit_state_tax_reported", - ] - if flat_tax.abolish_payroll_tax: - added_components = [ - c for c in added_components if c != "employee_payroll_tax" - ] - if flat_tax.abolish_federal_income_tax: - added_components = [ - c - for c in added_components - if c != "income_tax_before_refundable_credits" - ] - return add(household, period, added_components) - - class household_refundable_tax_credits(Variable): - value_type = float - entity = Household - label = "refundable tax credits" - definition_period = YEAR - unit = USD - - adds = ["income_tax_refundable_credits"] - - class reform(Reform): - def apply(self): - self.update_variable(household_tax_before_refundable_credits) - self.update_variable(household_refundable_tax_credits) - - return reform - - -def create_reported_state_income_tax_reform(parameters, period, bypass: bool = False): - if bypass: - return create_reported_state_income_tax() - - p = parameters(period).simulation - - if p.reported_state_income_tax: - return create_reported_state_income_tax() - else: - return None - - -reported_state_income_tax = create_reported_state_income_tax_reform( - None, None, bypass=True -) diff --git a/policyengine_us/reforms/reforms.py b/policyengine_us/reforms/reforms.py index 96a0c0589a6..0c0324ccb9a 100644 --- a/policyengine_us/reforms/reforms.py +++ b/policyengine_us/reforms/reforms.py @@ -14,7 +14,6 @@ from .congress.wyden_smith import create_ctc_expansion_reform from .federal import create_abolish_federal_income_tax_reform from .federal import create_abolish_payroll_tax_reform -from .federal import create_reported_state_income_tax_reform from .biden.budget_2025 import ( create_medicare_and_investment_tax_increase_reform, ) @@ -227,9 +226,6 @@ def create_structural_reforms_from_parameters(parameters, period): parameters, period ) abolish_payroll_tax = create_abolish_payroll_tax_reform(parameters, period) - reported_state_income_tax = create_reported_state_income_tax_reform( - parameters, period - ) capital_gains_tax_increase = create_capital_gains_tax_increase_reform( parameters, period ) @@ -387,7 +383,6 @@ def create_structural_reforms_from_parameters(parameters, period): ctc_expansion, abolish_federal_income_tax, abolish_payroll_tax, - reported_state_income_tax, medicare_and_investment_tax_increase, capital_gains_tax_increase, halve_joint_eitc_phase_out_rate, diff --git a/policyengine_us/tests/microsimulation/test_microsim.py b/policyengine_us/tests/microsimulation/test_microsim.py index 1e99c266e93..1b0efb97c9b 100644 --- a/policyengine_us/tests/microsimulation/test_microsim.py +++ b/policyengine_us/tests/microsimulation/test_microsim.py @@ -79,3 +79,23 @@ def test_county_persists_across_periods(): assert not np.any(county_2025 == County.ALBANY_COUNTY_NY.index), ( "Should not fall back to Albany county" ) + + +def test_microsim_snap_uses_modeled_amount_times_takeup(): + import numpy as np + from policyengine_us import Microsimulation + + sim = Microsimulation( + dataset="hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5" + ) + sim.subsample(500) + + snap = sim.calc("snap", period=2024).values + takes_up = sim.calc("takes_up_snap_if_eligible", period=2024).values.astype(float) + modeled_amount = ( + sim.calc("snap_normal_allotment", period=2024).values + + sim.calc("snap_emergency_allotment", period=2024).values + + sim.calc("dc_snap_temporary_local_benefit", period=2024).values + ) + + np.testing.assert_allclose(snap, modeled_amount * takes_up) diff --git a/policyengine_us/tests/policy/baseline/gov/states/tax/income/state_income_tax.yaml b/policyengine_us/tests/policy/baseline/gov/states/tax/income/state_income_tax.yaml index aa2a7f3da44..66217b58c11 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/tax/income/state_income_tax.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/tax/income/state_income_tax.yaml @@ -1,47 +1,24 @@ -- name: Reported state income tax sim false +- name: State income tax uses modeled liability period: 2021 input: - simulation.reported_state_income_tax: false state_income_tax_before_refundable_credits: 1_000 state_refundable_credits: 300 output: state_income_tax: 700 -- name: Reported state income tax sim false, negative amount +- name: State income tax can be negative after refundable credits period: 2021 input: - simulation.reported_state_income_tax: false state_income_tax_before_refundable_credits: 0 state_refundable_credits: 300 output: state_income_tax: -300 -- name: Reported state income tax sim, one head +- name: State income tax ignores reported SPM totals period: 2021 input: - simulation.reported_state_income_tax: true - people: - person1: - is_tax_unit_head: true - spm_units: - spm_unit: - members: [person1] - spm_unit_state_tax_reported: 1_000 - output: - state_income_tax: 1_000 - -- name: Reported state income tax sim, one head - period: 2021 - input: - simulation.reported_state_income_tax: true - people: - person1: - is_tax_unit_head: true - person2: - is_tax_unit_head: true - spm_units: - spm_unit: - members: [person1, person2] - spm_unit_state_tax_reported: 1_000 + state_income_tax_before_refundable_credits: 1_000 + state_refundable_credits: 300 + spm_unit_state_tax_reported: 1_000 output: - state_income_tax: 500 + state_income_tax: 700 diff --git a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml index 7fec755e685..bf032a5cf1f 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/snap/snap.yaml @@ -39,6 +39,48 @@ output: snap: 6 +- name: SNAP ignores reported values when computing modeled benefits. + period: 2024 + input: + snap_reported: 99 + snap_normal_allotment: 1 + snap_emergency_allotment: + 2024-01: 2 + 2024-02: 0 + 2024-03: 0 + 2024-04: 0 + 2024-05: 0 + 2024-06: 0 + 2024-07: 0 + 2024-08: 0 + 2024-09: 0 + 2024-10: 0 + 2024-11: 0 + 2024-12: 0 + output: + snap: 3 + +- name: SNAP is zero when abolished. + period: 2024 + input: + gov.usda.snap.abolish_snap: true + snap_normal_allotment: 1 + snap_emergency_allotment: + 2024-01: 2 + 2024-02: 0 + 2024-03: 0 + 2024-04: 0 + 2024-05: 0 + 2024-06: 0 + 2024-07: 0 + 2024-08: 0 + 2024-09: 0 + 2024-10: 0 + 2024-11: 0 + 2024-12: 0 + output: + snap: 0 + - name: North Carolina 2025, yearly integration test period: 2025 absolute_error_margin: 0.3 diff --git a/policyengine_us/tests/policy/baseline/household/household_state_income_tax.yaml b/policyengine_us/tests/policy/baseline/household/household_state_income_tax.yaml index 14a889fea5c..afc6d599ea0 100644 --- a/policyengine_us/tests/policy/baseline/household/household_state_income_tax.yaml +++ b/policyengine_us/tests/policy/baseline/household/household_state_income_tax.yaml @@ -5,10 +5,10 @@ output: household_state_income_tax: 100 -- name: Household state income tax with switch +- name: Household state income tax ignores reported toggle inputs period: 2022 input: - dc_income_tax: 100 - simulation.reported_state_income_tax: true + dc_income_tax_before_refundable_credits: 100 + spm_unit_state_tax_reported: 999 output: - household_state_income_tax: 0 + household_state_income_tax: 100 diff --git a/policyengine_us/tests/policy/baseline/household/income/household/household_state_income_tax.yaml b/policyengine_us/tests/policy/baseline/household/income/household/household_state_income_tax.yaml index b9ba5a7247a..9f8ab86929b 100644 --- a/policyengine_us/tests/policy/baseline/household/income/household/household_state_income_tax.yaml +++ b/policyengine_us/tests/policy/baseline/household/income/household/household_state_income_tax.yaml @@ -1,7 +1,6 @@ -- name: Reported state income tax sim false +- name: Household state income tax uses modeled components period: 2021 input: - simulation.reported_state_income_tax: false co_income_tax_before_refundable_credits: 3_000 ne_income_tax_before_refundable_credits: 2_000 pa_income_tax: 100 @@ -11,32 +10,15 @@ output: household_state_income_tax: 3_900 -- name: Reported state income tax sim, one head +- name: Household state income tax ignores reported SPM totals period: 2021 input: - simulation.reported_state_income_tax: true - people: - person1: - is_tax_unit_head: true - spm_units: - spm_unit: - members: [person1] - spm_unit_state_tax_reported: 1_000 - output: - household_state_income_tax: 1_000 - -- name: Reported state income tax sim, one head - period: 2021 - input: - simulation.reported_state_income_tax: true - people: - person1: - is_tax_unit_head: true - person2: - is_tax_unit_head: true - spm_units: - spm_unit: - members: [person1, person2] - spm_unit_state_tax_reported: 1_000 + co_income_tax_before_refundable_credits: 3_000 + ne_income_tax_before_refundable_credits: 2_000 + pa_income_tax: 100 + hi_refundable_credits: 300 + ok_refundable_credits: 500 + ut_refundable_credits: 400 + spm_unit_state_tax_reported: 1_000 output: - household_state_income_tax: 500 + household_state_income_tax: 3_900 diff --git a/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_broadband_subsidy.yaml b/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_broadband_subsidy.yaml index 4b0d034d8d7..9aa51d10ad0 100644 --- a/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_broadband_subsidy.yaml +++ b/policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_broadband_subsidy.yaml @@ -1,15 +1,15 @@ -- name: By default only use reported amount. +- name: Broadband subsidy ignores reported amount period: 2023 input: spm_unit_broadband_subsidy_reported: 1 + acp: 2 + ebb: 3 output: - spm_unit_broadband_subsidy: 1 + spm_unit_broadband_subsidy: 5 -- name: Otherwise sum ACP, EBB, and Lifeline. +- name: Broadband subsidy sums ACP and EBB period: 2023 input: - gov.simulation.reported_broadband_subsidy: false - lifeline: 1 acp: 2 ebb: 3 output: @@ -18,9 +18,7 @@ - name: Baseline subsidy test with relevant inputs period: 2023 input: - gov.simulation.reported_broadband_subsidy: false acp: 1 ebb: 2 output: spm_unit_broadband_subsidy: 3 - diff --git a/policyengine_us/tests/policy/contrib/federal/reported_state_income_tax.yaml b/policyengine_us/tests/policy/contrib/federal/reported_state_income_tax.yaml deleted file mode 100644 index 446379addc7..00000000000 --- a/policyengine_us/tests/policy/contrib/federal/reported_state_income_tax.yaml +++ /dev/null @@ -1,24 +0,0 @@ -- name: No reform - period: 2022 - input: - simulation.reported_state_income_tax: false - employee_payroll_tax: 800 - co_income_tax_before_refundable_credits: 300 - ga_refundable_credits: 400 - income_tax_refundable_credits: 600 - output: - household_tax_before_refundable_credits: 1_100 - household_refundable_tax_credits: 1_000 - -- name: Abolish federal income tax reform - period: 2022 - reforms: policyengine_us.reforms.federal.reported_state_income_tax.reported_state_income_tax - input: - simulation.reported_state_income_tax: true - employee_payroll_tax: 800 - co_income_tax_before_refundable_credits: 300 - ga_refundable_credits: 400 - income_tax_refundable_credits: 600 - output: - household_tax_before_refundable_credits: 800 - household_refundable_tax_credits: 600 diff --git a/policyengine_us/tests/policy/contrib/reported_state_income_tax.yaml b/policyengine_us/tests/policy/contrib/reported_state_income_tax.yaml deleted file mode 100644 index 864d283120a..00000000000 --- a/policyengine_us/tests/policy/contrib/reported_state_income_tax.yaml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Disabled State income tax uses reported value - period: 2022 - input: - simulation.reported_state_income_tax: true - employment_income: 50_000 - spm_unit_state_tax_reported: 3_000 - output: - state_income_tax: 3_000 diff --git a/policyengine_us/tests/test_batched.py b/policyengine_us/tests/test_batched.py index fd44564e20e..ae4de033bd9 100644 --- a/policyengine_us/tests/test_batched.py +++ b/policyengine_us/tests/test_batched.py @@ -57,7 +57,6 @@ def split_into_batches( "dc_single_joint_threshold_ratio.yaml", "reconciliation", "dc_kccatc.yaml", - "reported_state_income_tax.yaml", ] BATCH_6 = ["crfb"] # ~8.9 GB, always alone BATCH_7 = ["congress"] # ~6.3 GB diff --git a/policyengine_us/tools/default_uprating.py b/policyengine_us/tools/default_uprating.py index a69922ba8fe..d0a8ff9a094 100644 --- a/policyengine_us/tools/default_uprating.py +++ b/policyengine_us/tools/default_uprating.py @@ -59,7 +59,6 @@ "taxable_interest_income", "spm_unit_spm_threshold", "non_sch_d_capital_gains", - "spm_unit_state_tax_reported", "spm_unit_capped_work_childcare_expenses", "farm_income", "taxable_403b_distributions", @@ -73,7 +72,6 @@ "alimony_expense", "taxable_private_pension_income", "charitable_cash_donations", - "spm_unit_broadband_subsidy_reported", "free_school_meals_reported", "non_qualified_dividend_income", "excess_withheld_payroll_tax", @@ -85,7 +83,6 @@ "self_employed_pension_contribution_ald", "spm_unit_wic_reported", "unrecaptured_section_1250_gain", - "snap_reported", "long_term_capital_gains_on_collectibles", "self_employment_income_last_year", "tax_exempt_pension_income", diff --git a/policyengine_us/variables/gov/states/tax/income/state_income_tax.py b/policyengine_us/variables/gov/states/tax/income/state_income_tax.py index f490643db0e..ef811a838d8 100644 --- a/policyengine_us/variables/gov/states/tax/income/state_income_tax.py +++ b/policyengine_us/variables/gov/states/tax/income/state_income_tax.py @@ -9,22 +9,10 @@ class state_income_tax(Variable): definition_period = YEAR def formula(tax_unit, period, parameters): - if parameters(period).simulation.reported_state_income_tax: - spm_unit = tax_unit.spm_unit - person = spm_unit.members - is_head = person("is_tax_unit_head", period) - total_tax_unit_heads = spm_unit.sum(is_head) - spm_unit_state_tax = spm_unit("spm_unit_state_tax_reported", period) - return where( - total_tax_unit_heads > 0, - spm_unit_state_tax / total_tax_unit_heads, - 0, - ) - else: - income_tax_before_refundable_credits = add( - tax_unit, - period, - ["state_income_tax_before_refundable_credits"], - ) - refundable_credits = add(tax_unit, period, ["state_refundable_credits"]) - return income_tax_before_refundable_credits - refundable_credits + income_tax_before_refundable_credits = add( + tax_unit, + period, + ["state_income_tax_before_refundable_credits"], + ) + refundable_credits = add(tax_unit, period, ["state_refundable_credits"]) + return income_tax_before_refundable_credits - refundable_credits diff --git a/policyengine_us/variables/gov/usda/snap/snap.py b/policyengine_us/variables/gov/usda/snap/snap.py index fbee593ebb5..c681221fd73 100644 --- a/policyengine_us/variables/gov/usda/snap/snap.py +++ b/policyengine_us/variables/gov/usda/snap/snap.py @@ -21,19 +21,16 @@ def formula(spm_unit, period, parameters): is_in_microsim = hasattr(spm_unit.simulation, "dataset") if parameters(period).gov.usda.snap.abolish_snap: return 0 - elif parameters(period).gov.simulation.reported_snap: - return spm_unit("snap_reported", period) + value = add( + spm_unit, + period, + [ + "snap_normal_allotment", + "snap_emergency_allotment", + "dc_snap_temporary_local_benefit", + ], + ) + if is_in_microsim: + return value * takes_up else: - value = add( - spm_unit, - period, - [ - "snap_normal_allotment", - "snap_emergency_allotment", - "dc_snap_temporary_local_benefit", - ], - ) - if is_in_microsim: - return value * takes_up - else: - return value + return value diff --git a/policyengine_us/variables/household/expense/tax/spm_unit_state_tax.py b/policyengine_us/variables/household/expense/tax/spm_unit_state_tax.py index 43d69249d86..f7897e2ad82 100644 --- a/policyengine_us/variables/household/expense/tax/spm_unit_state_tax.py +++ b/policyengine_us/variables/household/expense/tax/spm_unit_state_tax.py @@ -15,7 +15,5 @@ class spm_unit_state_tax(Variable): def formula(spm_unit, period, parameters): person = spm_unit.members head = person("is_tax_unit_head", period) - if parameters(period).simulation.reported_state_income_tax: - return spm_unit("spm_unit_state_tax_reported", period) tax = person.tax_unit("state_income_tax", period) return spm_unit.sum(head * tax) diff --git a/policyengine_us/variables/household/income/household/household_state_income_tax.py b/policyengine_us/variables/household/income/household/household_state_income_tax.py index f291c01fcca..16b82cf066e 100644 --- a/policyengine_us/variables/household/income/household/household_state_income_tax.py +++ b/policyengine_us/variables/household/income/household/household_state_income_tax.py @@ -10,18 +10,8 @@ class household_state_income_tax(Variable): definition_period = YEAR def formula(tax_unit, period, parameters): - if parameters(period).simulation.reported_state_income_tax: - spm_unit = tax_unit.spm_unit - total_tax_unit_heads = add(spm_unit, period, ["is_tax_unit_head"]) - spm_unit_state_tax = spm_unit("spm_unit_state_tax_reported", period) - return where( - total_tax_unit_heads > 0, - spm_unit_state_tax / total_tax_unit_heads, - 0, - ) - else: - return add( - tax_unit, - period, - ["state_income_tax_before_refundable_credits"], - ) - add(tax_unit, period, ["state_refundable_credits"]) + return add( + tax_unit, + period, + ["state_income_tax_before_refundable_credits"], + ) - add(tax_unit, period, ["state_refundable_credits"]) diff --git a/policyengine_us/variables/household/income/spm_unit/spm_unit_broadband_subsidy.py b/policyengine_us/variables/household/income/spm_unit/spm_unit_broadband_subsidy.py index a2f61d97875..382725130d5 100644 --- a/policyengine_us/variables/household/income/spm_unit/spm_unit_broadband_subsidy.py +++ b/policyengine_us/variables/household/income/spm_unit/spm_unit_broadband_subsidy.py @@ -9,6 +9,4 @@ class spm_unit_broadband_subsidy(Variable): unit = USD def formula(spm_unit, period, parameters): - if parameters(period).gov.simulation.reported_broadband_subsidy: - return spm_unit("spm_unit_broadband_subsidy_reported", period) return add(spm_unit, period, ["ebb", "acp"])