Skip to content

UK dated reforms skip fiscal-year processing in Simulation(policy=...) and calculate_household, and dict policies cannot carry an end date #572

Closed

Description

@MaxGhenis

Summary

UK dated reforms through policyengine.py give a different answer from the same reform written as a policyengine-uk statutory change.

  1. Simulation(policy=...) builds an unreformed Microsimulation, then applies ParameterValues through simulation_modifier_from_parameter_values. That edits the already-annualised parameters (tax_benefit_models/uk/model.py, run). So a change from 6 April misses that fiscal year, and derived parameters stay on the baseline: indexed thresholds, aligned NICs thresholds, and anything uprated from a changed forecast. Reforms also arrive after policyengine-uk has computed its UC rebalancing inputs and parameter-gated structural reforms, so reforms of those parameters do nothing.
  2. pe.uk.calculate_household(reform=...) passes dated keys straight to policyengine-uk's dict route, which reads a lone "YYYY-MM-DD" key as a one-day override. So {"gov.hmrc.income_tax.rates.uk[0].rate": {"2027-04-06": 0.21}} changes nothing. Simulation(policy=...) reads the same key as an effective date.
  3. The dict compiler (common/reform.py, _reform_dict_to_parameter_values) parses keys strictly as %Y-%m-%d, so a finite change ("2027-04-06.2028-04-05") cannot be written as a dict. The sim API therefore drops stop dates before calling the wrapper (PolicyEngine/policyengine-sim-api, _normalise_period_key).
  4. tests/test_household_impact.py only asserts that a UK child benefit reform returns floats, so it passes when the reform has no effect.

Fix

  • Pass UK policies to policyengine-uk as an explicit-interval reform dict. policyengine-uk (Apply dated reforms on the statutory timeline on every route policyengine-uk#2305) then writes them onto the statutory timeline and processes them as current law.
  • Give the household route the same effective-date reading as Simulation(policy=...).
  • Accept "start.stop" interval keys in dict policies, and reject bare years with an explanation.

Part of the UK Autumn Budget 2026 CI plan (workstream W1).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions