Repository navigation
Conversation
policyengine-us declares in_denver, in_yonkers, in_wilmington and pa_philadelphia_wage_tax_resident as inputs with no formula. The registry maps each to its 2020 county (Denver 08031, Philadelphia 42101) or place (Yonkers 36/84000, Wilmington 10/77580), checked against the 2020 Gazetteer, P.L. 94-171 P1_001N and block ladders 7ba39b95 and 6840b990. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The block-ladder frame wrapper derives all four flags from the block's county and place. The PUMA ladder and the pooled ACS line derive the county-rule flags (in_denver, pa_philadelphia_wage_tax_resident) from the final county and remove the place-rule flags (in_yonkers, in_wilmington), which no place rung can decide there. Summaries record each flag as derived or unavailable, and both ladder gates fail a present flag that disagrees with its rule. The pool manifest moves the county-rule flags to geography_derived_jurisdiction_input (assembled) and the place-rule flags to unavailable_place_jurisdiction_input, and relabels county_fips and congressional_district_geoid, which the stacked PUMA operator writes, as preserved_stacked_engine_input. tools/repin_us_pool_engine_contracts.py re-derived the provision counts, the manifest digest and the engine ABI lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-derived with the repo tools after the derivation change: repin_us_spec_engine_contracts.py (--legacy-only, then full), generate_us_bundle_from_constants.py (US spec_sha256 0b5c29e4...) and spec_engine_coverage.py (42305/42305 fields, 41/41 checks); --check passes on all three and on repin_us_pool_engine_contracts.py. Tests: Hypothesis properties for the iff rule, block-population conservation, row-order invariance and person broadcast, plus registry pin, gate, PUMA and pooled-line cases (engine_free); an engine contract that each flag is an input-only boolean its consumers read; and an engine scenario in which Yonkers, Wilmington, Denver and Philadelphia residents placed by the block ladder get their local tax or benefit and their neighbours do not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
November 2, 2026 13:40
…, record the no-ladder pool receipt Answers the round-1 review of b7b3e21: - rederive_us_local_jurisdiction_flags reads the rungs an existing artifact's own geography supports (county when county_fips is on every row; place only when place_fips and a 15-digit block_geoid are too), refuses carried household or person flags that disagree, and writes the flags. export_us_l0_refit_h5 and the fiscal refresh release builder call it on the loaded base and record the receipt. - Both ladder gates fail an absent flag whose rule the line's own rung decides (block: county and place; PUMA: county), so a missing column can no longer reach the engine as an all-False default. - build_optional_acs_multispine records the pool's flag receipt in provenance on both the ladder and no-ladder paths. Also classifies local_jurisdictions.py for the spine-blindness test, repins the engine ABI digest, and reruns the US spec repin chain (seed-kernel attestations hash geography_ladder.py and puma_ladder.py). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nifest tools/graph_us_post_transfer_fixture.py rewrote the pinned graph's remaining_stage_manifest_sha256 (d4fb9de9 -> 6e70bc74) after this PR moved the pool manifest. Sources and expected.csv are byte-identical; the tool's own graph-parity check passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r2 finding 1: the rungs belong to the whole household table, so a pooled base whose ACS rows carry no block decides only the county-rule flags, and a frozen support or L0 support that keeps only block-anchored donors would export without in_yonkers and in_wilmington even though its own geography decides them. The fiscal refresh builder now derives the flags on the loaded base, again right after frozen-support selection (before target materialization), and again on the export frame once the L0 or full-pool weights attach, before any export gate or the H5 write. The calibration diagnostics record each receipt under support_value_repairs.local_jurisdiction_flags, keyed base, frozen_support and export. rederive_us_local_jurisdiction_flags returns the same frame when it already carries exactly the flags its rungs decide, as boolean columns, so the repeat calls copy no tables. Property tests check that deriving a selection of a derived support equals deriving the kept rows from scratch and leaves every decidable flag, and that the unchanged return equals a rewrite. The commit also adds us_local_jurisdiction_artifact_receipt, which refuses an artifact that lacks or contradicts a flag its own geography decides and otherwise returns the receipt a derivation would give. The selection property test uses it as its completeness oracle; the annual static-aging lane uses it in the next commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r2 finding 2: the annual lane copies its parent's base year byte for byte and keeps the parent's columns in every projected year, and the annual publication validator requires exactly those columns. A parent built before the local-jurisdiction flags therefore produced annual files without in_yonkers or in_denver, and the engine defaulted every resident to False. The lane cannot write the flags without breaking that preservation contract (the base-year file is the certified release's own base artifact), so it now requires them. build_annual_static_aging reads the parent before the model provenance check and calls us_local_jurisdiction_artifact_receipt, which refuses a parent that lacks a flag its own geography decides, carries one that disagrees with it, or carries one its rungs cannot decide. The candidate manifest records the receipt as base.local_jurisdiction_flags. Engine-free tests write parents with block, county-only and no geography: six refusal cases fail before the model provenance check and before the output directory exists, and complete parents reach it. Against the previous lane the six refusal cases and the three receipt cases fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review r2 nit 3: an assembled checkpoint from before the local-jurisdiction flags holds a passing PUMA-ladder receipt but no in_denver. The live gate now fails it, and the rejection said only that the receipt changed from live output, so the operator could not see the repair it needs. _validate_stacked_geography_assignment_receipt now appends the live gate's failure lines (in_denver: absent, but this table's county rung decides it, ...) when the live gate fails, and says that the live gate passes but its details differ otherwise. It still fails closed in both cases. Engine-free tests build an assembled pool with every column the live gate reads, with and without in_denver, and check that the message names the missing flag only when it is missing; a third test covers the passing, changed-details branch. All three fail against the previous message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in main at 3a9c808. Both sides moved the US seed-protocol digests: main through housing_inputs (microcosm#1444), this branch through geography_ladder and puma_ladder. The four conflicts were all digest pins, so none keeps either side's value: tools/repin_us_spec_engine_contracts.py recomputed EXPECTED_HASHES seed_map and seed_protocol, the loader golden spec_sha256 and the pool-tool run_config spec_sha256, and tools/spec_engine_coverage.py rewrote docs/evidence/spec-engine/ us-f0-coverage.json (42210/42210 configuration fields, 41/41 inventory checks). A comment above the seed pins names both causes. same_edit.py found no edit both sides made identically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewrites six passive comments and docstring lines from the support re-derivation commit so each names its actor (_main, the derivation, the release engine). Comments only; the builder tests pass unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
policyengine-us 2.2.1 (and 2.60.4) declares four local-tax jurisdiction flags as inputs with no formula, so each stays
Falseunless the dataset writes it:in_denverin_yonkersny_yonkers_income_tax(resident surcharge)in_wilmingtonde_wilmington_earned_income_taxpa_philadelphia_wage_tax_residentpa_philadelphia_wage_tax(resident rate)engine_abi.lock.jsonlisted all four asdeclared_absent_engine_input, so every built dataset charged no Yonkers surcharge or Wilmington earned-income tax and gave no Denver relief.Change
Registry.
us_runtime/us_local_jurisdictions.jsonmaps each flag to one 2020 geography, andlocal_jurisdictions.pypins its SHA-256 (45035eee…).county_fips[:2]as well.tools/verify_us_local_jurisdiction_registry.pychecked every code against Census data; none came from memory:in_denverin_wilmingtonin_yonkerspa_philadelphia_wage_tax_residentP1_001Nfrom the Census API matches each population.Lines.
with_household_us_geography_ladder): writes all four flags from the block's county and place. Person flags go throughperson_household_id.with_household_us_puma_ladder, used by the stacked pool): writes the county-rule flags from the drawn county. It never writesin_yonkersorin_wilmingtonand removes any stale column. The summary records them asunavailablewith the reason.with_optional_acs_spine): re-derives the county-rule flags for every row from the final county and removes the place-rule flags. Without a PUMA ladder it removes every flag, since ACS rows then have no county.with_us_local_jurisdiction_flags(frame, rungs=BLOCK_GEOGRAPHY_RUNGS).place_fips; andin_denver,in_yonkersandin_wilmington; the PUMA gate requiresin_denver.Existing artifacts. A base H5 built before this change carries no flags. Two steps start from an existing artifact, and both now call
rederive_us_local_jurisdiction_flagsfirst:export_us_l0_refit_h5records the receipt aslocal_jurisdiction_flagsin its summary.tools/build_us_fiscal_refresh_release.pyruns it on the loaded base or prepared pool, before frozen-support selection. It records the receipt undersupport_value_repairsin the calibration diagnostics and as a telemetry stage.The helper reads the rungs from the artifact's own geography. The county rung needs
county_fipson every row. The place rung also needsplace_fipsand a 15-digitblock_geoidon every row, so a pooled artifact whose ACS rows have no block gets only the county-rule flags. A carried household or person flag that disagrees with the geography stops the step.The next certified build from main therefore carries the flags even from a pre-change base, which moves its Yonkers, Wilmington and Denver aggregates. The running Route A build pins its own commit and is untouched.
Pooled ACS receipt.
build_optional_acs_multispinerecordsprovenance["local_jurisdiction_flags"]with or without a PUMA ladder. Without one, every flag is listed as unavailable with its reason; before this change that receipt was dropped.Philadelphia.
pa_philadelphia_wage_tax_residentexists in the pinned engine, so the registry decides it from county 42101 and records the rule. The tax also needspa_philadelphia_wage_tax_taxable_wages, which no line supplies yet, so built datasets still compute zero Philadelphia wage tax. That follow-up is split out.Engine ABI lock.
tools/repin_us_pool_engine_contracts.pyre-derived the pool manifest:in_denverandpa_philadelphia_wage_tax_resident→geography_derived_jurisdiction_input, available atassembled.in_yonkersandin_wilmington→unavailable_place_jurisdiction_input, with fallbackpolicyengine_default_no_place_rung.county_fipsandcongressional_district_geoid→preserved_stacked_engine_input. The stacked PUMA operator writes both, and the lock had them as declared absent; without this the new rows would cite a source the lock calls absent.The stacked checkpoint identity binds that digest, so a checkpoint built before this change is refused on resume rather than reused without flags.
Spec pins.
repin_us_spec_engine_contracts.py,generate_us_bundle_from_constants.pyandspec_engine_coverage.pyre-derived the spec bundle (US spec_sha256 0b5c29e4…), inventory digests, coverage evidence and test pins.--checkpasses on all three tools (42305/42305 fields, 41/41 checks).Invariants
These hold for every input. Hypothesis tests in
tests/engine_free/us/test_us_local_jurisdictions.pycheck them:county_fipsequals the registry county. A place-rule flag is true exactly whencounty_fips[:2]andplace_fipsequal the registry state and place. The oracle is the four codes written out in the test, independent of the registry file. Generated codes include near misses: place 84000 in other states, 08032, 18031 and random codes.assign_us_geography_ladderon random ladders. The verification tool checks the same identity on the real ladders against P1_001N.in_denver.Mutation check, with the Hypothesis DB cleared for each mutant:
Tests
engine_free/us/test_us_local_jurisdictions.py(new): registry pin and validation, the Hypothesis properties above, the block and PUMA lines end to end, the frame helper for US household location v1: one census block per household, every geography derived #1047, and gate failures. It also covers rung inference, person-flag checks, and re-derivation of pre-flag, corrupt, pooled and county-less artifacts.engine_free/us/test_us_l0_refit_export.py: a pre-flag base on a Yonkers block exportsin_yonkers=Trueand records the receipt. A base whose carried flag disagrees is refused before the writer runs.engine_free/us/test_us_fiscal_refresh_builder.py: the builder derives the flags once, after the base load and before selection and export, and the diagnostics carry the receipt.engine_free/us/test_us_acs_multispine.py: the pooled receipt is recorded with and without a PUMA ladder.engine_free/us/test_us_geography_ladder.py,test_us_puma_ladder.pyandtest_us_county_vintage_ladders.py: gate fixtures carry the flags, and new cases cover a missing required flag.engine_free/us/test_us_spine_blindness.py: classifieslocal_jurisdictions.pyand pins the pool tool's runtime graph at 82 modules.engine_contract/us/test_spec_engine_engine_abi.py: repins the remaining-stage manifest digest to6e70bc74….engine_free/us/test_us_base_pool.py: the pooled line re-derives the county flags for every row and drops the place flags, or drops every flag without a ladder.engine_free/us/test_us_multispine_pool.py: new provision counts and rows.engine_contract/us/test_us_local_jurisdiction_engine_contract.py(new): each flag is an input-only boolean (default False) on its entity in the pinned engine, and each listed consumer reads it.engine_scenario/us/test_us_local_jurisdiction_flags_engine.py(new): synthetic households placed bywith_household_us_geography_ladderand run throughPolicyEngineUSEngine.materialize.Review
GPT-6.1 Sol reviewed b7b3e21 and asked for two changes (
review-r1.md). Both are fixed in 84ab874:l0_refit_exportwrote the artifact without deriving them. Now both the export and the release builder re-derive the flags from the artifact's own geography, and both ladder gates fail a missing flag their rung decides.build_optional_acs_multispinenow records it on both paths.Commit 84ab874 also fixes the two CI failures on b7b3e21: the spine-blindness module classification and the stale ABI manifest digest pin. Sol's round-2 review of 84ab874 is pending.
Out of scope
PUMA×county×CD atom tables, congressional-district plans (#1041, #1043), making the block canonical (#1047), and every running Route A build.
Follow-up: Yonkers city may cover exactly 2020 residence PUMA 36-03112. If block-level checks confirm that, the PUMA line could decide
in_yonkersinstead of recording it unavailable. That needs its own Census verification, registry rule and repin, so it is a separate change.Axiom: n/a (data/infra).
🤖 Generated with Claude Code