policyengine 6.4.1__tar.gz → 6.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. {policyengine-6.4.1 → policyengine-6.4.2}/CHANGELOG.md +7 -0
  2. {policyengine-6.4.1/src/policyengine.egg-info → policyengine-6.4.2}/PKG-INFO +1 -1
  3. {policyengine-6.4.1 → policyengine-6.4.2}/pyproject.toml +1 -1
  4. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/bundle/manifest.json +10 -10
  5. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/bundle/uk.trace.tro.jsonld +5 -5
  6. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/bundle/us.trace.tro.jsonld +5 -5
  7. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/budget_reform_population.py +126 -16
  8. {policyengine-6.4.1 → policyengine-6.4.2/src/policyengine.egg-info}/PKG-INFO +1 -1
  9. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_budget_reform_contract.py +227 -1
  10. {policyengine-6.4.1 → policyengine-6.4.2}/uv.lock +1 -1
  11. {policyengine-6.4.1 → policyengine-6.4.2}/.claude/policyengine-guide.md +0 -0
  12. {policyengine-6.4.1 → policyengine-6.4.2}/.claude/quick-reference.md +0 -0
  13. {policyengine-6.4.1 → policyengine-6.4.2}/.github/CONTRIBUTING.md +0 -0
  14. {policyengine-6.4.1 → policyengine-6.4.2}/.github/bump_version.py +0 -0
  15. {policyengine-6.4.1 → policyengine-6.4.2}/.github/capture-version.sh +0 -0
  16. {policyengine-6.4.1 → policyengine-6.4.2}/.github/changelog_template.md +0 -0
  17. {policyengine-6.4.1 → policyengine-6.4.2}/.github/check-changelog.sh +0 -0
  18. {policyengine-6.4.1 → policyengine-6.4.2}/.github/copilot-instructions.md +0 -0
  19. {policyengine-6.4.1 → policyengine-6.4.2}/.github/dispatch-policyengine-release.sh +0 -0
  20. {policyengine-6.4.1 → policyengine-6.4.2}/.github/fetch_version.py +0 -0
  21. {policyengine-6.4.1 → policyengine-6.4.2}/.github/get-changelog-diff.sh +0 -0
  22. {policyengine-6.4.1 → policyengine-6.4.2}/.github/has-functional-changes.sh +0 -0
  23. {policyengine-6.4.1 → policyengine-6.4.2}/.github/is-version-number-acceptable.sh +0 -0
  24. {policyengine-6.4.1 → policyengine-6.4.2}/.github/publish-git-tag.sh +0 -0
  25. {policyengine-6.4.1 → policyengine-6.4.2}/.github/wait-for-pypi.sh +0 -0
  26. {policyengine-6.4.1 → policyengine-6.4.2}/.github/workflows/draft-pdf.yml +0 -0
  27. {policyengine-6.4.1 → policyengine-6.4.2}/.github/workflows/pr_code_changes.yaml +0 -0
  28. {policyengine-6.4.1 → policyengine-6.4.2}/.github/workflows/pr_docs_changes.yaml +0 -0
  29. {policyengine-6.4.1 → policyengine-6.4.2}/.github/workflows/push.yaml +0 -0
  30. {policyengine-6.4.1 → policyengine-6.4.2}/.gitignore +0 -0
  31. {policyengine-6.4.1 → policyengine-6.4.2}/.python-version +0 -0
  32. {policyengine-6.4.1 → policyengine-6.4.2}/AGENTS.md +0 -0
  33. {policyengine-6.4.1 → policyengine-6.4.2}/CITATION.cff +0 -0
  34. {policyengine-6.4.1 → policyengine-6.4.2}/CLAUDE.md +0 -0
  35. {policyengine-6.4.1 → policyengine-6.4.2}/CODE_OF_CONDUCT.md +0 -0
  36. {policyengine-6.4.1 → policyengine-6.4.2}/CONTRIBUTING.md +0 -0
  37. {policyengine-6.4.1 → policyengine-6.4.2}/LICENSE +0 -0
  38. {policyengine-6.4.1 → policyengine-6.4.2}/Makefile +0 -0
  39. {policyengine-6.4.1 → policyengine-6.4.2}/README.md +0 -0
  40. {policyengine-6.4.1 → policyengine-6.4.2}/architecture.png +0 -0
  41. {policyengine-6.4.1 → policyengine-6.4.2}/architecture.svg +0 -0
  42. {policyengine-6.4.1 → policyengine-6.4.2}/changelog.d/.gitkeep +0 -0
  43. {policyengine-6.4.1 → policyengine-6.4.2}/docs/.gitignore +0 -0
  44. {policyengine-6.4.1 → policyengine-6.4.2}/docs/_generator/README.md +0 -0
  45. {policyengine-6.4.1 → policyengine-6.4.2}/docs/_generator/build_reference.py +0 -0
  46. {policyengine-6.4.1 → policyengine-6.4.2}/docs/_quarto.yml +0 -0
  47. {policyengine-6.4.1 → policyengine-6.4.2}/docs/bundles.md +0 -0
  48. {policyengine-6.4.1 → policyengine-6.4.2}/docs/countries.md +0 -0
  49. {policyengine-6.4.1 → policyengine-6.4.2}/docs/data-publishing-design.md +0 -0
  50. {policyengine-6.4.1 → policyengine-6.4.2}/docs/decile-impact-spec.md +0 -0
  51. {policyengine-6.4.1 → policyengine-6.4.2}/docs/dev.md +0 -0
  52. {policyengine-6.4.1 → policyengine-6.4.2}/docs/disclosure.md +0 -0
  53. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/runbooks/acs-local-wic-replacement.md +0 -0
  54. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/runbooks/build-m-us-populace-certification.md +0 -0
  55. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/runbooks/canonical-spm-development.md +0 -0
  56. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/runbooks/us-legacy-spm-sources.md +0 -0
  57. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/skills/README.md +0 -0
  58. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/skills/data-certification.md +0 -0
  59. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/skills/github-prs.md +0 -0
  60. {policyengine-6.4.1 → policyengine-6.4.2}/docs/engineering/skills/repository-guidance.md +0 -0
  61. {policyengine-6.4.1 → policyengine-6.4.2}/docs/examples.md +0 -0
  62. {policyengine-6.4.1 → policyengine-6.4.2}/docs/getting-started.md +0 -0
  63. {policyengine-6.4.1 → policyengine-6.4.2}/docs/households.md +0 -0
  64. {policyengine-6.4.1 → policyengine-6.4.2}/docs/impact-analysis.md +0 -0
  65. {policyengine-6.4.1 → policyengine-6.4.2}/docs/index.md +0 -0
  66. {policyengine-6.4.1 → policyengine-6.4.2}/docs/methodology/index.md +0 -0
  67. {policyengine-6.4.1 → policyengine-6.4.2}/docs/methodology/model-architecture.md +0 -0
  68. {policyengine-6.4.1 → policyengine-6.4.2}/docs/methodology/us-health-costs.md +0 -0
  69. {policyengine-6.4.1 → policyengine-6.4.2}/docs/microsim.md +0 -0
  70. {policyengine-6.4.1 → policyengine-6.4.2}/docs/outputs.md +0 -0
  71. {policyengine-6.4.1 → policyengine-6.4.2}/docs/programs/index.md +0 -0
  72. {policyengine-6.4.1 → policyengine-6.4.2}/docs/programs/us-chip.md +0 -0
  73. {policyengine-6.4.1 → policyengine-6.4.2}/docs/reference/index.md +0 -0
  74. {policyengine-6.4.1 → policyengine-6.4.2}/docs/reforms.md +0 -0
  75. {policyengine-6.4.1 → policyengine-6.4.2}/docs/regions.md +0 -0
  76. {policyengine-6.4.1 → policyengine-6.4.2}/docs/release-bundles.md +0 -0
  77. {policyengine-6.4.1 → policyengine-6.4.2}/docs/run-records.md +0 -0
  78. {policyengine-6.4.1 → policyengine-6.4.2}/docs/trace-case-study.md +0 -0
  79. {policyengine-6.4.1 → policyengine-6.4.2}/docs/visualisation.md +0 -0
  80. {policyengine-6.4.1 → policyengine-6.4.2}/examples/belgium_axiom_pilot.py +0 -0
  81. {policyengine-6.4.1 → policyengine-6.4.2}/examples/employment_income_variation_uk.py +0 -0
  82. {policyengine-6.4.1 → policyengine-6.4.2}/examples/employment_income_variation_us.py +0 -0
  83. {policyengine-6.4.1 → policyengine-6.4.2}/examples/household_impact_example.py +0 -0
  84. {policyengine-6.4.1 → policyengine-6.4.2}/examples/income_bands_uk.py +0 -0
  85. {policyengine-6.4.1 → policyengine-6.4.2}/examples/income_distribution_us.py +0 -0
  86. {policyengine-6.4.1 → policyengine-6.4.2}/examples/paper_repro_uk.py +0 -0
  87. {policyengine-6.4.1 → policyengine-6.4.2}/examples/policy_change_uk.py +0 -0
  88. {policyengine-6.4.1 → policyengine-6.4.2}/examples/speedtest_us_simulation.py +0 -0
  89. {policyengine-6.4.1 → policyengine-6.4.2}/examples/uk_geography_disclosure.py +0 -0
  90. {policyengine-6.4.1 → policyengine-6.4.2}/examples/us_budgetary_impact.py +0 -0
  91. {policyengine-6.4.1 → policyengine-6.4.2}/paper-preview.html +0 -0
  92. {policyengine-6.4.1 → policyengine-6.4.2}/paper.bib +0 -0
  93. {policyengine-6.4.1 → policyengine-6.4.2}/paper.md +0 -0
  94. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/bundle.py +0 -0
  95. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/certify_data_release.py +0 -0
  96. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/check_data_staleness.py +0 -0
  97. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/check_native_spm_loading.py +0 -0
  98. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/check_release_credentials.py +0 -0
  99. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/export_bundle_release_assets.py +0 -0
  100. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/generate_bundle_artifacts.py +0 -0
  101. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/generate_trace_tros.py +0 -0
  102. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/prepare_package_bundle_update.py +0 -0
  103. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/release_lock.py +0 -0
  104. {policyengine-6.4.1 → policyengine-6.4.2}/scripts/spm_bundle.py +0 -0
  105. {policyengine-6.4.1 → policyengine-6.4.2}/setup.cfg +0 -0
  106. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/__init__.py +0 -0
  107. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/bundle.py +0 -0
  108. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/cli.py +0 -0
  109. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/__init__.py +0 -0
  110. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/cache.py +0 -0
  111. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/dataset.py +0 -0
  112. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/dynamic.py +0 -0
  113. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/output.py +0 -0
  114. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/parameter.py +0 -0
  115. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/parameter_node.py +0 -0
  116. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/parameter_value.py +0 -0
  117. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/policy.py +0 -0
  118. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/region.py +0 -0
  119. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/run_record.py +0 -0
  120. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/scoping_strategy.py +0 -0
  121. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/simulation.py +0 -0
  122. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/spm.py +0 -0
  123. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/tax_benefit_model.py +0 -0
  124. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/tax_benefit_model_version.py +0 -0
  125. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/core/variable.py +0 -0
  126. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/__init__.py +0 -0
  127. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/uk/__init__.py +0 -0
  128. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/uk/regions.py +0 -0
  129. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/__init__.py +0 -0
  130. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/data/__init__.py +0 -0
  131. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/data/districts.py +0 -0
  132. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/data/places.py +0 -0
  133. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/data/states.py +0 -0
  134. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/countries/us/regions.py +0 -0
  135. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/__init__.py +0 -0
  136. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/schemas/trace_tro.schema.json +0 -0
  137. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/data/uk_geography_assets.py +0 -0
  138. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/derivations/__init__.py +0 -0
  139. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/derivations/narrate.py +0 -0
  140. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/derivations/trace.py +0 -0
  141. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/__init__.py +0 -0
  142. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/__main__.py +0 -0
  143. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/areas.py +0 -0
  144. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/estimate.py +0 -0
  145. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/noise.py +0 -0
  146. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/release.py +0 -0
  147. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/schema.py +0 -0
  148. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/support.py +0 -0
  149. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/disclosure/validate.py +0 -0
  150. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/graph/__init__.py +0 -0
  151. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/graph/extractor.py +0 -0
  152. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/graph/graph.py +0 -0
  153. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/__init__.py +0 -0
  154. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/aggregate.py +0 -0
  155. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/change_aggregate.py +0 -0
  156. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/cliff_impact.py +0 -0
  157. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/congressional_district_impact.py +0 -0
  158. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/constituency_impact.py +0 -0
  159. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/decile_analysis.py +0 -0
  160. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/decile_grouping.py +0 -0
  161. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/decile_impact.py +0 -0
  162. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/extra_variables.py +0 -0
  163. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/inequality.py +0 -0
  164. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/intra_decile_impact.py +0 -0
  165. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/labor_supply_response.py +0 -0
  166. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/local_authority_impact.py +0 -0
  167. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/poverty.py +0 -0
  168. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/program_statistics.py +0 -0
  169. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/uk_geography_assets.py +0 -0
  170. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/uk_geography_disclosure.py +0 -0
  171. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/outputs/uk_geography_impact.py +0 -0
  172. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/__init__.py +0 -0
  173. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/bundle_validation.py +0 -0
  174. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/certification.py +0 -0
  175. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/dataset_materialization.py +0 -0
  176. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/manifest.py +0 -0
  177. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/pyproject_pins.py +0 -0
  178. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/spm_configuration.py +0 -0
  179. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/trace.py +0 -0
  180. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/verify.py +0 -0
  181. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/provenance/zenodo.py +0 -0
  182. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/results/__init__.py +0 -0
  183. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/results/schema.py +0 -0
  184. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/results/trace_tro.py +0 -0
  185. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/results/tracking.py +0 -0
  186. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/be/__init__.py +0 -0
  187. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/be/datasets.py +0 -0
  188. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/be/model.py +0 -0
  189. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/__init__.py +0 -0
  190. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/axes.py +0 -0
  191. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/extra_variables.py +0 -0
  192. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/household.py +0 -0
  193. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/model_version.py +0 -0
  194. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/reform.py +0 -0
  195. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/common/result.py +0 -0
  196. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/__init__.py +0 -0
  197. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/analysis.py +0 -0
  198. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/budget_reform_contract.py +0 -0
  199. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/datasets.py +0 -0
  200. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/household.py +0 -0
  201. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/uk/model.py +0 -0
  202. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/__init__.py +0 -0
  203. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/analysis.py +0 -0
  204. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/datasets.py +0 -0
  205. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/household.py +0 -0
  206. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_inputs.py +0 -0
  207. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/__init__.py +0 -0
  208. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/declarations.py +0 -0
  209. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/independence.py +0 -0
  210. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/model_adapter.py +0 -0
  211. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/record.py +0 -0
  212. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/registry.py +0 -0
  213. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/runs.py +0 -0
  214. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/legacy_spm/universe.py +0 -0
  215. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/model.py +0 -0
  216. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/tax_benefit_models/us/spm.py +0 -0
  217. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/__init__.py +0 -0
  218. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/dates.py +0 -0
  219. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/design.py +0 -0
  220. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/entity_utils.py +0 -0
  221. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/errors.py +0 -0
  222. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/hashing.py +0 -0
  223. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/household_validation.py +0 -0
  224. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/parameter_labels.py +0 -0
  225. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/parametric_reforms.py +0 -0
  226. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine/utils/plotting.py +0 -0
  227. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine.egg-info/SOURCES.txt +0 -0
  228. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine.egg-info/dependency_links.txt +0 -0
  229. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine.egg-info/entry_points.txt +0 -0
  230. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine.egg-info/requires.txt +0 -0
  231. {policyengine-6.4.1 → policyengine-6.4.2}/src/policyengine.egg-info/top_level.txt +0 -0
  232. {policyengine-6.4.1 → policyengine-6.4.2}/tests/__init__.py +0 -0
  233. {policyengine-6.4.1 → policyengine-6.4.2}/tests/conftest.py +0 -0
  234. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/__init__.py +0 -0
  235. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/filtering_fixtures.py +0 -0
  236. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/uk_couple_two_kids.json +0 -0
  237. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/uk_model_surface.json +0 -0
  238. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/uk_single_adult_employment_income.json +0 -0
  239. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/uk_single_adult_no_income.json +0 -0
  240. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/uk_single_parent_one_child.json +0 -0
  241. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/us_married_two_kids_high_income.json +0 -0
  242. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/us_model_surface.json +0 -0
  243. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/us_single_adult_employment_income.json +0 -0
  244. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/us_single_adult_no_income.json +0 -0
  245. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/household_calculator_snapshots/us_single_parent_one_child.json +0 -0
  246. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/parameter_labels_fixtures.py +0 -0
  247. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/parametric_reforms_fixtures.py +0 -0
  248. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/poverty_by_demographics_fixtures.py +0 -0
  249. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/region_fixtures.py +0 -0
  250. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/release_tros/README.md +0 -0
  251. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/release_tros/country-models.lock.toml +0 -0
  252. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/release_tros/manifest.json +0 -0
  253. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/release_tros/us-release_manifest.json +0 -0
  254. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/release_tros/us.trace.tro.jsonld +0 -0
  255. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/spm_development.py +0 -0
  256. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/uk_contract/evaluate_case_rows.json +0 -0
  257. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/us_reform_fixtures.py +0 -0
  258. {policyengine-6.4.1 → policyengine-6.4.2}/tests/fixtures/variable_label_fixtures.py +0 -0
  259. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_aggregate.py +0 -0
  260. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_be_axiom_pilot.py +0 -0
  261. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_budgetary_impact.py +0 -0
  262. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_bump_version.py +0 -0
  263. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_bundle.py +0 -0
  264. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_bundle_metadata.py +0 -0
  265. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_cache.py +0 -0
  266. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_certify_data_release.py +0 -0
  267. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_change_aggregate.py +0 -0
  268. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_cliff_impact.py +0 -0
  269. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_cliff_impact_analysis.py +0 -0
  270. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_congressional_district_impact.py +0 -0
  271. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_constituency_impact.py +0 -0
  272. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_dataset_materialization.py +0 -0
  273. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_dataset_persistence.py +0 -0
  274. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_dataset_runtime.py +0 -0
  275. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_dataset_source.py +0 -0
  276. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_decile_grouping.py +0 -0
  277. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_derivations.py +0 -0
  278. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_dict_reforms_on_simulation.py +0 -0
  279. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_areas.py +0 -0
  280. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_estimate.py +0 -0
  281. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_noise.py +0 -0
  282. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_release.py +0 -0
  283. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_schema.py +0 -0
  284. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_support.py +0 -0
  285. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_disclosure_validate.py +0 -0
  286. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_entity_mapping.py +0 -0
  287. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_entity_utils.py +0 -0
  288. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_entity_utils_characterization.py +0 -0
  289. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_errors.py +0 -0
  290. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_extra_variables.py +0 -0
  291. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_filtering.py +0 -0
  292. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_generate_trace_tros.py +0 -0
  293. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_graph/__init__.py +0 -0
  294. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_graph/conftest.py +0 -0
  295. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_graph/test_extractor.py +0 -0
  296. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_household_calculator_snapshot.py +0 -0
  297. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_household_impact.py +0 -0
  298. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_inequality.py +0 -0
  299. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_intra_decile_impact.py +0 -0
  300. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_labor_supply_response.py +0 -0
  301. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_local_authority_impact.py +0 -0
  302. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_manifest_version_mismatch.py +0 -0
  303. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_models.py +0 -0
  304. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_pandas3_compatibility.py +0 -0
  305. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_parameter_labels.py +0 -0
  306. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_parameter_nodes.py +0 -0
  307. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_parameter_values.py +0 -0
  308. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_parametric_reforms.py +0 -0
  309. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_poverty.py +0 -0
  310. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_poverty_by_demographics.py +0 -0
  311. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_poverty_run.py +0 -0
  312. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_preservation_mirror.py +0 -0
  313. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_program_statistics.py +0 -0
  314. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_pyproject_pins.py +0 -0
  315. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_region.py +0 -0
  316. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_region_group_strategy.py +0 -0
  317. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_release_credentials.py +0 -0
  318. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_release_lock.py +0 -0
  319. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_release_manifests.py +0 -0
  320. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_release_tro_generation.py +0 -0
  321. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_results.py +0 -0
  322. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_run_record.py +0 -0
  323. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_scoping_strategy.py +0 -0
  324. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_small_follow_ups.py +0 -0
  325. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_bundle_bootstrap.py +0 -0
  326. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_bundle_tooling.py +0 -0
  327. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_decile.py +0 -0
  328. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_development_authentication.py +0 -0
  329. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_household.py +0 -0
  330. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_model.py +0 -0
  331. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_selection.py +0 -0
  332. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_spm_selection_schema.py +0 -0
  333. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_trace_tro.py +0 -0
  334. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_trace_tro_verify.py +0 -0
  335. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_analysis.py +0 -0
  336. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_dated_reforms.py +0 -0
  337. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_geography_assets.py +0 -0
  338. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_geography_disclosure.py +0 -0
  339. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_program_statistics.py +0 -0
  340. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_regions.py +0 -0
  341. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_uk_year_file_data_year.py +0 -0
  342. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_legacy_inputs.py +0 -0
  343. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_legacy_inputs_integration.py +0 -0
  344. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_legacy_spm.py +0 -0
  345. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_legacy_spm_integration.py +0 -0
  346. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_legacy_spm_model_contract.py +0 -0
  347. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_long_term_datasets.py +0 -0
  348. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_microsim_structural_reforms.py +0 -0
  349. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_native_alignment.py +0 -0
  350. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_native_hdf_weights.py +0 -0
  351. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_program_statistics.py +0 -0
  352. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_reform_application.py +0 -0
  353. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_regions.py +0 -0
  354. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_us_year_file_stamp.py +0 -0
  355. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_variable_labels.py +0 -0
  356. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_variable_metadata.py +0 -0
  357. {policyengine-6.4.1 → policyengine-6.4.2}/tests/test_zenodo_mirror.py +0 -0
  358. {policyengine-6.4.1 → policyengine-6.4.2}/tests/uk_contract_row_scenarios.py +0 -0
