policyengine 6.2.0__tar.gz → 6.2.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 (318) hide show
  1. {policyengine-6.2.0 → policyengine-6.2.2}/.github/workflows/draft-pdf.yml +4 -0
  2. {policyengine-6.2.0 → policyengine-6.2.2}/.github/workflows/pr_code_changes.yaml +19 -11
  3. {policyengine-6.2.0 → policyengine-6.2.2}/.github/workflows/pr_docs_changes.yaml +4 -0
  4. {policyengine-6.2.0 → policyengine-6.2.2}/.github/workflows/push.yaml +1 -1
  5. {policyengine-6.2.0 → policyengine-6.2.2}/CHANGELOG.md +19 -0
  6. {policyengine-6.2.0/src/policyengine.egg-info → policyengine-6.2.2}/PKG-INFO +5 -5
  7. {policyengine-6.2.0 → policyengine-6.2.2}/docs/bundles.md +11 -5
  8. policyengine-6.2.2/docs/engineering/runbooks/build-m-us-populace-certification.md +129 -0
  9. {policyengine-6.2.0 → policyengine-6.2.2}/docs/engineering/skills/data-certification.md +19 -8
  10. {policyengine-6.2.0 → policyengine-6.2.2}/docs/households.md +1 -1
  11. {policyengine-6.2.0 → policyengine-6.2.2}/docs/microsim.md +6 -5
  12. {policyengine-6.2.0 → policyengine-6.2.2}/docs/regions.md +9 -6
  13. {policyengine-6.2.0 → policyengine-6.2.2}/docs/release-bundles.md +21 -13
  14. {policyengine-6.2.0 → policyengine-6.2.2}/pyproject.toml +5 -5
  15. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/bundle.py +2 -2
  16. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/certify_data_release.py +2 -2
  17. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/region.py +9 -11
  18. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/regions.py +12 -2
  19. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/bundle/manifest.json +27 -22
  20. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/bundle/uk.trace.tro.jsonld +5 -5
  21. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/bundle/us.trace.tro.jsonld +5 -5
  22. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/certification.py +123 -7
  23. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/manifest.py +5 -1
  24. {policyengine-6.2.0 → policyengine-6.2.2/src/policyengine.egg-info}/PKG-INFO +5 -5
  25. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine.egg-info/requires.txt +4 -4
  26. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_bundle.py +27 -0
  27. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_certify_data_release.py +144 -7
  28. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_release_manifests.py +24 -20
  29. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_release_tro_generation.py +30 -5
  30. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_regions.py +48 -10
  31. {policyengine-6.2.0 → policyengine-6.2.2}/uv.lock +15 -14
  32. policyengine-6.2.0/docs/engineering/runbooks/build-m-us-populace-certification.md +0 -145
  33. {policyengine-6.2.0 → policyengine-6.2.2}/.claude/policyengine-guide.md +0 -0
  34. {policyengine-6.2.0 → policyengine-6.2.2}/.claude/quick-reference.md +0 -0
  35. {policyengine-6.2.0 → policyengine-6.2.2}/.github/CONTRIBUTING.md +0 -0
  36. {policyengine-6.2.0 → policyengine-6.2.2}/.github/bump_version.py +0 -0
  37. {policyengine-6.2.0 → policyengine-6.2.2}/.github/capture-version.sh +0 -0
  38. {policyengine-6.2.0 → policyengine-6.2.2}/.github/changelog_template.md +0 -0
  39. {policyengine-6.2.0 → policyengine-6.2.2}/.github/check-changelog.sh +0 -0
  40. {policyengine-6.2.0 → policyengine-6.2.2}/.github/copilot-instructions.md +0 -0
  41. {policyengine-6.2.0 → policyengine-6.2.2}/.github/dispatch-policyengine-release.sh +0 -0
  42. {policyengine-6.2.0 → policyengine-6.2.2}/.github/fetch_version.py +0 -0
  43. {policyengine-6.2.0 → policyengine-6.2.2}/.github/get-changelog-diff.sh +0 -0
  44. {policyengine-6.2.0 → policyengine-6.2.2}/.github/has-functional-changes.sh +0 -0
  45. {policyengine-6.2.0 → policyengine-6.2.2}/.github/is-version-number-acceptable.sh +0 -0
  46. {policyengine-6.2.0 → policyengine-6.2.2}/.github/publish-git-tag.sh +0 -0
  47. {policyengine-6.2.0 → policyengine-6.2.2}/.github/wait-for-pypi.sh +0 -0
  48. {policyengine-6.2.0 → policyengine-6.2.2}/.gitignore +0 -0
  49. {policyengine-6.2.0 → policyengine-6.2.2}/.python-version +0 -0
  50. {policyengine-6.2.0 → policyengine-6.2.2}/AGENTS.md +0 -0
  51. {policyengine-6.2.0 → policyengine-6.2.2}/CITATION.cff +0 -0
  52. {policyengine-6.2.0 → policyengine-6.2.2}/CLAUDE.md +0 -0
  53. {policyengine-6.2.0 → policyengine-6.2.2}/CODE_OF_CONDUCT.md +0 -0
  54. {policyengine-6.2.0 → policyengine-6.2.2}/CONTRIBUTING.md +0 -0
  55. {policyengine-6.2.0 → policyengine-6.2.2}/LICENSE +0 -0
  56. {policyengine-6.2.0 → policyengine-6.2.2}/Makefile +0 -0
  57. {policyengine-6.2.0 → policyengine-6.2.2}/README.md +0 -0
  58. {policyengine-6.2.0 → policyengine-6.2.2}/architecture.png +0 -0
  59. {policyengine-6.2.0 → policyengine-6.2.2}/architecture.svg +0 -0
  60. {policyengine-6.2.0 → policyengine-6.2.2}/changelog.d/.gitkeep +0 -0
  61. {policyengine-6.2.0 → policyengine-6.2.2}/docs/.gitignore +0 -0
  62. {policyengine-6.2.0 → policyengine-6.2.2}/docs/_generator/README.md +0 -0
  63. {policyengine-6.2.0 → policyengine-6.2.2}/docs/_generator/build_reference.py +0 -0
  64. {policyengine-6.2.0 → policyengine-6.2.2}/docs/_quarto.yml +0 -0
  65. {policyengine-6.2.0 → policyengine-6.2.2}/docs/countries.md +0 -0
  66. {policyengine-6.2.0 → policyengine-6.2.2}/docs/data-publishing-design.md +0 -0
  67. {policyengine-6.2.0 → policyengine-6.2.2}/docs/decile-impact-spec.md +0 -0
  68. {policyengine-6.2.0 → policyengine-6.2.2}/docs/dev.md +0 -0
  69. {policyengine-6.2.0 → policyengine-6.2.2}/docs/engineering/runbooks/canonical-spm-development.md +0 -0
  70. {policyengine-6.2.0 → policyengine-6.2.2}/docs/engineering/skills/README.md +0 -0
  71. {policyengine-6.2.0 → policyengine-6.2.2}/docs/engineering/skills/github-prs.md +0 -0
  72. {policyengine-6.2.0 → policyengine-6.2.2}/docs/engineering/skills/repository-guidance.md +0 -0
  73. {policyengine-6.2.0 → policyengine-6.2.2}/docs/examples.md +0 -0
  74. {policyengine-6.2.0 → policyengine-6.2.2}/docs/getting-started.md +0 -0
  75. {policyengine-6.2.0 → policyengine-6.2.2}/docs/impact-analysis.md +0 -0
  76. {policyengine-6.2.0 → policyengine-6.2.2}/docs/index.md +0 -0
  77. {policyengine-6.2.0 → policyengine-6.2.2}/docs/methodology/index.md +0 -0
  78. {policyengine-6.2.0 → policyengine-6.2.2}/docs/methodology/model-architecture.md +0 -0
  79. {policyengine-6.2.0 → policyengine-6.2.2}/docs/methodology/us-health-costs.md +0 -0
  80. {policyengine-6.2.0 → policyengine-6.2.2}/docs/outputs.md +0 -0
  81. {policyengine-6.2.0 → policyengine-6.2.2}/docs/programs/index.md +0 -0
  82. {policyengine-6.2.0 → policyengine-6.2.2}/docs/programs/us-chip.md +0 -0
  83. {policyengine-6.2.0 → policyengine-6.2.2}/docs/reference/index.md +0 -0
  84. {policyengine-6.2.0 → policyengine-6.2.2}/docs/reforms.md +0 -0
  85. {policyengine-6.2.0 → policyengine-6.2.2}/docs/run-records.md +0 -0
  86. {policyengine-6.2.0 → policyengine-6.2.2}/docs/trace-case-study.md +0 -0
  87. {policyengine-6.2.0 → policyengine-6.2.2}/docs/visualisation.md +0 -0
  88. {policyengine-6.2.0 → policyengine-6.2.2}/examples/belgium_axiom_pilot.py +0 -0
  89. {policyengine-6.2.0 → policyengine-6.2.2}/examples/employment_income_variation_uk.py +0 -0
  90. {policyengine-6.2.0 → policyengine-6.2.2}/examples/employment_income_variation_us.py +0 -0
  91. {policyengine-6.2.0 → policyengine-6.2.2}/examples/household_impact_example.py +0 -0
  92. {policyengine-6.2.0 → policyengine-6.2.2}/examples/income_bands_uk.py +0 -0
  93. {policyengine-6.2.0 → policyengine-6.2.2}/examples/income_distribution_us.py +0 -0
  94. {policyengine-6.2.0 → policyengine-6.2.2}/examples/paper_repro_uk.py +0 -0
  95. {policyengine-6.2.0 → policyengine-6.2.2}/examples/policy_change_uk.py +0 -0
  96. {policyengine-6.2.0 → policyengine-6.2.2}/examples/speedtest_us_simulation.py +0 -0
  97. {policyengine-6.2.0 → policyengine-6.2.2}/examples/us_budgetary_impact.py +0 -0
  98. {policyengine-6.2.0 → policyengine-6.2.2}/paper-preview.html +0 -0
  99. {policyengine-6.2.0 → policyengine-6.2.2}/paper.bib +0 -0
  100. {policyengine-6.2.0 → policyengine-6.2.2}/paper.md +0 -0
  101. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/check_data_staleness.py +0 -0
  102. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/check_native_spm_loading.py +0 -0
  103. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/check_release_credentials.py +0 -0
  104. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/export_bundle_release_assets.py +0 -0
  105. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/generate_bundle_artifacts.py +0 -0
  106. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/generate_trace_tros.py +0 -0
  107. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/prepare_package_bundle_update.py +0 -0
  108. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/release_lock.py +0 -0
  109. {policyengine-6.2.0 → policyengine-6.2.2}/scripts/spm_bundle.py +0 -0
  110. {policyengine-6.2.0 → policyengine-6.2.2}/setup.cfg +0 -0
  111. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/__init__.py +0 -0
  112. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/bundle.py +0 -0
  113. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/cli.py +0 -0
  114. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/__init__.py +0 -0
  115. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/cache.py +0 -0
  116. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/dataset.py +0 -0
  117. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/dynamic.py +0 -0
  118. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/output.py +0 -0
  119. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/parameter.py +0 -0
  120. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/parameter_node.py +0 -0
  121. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/parameter_value.py +0 -0
  122. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/policy.py +0 -0
  123. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/run_record.py +0 -0
  124. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/scoping_strategy.py +0 -0
  125. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/simulation.py +0 -0
  126. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/spm.py +0 -0
  127. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/tax_benefit_model.py +0 -0
  128. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/tax_benefit_model_version.py +0 -0
  129. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/core/variable.py +0 -0
  130. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/__init__.py +0 -0
  131. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/uk/__init__.py +0 -0
  132. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/uk/regions.py +0 -0
  133. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/__init__.py +0 -0
  134. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/data/__init__.py +0 -0
  135. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/data/districts.py +0 -0
  136. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/data/places.py +0 -0
  137. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/countries/us/data/states.py +0 -0
  138. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/__init__.py +0 -0
  139. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/schemas/trace_tro.schema.json +0 -0
  140. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/data/uk_geography_assets.py +0 -0
  141. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/derivations/__init__.py +0 -0
  142. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/derivations/narrate.py +0 -0
  143. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/derivations/trace.py +0 -0
  144. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/graph/__init__.py +0 -0
  145. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/graph/extractor.py +0 -0
  146. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/graph/graph.py +0 -0
  147. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/__init__.py +0 -0
  148. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/aggregate.py +0 -0
  149. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/change_aggregate.py +0 -0
  150. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/cliff_impact.py +0 -0
  151. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/congressional_district_impact.py +0 -0
  152. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/constituency_impact.py +0 -0
  153. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/decile_analysis.py +0 -0
  154. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/decile_grouping.py +0 -0
  155. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/decile_impact.py +0 -0
  156. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/extra_variables.py +0 -0
  157. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/inequality.py +0 -0
  158. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/intra_decile_impact.py +0 -0
  159. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/labor_supply_response.py +0 -0
  160. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/local_authority_impact.py +0 -0
  161. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/poverty.py +0 -0
  162. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/program_statistics.py +0 -0
  163. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/uk_geography_assets.py +0 -0
  164. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/outputs/uk_geography_impact.py +0 -0
  165. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/__init__.py +0 -0
  166. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/bundle_validation.py +0 -0
  167. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/dataset_materialization.py +0 -0
  168. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/pyproject_pins.py +0 -0
  169. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/spm_configuration.py +0 -0
  170. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/trace.py +0 -0
  171. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/verify.py +0 -0
  172. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/provenance/zenodo.py +0 -0
  173. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/results/__init__.py +0 -0
  174. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/results/schema.py +0 -0
  175. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/results/trace_tro.py +0 -0
  176. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/results/tracking.py +0 -0
  177. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/be/__init__.py +0 -0
  178. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/be/datasets.py +0 -0
  179. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/be/model.py +0 -0
  180. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/__init__.py +0 -0
  181. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/axes.py +0 -0
  182. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/extra_variables.py +0 -0
  183. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/household.py +0 -0
  184. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/model_version.py +0 -0
  185. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/reform.py +0 -0
  186. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/common/result.py +0 -0
  187. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/uk/__init__.py +0 -0
  188. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/uk/analysis.py +0 -0
  189. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/uk/datasets.py +0 -0
  190. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/uk/household.py +0 -0
  191. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/uk/model.py +0 -0
  192. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/__init__.py +0 -0
  193. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/analysis.py +0 -0
  194. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/datasets.py +0 -0
  195. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/household.py +0 -0
  196. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/legacy_inputs.py +0 -0
  197. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/model.py +0 -0
  198. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/tax_benefit_models/us/spm.py +0 -0
  199. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/__init__.py +0 -0
  200. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/dates.py +0 -0
  201. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/design.py +0 -0
  202. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/entity_utils.py +0 -0
  203. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/errors.py +0 -0
  204. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/hashing.py +0 -0
  205. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/household_validation.py +0 -0
  206. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/parameter_labels.py +0 -0
  207. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/parametric_reforms.py +0 -0
  208. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine/utils/plotting.py +0 -0
  209. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine.egg-info/SOURCES.txt +0 -0
  210. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine.egg-info/dependency_links.txt +0 -0
  211. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine.egg-info/entry_points.txt +0 -0
  212. {policyengine-6.2.0 → policyengine-6.2.2}/src/policyengine.egg-info/top_level.txt +0 -0
  213. {policyengine-6.2.0 → policyengine-6.2.2}/tests/__init__.py +0 -0
  214. {policyengine-6.2.0 → policyengine-6.2.2}/tests/conftest.py +0 -0
  215. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/__init__.py +0 -0
  216. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/filtering_fixtures.py +0 -0
  217. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/uk_couple_two_kids.json +0 -0
  218. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/uk_model_surface.json +0 -0
  219. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/uk_single_adult_employment_income.json +0 -0
  220. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/uk_single_adult_no_income.json +0 -0
  221. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/uk_single_parent_one_child.json +0 -0
  222. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/us_married_two_kids_high_income.json +0 -0
  223. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/us_model_surface.json +0 -0
  224. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/us_single_adult_employment_income.json +0 -0
  225. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/us_single_adult_no_income.json +0 -0
  226. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/household_calculator_snapshots/us_single_parent_one_child.json +0 -0
  227. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/parameter_labels_fixtures.py +0 -0
  228. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/parametric_reforms_fixtures.py +0 -0
  229. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/poverty_by_demographics_fixtures.py +0 -0
  230. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/region_fixtures.py +0 -0
  231. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/release_tros/README.md +0 -0
  232. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/release_tros/country-models.lock.toml +0 -0
  233. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/release_tros/manifest.json +0 -0
  234. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/release_tros/us-release_manifest.json +0 -0
  235. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/release_tros/us.trace.tro.jsonld +0 -0
  236. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/spm_development.py +0 -0
  237. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/us_reform_fixtures.py +0 -0
  238. {policyengine-6.2.0 → policyengine-6.2.2}/tests/fixtures/variable_label_fixtures.py +0 -0
  239. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_aggregate.py +0 -0
  240. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_be_axiom_pilot.py +0 -0
  241. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_budgetary_impact.py +0 -0
  242. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_bump_version.py +0 -0
  243. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_bundle_metadata.py +0 -0
  244. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_cache.py +0 -0
  245. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_change_aggregate.py +0 -0
  246. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_cliff_impact.py +0 -0
  247. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_cliff_impact_analysis.py +0 -0
  248. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_congressional_district_impact.py +0 -0
  249. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_constituency_impact.py +0 -0
  250. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_dataset_materialization.py +0 -0
  251. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_dataset_persistence.py +0 -0
  252. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_dataset_runtime.py +0 -0
  253. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_dataset_source.py +0 -0
  254. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_decile_grouping.py +0 -0
  255. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_derivations.py +0 -0
  256. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_dict_reforms_on_simulation.py +0 -0
  257. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_entity_mapping.py +0 -0
  258. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_entity_utils.py +0 -0
  259. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_entity_utils_characterization.py +0 -0
  260. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_errors.py +0 -0
  261. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_extra_variables.py +0 -0
  262. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_filtering.py +0 -0
  263. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_generate_trace_tros.py +0 -0
  264. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_graph/__init__.py +0 -0
  265. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_graph/conftest.py +0 -0
  266. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_graph/test_extractor.py +0 -0
  267. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_household_calculator_snapshot.py +0 -0
  268. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_household_impact.py +0 -0
  269. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_inequality.py +0 -0
  270. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_intra_decile_impact.py +0 -0
  271. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_labor_supply_response.py +0 -0
  272. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_local_authority_impact.py +0 -0
  273. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_manifest_version_mismatch.py +0 -0
  274. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_models.py +0 -0
  275. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_pandas3_compatibility.py +0 -0
  276. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_parameter_labels.py +0 -0
  277. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_parameter_nodes.py +0 -0
  278. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_parameter_values.py +0 -0
  279. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_parametric_reforms.py +0 -0
  280. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_poverty.py +0 -0
  281. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_poverty_by_demographics.py +0 -0
  282. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_poverty_run.py +0 -0
  283. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_preservation_mirror.py +0 -0
  284. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_program_statistics.py +0 -0
  285. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_pyproject_pins.py +0 -0
  286. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_region.py +0 -0
  287. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_region_group_strategy.py +0 -0
  288. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_release_credentials.py +0 -0
  289. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_release_lock.py +0 -0
  290. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_results.py +0 -0
  291. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_run_record.py +0 -0
  292. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_scoping_strategy.py +0 -0
  293. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_small_follow_ups.py +0 -0
  294. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_bundle_bootstrap.py +0 -0
  295. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_bundle_tooling.py +0 -0
  296. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_decile.py +0 -0
  297. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_development_authentication.py +0 -0
  298. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_household.py +0 -0
  299. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_model.py +0 -0
  300. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_selection.py +0 -0
  301. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_spm_selection_schema.py +0 -0
  302. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_trace_tro.py +0 -0
  303. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_trace_tro_verify.py +0 -0
  304. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_uk_analysis.py +0 -0
  305. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_uk_geography_assets.py +0 -0
  306. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_uk_program_statistics.py +0 -0
  307. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_uk_regions.py +0 -0
  308. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_legacy_inputs.py +0 -0
  309. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_legacy_inputs_integration.py +0 -0
  310. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_long_term_datasets.py +0 -0
  311. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_microsim_structural_reforms.py +0 -0
  312. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_native_alignment.py +0 -0
  313. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_native_hdf_weights.py +0 -0
  314. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_program_statistics.py +0 -0
  315. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_us_reform_application.py +0 -0
  316. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_variable_labels.py +0 -0
  317. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_variable_metadata.py +0 -0
  318. {policyengine-6.2.0 → policyengine-6.2.2}/tests/test_zenodo_mirror.py +0 -0
