PolicyEngine / PolicyEngine/policyengine-core

Allow metadata propagation to exclude selected fields

Open
#537 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
22
Forks
30
Avg merge
14h 33m
Merged PRs (30d)
7

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating parameter loading and the metadata propagation validation over the complete parameter tree. Add coverage for boolean propagation, denied fields, nested descendants, invalid deny-lists, and strict validation with omitted or explicit false decisions. Done means the listed validation and propagation cases pass while existing boolean behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.