PolicyEngine / PolicyEngine/microcosm
Recompute audit (SEVERE): one-shot materializations lack #461 system-reuse (340+ engine builds); smoke+validation run 85 standalone sims; preflight registry identity gap
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 4
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 94
Description
Cross-model recompute audit of the US release pipeline (gpt-5.6-sol sweep, fable-adjudicated), prompted by the #463 reconcile finding: where else does the pipeline recompute the invariant? Verdict: SEVERE. Findings ranked by impact, with adjudication:
Adjudication summary: findings 1, 2, 4 CONFIRMED against the code (2 is #461's own family-system pattern never applied to the one-shot ACA/Medicaid/SSI/SNAP/other-health materializations — 340+ full engine-system builds per release at 68 batches × 5 families, each paying the core#520 module leak; this is the remaining post-#461 memory floor). Finding 3 documents further invariant work inside the reconcile loop — historical once the #463 deletion lands, listed for completeness. Findings 5-7 are real frame-copy/IO class. Finding 8 contains a correctness defect beyond waste: standalone preflight compiles the registry without the build's CD-inclusion/crosswalk/exclusion identity inputs, so preflight can pass a configuration the build rejects — that gap should be closed regardless of caching. Refutations (preflight double-materialization, eCPS reference reloads, aging row-work, QRF refit duplication) verified as stated.
Sequencing: findings 2+4+5 belong to the #463 staging work (same surfaces, same acceptance run); finding 1 is a separable increment (shared baseline + branch per reform, content-addressed totals — the #461 verification bar applies: byte-identical scoring vs independent simulations on a pinned slice); findings 6+7 are small cleanups; finding 8's identity gap gets its own fix. Raw audit follows.
VERDICT: SEVERE
-
(
packages/populace-build/src/populace/build/us_runtime/reform_coverage_smoke.py:99,packages/populace-build/src/populace/build/us_runtime/reform_validation.py:739,packages/populace-build/src/populace/build/us_runtime/reform_validation.py:769,packages/populace-build/src/populace/build/us_runtime/reform_validation.py:805,packages/populace-build/src/populace/build/us_runtime/reform_validation.py:677) — Smoke and reform validation repeatedly load the written H5 and construct independent full-release simulations. Smoke executes 40 simulations: onebaseline, then onereformedfor each of 39probevalues. Reform validation executes 45 more: for OBBBA,group× (pre-baseline+ eachspec) = 2 + 18 = 20; for the 24 non-OBBBA out-of-samplespecvalues, one shared baseline plus 24 reforms = 25. Total: 85 full simulations and 85 H5 dataset constructions per default release, before the separate demographics simulation. What changes: only the reform parameter patch; the exported records, weights, entity maps, baseline policy, and most computed dependency graph are INVARIANT. Alternative: load the dataset once, construct one baseline simulation/system, branch or clone it for each reform, cache baseline totals by(measure, period), and share content-addressed reform totals between smoke and reform-validation when reform identity matches. For simple neutralizations, persist or reuse per-record baseline/reform tax deltas already materialized for calibration. Cost: engine-simulation + IO. Highest build-time and peak-memory impact. -
(
tools/build_us_fiscal_refresh_release.py:2458,tools/build_us_fiscal_refresh_release.py:2672,tools/build_us_fiscal_refresh_release.py:2759,tools/build_us_fiscal_refresh_release.py:2974,packages/populace-build/src/populace/build/us_runtime/other_health_insurance.py:590) — The “one-shot” ACA, Medicaid, SSI, SNAP, and other-health materializations still build simulations inside household-batch loops. The first four callMicrosimulation(dataset=...)for everyhousehold_positions; other-health callsengine.materialize(...)for everystart, whose adapter creates a freshMicrosimulation(dataset=dataset)internally. WithB = ceil(n_households / 5,000), this is at least5Bsimulation constructions before reconciliation:household_positionsfor ACA, Medicaid, SSI, SNAP, plusstartfor other-health. On a 338k-household pool,B=68, hence at least 340 constructions. What changes: only batch records; the tax-benefit system, parameter tree, variable metadata, entity definitions, and requested-variable set are INVARIANT. Alternative: construct one family/system object per one-shot materialization and pass it explicitly to all batch simulations, matching the already-correct JCT family-system pattern attools/build_us_fiscal_refresh_release.py:3321; the adapter should likewise accept/reuse that system. Cost: engine-simulation, with permanent metadata/module memory growth risk. -
(
tools/build_us_fiscal_refresh_release.py:5522,tools/build_us_fiscal_refresh_release.py:5603,tools/build_us_fiscal_refresh_release.py:5411) — Additional invariant engine work remains inside the known SSI reconciliation loop beyond target rematerialization. Eachpass_numbercomputesuncapped_ssitwice: once oncurrent_support, then again onexport_frame.uncapped_ssiis explicitly documented as independent of SSI take-up attools/build_us_fiscal_refresh_release.py:2717; weight changes also cannot affect its per-person values. Thus both calls are INVARIANT across the two evaluations and across passes unless actual SSI-formula inputs change—which this loop does not do. Each call costsBsimulations, so 2B perpass_number, up to2B × max_passes. Additionally,_ssi_take_up_fresh_pair_exitrecomputes Medicaid eligibility for stale diagnostics after the dependency replay already computed eligibility on the same fixed flags; only weights changed. Alternative: computeuncapped_ssionce beforefor pass_number, retain it aligned by person ID, and pass cached Medicaid eligibility vectors into diagnostics; recompute Medicaid only after a take-up/input mutation that can change eligibility. Cost: engine-simulation. This is separate from populace#463’s target-family rematerialization defect. -
(
tools/build_us_fiscal_refresh_release.py:301,tools/build_us_fiscal_refresh_release.py:1104,tools/build_us_fiscal_refresh_release.py:3174) — Batch size defaults unconditionally to 5,000 households. Every applicable family executesfor start in range(0, n_households, batch_size)orfor household_positions in batches; there is no RAM-based sizing or post-#461 system-footprint estimate. On 338k households this forces 68 batches per family even on machines capable of materially larger batches. What changes: only record slices; batch-control and family metadata are INVARIANT. Alternative: select batch size from an explicit memory budget or measured bytes-per-household after constructing the family system, with 5,000 retained only as a conservative fallback; allow one full batch when projected working-set memory fits. Cost: engine-simulation + frame-copy. Verdict on suspect 8: CONFIRMED. -
(
tools/build_us_fiscal_refresh_release.py:3113,tools/build_us_fiscal_refresh_release.py:3338,packages/populace-build/src/populace/build/us_runtime/other_health_insurance.py:606) — Every batch creates a new selectedFrameand then_dataset_from_framecopies every entity table again. Execution count is once perhousehold_positionsfor each batched family and reform, includingB × requested JCT reform families, plus the one-shot and reconciliation families. What changes: row membership only; schema, columns, entity linkage definitions, and most columns’ backing values are INVARIANT. The copy is particularly redundant because selection materializes entity frames and dataset conversion immediately copies them again. Alternative: construct batch index maps once, slice arrays directly into the engine dataset, or add a non-copying/ownership-transfer dataset adapter so each batch performs at most one materialization. Cost: frame-copy. Material at 68 batches multiplied across families; also amplifies peak memory during simulation construction. -
(
tools/build_us_fiscal_refresh_release.py:4429,tools/build_us_fiscal_refresh_release.py:4469,tools/build_us_fiscal_refresh_release.py:4685,tools/build_us_fiscal_refresh_release.py:8590) — Gate setup reconstructs identical engine metadata surfaces._engine_input_variables()creates a freshPolicyEngineUSEngineon every call; it is invoked by the pre-calibration input-mass gate, eCPS parity evaluation, and export-mass gate, while the degenerate-input gate receives another separately constructed adapter. Execution: approximately four engine-system metadata builds per release, outside the cached_FORMULA_OWNED_GATE_ADAPTER; loop variable: gate invocation, not records. What changes: nothing—installed PolicyEngine-US version and variable registry are INVARIANT for the process. Alternative: one process-wide adapter and one cached tuple of input-variable names shared by every gate. Cost: engine-simulation/metadata construction and retained module memory. Verdict on suspect 4’s registry-compilation aspect: repeated engine registry compilation is CONFIRMED, although the pinned eCPS JSON reference itself is loaded only once by_ecps_parity_gate. -
(
tools/build_us_fiscal_refresh_release.py:4438,tools/build_us_fiscal_refresh_release.py:9060) — Reference H5 loading is not shared between mass gates._input_mass_reference_gateloads and scansreference_h5; later the export gate independently callsload_us_frame(args.export_input_mass_reference_h5)and rescans it. If the two CLI paths identify the same certified release—the normal useful configuration—the full reference is loaded twice during the build. With standalone preflight, that process loads it a third time. What changes: only the candidate frame changes frombase_frametoexport_frame; the reference frame and reference weighted totals are INVARIANT. Alternative: load once, cache by resolved path plus file hash, precomputereference_totalsonce, and pass those totals to both gates. Cost: IO + frame-copy/full-column matrix scan. -
(
packages/populace-build/src/populace/build/us_runtime/release_gate_preflight.py:776,tools/build_us_fiscal_refresh_release.py:7171) —compile_us_fiscal_target_registryexecutes once in standalone preflight and once again in the build: two calls per preflight+release workflow. It is not called by later build gates, smoke, or reform validation. What changes: nothing when the ledger facts, target period, aging flag, CD flag/crosswalk, support exclusions, and installed target-profile resources match; under those complete inputs the result is deterministic. Preflight currently omits several build identity inputs—CD inclusion/crosswalk,allow_unaged_dollar_targets, and extra exclusions—so its result is not necessarily identical to the build result despite using the same feed. Alternative: serialize a content-addressed compiled registry keyed by ledger artifact hash plus every compilation flag/resource hash, and have both commands consume it; alternatively run preflight through the build’s exact compilation configuration. Cost: matrix-op/registry compilation. Lower than the simulation findings but potentially material for large CD feeds. Verdict on suspect 5: CONFIRMED at two workflow calls, not repeated per gate.
Refuted suspects:
- Suspect 2, preflight/build double target materialization: REFUTED. Preflight loads the base/reference frames and performs static support/mass checks; it never calls
_materialize_target_frame. Therefore there is no preflight target-frame cache identity to share or mismatch. Its registry compilation is duplicated, as finding 8 records. - Suspect 4, repeated pinned eCPS reference loading per gate: REFUTED.
_ecps_parity_gateloads the checked-in reference and known-gaps register once per invocation. The separate live H5 mass-reference duplication is finding 7. - Suspect 6, aging repeated work per
(period, series): REFUTED.age_us_dollar_targetsprecomputesprojectionsandchain_seriesonce beforefor spec in registry.specs; per-row work is lookup, factor application, and metadata construction. - Suspect 7, identical QRF refits across release arms/attempts: REFUTED in the in-process release path. Each source/imputation stage is invoked once for its output family; no enclosing arm/attempt loop refits an identical
(donor, receiver, predictors, targets, seed)model. Cross-process failed-attempt reuse is absent, but no repeated identical fit within one build was found.
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.
Research direction
Start with the sequenced surfaces in tools/build_us_fiscal_refresh_release.py, packages/populace-build/src/populace/build/us_runtime/reform_validation.py, reform_coverage_smoke.py, other_health_insurance.py, and release_gate_preflight.py. Pick one separately scoped increment, then run its named smoke, validation, or preflight workflow; done requires the stated reuse or identity behavior without changing results, including byte-identical scoring where specified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system, data-engineering, performance
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100