@@ -10,6 +10,10 @@ on:
10
10
  - paper.bib
11
11
  - architecture.png
12
12
 
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
15
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
16
+
13
17
  jobs:
14
18
  paper:
15
19
  runs-on: ubuntu-latest
@@ -14,6 +14,10 @@ on:
14
14
  - src/policyengine/data/bundle/manifest.json
15
15
  workflow_dispatch:
16
16
 
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
19
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
20
+
17
21
  jobs:
18
22
  check-changelog:
19
23
  name: Check changelog fragment
@@ -77,7 +81,7 @@ jobs:
77
81
  - name: Smoke-import core modules
78
82
  run: python -c "import policyengine; from policyengine.core import Dataset, Policy, Simulation; from policyengine.outputs import aggregate, poverty, inequality; print('import OK')"
79
83
  BundleVerification:
80
- name: Verify bundle metadata
84
+ name: Verify release inputs and bundle packages
81
85
  # Private manifest credentials are available only to trusted repository PRs.
82
86
  if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
83
87
  runs-on: ubuntu-latest
@@ -93,8 +97,19 @@ jobs:
93
97
  uses: actions/setup-python@v6
94
98
  with:
95
99
  python-version: '3.13'
96
- - name: Check derived bundle metadata
97
- run: python scripts/bundle.py check
100
+ - name: Install package for TRACE verification
101
+ run: uv pip install -e . h5py --system
102
+ - name: Check reviewed release inputs
103
+ env:
104
+ HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
105
+ run: |
106
+ if [[ -z "${HUGGING_FACE_TOKEN:-}" ]]; then
107
+ echo "::error::Full private release verification requires HUGGING_FACE_TOKEN"
108
+ exit 1
109
+ fi
110
+ python scripts/check_release_credentials.py
111
+ python scripts/bundle.py check --published-spm --include-tros --strict-tros
112
+ python scripts/release_lock.py
98
113
  - name: Install bundle package scaffold
