Repository navigation
Bind state × AGI-band SOI targets and re-pin the US feed for TY2023 state bands (#940) - #1102
Conversation
…tal (#940) State return-count and AGI bands from IRS SOI Historic Table 2 compiled to nothing: every bounded AGI slice from another tax year is refused as a stale nominal level, and only EITC and taxable-interest families were rescued. So a state's top tail was free as long as its totals matched (Colorado: returns and AGI within 0.12%, 24% of SOI's AGI above $1M in Build P ACS-local, #940). - `_is_soi_state_agi_band_fact`: state HT2 AGI-table bands, return_count and AGI, all filing statuses, lower edge >= $100k (the SOI slice materializer has no filer filter; same floor as the national size classes, #958). - `_rebase_soi_state_agi_bands`: each band binds as control x band / partition, where partition is the state's published bands of that vintage over the whole AGI line and control is the state's latest HT2 all-returns total (the row that already binds). Values land at the control's period and age with it; counts never age. One vintage per state and measure, so a collapsed 500k_plus row never binds beside split 500k_to_1m/1m_plus rows. Gaps drop a state's bands; overlaps raise. - Release coverage requirement `irs_state_agi_top_tail`: 51 state $1M+ AGI rows, so a feed without the split bands fails instead of shipping without the constraint. Tests: synthetic rule tests plus a Hypothesis property test (share identity, band-sum identity, control homogeneity, feed-order invariance), and feed-gated tests for the pinned feed (exact shares, band means inside their edges, differential against Table 1.1's TY2023 classes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/us-fact-to-target.md: which state HT2 bands bind, the share-of-state- total value, periods, one-vintage rule, receipts, release gate and the Table 1.1 agreement check. experiments/940-state-agi-bands: pre-calibration, proxy-AGI support per state and band on the #982 fix's offline outputs (both predictor designs), with the solver's necessary feasibility conditions under the 5x upward weight cap. Deterministic; reproduces its committed outputs byte for byte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
soi-historic-table-2-state-agi-2023 joins the hard-target SOI filer family in source_coverage.py and the fiscal refresh's DIRECT_ACTIVE_ALIASES, so the release's source-coverage receipt and reviewed-exclusion list stay exact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tract period Review of the state AGI band rescue (round 1, lens math-and-selection): - The Colorado TY2023 fixture had wrong stubs 1-7; it now carries the published cells and a test that they sum to the file's stub 0. - State HT2 bands below the $100k floor (or not for all filing statuses) are refused at every period, not only across periods, so a same-year vintage cannot bind raw sub-floor levels. - One vintage per state and measure is now the newest one whose published partition is complete; a gapped newest vintage falls back instead of dropping the state. Only requested vintages are validated, identical re-emissions collapse, a conflicting re-emission raises. - find_period_contract_violations reads uprating_to_period for rebased rows, the period _age_spec ages them from. - New release requirement irs_state_agi_top_tail_returns (M+ counts, 51 states) beside the AGI one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main split the tests by execution environment (#998): the state band tests move to tests/engine_free/us/, load tools through test_support.paths, and the coverage fixture's 51-state $1M+ AGI and count rows move to test_support/microcosm_build/us_fiscal_targets.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test Per-band latest selection let a gapped TY2023 band shadow its complete TY2022 twin before _rebase_soi_state_agi_bands could fall back, so the fallback bound only rows with no newer twin. Binding state bands now carry their period in the selection key, and the pass is their one vintage selector. The period-contract test now strips the waivers _compile stamps at its own build before asking the contract at other periods. Docs updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…940) The pin moves from c5e5bf8 to 51aa40f: Chronicle c5e5bf8 plus only the TY2023 Historic Table 2 state AGI package (chronicle#291; branch feed/us-c5e5bf8-state-agi-2023, tag microcosm-us-feed-940-v1). Re-pinning to Chronicle main instead would also adopt the restamp guard (ten scoped pairs produce no row there) and chronicle#304's concept renames, which are microcosm#1030's re-pin. Measured (experiments/940-state-agi-bands/feed-repin/compare.json): all 39,158 c5e5bf8 cells present with equal values and no changed field; 1,020 cells added, all TY2023 state_agi; compiled at 2024 as the release does, no non-band target added, removed or changed; state bands 306 -> 408. Scope 586 -> 637 pairs, 62 -> 63 runs; feed 40,178 rows (965a29ac...). Parity regenerated: 32 compiled / 52 reviewed, irs_soi.historic_table_2 5,654 -> 6,674. Feed-gated pins re-measured: 33,250 targets, 6,102 national_state at f96be9f41781; ACS-local state surface irs_soi 4,227 (state_agi spec 1,320), state_cd 26,272 SOI. Docs updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ge, per-state gates Independent review of ea8940d (GPT-6.1 Sol, REQUEST_CHANGES; report in ~/reviews/microcosm-940/review-out-b.md): - major: the control came from raw facts, so it could differ from the state total the registry binds (two same-key totals: recorded share 0.1505, actual 0.3010) and an excluded total still anchored bands. Controls are now read from the registry: the selected, non-excluded state_broad row. Two bound totals for one state and measure raise. - minor: every band vintage reached the exclusion vintage guard, so a discarded vintage could trip it. The one-vintage choice moves into latest-vintage selection (_with_one_state_agi_band_vintage), before the guard and the receipt. - minor: NaN bounds or values in a partition raise instead of slipping through the tiling comparisons. - minor: the coverage gate counted names. It is now one requirement per state and measure (102), keyed on state_fips and the [1M, inf) band, so a duplicate of another state cannot stand in. - major (duplicates): a binding band's fact is a target fact, and the compile's one-fact-per-record-id rule refuses any duplicate of one for every family. That stays; the docstring and test now say so, and the partition still counts an identical sub-floor re-emission once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt round 2 The round-2 selection-time vintage choice stamped a state_agi_band_record_set key on every band row, which entered the hashed target surface. Selection now keeps each band id's (period, record set) beside the candidates instead, so band metadata is what the reviewed head produced: on the pinned feed the national_state surface is f96be9f41781 again (33,250 / 6,102), which also shows the registry-derived controls give the same values as before there and that the merge of main moved nothing on this surface. docs/us-fact-to-target.md: control read from the bound registry row, vintage chosen inside selection, malformed-partition rules, per-state release requirements. Changelog fragment updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ards Round-3 independent review of 39f3722 (GPT-6.1 Sol): APPROVE, with two minors and two nits (report: ~/reviews/microcosm-940/review-out-r3.md). - Partition values must parse and be finite. An infinite sub-floor value made every share 0.0 (and still satisfied the coverage gate); an unparseable one counted as 0.0 and moved the $1M+ count share by 1.7%. Both now raise; bounds still only need to be non-NaN. - Tests for the guards no test exercised: two bound state totals raise; the control filters (filing status, AGI bounds, universe, CD geography, record set) each reject a decoy; a $1M+ row with a closed upper edge fails its state's requirement. The reviewer's three surviving mutations (last control wins, requirement without agi_upper_bound, control accepts any filing status) are now each caught. - "Every vintage" -> "every eligible vintage" in the docs and docstrings. - The Hypothesis property test suppresses the too_slow health check, which tripped once at load ~300. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged at Gates at the merged head: all 10 CI checks pass; mergeable CLEAN; independent reviews by GPT-6.1 Sol: round 2 REQUEST_CHANGES on Chronicle side: PolicyEngine/chronicle#291 merged ( Next launch on this surface: re-freeze the exact-k target surface; expect soft misses in the 9 thin $1M+ states ( |
Summary
Binds IRS SOI Historic Table 2 state × AGI-band targets, return counts and AGI amounts, for every state's bands from $100k up, with $500k–$1M and $1M+ split. It re-pins the US Chronicle feed to add the TY2023 state file that publishes those split classes.
Fixes #940.
Why
A state's total return count and AGI calibrate tightly, while its income above $1M, which progressive state rate schedules tax, is unconstrained.
Before this PR, the state return-count and AGI bands already in the feed (TY2022, 9 bands with a summed
500k_plus) compiled to nothing:_is_untransformed_cross_period_agi_slicerefuses every bounded AGI slice from another tax year, and only the EITC and taxable-interest families were rescued.What changes
The rule (
us_runtime/fiscal_targets.py)_soi_state_agi_band_statusand_is_soi_state_agi_band_factflag a fact only when all of these hold:return_countoradjusted_gross_income;irs_soi.<ty>.historic_table_2.state_agi.<st>) at state geography;US_SOI_STATE_AGI_BAND_MINIMUM_LOWER_BOUND($100,000). The national size-of-AGI floor uses the same edge for the same reason: the SOI slice materializer counts every tax unit in a band, filer or not.usrows never qualify; the national shape belongs to Table 1.1._rebase_soi_state_agi_bandsruns after the capital-gains rebase. Each band's value iscontrol × band / partition:partitionsums the state's published bands of that vintage (sub-floor bands and negative AGI under $1 included).controlis the state's HT2state_broadall-returns total as the registry binds it: the row latest-vintage selection kept and the exclusions let through, read from the compiled registry, not the facts. A state whose total is excluded binds no bands of that measure; two bound totals for one state and measure raise. Congressional-district<st>_totalrows never anchor a state.uprating_to_period). Target aging then ages AGI on the CBO AGI series with the state total; counts never age. Each rebased row recordsstate_agi_band_share,uprating_factorand the control's record id._with_one_state_agi_band_vintagethen keeps, per state and measure, the newest vintage whose published partition tiles the AGI line.Other code
target_aging.find_period_contract_violationsreadsuprating_to_periodfor rebased rows, the period_age_specages them from.irs_state_agi_top_tail_<st>_<measure>, 102 in all): each matches that state's[$1M, inf)row bystate_fipsand both AGI bounds, so a missing state fails by name and another state's row cannot stand in. The release builder already enforcesUS_FISCAL_TARGET_COVERAGE_REQUIREMENTS; the scoring tools only record the gate result.soi-historic-table-2-state-agi-2023is registered insource_coverage.pyandDIRECT_ACTIVE_ALIASES.Feed re-pin
c5e5bf8to51aa40f: Chroniclec5e5bf8plus only the TY2023 state AGI package from Add IRS SOI Historic Table 2 TY2023 state AGI-band facts chronicle#291. That commit lives on branchfeed/us-c5e5bf8-state-agi-2023with tagmicrocosm-us-feed-940-v1.state_2022US rows no longer restamp to ty2023. chronicle#304 also renames the HT2 and CD capital-gains concepts. Adopting both is Read restamped Chronicle facts at their data year before aging #1030's re-pin and needs its own decisions. I ran the main-based build; it failed on exactly those pairs.experiments/940-state-agi-bands/feed-repin/compare.json):c5e5bf8cells are present with equal values and no changed field.irs_soi.ty2023.historic_table_2.state_agi.965a29ac….irs_soi.historic_table_25,654 → 6,674.national_state: 5,694 → 6,102 atf96be9f41781;state:irs_soi3,819 → 4,227;state_cd: SOI 25,864 → 26,272.tools/spec_engine_coverage.py --checkis unchanged (42,184/42,184).Invariants (property-tested in
tests/engine_free/us/test_us_soi_state_agi_bands.py)Share identity: each bound band = control × band / partition (Hypothesis over generated partitions, controls and up to three states).
Control homogeneity: scaling one state's total scales exactly that state's bands.
Feed-order invariance: shuffled facts compile to the same bands.
Partition after aging: each aged AGI band divided by the aged state total equals its published share; counts are unaged (synthetic and feed-gated, for all 408 rows).
One vintage per state and measure: the bound bands tile; a collapsed
500k_plusnever binds beside split rows.Means inside edges: every state band's aged AGI per return lies inside the band (feed-gated, all 204 AGI rows).
Differential against the national owner: summed over the 51 states, the aged $500k–$1M and $1M+ rows are 97–100% of Table 1.1's TY2023 classes aged the same way. They measure 98–99%; Table 1.1 also counts returns filed from other areas and Puerto Rico.
Bands are shares of the bound total: with two same-key state totals of different values, in either feed order every band's share of the total the registry binds equals the share it records.
There are also example tests for: the floor at every period, a gap falling back to an older complete vintage, CD totals never anchoring a state, an excluded state total anchoring nothing, the exclusion guard seeing only the chosen vintage, overlap, NaN and duplicate handling, the period contract, and the per-state coverage requirements (a missing Colorado row plus an Alabama stand-in fails exactly Colorado's requirement). The Colorado fixture is the published TY2023 cells, with a test that they sum to the file's stub 0.
Review
Round 1 (adversarial workflow, math-and-selection lens) found five issues, all fixed in 8042842 and 7a90473:
Fixing the vintage fallback exposed a sixth issue: per-band latest selection shadowed older vintages. It is fixed by the selection-key change.
Round 2 (independent GPT-6.1 Sol review of
ea8940de2): REQUEST_CHANGES with two majors and three minors. It also ran six source mutations (all caught by the tests), verified the feed byte for byte (39,158 old rows unchanged, 1,020 added, each equal to its IRS cell) and compiled the pipeline end to end (33,250 targets, 408 bands, all materialize, coverage passes). Fixed incdd45625eand39f37229b:On the pinned feed the round-2 changes move nothing: the
national_statesurface is stillf96be9f41781, and the feed comparison is identical to the committed receipt.Round 3 (independent GPT-6.1 Sol re-review of
39f37229b): APPROVE. All five round-2 findings resolved or accepted as argued; it re-ran its counterexamples and 17 mutations, and confirmed the pinned-feed registry is byte-identical to before (33,250 atfc776a2b6eb7;national_state6,102 atf96be9f41781). Its two minors and two nits are fixed ine2c34ac75:too_slowhealth check suppressed.A confirmation review of
39f37229b..e2c34ac75is linked in a comment.Launch notes (not done here)
experiments/940-state-agi-bands/README.mdmeasures pre-calibration support per state and band on the US PUF imputation predicts each income item from the recipient's own survey value, so the PUF clone half reproduces ASEC income #982 outputs, all proxy AGI:--frozen-target-surface-sha256and re-score the incumbent.fiscal_targets.pyanddocs/us-fact-to-target.md.axiom: n/a: calibration-target compilation and data feed (no tax-benefit rule changes)
🤖 Generated with Claude Code