Repository navigation
Conversation
Move every extra that installs policyengine-us to >=2.60.4,<3 and its core pin to 3.33.3, the core policyengine.py's bundle certifies against. The lock changes only policyengine-us (2.2.1 -> 2.60.4) and drops the separate 3.32.5 core entry; spm-calculator stays at 1.0.0. APPROVED_UV_LOCK_SHA256 follows the new lock. Compatibility fixes follow in later commits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-us 2.60 writes ["adjusted_gross_income", *TAX_UNIT_ADDITIONS]. A starred item now contributes its items when it evaluates to an exact sequence; anything else stays unknown and still fails closed. Four more 2.60.4 sites remain unresolved (see PR body). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 of 12 tasks
…-up flag The static consumer index now resolves the five 2.60.4 sites it refused: starred list items (module constants and parameter lists), one-argument dict.get with an `is None` skip, a run-time key into a fully known name table (every value is a possible read), and helper return values bound by assignment, including tuple unpacking. Return values are evaluated with sinks deferred; the enqueued helper context still checks them strictly. On the policyengine-us 2.2.1 source the index's receipts are byte-identical to main's (5,729 targets, 17,772 receipts). policyengine-us 2.60 adds takes_up_medicare_part_d_if_eligible (person, default true). It joins the take-up contract as rate_unsourced at the engine default, which keeps the Part D income-related premium on every enrollee above the thresholds, as 2.2.1 charged it. The generated-variable audit is regenerated for 2.60.4 (119 -> 120 variables; mt_agi). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-us 2.60 removed the tax-unit first/second_home_mortgage_interest inputs (policyengine-us#9605). The PUF tax-detail QRF no longer produces them; the person-level home_mortgage_interest already carried the whole amount. On the certified d1386 H5, first_home_mortgage_interest equals the person-level sum in every tax unit, second_home_mortgage_interest is zero everywhere, and no unit relied on 2.2.1's structured fallback, so the deduction base is unchanged. The late transfer surface loses that target (70 -> 69; terminal stacked surface 134 with the Part D take-up flag added). 2.60 also defines tax_unit_role_input, parent_1_id and parent_2_id as inputs, so they leave the stored non-variable register (51 -> 48 entries); the engine-contract premise test now pins their 2.60 shapes. The batched-materialization drift scan finds 30 new formulas in 2.60.4. Each is triaged as constant membership (17 np.isin over parameter or literal lists) or a household-local join (parent links resolved among co-residents, family-keyed Wisconsin CTS units, SSI deemor pools, an error-count .sum()); none joins the population-aggregate list. The reviewed-source digest moves. The concept mapping is reviewed against 2.60.4: every binding still names a pure input; the coverage golden adds 2.60's 148 new inputs as uncovered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r 2.60 The list-valued reform-coverage probes pinned whole 2.2.1 parameter lists. Applied on 2.60.4 they would also have stripped about 45 state SSP items from SNAP unearned income and undone the educator_expense_ald and traditional_ira_deduction renames, so each probe would have measured a different reform. Every list is re-derived from the 2.60.4 baseline with only its own item changed; the educator probe now removes the renamed educator_expense_ald leaf. Reason texts that state engine facts were re-checked on 2.60.4 before moving their version. The eCPS parity reference still carries the retired first/second home mortgage interest layers. REFERENCE_ECPS_RETIRED_LAYERS names their live successor (home_mortgage_interest): they are no coverage requirement, the parity gate skips them and records the skip, and the retirement refuses an engine that still defines them or lacks the successor. The Medicare IRMAA holdout now expects the top tier for a single-year household: 2.60 includes policyengine-us#10106 and falls back to the earliest input year's income, deflated ($543,850 from $600,000 of 2024 wages). Engine version guards, the known-gap evidence records (facts re-verified), the core-pin test, the OBBBA premise pin, docs and the changelog move to 2.60.4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
repin_us_pool_engine_contracts.py and generate_us_bundle_from_constants.py rewrote every engine-derived pin; nothing was set by hand: - SSI dependency closure 54/63/187 -> 96/121/351 (input leaves / formula nodes / edges); 59 of the 96 leaves are declared absent engine inputs, up from 18, so they run at their engine defaults. - Engine input projection 926 -> 1,074 inputs (1,073 defaults); the remaining-stage manifest has 1,250 rows. - The engine ABI lock covers 18 take-up programs (Part D added). - The spec bundle drops the two retired mortgage outputs (PUF QRF 65 -> 63 targets, late DAG 70 -> 69, producer graph 2,744/227/213 -> 2,741/224/211, catalog 176 -> 175 keys) and the frozen generation-0 resources (source_stages.json, take_up_contract.json) are re-attested. The PUF QRF target-order digest follows the shorter order. --check passes; spec_sha256 5ff97a0b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
first_home_mortgage_interest leaves the required surface (167 -> 166); the nine re-derived reform probe lists and the re-verified reason texts land in the manifest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every value below was observed at this head and written verbatim: - field usage: 43,674 configuration fields (32,352 authored, 11,322 resolved; was 42,184 / 32,404 / 9,780), seven claim pointer pins, mode and generation-0 effect counts, and the pointer-inventory digest. - inventory coverage: 41/41 again. The moved digests and counts follow the retired mortgage outputs (PUF QRF 63 targets/tuples, late 69, producer inputs 2,741, compiled outputs 224, tail control fields 930, catalog 175 columns) and the Part D take-up program (18 programs, 29 steps); the seed protocol moves because it attests puf_support, puf_qrf_chain and acs_transfer. - docs/evidence/spec-engine/us-f0-coverage.json regenerated by tools/spec_engine_coverage.py; the US spec_sha256 is 5ff97a0b, and the minimal-bundle loader golden, schedule (50aa8412) and payload (c04c59fa) digests follow. The H3 US post-transfer parity fixture is regenerated with tools/graph_us_post_transfer_fixture.py under 2.60.4: it gains the Part D take-up column and the take-up digest moves; expected.csv is byte-identical, so derive/seed/materialize outputs are unchanged by the engine move. The tool now loads its helpers from test_support (the tests were reorganized into category directories). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1,250 rows (34 derive, 34 seed, 1,182 simulate; the Part D take-up flag is the new seed row) over a 1,074-input engine projection with 1,073 defaults, as repin_us_pool_engine_contracts.py derived them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ement The consumer index reads exactly the union of a starred display's parts for any lists, and the eCPS reference retirement partitions any share map into kept and retired layers, retiring only registered layers onto their registered successor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…battery tests The manifest currency check now leaves the retired mortgage layers out of the required reference surface, as the generator does. The shipped-probe tests pin the re-derived 2.60.4 lists; the battery has one more boolean target (Part D take-up) and one fewer monetary target (the retired mortgage leg); the calibration legacy projection digest follows the shorter calibrated-input list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The post-PUF completion receipt and its labels now name the 69-target late surface; the stacked-spine tests follow the Part D take-up flag (one more seeded boolean and battery target) and the retired mortgage leg (one fewer monetary target, two fewer late occurrences), and the lineage tests follow the 63/69-target imputation families (180 imputed variables, 129 amounts). policyengine-us 2.60 treats California as a state that excludes child support paid from SNAP gross income (the state parameter flipped), so the $200 monthly payment moves from snap_child_support_deduction to snap_child_support_gross_income_deduction. The engine test now asserts the invariant: the countable payment is $200 and the exclusion plus the deduction count it exactly once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- educator_expense is uprated by per-capita CBO AGI in 2.60, the ALD list names educator_expense_ald, and above_the_line_deductions sums that list in a formula; the contract and abolition-probe tests say so. - The spec-engine coverage tool test pins 2,741 producer inputs and 930 tail control fields. - The late-transfer completion receipt fixtures carry 69 targets, and the legacy publication manifest golden moves with the engine identity surface (pool_h5 and agreement digests are unchanged). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The pool's remaining-stage manifest has 1,250 rows (34 derive, 34 seed, 1,182 simulate) and digest 7681ca45 in the ABI lock tests. - The post-transfer graph's create node owns 77 columns and its seed node 18 (the Part D take-up flag). - The frame metadata index reads 6,797 definitions, 1,074 inputs and 5,723 formula-owned outputs; mt_agi joins the generated state MFS variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The same nine counts the spec-engine inventory moved: 63 primary targets and tuples, 69 late targets, 224 compiled outputs, 2,741 producer inputs, 930 tail control fields, 18 take-up programs, 29 pipeline steps and 175 typed columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The declared surface, post-PUF transfer surface, metric registry and late producer schedule digests follow the Part D take-up target and the retired mortgage leg. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
117 transfer targets (69 late, 42 PUF-clone producers), 141 pool input surface rows, 18 take-up programs, a 63-target primary QRF whose last target sees 70 predictors, and the transfer target-name digest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tures The examined files now also refuse the retired tax-unit mortgage legs on each tax-unit table and register one fewer entry (tax_unit_role_input is an engine variable). The take-up semantics test counts 18 programs; the PUF support fixtures and pool consumer expectations drop the mortgage legs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… consumer index On policyengine-us 2.60.4 the static consumer index missed reads it could not see and raised nothing: - 77 tax-unit sums moved onto tax_unit_non_dep_add, a package helper outside variables/ (net_capital_gain lost its form 4952 reader). Every helper the formulas call now needs a review in POLICYENGINE_US_HELPER_REVIEWS naming the arguments it reads and its own reads, pinned to a digest of its code, the package functions it uses and their constants. An unreviewed or changed helper stops the index. Class-body factories (all_of_variables, sum_among_non_dependents) are read the same way. - branch.calculate(name), get_holder(name) and simulation.get_array(name) record simulation_read receipts (21 calculate sites on 2.60.4). - Functions defined inside a formula are interpreted at each call in the caller's scope (the IRMAA lookback's provided(), Oklahoma's applied()); one used as a value is interpreted where defined. Lambda bodies are scanned. - An equality or membership test on an opaque value (period.start.year != 2021) no longer decides a branch, which had hidden Alabama's 2021 Part II. On 2.60.4 the receipts are a strict superset of the previous index's (771 added, none removed). The pool input consumer guard moves to engine_contract so engine-us runs it; it had skipped itself in engine-free CI, and the test plan now rejects that pattern. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Catalog and typed closure: 175 columns (two retired mortgage legs, one Part D flag), units 87 undeclared / 52 boolean, 224 compiled producer outputs. - Canonical battery: 369 metric legs, 78 monetary and 52 incidence metrics. - Alimony: 2.60 deducts each non-dependent's eligible alimony through alimony_expense_ald_person; the divorce-year test is unchanged. - weeks_unemployed gains a live consumer, unemployment_compensation_months (SNAP work registration exemption), alongside the four blocked UI programs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-us 2.60.4 adds the published LA County utility allowance to HUD gross rent: $3,252 a year for the probe's one-bedroom, so the payment is $12,000 + $3,252 - $25 = $15,227 (2.2.1: $11,975). 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.
Moves main's US engine lock from policyengine-us 2.2.1 (core 3.32.5) to policyengine-us 2.60.4 on policyengine-core 3.33.3, so the next certified US Route A build calibrates and scores natively on the current engine. No certified build is started here.
Why
The certified d1386 release (8b0c195) claims
policyengine-us==2.2.1. PolicyBench v2 waits for a policyengine.py bundle certified with 2.60.x (ruled 2026-10-23). The short-term bridge is acompatibility_recertificationsource-enrichment child that the PolicyBench session is building separately; this PR does not touchmicrocosm.data.contract,source_enrichment, or that tool. This is the long-term half.Versions (verified on PyPI 2026-10-23)
==, and policyengine.py's certification requires the runtime core to be the build core or covered by that claim. policyengine.py 6.10.1 pins core 3.33.3, so a 2.60.x bundle can match without a second core bump, and the UK fork stays on its locked 3.33.3. Core 3.33.4 to 3.33.12 (rate-scale,set_inputcache and dataset-membership fixes) is a follow-up to coordinate with policyengine.py.The lock diff moves only policyengine-us and drops the separate 3.32.5 core entry.
APPROVED_UV_LOCK_SHA256follows.What 2.60.4 changes for Microcosm
The full surface diff (6,167 to 6,797 variables) was cross-referenced against every tracked file. Evidence is in
~/PolicyEngine/_build_artifacts/engine-lock-pe-us-2.60/.Removed inputs Microcosm produced:
first_home_mortgage_interest,second_home_mortgage_interest(tax unit; policyengine-us#9605).home_mortgage_interestwas reported.first_home_mortgage_interestequals the person-level sum in every one of the 64,774 units that carry it,second_home_mortgage_interestis zero everywhere, and no unit relied on the fallback. The deduction base is therefore unchanged.REFERENCE_ECPS_RETIRED_LAYERSnames their successor (home_mortgage_interest). The parity gate skips them and records the skip, and the input-coverage manifest drops the requirement (167 to 166 required columns).New engine inputs Microcosm already writes:
tax_unit_role_input,parent_1_id,parent_2_id.person_id0 and cannot be named as a parent; that was already documented ineligibility_inputs.New take-up flag:
takes_up_medicare_part_d_if_eligible(person, default true).rate_unsourcedat the engine default. The ASEC has no Part D item; CMS publishes enrollment counts, so a count-calibrated stage is the follow-up.IRMAA lookback (#10106).
Other 2.60.4 model changes the pins follow (each checked against the 2.60.4 source).
bedrooms,tenant_pays_utilitiesandis_sro, which the release does not store (engine defaults apply).alimony_expense_ald_person, leaving dependents out. The pre-2019 divorce-year test is unchanged, anddivorce_yearstill defaults to 2010, so stored alimony stays deductible.weeks_unemployedgains a live consumer,unemployment_compensation_months, for SNAP's work-registration exemption. The release already stores the column.Reform-coverage probes pinned whole 2.2.1 parameter lists.
educator_expense_aldandtraditional_ira_deductionrenames, so each probe would have measured a different reform.educator_expense_ald. Every reason text that states an engine fact was re-checked on 2.60.4.Post-export watched-formula lists.
US_POPULATION_AGGREGATE_VARIABLESandPOST_EXPORT_BASELINE_BRANCH_READERSare unchanged on the 2.60.4 scan.np.isin). The other 13 are household-local joins: parent links resolved among co-residents, family-keyed Wisconsin CTS units, SSI deemor pools, and an error-count.sum().Static consumer index (frame adapter; it gates every generator).
dict.getwith anis Noneskip;variables/. 2.60 moved 77 tax-unit sums ontotax_unit_non_dep_add(tools/general.py), sonet_capital_gainlost its form 4952 reader, for example. Every helper the formulas call now needs a review in_policyengine_us_helper_reviews.py: which arguments name variables it reads, what its body reads on its own, and reads made only when an argument is omitted. All 41 helpers 2.60.4 calls were read and reviewed. Each review pins a digest of the helper's code, every package function it uses and the module constants they read (docstrings excluded). An unreviewed or changed helper stops the index. The same reviews cover class-body factories (formula = sum_among_non_dependents("earned_income")).branch.calculate(name),get_holder(name)andsimulation.get_array(name)now recordsimulation_readreceipts (21calculatesites on 2.60.4, 11 on 2.2.1).provided()and Oklahoma'sapplied().period.start.year != 2021used to count as exactly true, which hid Alabama's 2021 Part II recompute. Equality and membership tests now decide a branch only when both sides are exact data.test_us_pool_input_consumers.pymoves fromengine_freetoengine_contract. It skipped itself when the engine was missing, so CI never ran it, and its 2.60.4 pins had drifted.tools/ci_test_plan.pynow rejects that skip pattern.SSI closure grows from 54 to 96 input leaves. 59 of them run at engine defaults (up from 18): state UI wage inputs (modelled UI applies only when no reported amount exists, and pays nothing at zero wages), SSI living-arrangement and deeming detail, and some pension splits.
Re-derived pins (all observed and written verbatim, none hand-derived)
mt_agi).--checkpasses; spec_sha2565ff97a0b).expected.csvis byte-identical.Invariants (executed)
test_policyengine_us_helper_reviews.py).get, an unreviewed or changed package helper, a run-time name incalculate, a local function or lambda passed a run-time name, and a class-body call to a formula-module factory all raise.home_mortgage_interest+second_residence_mortgage_interest) equals 2.2.1'shome_mortgage_interest_tax_unitin every tax unit. This is a data property of the certified file, verified directly.test_engine_core_pins.py).Consequences while main is ahead of the certified default
Main's loader enforces each release's
==claim. So on this lock,microcosm.data.load("us")refuses the 2.2.1-certified default until the recertification child (or a native 2.60.x build) exists.Follow-ups (not in this PR)
tax_unit_role_inputon the pool input surface, so the SSI agreement simulation reads the constructor's roles. It currently falls back to age ordering, as 2.2.1 did.bedrooms(and considertenant_pays_utilities), which 2.60's HUD utility allowance and the payment standard read; the release leaves them at engine defaults.spm_measurement_adults,spm_measurement_children) that the source index cannot see, so closures stop at them.Status
Draft. CI on the latest pins and the Sol review are pending (Subfleet lanes reopen about 02:00Z).
axiom: n/a: engine lock and data-pipeline compatibility; no policy rule changes.
🤖 Generated with Claude Code