PolicyEngine / PolicyEngine/microcosm-dynamics
Employer–firm: where we are
@MaxGhenis is already working on this.
Since Aug 12, 2026.
- Dominant language
- Python
- Stars
- 1
- Forks
- 1
- Avg merge
- 1h 46m
- Merged PRs (30d)
- 28
Description
The plan assumed we would have to invent synthetic firms, because it was believed no public firm microdata existed.
It does. So the firm side now uses real firms.
Where the data comes from
| Side | Source | What it gives |
|---|---|---|
| Workers | SIPP, CPS ASEC, PSID | real people and real job records |
| Firms | Form 5500 (DOL/EBSA) | 828,330 real employers |
| Firms | OSHA ITA | 383,283 real workplaces |
| Targets | SUSB, BDS, QWI / J2J | official national totals to match against |
All are US federal government works: free, no data-use agreement, no FSRDC, and redistributable.
Form 5500 is the same frame the US Department of Labor's own PENSIM microsimulation has used since 1997.
What we built
Firm side — read the real firm records and reweight them so the totals match official US statistics. No firm is invented. #386 (readers), #390 (frame).
Worker side — give CPS people job details predicted from real SIPP workers, using the same quantile-regression method the Enhanced CPS uses for earnings.
The connection — place workers into firms, respecting how many employees each firm actually has, with a fixed random seed so the result is exactly reproducible.
Cleanup — merged seven stuck PRs (#277, #274, #224, #228, #235, #236, #212), including all of Workstream A's evidence (the person side — SIPP and CPS readers, noise floors, the seam reconciliation) before the branches went stale. #276 is in CI.
The pipeline, and where each piece stands
flowchart LR
DATA["<b>Public data</b><br/>SIPP · CPS · PSID<br/>Form 5500 · OSHA<br/>SUSB · QWI"]
PEOPLE["<b>Workers</b><br/>real CPS people,<br/>job details imputed"]
FIRMS["<b>Firms</b><br/>real employers,<br/>reweighted to official totals"]
LINK["<b>Match them</b><br/>assign workers to firms"]
IC3{"<b>Lock IC3</b><br/>freeze the scorecard"}
SCORE["<b>Score</b><br/>run on real people,<br/>compare against the gates"]
DATA --> PEOPLE
DATA --> FIRMS
PEOPLE --> LINK
FIRMS --> LINK
LINK --> IC3
IC3 -.-> SCORE
style DATA fill:#2f6f52,color:#fff
style PEOPLE fill:#b8721a,color:#fff
style FIRMS fill:#b8721a,color:#fff
style LINK fill:#b8721a,color:#fff
style IC3 fill:#8b3a3a,color:#fff
style SCORE stroke-dasharray:4
| 🟩 | Done — readers, targets and noise floors are merged |
| 🟧 | Built, but unreviewed — all of it sits in #386 and #390 |
| 🟥 | Blocked — IC3 needs an independent referee |
| ⬜ | Not started — the pipeline has never run on real people |
The critical path runs through the red box: nothing downstream can begin until IC3 locks.
What IC3 is, briefly
IC3 is the pre-registered scorecard: the exact list of tests the model must pass, with thresholds, written down and frozen before anyone fits a model. The point is that nobody can move the goalposts after seeing results.
It is not locked yet, and locking it needs an independent referee — someone who did not build the model. That is the main thing blocking progress.
What is still missing
- Nothing is reviewed. About 3,000 lines of new code across #386 and #390, written by one person, with zero independent review.
- It has never run on real people. SIPP is not staged on the machine used, so the pipeline has only been exercised on fixtures and test panels.
- IC3 cannot lock without an independent referee.
- Job-change dynamics (phase 1) are not started.
- The plan page and the unmerged #230 still describe synthetic firms and need updating.
One number worth registering before thresholds lock
Two independent official administrative measures of firm size — Form 5500 and OSHA — disagree about which size band a firm belongs to 34% of the time across the 43,001 employers they share.
A firm-size gate set tighter than that is finer than the measuring instruments can resolve. This belongs with the existing noise floors, and it is only useful before IC3 locks.
Related
- #387 — repo cleanup: superseded registration issues and stale PRs
- #282 — synthetic-firm scoping; its original premise ("we cannot get firm microdata") no longer holds for the firm frame, though the E12 question about the worker-to-firm link still stands
What has not changed
No public data links a worker to their actual employer. The worker-to-firm assignment is still simulated, and the claims boundary recorded on #282 stands: no identified firm effects, no coworker sorting, no AKM-style decompositions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.