99
114
  run: |
100
115
  uv pip install -e ".[models]" --system
@@ -117,17 +132,10 @@ jobs:
117
132
  PY
118
133
  - name: Check installed package consistency
119
134
  run: python -m pip check
120
- # Only the reviewed registry lock is a pull-request concern. The
121
- # read-only credential, published-measurement and TRACE sidecar gates
122
- # are release gates: the release workflow regenerates the sidecars and
123
- # publishes the wheels immediately before checking them, so they cannot
124
- # be satisfied from a pull request. They run in push.yaml instead.
125
- - name: Check the reviewed registry lock
126
- run: python scripts/release_lock.py
127
135
  - name: Verify bundle packages
128
136
  run: policyengine bundle verify --country us --country uk --packages-only --json
129
137
  Test:
130
- runs-on: macos-latest
138
+ runs-on: ubuntu-latest
131
139
  strategy:
132
140
  fail-fast: false
133
141
  matrix:
@@ -11,6 +11,10 @@ on:
11
11
  - .github/**
12
12
  workflow_dispatch:
13
13
 
14
+ concurrency:
15
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
16
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
17
+
14
18
  jobs:
15
19
  Test:
16
20
  runs-on: ubuntu-latest
@@ -39,7 +39,7 @@ jobs:
39
39
 
40
40
  Test:
41
41
  if: github.event.head_commit.message != 'Update package version'
42
- runs-on: macos-latest
42
+ runs-on: ubuntu-latest
43
43
  strategy:
44
44
  fail-fast: false
45
45
  matrix:
@@ -1,3 +1,22 @@
1
+ ## [6.2.2] - 2026-10-07
2
+
3
+ ### Changed
4
+
5
+ - Use the ACS-local Populace dataset by default for US state and congressional-district simulations while retaining the sparse Populace dataset as the national default.
6
+
7
+
8
+ ## [6.2.1] - 2026-09-30
9
+
10
+ ### Changed
11
+
12
+ - Update the certified PolicyEngine bundle to PolicyEngine Core 3.32.10.
13
+ - Run the full Python test matrices on GitHub-hosted Ubuntu machines and cancel earlier workflow runs when a pull request receives a new commit.
14
+
15
+ ### Fixed
16
+
17
+ - Correct the US and UK TRACE composition fingerprints after the PolicyEngine Core 3.32.10 bundle update, and run the authenticated TRACE comparison on same-repository pull requests.
18
+
19
+
1
20
  ## [6.2.0] - 2026-09-29
2
21
 
3
22
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine
3
- Version: 6.2.0
3
+ Version: 6.2.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
@@ -685,15 +685,15 @@ Requires-Dist: plotly>=5.0.0; extra == "plotting"
685
685
  Provides-Extra: graph
686
686
  Requires-Dist: networkx>=3.0; extra == "graph"
687
687
  Provides-Extra: models
688
- Requires-Dist: policyengine-core==3.32.5; extra == "models"
688
+ Requires-Dist: policyengine-core==3.32.10; extra == "models"
689
689
  Requires-Dist: policyengine-us==2.2.1; extra == "models"
690
690
  Requires-Dist: policyengine-uk==2.102.3; extra == "models"
691
691
  Requires-Dist: spm-calculator==1.0.0; extra == "models"
692
692
  Provides-Extra: uk
693
- Requires-Dist: policyengine-core==3.32.5; extra == "uk"
693
+ Requires-Dist: policyengine-core==3.32.10; extra == "uk"
694
694
  Requires-Dist: policyengine-uk==2.102.3; extra == "uk"
695
695
  Provides-Extra: us
696
- Requires-Dist: policyengine-core==3.32.5; extra == "us"
696
+ Requires-Dist: policyengine-core==3.32.10; extra == "us"
697
697
  Requires-Dist: policyengine-us==2.2.1; extra == "us"
698
698
  Requires-Dist: spm-calculator==1.0.0; extra == "us"
699
699
  Provides-Extra: dev
@@ -711,7 +711,7 @@ Requires-Dist: towncrier>=24.8.0; extra == "dev"
711
711
  Requires-Dist: mypy>=1.11.0; extra == "dev"
712
712
  Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
713
713
  Requires-Dist: hypothesis>=6.100.0; extra == "dev"
714
- Requires-Dist: policyengine-core==3.32.5; extra == "dev"
714
+ Requires-Dist: policyengine-core==3.32.10; extra == "dev"
715
715
  Requires-Dist: policyengine-us==2.2.1; extra == "dev"
716
716
  Requires-Dist: policyengine-uk==2.102.3; extra == "dev"
717
717
  Requires-Dist: spm-calculator==1.0.0; extra == "dev"
@@ -143,14 +143,20 @@ python scripts/bundle.py certify-data \
143
143
  --country us \
144
144
  --data-producer populace \
145
145
  --manifest-uri hf://dataset/policyengine/populace-us@<release>/releases/<release>/release_manifest.json \
146
+ --regional-manifest-uri hf://dataset/policyengine/populace-us@<local-area-release>/releases/<local-area-release>/release_manifest.json \
146
147
  --model-version <policyengine-us-version>
147
148
  ```
148
149
 
149
- US state and congressional-district regions scope the certified national
150
- Populace dataset with row filters. If a Populace release also publishes derived
151
- `states/*.h5` or `districts/*.h5` area slices, the bundle certification omits
152
- those slices from `data_releases.us.datasets`; they are not runtime dataset
153
- dependencies.
150
+ US state and congressional-district regions scope one certified ACS-local
151
+ Populace dataset with row filters. Pass its non-default local-area release
152
+ manifest through `--regional-manifest-uri`; certification adds the pinned H5
153
+ artifact to `data_releases.us.datasets` and writes both regional path templates
154
+ under `data_releases.us.region_datasets`. If a legacy release publishes derived
155
+ `states/*.h5` or `districts/*.h5` slices, certification still omits them.
156
+
157
+ `policyengine bundle install` continues to materialize only each country's
158
+ certified national `default_dataset`. Regional runtimes materialize the
159
+ additional certified dataset when the selected region declares it.
154
160
 
155
161
  Use `python scripts/bundle.py generate` to regenerate derived bundle metadata,
156
162
  and `python scripts/bundle.py generate --include-tros` when TRACE TRO sidecars
@@ -0,0 +1,129 @@
1
+ # US Populace certification runbook
2
+
3
+ Use this runbook to certify a new national US Populace release together with
4
+ the shared ACS-local release used for state and congressional-district
5
+ simulations. Read the [data certification](../skills/data-certification.md)
6
+ skill first for validation semantics.
7
+
8
+ This historical filename is retained so existing links remain valid; the
9
+ procedure itself is release-independent.
10
+
11
+ ## When to use
12
+
13
+ Both release manifests have been published to `policyengine/populace-us`, and
14
+ the model version used by the national release is known. The national release
15
+ will remain the default dataset; the local-area release will remain
16
+ non-default and be selected only for supported regional runs.
17
+
18
+ ## Prerequisites
19
+
20
+ - A clean worktree branched from current `origin/main`.
21
+ - Network access: certification fetches the release manifest and PyPI wheel
22
+ metadata and runs reachability `HEAD` checks against Hugging Face.
23
+ - `HUGGING_FACE_TOKEN` (or `HF_TOKEN`) exported — required to regenerate the
24
+ UK TRO in the `--include-tros` step and to run the UK data-release fetch in
25
+ the test suite. The US populace repo is public.
26
+
27
+ ## Step 1 — identify the releases
28
+
29
+ Set values from the two published release manifests rather than copying an
30
+ older certification:
31
+
32
+ ```
33
+ NATIONAL_RELEASE_ID = populace-us-2024-<national-build>-<sha>-<timestamp>Z
34
+ LOCAL_AREA_RELEASE_ID = populace-us-2024-<local-build>-<sha>-<timestamp>Z
35
+ MODEL_VERSION = <policyengine-us version declared by the national release>
36
+ ```
37
+
38
+ The local-area manifest must declare `dataset_role: non_default_local_area`,
39
+ `is_default: false`, no default datasets, and exactly one pinned H5 microdata
40
+ artifact.
41
+
42
+ ## Step 2 — certify both releases
43
+
44
+ ```bash
45
+ python scripts/bundle.py certify-data \
46
+ --country us \
47
+ --data-producer populace \
48
+ --model-version "$MODEL_VERSION" \
49
+ --manifest-uri "hf://dataset/policyengine/populace-us@$NATIONAL_RELEASE_ID/releases/$NATIONAL_RELEASE_ID/release_manifest.json" \
50
+ --regional-manifest-uri "hf://dataset/policyengine/populace-us@$LOCAL_AREA_RELEASE_ID/releases/$LOCAL_AREA_RELEASE_ID/release_manifest.json"
51
+ ```
52
+
53
+ This one command:
54
+
55
+ - rewrites `data_releases.us` in `src/policyengine/data/bundle/manifest.json`
56
+ from the national release manifest (default dataset, per-artifact
57
+ repo/revision/sha256 pins, certified artifact, certification block);
58
+ - runs `generate(check=False)`, which re-normalizes `manifest.json` and
59
+ updates `pyproject.toml` **only if the model pins moved**;
60
+ - writes the changelog fragment
61
+ `changelog.d/certify-us-$NATIONAL_RELEASE_ID.changed.md`.
62
+
63
+ ## Step 3 — regenerate TRACE sidecars
64
+
65
+ The certify step does not touch TRACE sidecars. Regenerate them so they record
66
+ the new bundle-manifest SHA-256:
67
+
68
+ ```bash
69
+ HUGGING_FACE_TOKEN="$HUGGING_FACE_TOKEN" python scripts/bundle.py generate --include-tros
70
+ ```
71
+
72
+ Both country sidecars contain the bundle-manifest hash, so both may change when
73
+ the bundle changes. If UK cannot be reached, the run writes a *limited* UK
74
+ sidecar; do not commit that degraded output.
75
+
76
+ ## Step 4 — update pinned expectations
77
+
78
+ Update tests that intentionally pin the outgoing national release, local-area
79
+ release, model version, or artifact hashes. Derive every replacement from the
80
+ new manifests; do not copy identifiers from this runbook.
81
+
82
+ If the model version changed, refresh the household snapshots with:
83
+
84
+ ```bash
85
+ PE_UPDATE_SNAPSHOTS=1 pytest tests/test_household_calculator_snapshot.py
86
+ ```
87
+
88
+ ## Step 5 — certify and verify the local-area release
89
+
90
+ The certification command passes the immutable ACS-local release manifest with
91
+ `--regional-manifest-uri`. Confirm all of the following:
92
+
93
+ - `default_dataset` remains the national Populace dataset;
94
+ - the local-area artifact appears in `data_releases.us.datasets` with its
95
+ repository type, immutable revision, and SHA-256;
96
+ - `region_datasets.national` selects the national artifact;
97
+ - `region_datasets.state` and `region_datasets.congressional_district` select
98
+ the shared local-area artifact;
99
+ - no derived `states/*.h5` or `districts/*.h5` artifacts are runtime inputs.
100
+
101
+ ```bash
102
+ pytest tests/test_certify_data_release.py \
103
+ tests/test_release_manifests.py \
104
+ tests/test_us_regions.py \
105
+ -q
106
+ ```
107
+
108
+ ## Step 6 — check, format, lint, test
109
+
110
+ ```bash
111
+ python scripts/bundle.py check # must exit 0
112
+ make format
113
+ make lint
114
+ make test # needs HUGGING_FACE_TOKEN for UK
115
+ ```
116
+
117
+ ## Step 7 — inspect and commit the generated changes
118
+
119
+ The expected diff normally includes the bundle manifest, TRACE sidecars, one
120
+ Towncrier fragment, and pinned test expectations. Include package pins and
121
+ snapshots only when the certified model version changed. Investigate any other
122
+ generated difference before committing it.
123
+
124
+ ## Step 8 — open the PR
125
+
126
+ Follow [github-prs](../skills/github-prs.md): open/find the issue, put
127
+ `Fixes #ISSUE` first, push to the canonical repo, and open a **draft** PR. The
128
+ certify step already wrote the changelog fragment, so the changelog check
129
+ passes.
@@ -31,21 +31,30 @@ For US Populace certification, certify the Populace release manifest directly:
31
31
  ```bash
32
32
  python scripts/bundle.py certify-data --country us --data-producer populace \
33
33
  --manifest-uri "hf://dataset/policyengine/populace-us@<tag>/releases/<tag>/release_manifest.json" \
34
+ --regional-manifest-uri "hf://dataset/policyengine/populace-us@<local-area-tag>/releases/<local-area-tag>/release_manifest.json" \
34
35
  --model-version "<policyengine-us-version>"
35
36
  ```
36
37
 
37
- US state and congressional-district regions are row filters over the certified
38
- national Populace dataset. Certification writes:
38
+ US state and congressional-district regions are row filters over one shared,
39
+ certified ACS-local Populace dataset. Its release manifest must declare
40
+ `dataset_role: non_default_local_area`, `is_default: false`, no default
41
+ datasets, and exactly one pinned H5 microdata artifact. Certification writes:
39
42
 
40
43
  ```json
41
44
  "region_datasets": {
42
- "national": {"path_template": "populace_us_2024.h5"}
45
+ "national": {"path_template": "populace_us_2024.h5"},
46
+ "state": {"path_template": "populace_us_2024_acs_local.h5"},
47
+ "congressional_district": {"path_template": "populace_us_2024_acs_local.h5"}
43
48
  }
44
49
  ```
45
50
 
51
+ The ACS-local artifact is a second entry in `data_releases.us.datasets`; it is
52
+ not a dataset overlay and it never replaces the national `default_dataset`.
53
+
46
54
  If the Populace release publishes derived `states/*.h5` or `districts/*.h5`
47
55
  files for compatibility checks, certification omits them from the runtime
48
- bundle. The national H5 is the canonical `.py` dataset.
56
+ bundle. The country-wide default and ACS-local dataset are each single shared
57
+ files; region registries select one and then filter its rows.
49
58
 
50
59
  The script fetches and validates the manifest (every artifact must carry a
51
60
  revision pin; the certified dataset must be reachable), writes the canonical
@@ -74,8 +83,9 @@ A certification PR should normally change only:
74
83
  Hard failures (certification refuses): missing national default dataset,
75
84
  default dataset absent from artifacts, any artifact without a revision pin,
76
85
  unreachable certified dataset, missing required supplemental release files
77
- (for example Populace-US `us_source_coverage.json`), missing or malformed US
78
- state overlay artifacts when `--regional-manifest-uri` is used, unknown country.
86
+ (for example Populace-US `us_source_coverage.json`), a malformed shared
87
+ local-area release or malformed legacy per-state artifacts when
88
+ `--regional-manifest-uri` is used, unknown country.
79
89
 
80
90
  Certification gate: the model version must either exactly match the
81
91
  build-time model (`compatibility_basis: built_with_model_package`) or be
@@ -92,8 +102,9 @@ publisher-claim basis above.
92
102
 
93
103
  Concrete, fill-in-the-id runbooks that replay a specific certification live
94
104
  under `docs/engineering/runbooks/`. See
95
- `runbooks/build-m-us-populace-certification.md` for the next US Populace
96
- `sparse-rmloss100` default.
105
+ `runbooks/build-m-us-populace-certification.md` for the reusable US national
106
+ and local-area certification procedure. The historical filename is retained
107
+ so existing links remain valid.
97
108
 
98
109
  ## Legacy paths
99
110
 
@@ -106,7 +106,7 @@ separate benefit inputs; they do not override SPM measurement composition.
106
106
 
107
107
  These changes require the coordinated canonical country/calculator bundle, which
108
108
  the packaged production manifest now pins and certifies: `policyengine-us`
109
- 2.2.1, `policyengine-core` 3.32.5, `spm-calculator` 1.0.0, and the US data
109
+ 2.2.1, `policyengine-core` 3.32.10, `spm-calculator` 1.0.0, and the US data
110
110
  release `populace-us-2024-spm-20260915`. Local-wheel development manifest
111
111
  fixtures remain explicitly uncertified. The measurement receipt identifies a
112
112
  calculation; it does not certify a population dataset or establish publication
@@ -134,15 +134,16 @@ pe.us.load_datasets() # or pe.uk.load_datasets()
134
134
 
135
135
  ### US local-area dataset
136
136
 
137
- Alongside the certified national default, the bundle registers a **non-default**
138
- US dataset for finer geographic work: `populace_us_2024_acs_local`. It is a
137
+ Alongside the certified national default, the bundle registers a US dataset for
138
+ finer geographic work: `populace_us_2024_acs_local`. It is a
139
139
  Populace US 2024 build of roughly **1.6 million households** on an **ACS 2024
140
140
  multispine**, with each household **PUMA-assigned** to a 119th-Congress
141
141
  congressional district, county, and state, and calibrated to **state
142
142
  administrative totals and state and congressional-district population**. Its
143
- release gate summary records **four reviewed limitations**, so read that gate
144
- summary before relying on it. It ships in its own immutable release and is never
145
- selected implicitly — you load it by name.
143
+ release validation summary records **four reviewed limitations**, so read that
144
+ summary before relying on it. It ships in its own immutable release. State and
145
+ congressional-district region simulations select it through the bundle's
146
+ `region_datasets` metadata; direct microsimulations can still load it by name.
146
147
 
147
148
  Two-line load:
148
149
 
@@ -23,9 +23,9 @@ ca_snap = Aggregate(
23
23
  ca_snap.run()
24
24
  ```
25
25
 
26
- Each state is a region in the US registry. State regions scope the certified
27
- national Populace dataset by `state_fips`; they do not require separate state
28
- H5 files:
26
+ Each state is a region in the US registry. State regions load the ACS-local
27
+ Populace dataset declared by `region.dataset_path`, then scope its rows by
28
+ `state_fips`. They do not require separate state H5 files:
29
29
 
30
30
  ```python
31
31
  states = pe.us.model.region_registry.get_by_type("state")
@@ -33,8 +33,9 @@ for region in states:
33
33
  print(region.code, region.label, region.scoping_strategy)
34
34
  ```
35
35
 
36
- For state-specific simulations, pass `scoping_strategy=region.scoping_strategy`
37
- with the certified national dataset.
36
+ For state-specific simulations, use both `region.dataset_path` and
37
+ `region.scoping_strategy`. The regional simulation API performs both steps from
38
+ the registry entry.
38
39
 
39
40
  ## US congressional districts
40
41
 
@@ -49,7 +50,9 @@ for row in impacts.district_results:
49
50
  print(row["district_geoid"], row["avg_change"], row["winner_percentage"])
50
51
  ```
51
52
 
52
- `district_geoid` is the SSDD integer (state FIPS × 100 + district number; at-large districts use `00`). Congressional district regions scope the certified national Populace dataset by `congressional_district_geoid`.
53
+ `district_geoid` is the SSDD integer (state FIPS × 100 + district number;
54
+ at-large districts use `00`). Congressional district regions load the same
55
+ ACS-local file and scope its rows by `congressional_district_geoid`.
53
56
 
54
57
  ## UK parliamentary constituencies
55
58
 
@@ -201,31 +201,32 @@ US Populace certification uses the Populace release manifest directly:
201
201
  ```bash
202
202
  python scripts/bundle.py certify-data --country us --data-producer populace \
203
203
  --manifest-uri "hf://dataset/policyengine/populace-us@<tag>/releases/<tag>/release_manifest.json" \
204
+ --regional-manifest-uri "hf://dataset/policyengine/populace-us@<local-area-tag>/releases/<local-area-tag>/release_manifest.json" \
204
205
  --model-version "<policyengine-us-version>"
205
206
  ```
206
207
 
207
208
  That produces one US bundle manifest entry containing the Populace national
208
- default dataset. State and congressional-district regions are runtime row
209
- filters over that national dataset, so derived `states/*.h5` or
210
- `districts/*.h5` files are not vendored into `data_releases.us.datasets`.
209
+ default dataset and the certified ACS-local regional dataset. State and
210
+ congressional-district simulations use the latter with runtime row filters, so
211
+ derived `states/*.h5` or `districts/*.h5` files are not vendored into
212
+ `data_releases.us.datasets`.
211
213
 
212
214
  ### Non-default dataset overlays
213
215
 
214
216
  `certify_data_release` rewrites `data_releases.{country}` wholesale from the
215
- certified release manifest, so that block only ever holds datasets from the
216
- certified release. A staged artifact published in its own release — one that is
217
- deliberately not the certified default — is registered instead under the
217
+ certified release manifest or manifests. A staged artifact that is not part of
218
+ that certification and is deliberately not a default is registered under the
218
219
  sibling `dataset_overlays.{country}` map:
219
220
 
220
221
  ```json
221
222
  "dataset_overlays": {
222
- "us": {
223
- "populace_us_2024_acs_local": {
223
+ "uk": {
224
+ "populace_uk_2023": {
224
225
  "data_package_name": "populace-data",
225
- "path": "populace_us_2024_acs_local.h5",
226
- "repo_id": "policyengine/populace-us",
226
+ "path": "populace_uk_2023.h5",
227
+ "repo_id": "policyengine/populace-uk-private",
227
228
  "repo_type": "dataset",
228
- "revision": "populace-us-2024-buildo-acs-local-...",
229
+ "revision": "populace-uk-2023-...",
229
230
  "sha256": "..."
230
231
  }
231
232
  }
@@ -237,8 +238,15 @@ sibling `dataset_overlays.{country}` map:
237
238
  their own pinned, sha-verified revision. Overlays are strictly additive: an
238
239
  overlay may not shadow the certified default or any certified dataset, so
239
240
  default resolution is untouched. Because certification only rewrites
240
- `data_releases`, overlays survive re-certification without any manual
241
- re-add step.
241
+ `data_releases`, overlays survive re-certification without any manual re-add
242
+ step.
243
+
244
+ Datasets used automatically for a region type are not overlays. They are
245
+ certified into `data_releases.{country}.datasets`, and
246
+ `data_releases.{country}.region_datasets` maps each region type to its artifact
247
+ path. The national `default_dataset` remains unchanged. Ordinary bundle
248
+ installation downloads only that national default; a regional runtime is
249
+ responsible for materializing the additional certified dataset.
242
250
 
243
251
  Cross-package overlays must declare `data_package_name` and `repo_type`
244
252
  explicitly. Ordinary artifacts inherit these values from the country release's
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "policyengine"
7
- version = "6.2.0"
7
+ version = "6.2.2"
8
8
  description = "A package to conduct policy analysis using PolicyEngine tax-benefit models."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -40,17 +40,17 @@ graph = [
40
40
  "networkx>=3.0",
41
41
  ]
42
42
  models = [
43
- "policyengine-core==3.32.5",
43
+ "policyengine-core==3.32.10",
44
44
  "policyengine-us==2.2.1",
45
45
  "policyengine-uk==2.102.3",
46
46
  "spm-calculator==1.0.0",
47
47
  ]
48
48
  uk = [
49
- "policyengine-core==3.32.5",
49
+ "policyengine-core==3.32.10",
50
50
  "policyengine-uk==2.102.3",
51
51
  ]
52
52
  us = [
53
- "policyengine-core==3.32.5",
53
+ "policyengine-core==3.32.10",
54
54
  "policyengine-us==2.2.1",
55
55
  "spm-calculator==1.0.0",
56
56
  ]
@@ -69,7 +69,7 @@ dev = [
69
69
  "mypy>=1.11.0",
70
70
  "pytest-cov>=5.0.0",
71
71
  "hypothesis>=6.100.0",
72
- "policyengine-core==3.32.5",
72
+ "policyengine-core==3.32.10",
73
73
  "policyengine-us==2.2.1",
74
74
  "policyengine-uk==2.102.3",
75
75
  "spm-calculator==1.0.0",
@@ -202,11 +202,11 @@ def _parser() -> argparse.ArgumentParser:
202
202
  )
203
203
  certify.add_argument(
204
204
  "--regional-artifact-prefix",
205
- help="Regional artifact prefix to import. Defaults to states/.",
205
+ help="Legacy per-state artifact prefix to import. Defaults to states/.",
206
206
  )
207
207
  certify.add_argument(
208
208
  "--regional-path-template",
209
- help="Region dataset path template to certify.",
209
+ help="Legacy per-state dataset path template to certify.",
210
210
  )
211
211
  certify.add_argument(
212
212
  "--no-generate",
@@ -60,12 +60,12 @@ def main(argv=None) -> int:
60
60
  parser.add_argument(
61
61
  "--regional-artifact-prefix",
62
62
  default="states/",
63
- help="Regional artifact path prefix to import. Defaults to states/.",
63
+ help="Legacy per-state artifact path prefix to import. Defaults to states/.",
64
64
  )
65
65
  parser.add_argument(
66
66
  "--regional-path-template",
67
67
  default="states/{state_code}.h5",
68
- help="Region dataset path template to certify into the bundle manifest.",
68
+ help="Legacy per-state dataset path template to certify.",
69
69
  )
70
70
  parser.add_argument(
71
71
  "--model-version",
@@ -1,10 +1,10 @@
1
1
  """Region definitions for geographic simulations.
2
2
 
3
3
  This module provides the Region and RegionRegistry classes for defining
4
- geographic regions that a tax-benefit model supports. Regions can have:
5
- 1. A dedicated dataset, usually for the national default.
6
- 2. A scoping strategy that derives the region from a parent dataset
7
- (row filter or weight replacement).
4
+ geographic regions that a tax-benefit model supports. Regions can select an
5
+ input dataset, apply a scoping strategy to a selected dataset, or do both. For
6
+ example, US states and congressional districts select the shared ACS-local
7
+ dataset and then filter its rows.
8
8
  """
9
9
 
10
10
  from typing import Literal, Optional, Union
@@ -22,10 +22,8 @@ RegionType = Union[USRegionType, UKRegionType]
22
22
  class Region(BaseModel):
23
23
  """Geographic region for tax-benefit simulations.
24
24
 
25
- Regions can either have:
26
- 1. A dedicated dataset (``dataset_path`` is set).
27
- 2. A scoping strategy that derives the region from a parent dataset
28
- (``scoping_strategy`` is set).
25
+ ``dataset_path`` selects the input dataset. ``scoping_strategy`` optionally
26
+ scopes that dataset to the requested geography. A region may declare both.
29
27
 
30
28
  The unique identifier is the code field, which uses a prefixed format:
31
29
  - National: "us", "uk"
@@ -56,7 +54,7 @@ class Region(BaseModel):
56
54
  # Dataset configuration
57
55
  dataset_path: Optional[str] = Field(
58
56
  default=None,
59
- description="URI to a dedicated dataset when the region has one.",
57
+ description="URI to the input dataset selected before regional scoping.",
60
58
  )
61
59
 
62
60
  # Scoping strategy for regions that derive from a parent dataset
@@ -173,11 +171,11 @@ class RegionRegistry(BaseModel):
173
171
  return [r for r in self.regions if r.parent_code == parent_code]
174
172
 
175
173
  def get_dataset_regions(self) -> list[Region]:
176
- """Get all regions that have a dedicated dataset on disk."""
174
+ """Get all regions that select an input dataset."""
177
175
  return [r for r in self.regions if r.dataset_path is not None]
178
176
 
179
177
  def get_filter_regions(self) -> list[Region]:
180
- """Get all regions that derive from a parent dataset via a scoping strategy."""
178
+ """Get all regions that apply a scoping strategy to their input dataset."""
181
179
  return [r for r in self.regions if r.scoping_strategy is not None]
182
180
 
183
181
  def __len__(self) -> int: