Skip to content

Draft: Integrate modeled state unemployment insurance into income flows - #8303

Closed
daphnehanse11 wants to merge 3 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/state-ui-income-flow-integration
Closed

daphnehanse11 wants to merge 3 commits into
PolicyEngine:mainfrom
daphnehanse11:codex/state-ui-income-flow-integration

Conversation

@daphnehanse11

@daphnehanse11 daphnehanse11 commented May 14, 2026 •

Copy link
Copy Markdown
Collaborator

Tracks #8301.

Purpose

This is the draft umbrella PR for wiring modeled state unemployment insurance benefits into unemployment_compensation and downstream income flows.

Keep this PR as a draft until the relevant state rules and policyengine-us-data pipelines are ready. State UI rule implementations can still merge separately when they are calculator-safe; this PR is for the baseline microsimulation integration step.

Why draft

The current PA wiring is conceptually right for household calculations, but it should not enter baseline aggregation until enhanced CPS can populate or impute the required wage-history and unemployment inputs. Otherwise, the integration would be partial: modeled UI would depend on inputs that are not yet available in the microsim data pipeline, and could mix calculator-only logic into baseline income flows prematurely.

Scope

  • Add modeled state UI variables to unemployment_compensation only after each state has usable data inputs.
  • Coordinate with policyengine-us-data for extraction/imputation of required variables.
  • Add microsimulation regressions that protect reported unemployment compensation and validate nonzero modeled UI where expected.
  • Use this branch as the collection point for aggregator wiring across states.

Current contents

  • PA UC aggregator wiring and an income-flow test. This is kept here as the first candidate integration, but it is not merge-ready until the data pipeline prerequisites are met.

Checklist

  • Inventory state UI variables and required inputs for each modeled state.
  • Keep state UI rule/calculator PRs separate where they can safely merge without baseline aggregation.
  • Add or impute required inputs in policyengine-us-data.
  • Bump policyengine-us-data minimum policyengine-us version after any new model variables are released.
  • Validate enhanced CPS has nonzero modeled UI for expected state populations.
  • Add a microsim regression confirming unemployment_compensation does not drop relative to the reported baseline.
  • Add state UI variables to unemployment_compensation.adds once data-backed.
  • Re-run targeted UI, household income-flow, TaxSIM, and full CI checks.
  • Undraft only after the data pipeline and microsim validation are complete.

Tests so far

These passed for the current PA-only wiring, but they are not sufficient to merge this PR:

  • uv run python -m policyengine_core.scripts.policyengine_command test policyengine_us/tests/policy/baseline/gov/states/pa/dli/unemployment_compensation -c policyengine_us
  • uv run python -m policyengine_core.scripts.policyengine_command test policyengine_us/tests/policy/contrib/taxsim/taxsim_v11.yaml -c policyengine_us
  • uv run python -m policyengine_core.scripts.policyengine_command test policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_benefits.yaml -c policyengine_us
  • uv run --extra dev ruff check policyengine_us/variables/gov/states/unemployment_compensation.py
  • uv run --extra dev ruff format --check policyengine_us/variables/gov/states/unemployment_compensation.py

@codecov

codecov Bot commented May 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.20690% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.72%. Comparing base (8326a14) to head (f4aa5e9).
⚠️ Report is 572 commits behind head on main.

Files with missing lines Patch % Lines
...cyengine_us/variables/contrib/taxsim/taxsim_pui.py 0.00% 1 Missing ⚠️
...icyengine_us/variables/contrib/taxsim/taxsim_ui.py 0.00% 1 Missing ⚠️
...eductions/capped_qualified_tuition_expenses_ald.py 0.00% 1 Missing ⚠️
...ef/ut_homeowner_renter_relief_nontaxable_income.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##              main    #8303       +/-   ##
============================================
- Coverage   100.00%   73.72%   -26.28%     
============================================
  Files           12       15        +3     
  Lines          161      255       +94     
  Branches         0        9        +9     
============================================
+ Hits           161      188       +27     
- Misses           0       64       +64     
- Partials         0        3        +3     
Flag Coverage Δ
unittests 73.72% <86.20%> (-26.28%) ⬇️

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

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@MaxGhenis
MaxGhenis marked this pull request as draft May 19, 2026 13:18
@MaxGhenis MaxGhenis changed the title Integrate PA UC into unemployment compensation Draft: Integrate modeled state unemployment insurance into income flows May 19, 2026
@MaxGhenis

MaxGhenis commented May 19, 2026 •

Copy link
Copy Markdown
Contributor

Converted this to a draft umbrella PR for modeled state UI income-flow integration. The PA UC wiring is a useful first candidate, but we should not merge it into baseline unemployment_compensation until the corresponding policyengine-us-data inputs/imputations and microsim regression are in place. That avoids shipping a partial calculator-only aggregation path before enhanced CPS can support it.

