You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#114 added the delegation seam: USMicroplexPipeline._build_policyengine_tax_units_via_microunit calls microunit.construct_tax_unitsonly when the person frame carries microunit's raw CPS input columns, otherwise returns None and falls back to the legacy role-flag reconstruction. On today's data it always returns None — the delegation is inert. This issue is the activation.
Where the delegation actually runs
The microunit path is in PolicyEngine materialization: build_policyengine_entity_tables(population) → _build_policyengine_tax_units(persons) (src/microplex_us/pipelines/us.py, ~4095 / ~4134). persons there is the synthesized population carrying microplex's normalized columns (household_id, age, marital_status, spouse_person_number, relationship_to_head, …), not raw CPS names — cps.py renames the raw columns very early (PH_SEQ→household_id, A_SPOUSE→spouse_person_number).
So activation is not "un-drop raw columns in a reader." It is: build microunit's CPS-like input contract from the normalized columns microplex already carries at materialization — directly analogous to the ACS→CPS mapping microunit documents as the consumer's responsibility.
heuristic parent-line inference from relationship + ages (none carried)
The work
Add a normalized person frame → microunit CPS contract adapter at materialization (line-number assignment, marital + relationship code maps, spouse-line resolution, heuristic parent inference).
Gate it behind a default-OFF config flag so default behavior is unchanged until validated.
Have _build_policyengine_tax_units_via_microunit use the adapter when raw cols are absent but the normalized cols are present.
⚠️ This is the entity-convergence switch (see #113)
Activating this makes microplex's tax units converge toward eCPS's (microunit is eCPS's engine). Per #113, do not report any "microplex beats eCPS" result off this change — measure it as an entity-convergence effect with a matched-N, symmetric-refit, holdout before/after comparison on the same target surface. Expected direct effect: the tax-unit/SPM under-splitting #113 traces ~78% of the loss gap to (MP ~1.16 tax units/hh vs eCPS ~1.34).
Acceptance
The adapter builds a microunit-valid frame from the normalized columns; the delegation fires on real synthesized data.
The fidelity of the lossy maps (A_EXPRRP from relationship_to_head, heuristic PEPAR1/PEPAR2) is validated — e.g. agreement with the legacy role-flag reconstruction on households where both can run, before trusting it.
Existing entity/pipeline tests stay green; default behavior unchanged with the flag off.
The before/after isolation comparison is run and reported as an entity-convergence effect, not a quality claim.
Follow-up to #113 and #114.
#114 added the delegation seam:
USMicroplexPipeline._build_policyengine_tax_units_via_microunitcallsmicrounit.construct_tax_unitsonly when the person frame carries microunit's raw CPS input columns, otherwise returnsNoneand falls back to the legacy role-flag reconstruction. On today's data it always returnsNone— the delegation is inert. This issue is the activation.Where the delegation actually runs
The microunit path is in PolicyEngine materialization:
build_policyengine_entity_tables(population)→_build_policyengine_tax_units(persons)(src/microplex_us/pipelines/us.py, ~4095 / ~4134).personsthere is the synthesized population carrying microplex's normalized columns (household_id,age,marital_status,spouse_person_number,relationship_to_head, …), not raw CPS names —cps.pyrenames the raw columns very early (PH_SEQ→household_id,A_SPOUSE→spouse_person_number).So activation is not "un-drop raw columns in a reader." It is: build microunit's CPS-like input contract from the normalized columns microplex already carries at materialization — directly analogous to the ACS→CPS mapping microunit documents as the consumer's responsibility.
Available vs. must-be-derived
microunit needs
PH_SEQ, A_LINENO, A_AGE, A_MARITL, A_SPOUSE, PEPAR1, PEPAR2, A_EXPRRP:PH_SEQhousehold_id(direct)A_AGEage(direct)A_MARITLmarital_status→ CPS marital codes (map)A_LINENOA_SPOUSEspouse_person_number→ spouse's line number (after A_LINENO is assigned)A_EXPRRPrelationship_to_head(0/1/2/3) → CPS recode (lossy/approximate)PEPAR1/PEPAR2The work
normalized person frame → microunit CPS contractadapter at materialization (line-number assignment, marital + relationship code maps, spouse-line resolution, heuristic parent inference)._build_policyengine_tax_units_via_microunituse the adapter when raw cols are absent but the normalized cols are present.Activating this makes microplex's tax units converge toward eCPS's (microunit is eCPS's engine). Per #113, do not report any "microplex beats eCPS" result off this change — measure it as an entity-convergence effect with a matched-N, symmetric-refit, holdout before/after comparison on the same target surface. Expected direct effect: the tax-unit/SPM under-splitting #113 traces ~78% of the loss gap to (MP ~1.16 tax units/hh vs eCPS ~1.34).
Acceptance
A_EXPRRPfromrelationship_to_head, heuristicPEPAR1/PEPAR2) is validated — e.g. agreement with the legacy role-flag reconstruction on households where both can run, before trusting it.A first prototype of the adapter (flag-gated, default off) is in progress — see the linked PR.