Skip to content

Fix payroll tax revenue double-counted in aggregates.revenue (Issue #1199) - #1204

Merged
jdebacker merged 1 commit into
PSLmodels:masterfrom
arihantlodha-cmd:fix-payroll-double-count
Aug 17, 2026
Merged

Fix payroll tax revenue double-counted in aggregates.revenue (Issue #1199)#1204
jdebacker merged 1 commit into
PSLmodels:masterfrom
arihantlodha-cmd:fix-payroll-double-count

Conversation

@arihantlodha-cmd

Copy link
Copy Markdown
Contributor

Fixes #1199. Thanks @marcelolafleur for the precise diagnosis — this is a regression I introduced in #1184, so cleaning it up.

The bug. Each household's income_payroll_tax_liab already includes T_P = tau_payroll * labor_income (in tax.income_tax_liab), so payroll revenue is fully inside iit_payroll_tax_revenue. In #1184 I then added get_payroll_tax_revenue — the same take, re-derived from the aggregate wage bill tau_payroll * w * L — back into that same total whenever tau_payroll != 0. The two are the same money, so revenue was overstated by the payroll take, the government spent it, and the steady-state resource constraint failed. Any model with a nonzero tau_payroll broke (OG-PHL); OG-USA was unaffected only because its tau_payroll is 0.

The fix. Remove the erroneous if np.any(p.tau_payroll != 0): iit_payroll_tax_revenue += payroll_tax_revenue. iit_payroll_tax_revenue stays what the line above builds (household bills, payroll already inside). get_payroll_tax_revenue is kept — it still provides the income-vs-payroll reporting split (iit_revenue = iit_payroll_tax_revenue - payroll_tax_revenue), which is the genuinely useful part of #1184 and is unchanged.

I also restored the test_revenue golden values, which #1184 had inflated to match the double-count. I pulled them from the commit just before #1184's second commit and confirmed they are identical, so this returns the totals to exactly the pre-#1184 (correct) amounts.

Testing

  • pytest tests/test_aggregates.py → 43 passed; test_revenue (including the tau_payroll = 0.5 cases) and test_get_payroll_tax_revenue both green.
  • ruff format --check . / ruff check . clean.

Fixes PSLmodels#1199. Each household's income_payroll_tax_liab already includes
T_P = tau_payroll * labor_income, so payroll revenue is inside
iit_payroll_tax_revenue. PR PSLmodels#1184 then added get_payroll_tax_revenue (the
same amount re-derived from the aggregate wage bill) into that total again
when tau_payroll != 0, overstating revenue so the government over-spent
and the steady-state resource constraint failed for any model with a
nonzero tau_payroll (OG-USA was fine only because its tau_payroll is 0).

Removes the erroneous addition. get_payroll_tax_revenue still provides the
income-vs-payroll reporting split (iit_revenue = iit_payroll_tax_revenue -
payroll_tax_revenue), which is unchanged. Restores the test_revenue golden
values to their pre-PSLmodels#1184 amounts (verified identical to the values from
before the double-count was introduced).
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.73%. Comparing base (2b6a668) to head (4160653).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1204      +/-   ##
==========================================
- Coverage   72.74%   72.73%   -0.01%     
==========================================
  Files          22       22              
  Lines        5768     5766       -2     
==========================================
- Hits         4196     4194       -2     
  Misses       1572     1572              
Flag Coverage Δ
unittests 72.73% <ø> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
ogcore/aggregates.py 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jdebacker
jdebacker merged commit 6099304 into PSLmodels:master Aug 17, 2026
8 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.

v0.19.1 counts payroll tax revenue twice; models with a payroll tax no longer solve

3 participants