daphnehanse11 added a commit to daphnehanse11/policyengine-us that referenced this pull request Jul 28, 2026
Remove the adds wiring into unemployment_compensation (newer core
rejects adds combined with uprating, and the integration is deferred
to PolicyEngine#8303 pending policyengine-us-data support) and the coupled
integration assertion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
daphnehanse11 and others added 2 commits August 18, 2026 15:39
Builds on the PA UC integration: unemployment_compensation now adds the modeled
state UI benefits for all currently-merged programs (al_ui, ny_ui, ok_ui, pa_uc,
ut_ui). Adds a 'feeds unemployment compensation income flows' integration case to
each state's UI suite (mirroring PA Case 8), asserting the benefit flows to
unemployment_compensation / tax_unit_unemployment_compensation and the taxable_*
pair. Rebased onto current main.

State UI suites 47/47; taxable-UC + my_friend_ben and analytics-coverage partner
signature tests unaffected (adds is inert where unemployment_compensation is a set
input). See PR comment re: the baseline double-count / microsim question.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DTrim99
DTrim99 force-pushed the codex/state-ui-income-flow-integration branch from 6198da9 to 926a7f2 Compare August 18, 2026 19:54
@DTrim99

DTrim99 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@PavelMakarchuk — picking this draft up now that the AL/NY/OK/PA/UT UI programs are all merged. I've rebased onto current main and extended the wiring to every merged state UI program: unemployment_compensation now adds = ["al_ui", "ny_ui", "ok_ui", "pa_uc", "ut_ui"], with a "feeds unemployment compensation income flows" integration case added per state (mirroring Daphne's PA Case 8). State UI suites are 47/47 and the taxable-UC, my_friend_ben, and analytics-coverage partner signature tests are unaffected.

But before this comes out of draft I want your call on two things — you lead US encoding so this is your decision, not something to escalate.

1. Should modeled state UI feed baseline unemployment_compensation at all?

