Problem
propagate_metadata_to_children: true currently copies every parent metadata field to every descendant except for a fixed internal set (breakdown, label, name, and description). This includes operational fields such as uprating.
Country packages sometimes need descriptive metadata such as unit and period to reach value-bearing children without activating a parent-level uprating rule. For example, gov.usda.snap.asset_test.limit in PolicyEngine US declares unit, period, and uprating on its container. Enabling the existing propagation option would both repair its child metadata and generate new future values, combining a metadata correction with a policy-data change.
The same limitation currently requires PolicyEngine US to repeat unit and period metadata explicitly on four other container parameters:
gov.contrib.biden.budget_2025.capital_gains.income_threshold
gov.irs.income.exemption.phase_out.start
gov.states.az.tax.income.deductions.standard.amount
gov.states.co.tax.income.subtractions.collegeinvest_contribution.max_amount
See PolicyEngine/policyengine-us#5208 and PolicyEngine/policyengine-us#9375.
Proposed behavior
Add an explicit deny-list to metadata propagation. A parameter should be able to enable recursive propagation while naming fields, such as uprating, that must remain on the parent.
Requirements:
- Preserve the behavior of the existing boolean
propagate_metadata_to_children: true form when no deny-list is supplied.
- Exclude only the metadata keys explicitly named by the parameter; all other currently propagating fields should continue to propagate.
- Support any metadata key rather than special-casing
uprating.
- Validate the deny-list structure and entries during parameter loading.
- Preserve the existing parent-versus-child overwrite behavior unless that behavior is deliberately changed and documented separately.
- Apply the deny-list consistently to nested descendants.
Required opt-in/opt-out behavior
Core should reject the ambiguous case in which a container declares unit or period, at least one value-bearing descendant lacks the same field, and propagate_metadata_to_children is absent.
propagate_metadata_to_children: true means that all non-denied metadata fields are inherited and must match on value-bearing descendants after propagation.
propagate_metadata_to_children: false is an explicit decision not to inherit parent metadata; missing or different child fields are therefore permitted.
- If
propagate_metadata_to_children is omitted, every value-bearing descendant must already define matching unit and period metadata wherever the parent defines those fields. This supports explicit child metadata without requiring propagation.
- Fields named in the deny-list are treated as explicitly excluded and are not subject to the descendant-matching requirement.
- Validation errors should identify the parent parameter, the affected metadata fields, and representative descendants, and should instruct the author to enable propagation, disable it explicitly, or define child metadata.
This validation should run after the complete parameter tree is available so nested descendants can be checked. To avoid an immediate breaking change across country packages, it can initially be exposed as strict validation for package test suites and become default behavior in a later major release.
Tests
- Existing boolean propagation remains unchanged.
- Unit and period propagate while a denied
uprating field does not.
- Metadata fields not named in the deny-list still propagate.
- Multiple denied fields and nested descendants behave consistently.
- Invalid deny-list structures produce a clear parameter parsing error.
- A parent unit or period with missing child metadata and no propagation decision fails strict validation.
- Explicit
false permits intentionally unpropagated metadata.
- An omitted propagation decision is accepted when all children already define matching metadata.
- Denied fields are excluded from strict descendant-matching validation.
This issue tracks the Core capability only. Applying it to the US SNAP asset-limit parameter is separate follow-up work.
Problem
propagate_metadata_to_children: truecurrently copies every parent metadata field to every descendant except for a fixed internal set (breakdown,label,name, anddescription). This includes operational fields such asuprating.Country packages sometimes need descriptive metadata such as
unitandperiodto reach value-bearing children without activating a parent-level uprating rule. For example,gov.usda.snap.asset_test.limitin PolicyEngine US declaresunit,period, andupratingon its container. Enabling the existing propagation option would both repair its child metadata and generate new future values, combining a metadata correction with a policy-data change.The same limitation currently requires PolicyEngine US to repeat unit and period metadata explicitly on four other container parameters:
gov.contrib.biden.budget_2025.capital_gains.income_thresholdgov.irs.income.exemption.phase_out.startgov.states.az.tax.income.deductions.standard.amountgov.states.co.tax.income.subtractions.collegeinvest_contribution.max_amountSee PolicyEngine/policyengine-us#5208 and PolicyEngine/policyengine-us#9375.
Proposed behavior
Add an explicit deny-list to metadata propagation. A parameter should be able to enable recursive propagation while naming fields, such as
uprating, that must remain on the parent.Requirements:
propagate_metadata_to_children: trueform when no deny-list is supplied.uprating.Required opt-in/opt-out behavior
Core should reject the ambiguous case in which a container declares
unitorperiod, at least one value-bearing descendant lacks the same field, andpropagate_metadata_to_childrenis absent.propagate_metadata_to_children: truemeans that all non-denied metadata fields are inherited and must match on value-bearing descendants after propagation.propagate_metadata_to_children: falseis an explicit decision not to inherit parent metadata; missing or different child fields are therefore permitted.propagate_metadata_to_childrenis omitted, every value-bearing descendant must already define matching unit and period metadata wherever the parent defines those fields. This supports explicit child metadata without requiring propagation.This validation should run after the complete parameter tree is available so nested descendants can be checked. To avoid an immediate breaking change across country packages, it can initially be exposed as strict validation for package test suites and become default behavior in a later major release.
Tests
upratingfield does not.falsepermits intentionally unpropagated metadata.This issue tracks the Core capability only. Applying it to the US SNAP asset-limit parameter is separate follow-up work.