@@ -1,3 +1,10 @@
1
+ ## [6.4.2] - 2026-10-15
2
+
3
+ ### Fixed
4
+
5
+ - The UK Budget reform contract's Universal Credit allowance check now asserts on the award before deductions, and bounds how far deductions can lower the amount paid.
6
+
7
+
1
8
  ## [6.4.1] - 2026-10-15
2
9
 
3
10
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine
3
- Version: 6.4.1
3
+ Version: 6.4.2
4
4
  Summary: A package to conduct policy analysis using PolicyEngine tax-benefit models.
5
5
  Author-email: PolicyEngine <hello@policyengine.org>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "policyengine"
7
- version = "6.4.1"
7
+ version = "6.4.2"
8
8
  description = "A package to conduct policy analysis using PolicyEngine tax-benefit models."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -1,10 +1,10 @@
1
1
  {
2
- "bundle_version": "6.4.1",
2
+ "bundle_version": "6.4.2",
3
3
  "citation": {
4
4
  "publisher": "PolicyEngine",
5
- "title": "PolicyEngine bundle 6.4.1",
5
+ "title": "PolicyEngine bundle 6.4.2",
6
6
  "type": "software-bundle",
7
- "version": "6.4.1"
7
+ "version": "6.4.2"
8
8
  },
9
9
  "countries": {
10
10
  "uk": {
@@ -17,7 +17,7 @@
17
17
  "data_releases": {
18
18
  "uk": {
19
19
  "build_id": "policyengine-uk-data-1.58.1",
20
- "bundle_id": "uk-6.4.1",
20
+ "bundle_id": "uk-6.4.2",
21
21
  "certification": {
22
22
  "built_with_model_git_sha": "daad71cd26c107f1b784ff600d1464ba59c70e4a",
23
23
  "built_with_model_version": "2.122.2",
@@ -99,7 +99,7 @@
99
99
  "version": "2.130.1",
100
100
  "wheel_url": "https://files.pythonhosted.org/packages/1a/21/88e8addba0eabd9a7d3a29fa5293e141feb405baf0432209387f9a1f467a/policyengine_uk-2.130.1-py3-none-any.whl"
101
101
  },
102
- "policyengine_version": "6.4.1",
102
+ "policyengine_version": "6.4.2",
103
103
  "region_datasets": {
104
104
  "national": {
105
105
  "path_template": "enhanced_frs_2024_25.h5"
@@ -112,7 +112,7 @@
112
112
  },
113
113
  "us": {
114
114
  "build_id": "populace-us-2024-spm-20260915",
115
- "bundle_id": "us-6.4.1",
115
+ "bundle_id": "us-6.4.2",
116
116
  "certification": {
117
117
  "built_with_model_version": "2.2.1",
118
118
  "certified_by": "policyengine.py bundle certification",
@@ -217,7 +217,7 @@
217
217
  "version": "2.2.1",
218
218
  "wheel_url": "https://files.pythonhosted.org/packages/5e/09/86ac3968d2a18e28fce3ba1186fc21728e9f299b96a806d6f204f1e0aaed/policyengine_us-2.2.1-py3-none-any.whl"
219
219
  },
220
- "policyengine_version": "6.4.1",
220
+ "policyengine_version": "6.4.2",
221
221
  "region_datasets": {
222
222
  "congressional_district": {
223
223
  "path_template": "populace_us_2024.h5"
@@ -295,10 +295,10 @@
295
295
  "packages": {
296
296
  "policyengine": {
297
297
  "import_name": "policyengine",
298
- "install_requirement": "policyengine==6.4.1",
298
+ "install_requirement": "policyengine==6.4.2",
299
299
  "name": "policyengine",
300
300
  "role": "bundle_carrier",
301
- "version": "6.4.1"
301
+ "version": "6.4.2"
302
302
  },
303
303
  "policyengine-core": {
304
304
  "import_name": "policyengine_core",
@@ -334,6 +334,6 @@
334
334
  "wheel_url": "https://files.pythonhosted.org/packages/19/a0/c484f69a0ebf88a9b9fd0ac28176f8df66550f46714f1b0c5ec0b360824e/spm_calculator-1.0.0-py3-none-any.whl"
335
335
  }
336
336
  },
337
- "policyengine_version": "6.4.1",
337
+ "policyengine_version": "6.4.2",
338
338
  "schema_version": 2
339
339
  }
@@ -18,18 +18,18 @@
18
18
  "schema:url": "https://policyengine.org"
19
19
  },
20
20
  "schema:dateCreated": "2026-10-14T07:43:49.920588Z",
21
- "schema:description": "TRACE TRO for certified runtime bundle uk-6.4.1 covering the bundle manifest, the certified dataset artifact, the country model wheel, and the country data release manifest when it is available.",
21
+ "schema:description": "TRACE TRO for certified runtime bundle uk-6.4.2 covering the bundle manifest, the certified dataset artifact, the country model wheel, and the country data release manifest when it is available.",
22
22
  "schema:name": "policyengine uk certified bundle TRO",
23
23
  "trov:createdWith": {
24
24
  "@type": "schema:SoftwareApplication",
25
25
  "schema:name": "policyengine",
26
- "schema:softwareVersion": "6.4.1"
26
+ "schema:softwareVersion": "6.4.2"
27
27
  },
28
28
  "trov:hasArrangement": [
29
29
  {
30
30
  "@id": "arrangement/1",
31
31
  "@type": "trov:ArtifactArrangement",
32
- "rdfs:comment": "Certified arrangement for bundle uk-6.4.1.",
32
+ "rdfs:comment": "Certified arrangement for bundle uk-6.4.2.",
33
33
  "trov:hasArtifactLocation": [
34
34
  {
35
35
  "@id": "arrangement/1/location/bundle_manifest",
@@ -75,7 +75,7 @@
75
75
  "@type": "trov:ResearchArtifact",
76
76
  "schema:name": "policyengine.py bundle manifest for uk",
77
77
  "trov:mimeType": "application/json",
78
- "trov:sha256": "fc1abd76660e9b0bdfe6319a2ae5f221847750e087143e5ba6da859a9422e333"
78
+ "trov:sha256": "ca23fac0cbac5b2dfd0a7a4a9b9e5a04eda2c239e934b54769f2f286d88f09c1"
79
79
  },
80
80
  {
81
81
  "@id": "composition/1/artifact/data_release_manifest",
@@ -102,7 +102,7 @@
102
102
  "trov:hasFingerprint": {
103
103
  "@id": "composition/1/fingerprint",
104
104
  "@type": "trov:CompositionFingerprint",
105
- "trov:sha256": "102e08d71797eb44902e6b3bef6fbb0f9b2ea477a72c3196759f3a3e1157223e"
105
+ "trov:sha256": "315f4c63f5e8a0a1c2d5bb6348117acdb592c35105e6c41039ad073755f93b04"
106
106
  }
107
107
  },
108
108
  "trov:hasPerformance": {
@@ -17,18 +17,18 @@
17
17
  "schema:name": "PolicyEngine",
18
18
  "schema:url": "https://policyengine.org"
19
19
  },
20
- "schema:description": "TRACE TRO for certified runtime bundle us-6.4.1 covering the bundle manifest, the certified dataset artifact, the country model wheel, and the country data release manifest when it is available.",
20
+ "schema:description": "TRACE TRO for certified runtime bundle us-6.4.2 covering the bundle manifest, the certified dataset artifact, the country model wheel, and the country data release manifest when it is available.",
21
21
  "schema:name": "policyengine us certified bundle TRO",
22
22
  "trov:createdWith": {
23
23
  "@type": "schema:SoftwareApplication",
24
24
  "schema:name": "policyengine",
25
- "schema:softwareVersion": "6.4.1"
25
+ "schema:softwareVersion": "6.4.2"
26
26
  },
27
27
  "trov:hasArrangement": [
28
28
  {
29
29
  "@id": "arrangement/1",
30
30
  "@type": "trov:ArtifactArrangement",
31
- "rdfs:comment": "Certified arrangement for bundle us-6.4.1.",
31
+ "rdfs:comment": "Certified arrangement for bundle us-6.4.2.",
32
32
  "trov:hasArtifactLocation": [
33
33
  {
34
34
  "@id": "arrangement/1/location/bundle_manifest",
@@ -74,7 +74,7 @@
74
74
  "@type": "trov:ResearchArtifact",
75
75
  "schema:name": "policyengine.py bundle manifest for us",
76
76
  "trov:mimeType": "application/json",
77
- "trov:sha256": "fc1abd76660e9b0bdfe6319a2ae5f221847750e087143e5ba6da859a9422e333"
77
+ "trov:sha256": "ca23fac0cbac5b2dfd0a7a4a9b9e5a04eda2c239e934b54769f2f286d88f09c1"
78
78
  },
79
79
  {
80
80
  "@id": "composition/1/artifact/data_release_manifest",
@@ -101,7 +101,7 @@
101
101
  "trov:hasFingerprint": {
102
102
  "@id": "composition/1/fingerprint",
103
103
  "@type": "trov:CompositionFingerprint",
104
- "trov:sha256": "ac79ae8f3c4acb172ac186ae3da453e42629ace66f8b7eae636f1a522e76a922"
104
+ "trov:sha256": "a21df74d73d581321a7d2896ab65efd85983aa58061b8cc2d85231c310b8f28f"
105
105
  }
106
106
  },
107
107
  "trov:hasPerformance": {
@@ -26,7 +26,15 @@ Checks:
26
26
  ``population_uc_standard_allowance_plus_10``
27
27
  Every Universal Credit standard allowance 10% higher in 2027-28 raises
28
28
  each benefit unit's standard allowance by exactly 10%, lowers no award
29
- and raises total Universal Credit.
29
+ before deductions and raises total Universal Credit. The award before
30
+ deductions is ``universal_credit_pre_benefit_cap`` less
31
+ ``benefit_cap_reduction``: the benefit cap reduces the award by the
32
+ excess of welfare benefits over the cap (Universal Credit Regulations
33
+ 2013, SI 2013/376, reg 81), so a capped award stays flat. Deductions are
34
+ then taken from the award and set as percentages of the standard
35
+ allowance (Claims and Payments Regulations 2013, SI 2013/380, Sch 6), so
36
+ the amount paid (``universal_credit``) can fall. The check requires each
37
+ payment to move by its award's change less its deductions' change.
30
38
  ``population_state_pension_plus_10``
31
39
  The basic and new State Pension rates 10% higher in 2027-28 raise each
32
40
  person's basic and new State Pension by exactly 10% and raise total
@@ -121,6 +129,115 @@ def population_check_routes(routes: Sequence[str]) -> tuple[tuple[str, str], ...
121
129
  )
122
130
 
123
131
 
132
+ #: What the Universal Credit allowance check reads from each simulation.
133
+ UC_ALLOWANCE_VARIABLES = (
134
+ "uc_standard_allowance",
135
+ "universal_credit",
136
+ "universal_credit_pre_benefit_cap",
137
+ "benefit_cap_reduction",
138
+ "uc_deductions",
139
+ )
140
+
141
+ #: Universal Credit amounts are float32 annual pounds; sums of them carry
142
+ #: rounding of a few thousandths of a pound, so a penny is the smallest
143
+ #: difference the check treats as a change.
144
+ PENNY = 0.01
145
+
146
+ #: Deductions may not reduce the amount payable below a penny an assessment
147
+ #: period (SI 2013/380 Sch 6 para 3(1)(a)), twelve of them a year.
148
+ MINIMUM_PAYABLE_A_YEAR = 0.12
149
+
150
+
151
+ def uc_allowance_verdict(
152
+ base: dict[str, np.ndarray], reformed: dict[str, np.ndarray]
153
+ ) -> tuple[bool, dict]:
154
+ """Whether a 10% higher standard allowance moved Universal Credit lawfully.
155
+
156
+ ``base`` and ``reformed`` hold ``UC_ALLOWANCE_VARIABLES`` per benefit unit.
157
+
158
+ No award before deductions (``universal_credit_pre_benefit_cap`` less
159
+ ``benefit_cap_reduction``) may fall by more than a penny. The benefit cap
160
+ reduces the award by the excess of welfare benefits over the cap (SI
161
+ 2013/376 reg 81), counting Universal Credit before any deduction (reg
162
+ 80(2)), so a capped award stays flat. That holds in the model, which
163
+ applies no sanctions; in law a sanction, taken after the cap and set by
164
+ the standard allowance (regs 110 and 111), can lower a capped award.
165
+
166
+ Each payment (``universal_credit``) must move by its award's change less
167
+ its deductions' change, to the penny. Deductions are taken from the award
168
+ (SI 2013/380 Sch 6), so with the award unchanged a capped claimant's
169
+ payment falls by exactly as much as their deductions rise.
170
+
171
+ Whatever deductions are taken, at least a penny an assessment period
172
+ stays payable (SI 2013/380 Sch 6 para 3(1)(a)), so no payment falls below
173
+ the lesser of its award and 12p a year. Every value must be finite in both
174
+ runs: a missing value would otherwise pass every comparison.
175
+
176
+ How much deductions rise is not checked here. The law sets some
177
+ deductions as percentages of the standard allowance and others as fixed
178
+ amounts (advances, SI 2013/383 reg 10), starts deductions with a new
179
+ award, and keeps a penny payable; the model scales every deduction type
180
+ with the allowance (policyengine-uk#2410), so no allowance-proportional
181
+ bound is an invariant of both.
182
+ """
183
+
184
+ non_finite = int(
185
+ np.sum(
186
+ ~np.all(
187
+ [
188
+ np.isfinite(state[name])
189
+ for state in (base, reformed)
190
+ for name in UC_ALLOWANCE_VARIABLES
191
+ ],
192
+ axis=0,
193
+ )
194
+ )
195
+ )
196
+ allowance, base_allowance = (
197
+ reformed["uc_standard_allowance"],
198
+ base["uc_standard_allowance"],
199
+ )
200
+ scaled = bool(np.allclose(allowance, 1.1 * base_allowance, rtol=1e-6))
201
+ award = (
202
+ reformed["universal_credit_pre_benefit_cap"] - reformed["benefit_cap_reduction"]
203
+ )
204
+ base_award = (
205
+ base["universal_credit_pre_benefit_cap"] - base["benefit_cap_reduction"]
206
+ )
207
+ paid, base_paid = reformed["universal_credit"], base["universal_credit"]
208
+ deduction_change = reformed["uc_deductions"] - base["uc_deductions"]
209
+ unaccounted = (paid - base_paid) - ((award - base_award) - deduction_change)
210
+ awards_lower = int(np.sum(award < base_award - PENNY))
211
+ payments_unaccounted = int(np.sum(np.abs(unaccounted) > PENNY))
212
+ payments_higher = int(np.sum(paid > base_paid + PENNY))
213
+ payments_below_floor = int(
214
+ sum(
215
+ np.sum(
216
+ state_paid
217
+ < np.minimum(np.maximum(state_award, 0), MINIMUM_PAYABLE_A_YEAR) - PENNY
218
+ )
219
+ for state_paid, state_award in ((base_paid, base_award), (paid, award))
220
+ )
221
+ )
222
+ holds = (
223
+ non_finite == 0
224
+ and scaled
225
+ and awards_lower == 0
226
+ and payments_unaccounted == 0
227
+ and payments_below_floor == 0
228
+ and payments_higher > 0
229
+ )
230
+ return holds, {
231
+ "standard_allowance_scaled_10_percent": scaled,
232
+ "awards_lower": awards_lower,
233
+ "payments_lower": int(np.sum(paid < base_paid - PENNY)),
234
+ "payments_higher": payments_higher,
235
+ "payments_not_award_less_deductions": payments_unaccounted,
236
+ "payments_below_the_payable_floor": payments_below_floor,
237
+ "units_with_non_finite_values": non_finite,
238
+ }
239
+
240
+
124
241
  def plus_ten_percent(paths: Sequence[str]) -> dict:
125
242
  """Each parameter 10% above current law for the response year."""
126
243
  from policyengine_uk.system import system
@@ -346,8 +463,7 @@ def run_population_checks(
346
463
  base = {
347
464
  variable: values(unreformed, variable)
348
465
  for variable in (
349
- "uc_standard_allowance",
350
- "universal_credit",
466
+ *UC_ALLOWANCE_VARIABLES,
351
467
  "basic_state_pension",
352
468
  "new_state_pension",
353
469
  "state_pension",
@@ -355,23 +471,17 @@ def run_population_checks(
355
471
  }
356
472
  for route in country:
357
473
  simulation = build(route, plus_ten_percent(UC_STANDARD_ALLOWANCES))
358
- allowance = values(simulation, "uc_standard_allowance")
359
- award = values(simulation, "universal_credit")
360
- scaled = bool(
361
- np.allclose(allowance, 1.1 * base["uc_standard_allowance"], rtol=1e-6)
362
- )
363
- lower = int(np.sum(award < base["universal_credit"] - 1e-3))
364
- higher = int(np.sum(award > base["universal_credit"] + 1e-3))
474
+ uc_reformed = {
475
+ variable: values(simulation, variable)
476
+ for variable in UC_ALLOWANCE_VARIABLES
477
+ }
478
+ holds, detail = uc_allowance_verdict(base, uc_reformed)
365
479
  rows.append(
366
480
  _row(
367
481
  POPULATION_UC_STANDARD_ALLOWANCE_PLUS_10,
368
482
  route,
369
- "pass" if scaled and lower == 0 and higher > 0 else "fail",
370
- detail={
371
- "standard_allowance_scaled_10_percent": scaled,
372
- "awards_lower": lower,
373
- "awards_higher": higher,
374
- },
483
+ "pass" if holds else "fail",
484
+ detail=detail,
375
485
  )
376
486
  )
377
487
  for route in country:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine
3
- Version: 6.4.1
3
+ Version: 6.4.2
4
4
  Summary: A package to conduct policy analysis using PolicyEngine tax-benefit models.
5
5
  Author-email: PolicyEngine <hello@policyengine.org>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -505,6 +505,9 @@ def stub_population_checks(monkeypatch):
505
505
  return Simulation(dataset=None)
506
506
 
507
507
  def calculate(self, variable, year):
508
+ # No cap reduction or deductions, so a payment equals its award.
509
+ if variable in ("benefit_cap_reduction", "uc_deductions"):
510
+ return [0.0]
508
511
  if (
509
512
  variable == "income_tax"
510
513
  and year == 2027
@@ -512,7 +515,13 @@ def stub_population_checks(monkeypatch):
512
515
  ):
513
516
  return [2.0]
514
517
  if self.reform == {"response": population.UC_STANDARD_ALLOWANCES}:
515
- if variable in ("uc_standard_allowance", "universal_credit"):
518
+ # The award before deductions rises with the payment, so the
519
+ # payment is the award less (unchanged) deductions.
520
+ if variable in (
521
+ "uc_standard_allowance",
522
+ "universal_credit",
523
+ "universal_credit_pre_benefit_cap",
524
+ ):
516
525
  return [1.1]
517
526
  if self.reform == {"response": population.STATE_PENSION_RATES}:
518
527
  if variable in (
@@ -790,3 +799,220 @@ def test_household_result_totals_read_each_variable_from_its_own_entity():
790
799
  assert _result_total(result, "income_tax") == 150.0
791
800
  with pytest.raises(KeyError, match="benunit"):
792
801
  _result_total({"household": {"universal_credit": 1.0}}, "universal_credit")
802
+
803
+
804
+ # The Universal Credit allowance check's verdict, on synthetic benefit units.
805
+
806
+
807
+ def _uc_units(**columns):
808
+ import numpy as np
809
+
810
+ defaults = {
811
+ "uc_standard_allowance": [400.0],
812
+ "universal_credit": [500.0],
813
+ "universal_credit_pre_benefit_cap": [500.0],
814
+ "benefit_cap_reduction": [0.0],
815
+ "uc_deductions": [0.0],
816
+ }
817
+ defaults.update(columns)
818
+ return {name: np.array(values, dtype=float) for name, values in defaults.items()}
819
+
820
+
821
+ def _verdict(base, reformed):
822
+ from policyengine.tax_benefit_models.uk.budget_reform_population import (
823
+ uc_allowance_verdict,
824
+ )
825
+
826
+ return uc_allowance_verdict(base, reformed)
827
+
828
+
829
+ def _lawful_pair():
830
+ """A capped unit whose deductions rise, and an uncapped unit that gains."""
831
+
832
+ base = _uc_units(
833
+ uc_standard_allowance=[400.0, 400.0],
834
+ universal_credit_pre_benefit_cap=[900.0, 500.0],
835
+ benefit_cap_reduction=[100.0, 0.0],
836
+ uc_deductions=[20.0, 0.0],
837
+ universal_credit=[780.0, 500.0],
838
+ )
839
+ reformed = _uc_units(
840
+ uc_standard_allowance=[440.0, 440.0],
841
+ universal_credit_pre_benefit_cap=[940.0, 540.0],
842
+ benefit_cap_reduction=[140.0, 0.0],
843
+ uc_deductions=[22.0, 0.0],
844
+ universal_credit=[778.0, 540.0],
845
+ )
846
+ return base, reformed
847
+
848
+
849
+ def test_a_capped_award_whose_deductions_rise_with_the_allowance_holds():
850
+ """SI 2013/376 reg 81 holds a capped award flat; deductions come out of it
851
+ (SI 2013/380 Sch 6), so the amount paid falls by exactly their rise."""
852
+
853
+ holds, detail = _verdict(*_lawful_pair())
854
+ assert holds, detail
855
+ assert detail["payments_lower"] == 1
856
+ assert detail["awards_lower"] == 0
857
+
858
+
859
+ @pytest.mark.parametrize("rise", [2.0, 60.0, 357.0])
860
+ def test_how_much_deductions_rise_is_not_bounded(rise):
861
+ """Deductions can start with a new award or exceed the allowance rise."""
862
+
863
+ base, reformed = _lawful_pair()
864
+ reformed["uc_deductions"][0] = 20.0 + rise
865
+ reformed["universal_credit"][0] = 800.0 - 20.0 - rise
866
+ holds, detail = _verdict(base, reformed)
867
+ assert holds, detail
868
+
869
+
870
+ @pytest.mark.parametrize(
871
+ ("change", "failing_key", "passing_value"),
872
+ [
873
+ (
874
+ {"benefit_cap_reduction": 150.0, "universal_credit": 768.0},
875
+ "awards_lower",
876
+ 0,
877
+ ),
878
+ (
879
+ {"uc_deductions": 800.0, "universal_credit": 0.0},
880
+ "payments_below_the_payable_floor",
881
+ 0,
882
+ ),
883
+ ({"uc_deductions": float("nan")}, "units_with_non_finite_values", 0),
884
+ (
885
+ {"benefit_cap_reduction": float("nan")},
886
+ "units_with_non_finite_values",
887
+ 0,
888
+ ),
889
+ ({"universal_credit": 777.989}, "payments_not_award_less_deductions", 0),
890
+ ({"universal_credit": 778.011}, "payments_not_award_less_deductions", 0),
891
+ (
892
+ {"uc_deductions": 0.0, "universal_credit": 780.0},
893
+ "payments_not_award_less_deductions",
894
+ 0,
895
+ ),
896
+ (
897
+ {"uc_standard_allowance": 430.0},
898
+ "standard_allowance_scaled_10_percent",
899
+ True,
900
+ ),
901
+ ],
902
+ ids=[
903
+ "award-falls-with-its-payment",
904
+ "deductions-take-the-whole-award",
905
+ "deductions-not-finite",
906
+ "cap-reduction-not-finite",
907
+ "payment-below-award-less-deductions",
908
+ "payment-above-award-less-deductions",
909
+ "deductions-released-but-payment-unchanged",
910
+ "not-scaled",
911
+ ],
912
+ )
913
+ def test_the_uc_allowance_check_fails_on_each_unlawful_movement(
914
+ change, failing_key, passing_value
915
+ ):
916
+ base, reformed = _lawful_pair()
917
+ assert _verdict(base, reformed)[0]
918
+ for name, value in change.items():
919
+ reformed[name][0] = value
920
+ holds, detail = _verdict(base, reformed)
921
+ assert not holds
922
+ assert detail[failing_key] != passing_value, detail
923
+
924
+
925
+ @pytest.mark.parametrize(
926
+ "change",
927
+ [
928
+ {"benefit_cap_reduction": 140.009},
929
+ {"universal_credit": 777.991},
930
+ {"universal_credit": 778.009},
931
+ ],
932
+ ids=["award-within-a-penny", "payment-a-little-low", "payment-a-little-high"],
933
+ )
934
+ def test_float32_rounding_within_a_penny_holds(change):
935
+ base, reformed = _lawful_pair()
936
+ for name, value in change.items():
937
+ reformed[name][0] = value
938
+ holds, detail = _verdict(base, reformed)
939
+ assert holds, detail
940
+
941
+
942
+ def test_the_uc_allowance_check_fails_when_no_payment_rises():
943
+ base = _uc_units()
944
+ holds, detail = _verdict(base, _uc_units(uc_standard_allowance=[440.0]))
945
+ assert not holds and detail["payments_higher"] == 0
946
+
947
+
948
+ def test_errors_that_cancel_across_units_still_fail():
949
+ """The accounting identity holds per unit, not in aggregate."""
950
+
951
+ base, reformed = _lawful_pair()
952
+ reformed["universal_credit"][0] -= 5.0
953
+ reformed["universal_credit"][1] += 5.0
954
+ holds, detail = _verdict(base, reformed)
955
+ assert not holds
956
+ assert detail["payments_not_award_less_deductions"] == 2
957
+
958
+
959
+ @pytest.mark.parametrize(("gain", "holds"), [(0.009, False), (0.011, True)])
960
+ def test_a_gain_must_exceed_a_penny(gain, holds):
961
+ """Only a payment more than a penny higher counts as responsive."""
962
+
963
+ base = _uc_units(
964
+ universal_credit_pre_benefit_cap=[900.0],
965
+ benefit_cap_reduction=[100.0],
966
+ universal_credit=[800.0],
967
+ )
968
+ reformed = _uc_units(
969
+ uc_standard_allowance=[440.0],
970
+ universal_credit_pre_benefit_cap=[940.0],
971
+ benefit_cap_reduction=[140.0 - gain],
972
+ universal_credit=[800.0 + gain],
973
+ )
974
+ assert _verdict(base, reformed)[0] is holds
975
+
976
+
977
+ @pytest.mark.parametrize(("relative", "holds"), [(5e-7, True), (2e-6, False)])
978
+ def test_the_allowance_must_scale_by_ten_percent(relative, holds):
979
+ base, reformed = _lawful_pair()
980
+ reformed["uc_standard_allowance"] = reformed["uc_standard_allowance"] * (
981
+ 1 + relative
982
+ )
983
+ assert _verdict(base, reformed)[0] is holds
984
+
985
+
986
+ def test_deductions_may_leave_exactly_the_payable_floor():
987
+ """A penny an assessment period, 12p a year, is the lowest lawful payment."""
988
+
989
+ base, reformed = _lawful_pair()
990
+ reformed["uc_deductions"][0] = 800.0 - 0.12
991
+ reformed["universal_credit"][0] = 0.12
992
+ holds, detail = _verdict(base, reformed)
993
+ assert holds, detail
994
+
995
+
996
+ @pytest.mark.parametrize("route", ["country.reform_dict", "wrapper.policy"])
997
+ def test_extraction_errors_and_unsupported_rows_carry_distinct_ids(monkeypatch, route):
998
+ """#612 review: ids also label error, pending and unsupported rows."""
999
+
1000
+ from dataclasses import replace
1001
+
1002
+ checks = (
1003
+ Check("variable", "income_tax", 2027, 0.0, "missing value"),
1004
+ Check("variable", "income_tax", 2027, 0.0, "missing pending", pending="d1344"),
1005
+ Check("baseline_equals", "income_tax", 2027, "income_tax", "baseline"),
1006
+ )
1007
+ fake(monkeypatch, FakeRoute(reformed={}, unreformed={}))
1008
+ rows = [
1009
+ row
1010
+ for row in evaluate_case(replace(CASE, checks=checks), route)
1011
+ if "assertion_id" in row
1012
+ ]
1013
+ assert len(rows) == len(checks)
1014
+ assert len({row["assertion_id"] for row in rows}) == len(checks)
1015
+ statuses = [row["status"] for row in rows]
1016
+ assert statuses[:2] == ["error", "pending"]
1017
+ if route == "wrapper.policy":
1018
+ assert statuses[2] == "unsupported"
@@ -1807,7 +1807,7 @@ wheels = [
1807
1807
 
1808
1808
  [[package]]
1809
1809
  name = "policyengine"
1810
- version = "6.4.1"
1810
+ version = "6.4.2"
1811
1811
  source = { editable = "." }
1812
1812
  dependencies = [
1813
1813
  { name = "h5py" },