unemployment_compensation is the survey-reported income field (SOI-uprated from the enhanced CPS). Adding the modeled programs to it has an awkward interaction either way:

  • Double-count risk: the survey value already reflects the UC these households actually received. Layering modeled *_ui/*_uc on top would count the same benefit twice for anyone the model fires on.
  • Or it's inert: because unemployment_compensation is provided as a dataset input, input precedence means the adds formula isn't evaluated in the microsim — so in the baseline economy (web app) the modeled UI doesn't actually flow, even though the unit tests pass (they set the state-UI inputs and leave unemployment_compensation unset, so the formula fires). Classic "green unit test, no microsim effect."

So as written this is either a no-op in the baseline or a double-count — the unit tests can't distinguish them. This is exactly why ny_ui/ok_ui were left deliberately unwired with the "must not double-count with unemployment_compensation" note.

My read: modeled state UI probably shouldn't be additively wired into the baseline survey aggregate — it more naturally belongs behind a "use modeled UI" reform (replace the survey UC with the modeled amount for those states), or requires decomposing the survey UC so the modeled portion isn't double-counted. But I'd rather have your steer than pick unilaterally.

2. Needs a microsim validation before merge

Whatever we choose, this changes a calibrated national aggregate, so it needs a microsim run (not just the scalar tests) confirming national unemployment_compensation doesn't move unexpectedly (neither inflated by double-counting nor collapsed toward the modeled-only value). Happy to run that once we agree on the intended behavior.

Question for you: do you want modeled state UI in baseline income at all, or gated behind a reform? If baseline, how should it reconcile with the survey UC to avoid the double-count? I'll implement whichever you prefer across all five states and keep it draft until then.

Rebase/extension done with Claude Code assistance.

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one confirmed import regression at 926a7f2f6ea5d9dd825ec49b72b722af98ab83b3.

[P1] Resolve the incompatible computation modes in unemployment_compensation. The new adds on line 12 is combined with the existing uprating on line 11. Core rejects that combination during variable registration:

ValueError: Variable "unemployment_compensation" mixes computation modes: adds/subtracts and uprating.

This prevents the country package from importing, before any household calculation or state eligibility check runs. The head-matched smoke-import job installs successfully and then raises this error; the microsimulation job fails with the same exception. I reproduced it locally under Core 3.32.6 and checked the exact base/head variable definitions: the base initializes with uprating, while the head fails. Zero targeted YAML cases could execute.

Please use a compatible design for reported-income uprating and modeled state-benefit aggregation, then rerun package import and the five integration files. Also validate reported-benefit preservation, modeled fallback and future-year uprating against the intended microsimulation dataset; simply removing uprating would not establish that those semantics remain correct.

I am not treating draft status, branch staleness, or presumed loss of reported benefits as defects. The data review found CPS explicitly supplies reported unemployment compensation, and no population loss or double counting was demonstrated. The blocker here is the reproducible import failure.

Restores unemployment_compensation as the uprated reported input, adds
modeled_state_unemployment_compensation aggregating the five state UI
programs, and routes income flows through a total_unemployment_
compensation fallback (reported where present, else modeled), per
review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH
@DTrim99

DTrim99 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

@PavelMakarchuk Resolved the computation-mode conflict via Option A: unemployment_compensation is restored to the uprated reported input (uprating only, no adds), a new modeled_state_unemployment_compensation aggregates the five state UI programs (al_ui, ny_ui, ok_uc, pa_uc, ut_ui), and income flows now route through a new total_unemployment_compensation = where(reported > 0, reported, modeled) fallback, with the 13 direct consumers repointed. I rejected the rename alternatives (making unemployment_compensation itself a fallback formula, or adds over a reported twin) precisely because the enhanced-CPS microdata writes the unemployment_compensation dataset column directly: renaming it would zero out ~all reported UC in future-year microsim until a coordinated policyengine-us-data column remap ships, which is the regression you flagged. Option A keeps the dataset column mapping and the uprating attribute untouched, so future-year aggregates are unchanged (UI wage inputs are absent in microdata, so modeled=0 and total==reported). Package import now registers cleanly (the check_computation_modes ValueError is gone); the five integration files pass along with new reported-preservation, modeled-fallback, and no-double-count cases in each.

@DTrim99

DTrim99 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Superseded by #9558 — rebased onto current main under new ownership (original author has left PolicyEngine). Pavel's mode-conflict blocker is resolved there; review history referenced in the new PR.

@DTrim99 DTrim99 closed this Sep 21, 2026
hua7450 pushed a commit that referenced this pull request Oct 13, 2026
* Integrate modeled state unemployment insurance into income flows

Rebase of PR #8303 onto current main under new ownership (original
author has left PolicyEngine). Adds modeled_state_unemployment_compensation
(sums al_ui, nj_unemployment_insurance, ny_ui, ok_ui, pa_uc, ut_ui) and
total_unemployment_compensation (reported-wins fallback), repoints the
direct consumers of unemployment_compensation - including the
household_benefits parameter list - and extends the five state UI
integration suites with income-flow, reported-preservation, and
no-double-count cases.

Resolves the uprating/adds computation-mode conflict Pavel flagged on
#8303 via Option A: unemployment_compensation stays a pure uprated
survey input, so CPS-reported values and future-year uprating are
untouched and modeled UI reaches income flows only when no reported
amount is present. NJ UI, modeled on main after #8303 was opened, is
included in the modeled aggregate as part of the rebase.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* Route parameter-driven UI consumers through total unemployment compensation

Per review: migrate every income-source list under parameters/gov/ (SNAP,
TANF, SSI, WIC, school meals, Head Start, HUD, CBO, CCAP, state tax lists
and the VA subtraction) and four contrib reform benefit lists from the
reported unemployment_compensation input to total_unemployment_compensation.
Document the reported-zero rule, fold two always-true source appends into
direct substitutions, and add low-income SNAP, NJ, asymmetric-household,
monthly and reported-zero tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* Year-gate the modeled state unemployment insurance programs

Sum modeled state UI through a year-gated parameter list so each program
counts from its first verified year. Before 2022 the list is empty, so
pre-2015 simulations (e.g. the 2010 Alabama SSP cases reached via SSI
unearned income) no longer reach state UI parameters that start later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* Address review: pin the modeled-UI year gate and pass negative reports through

Add year-gate tests for states before and after they enter the
modeled-UI list (AL 2023 and 2010, NY 2024, OK 2022, and PA/UT/NJ
excluded years), SSI/TANF and taxable-SS-MAGI flow tests, and treat any
nonzero reported unemployment compensation (including negative amounts)
as reported, as on main. Have Virginia subtract taxable UC, count strike
benefits in Hawaii child care, fix a reference comma, and clarify the
year-gate docs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* Update modeled-UI SNAP tests for main's months-of-receipt UI exemption

Main's #9716 limits the SNAP work-registration UI exemption to the months
of receipt (26 weeks -> 6 months), so outside those months the PA adults
in these cases hit the ABAWD time limit and 7 CFR 273.11(c)(2)(ii)
prorates their income. Update the two expectations with the arithmetic;
no code change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* List total_unemployment_compensation in the AR line-comment check

Main's code-health test pins the AR1000F line for every Arkansas gross
income source; the unemployment line (21 from 2018) now reads
total_unemployment_compensation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

* Route the remaining unemployment compensation readers through the total

Thirteen readers that later merges of main brought in still read the
reported-only unemployment_compensation input, so they missed modeled state
UI when nothing was reported:

- the student loan interest ALD MAGI and the two IRA deduction MAGI
  formulas (ira_219g_magi, ira_219g_taxable_social_security), which now
  append total_unemployment_compensation. The total never reaches AGI, so
  there is no cycle;
- ten parameter source lists: NY HEAP, NJ LIHEAP, IN EAP, KS LIEAP,
  KY LIHEAP, MD MEAP, MO SAB, MS LIHEAP, NC LIEAP and OR LIHEAP.

Each reader gets regression cases in its own test file: a modeled-UI case
plus a reported-UI control where the state models UI (PA for the federal
MAGI formulas, NY, NJ), and a reported-UI control elsewhere. The two IRA
variables get new test files named for them.

Add a code-health guard that fails when a parameter list entry or a Python
string constant names the raw input, with an allowlist for uprating, the
TAXSIM generator and the total's own formula. Add a microsimulation guard
that modeled state UI is zero on the certified default build in 2025.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

4 participants