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
When the no-formula rule (formula_owned_export) and the eCPS-parity rule (parity) conflict, no-formula wins. A variable that PolicyEngine computes via formula must never be persisted as an input — even if enhanced CPS persists it.
Why
eCPS itself stores formula-derived values it shouldn't. Example: traditional_ira_contributions (and the other contribution variables) should follow from the *_desired inputs plus the statutory caps, computed by the engine — not be frozen as a stored column. eCPS storing the computed contribution is an eCPS bug. If populace matches eCPS (the parity gate requires populace to populate every layer eCPS populates), it inherits that bug and masks the engine's cap logic.
So the gates must be ordered: a formula-owned variable is dropped regardless of eCPS, and parity must exempt formula-owned variables from its "populate what eCPS populates" requirement (the engine computes them, so a "gap" there is correct, not a regression).
Scope / changes
parity_gate (or its runner) must treat formula-owned variables as exempt — not a parity gap when populace omits a formula-owned layer eCPS happens to store.
(person_id is a structural ID — keep via the structural_columns allow-list, not dropped)
The canonical "formula-owned" set is the oracle for both gates: has an engine formula ⇒ not persisted (minus a documented structural allow-list).
Follow-ups (separate, lower priority)
File the eCPS-side bug upstream in policyengine-us-data (eCPS shouldn't persist traditional_ira_contributions etc. either) — but populace should not wait on that; the precedence rule makes populace correct independently.
Decision
When the no-formula rule (
formula_owned_export) and the eCPS-parity rule (parity) conflict, no-formula wins. A variable that PolicyEngine computes via formula must never be persisted as an input — even if enhanced CPS persists it.Why
eCPS itself stores formula-derived values it shouldn't. Example:
traditional_ira_contributions(and the other contribution variables) should follow from the*_desiredinputs plus the statutory caps, computed by the engine — not be frozen as a stored column. eCPS storing the computed contribution is an eCPS bug. If populace matches eCPS (the parity gate requires populace to populate every layer eCPS populates), it inherits that bug and masks the engine's cap logic.So the gates must be ordered: a formula-owned variable is dropped regardless of eCPS, and
paritymust exempt formula-owned variables from its "populate what eCPS populates" requirement (the engine computes them, so a "gap" there is correct, not a regression).Scope / changes
parity_gate(or its runner) must treat formula-owned variables as exempt — not a parity gap when populace omits a formula-owned layer eCPS happens to store.traditional_ira_contributions(←*_desired+ statutory caps)self_employed_pension_contribution_aldspm_unit_capped_work_childcare_expensesperson_idis a structural ID — keep via thestructural_columnsallow-list, not dropped)Follow-ups (separate, lower priority)
traditional_ira_contributionsetc. either) — but populace should not wait on that; the precedence rule makes populace correct independently.Related: #24 (formula-owned over-export — this expands its drop list), PolicyEngine/populace-benchmarks#1 (parity gate — this adds the exemption).