PolicyEngine / PolicyEngine/microcosm

Sparse-57k export drops 94 no-formula input columns from the dense parent (tips, overtime, disability flags, ESI premiums, rent, QBI basis)

Open
#361 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
0
Forks
4
Avg merge
1d 3h
Merged PRs (30d)
94

Description

Summary

The sparse-57k export (populace-us-2024-sparse-l0-refit-57k-71a0887, certified default for bundles 4.18.8 and 4.20.0) drops 94 no-formula PolicyEngine-US input columns that the dense parent (f0af251, 4.18.7 default) populates. #278 documented mass-zeroing for a handful of bases and #356 the three SSI asset columns; this is the full inventory of the column-presence regression. The Build-H dense parent published today (populace-us-2024-buildh-dense-warmstart-b449eb7-20260708T100442Z) drops essentially the same set (129 of 133 columns), so the Build-I successor (#359) inherits the gap unless the export carries them.

Method: person-table column diff (dense 249 cols → sparse 222), filtered to pe-us 1.752.2 variables with no formula and no adds/subtracts (i.e., true inputs; formula-owned exports like employment_income/social_security are correctly dropped per #24 and excluded here). Mass = dense column × household weight, TY2024. Full list + per-column mass attached below.

Dollar inputs lost (default 0 → mass vanishes; selected, dense-weighted)

column dense mass consequence example
stock_assets + bank_account_assets + bond_assets $44.0T SSI/TANF/Medicaid resource tests dead (#356)
unadjusted_basis_qualified_property (+SSTB variants) $2.1T QBI deduction mis-scores
employer_sponsored_insurance_premiums $1,129B ESI/ACA interactions
pre_subsidy_rent $590B SNAP excess-shelter deduction, housing analyses
w2_wages_from_qualified_business (+SSTB) $332B QBI wage limit
unreimbursed_business_employee_expenses $218B itemized/state conformity
veterans_benefits $177B benefit-conditioned programs
taxable_401k/403b/SEP/keogh distributions, tax_exempt_ira_distributions $174B retirement-income policy
survivor_benefits $112B income surface
fsla_overtime_premium $103B OBBBA overtime deduction scores ~$0
tip_income $59B OBBBA tips deduction scores ~$0
salt_refund_income $44B AMT/itemizer interactions
child_support_received/expense, alimony_income/expense $89B means-tested income definitions
financial_assistance, disability_benefits, workers_compensation, casualty_loss, qualified_tuition_expenses, educator_expense, investment_interest_expense, … $10–40B each various

Flag inputs lost with real signal (default False → population zeroed)

  • is_disabled (12.6% weighted) — disability pathways in SSI/Medicaid, SNAP ABAWD exemptions (being actively seeded in #350–#353; those seeds vanish at export unless presence-gated)
  • is_blind (3.1%) — SSI/Medicaid blind category, extra standard deduction
  • is_pregnant (1.1%), receives_wic (0.8%) — WIC/Medicaid pregnancy pathways (#352)
  • is_full_time_college_student (3.8%), is_separated, is_surviving_spouse, AOTC enrollment flags (~1.7%) — filing status and education credits
  • immigration_status_str, ssn_card_type (categorical) — SSN/citizenship-conditioned policy (#225 family)

Currently-degenerate but contract-relevant (default True, stored all-true)

takes_up_ssi_if_eligible, takes_up_medicaid_if_eligible, takes_up_medicare_if_eligible, takes_up_{early_}head_start_if_eligible, would_claim_wic, is_wic_at_nutritional_risk, *_would_be_qualified QBI flags. Dropping these is a no-op today because the dense columns are all-true and the engine defaults match — but the moment real take-up rates are seeded (per the #312/#315 contract), the export must carry them or the seeds silently revert to full take-up.

Suggested fix

  • Extend the Build-I export gate (#359 checks export mass on 35 columns) to the full input surface: column presence + mass vs the dense parent, with reviewed exclusions only for formula-owned exports (#24) and justified band-math cases.
  • The selection step doesn't need new data — every dropped column exists on the pool rows; the subset export just needs to keep them.
  • Classify each column in the #49 inventory (populated / upstream-populated / reviewed-excluded) as acceptance criteria.

Relates #278, #356, #359, #312, #315, #350, #352, #225, #38, #49. Found while re-running the SSI asset-limit analysis (PolicyEngine/ssi-asset-limits) on the certified small default via policyengine.py 4.20.0.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Build-I export gate in #359 and compare its current 35-column checks with the full input surface described here. Use the #49 inventory to classify columns, then verify sparse output presence and dense-weighted mass, excluding only formula-owned or reviewed band-math columns.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data-engineering
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.