Repository navigation
Conversation
…l each (#1343) Tests only. On the pinned feed (Chronicle 51aa40f, facts 965a29ac...), the compiled 2024 targets label three values two ways, and this test fails for each: - us:statutes/26/62#adjusted_gross_income = under_1: 2 targets (the week-47 filing-season EITC rows) read "No adjusted gross income and deficit"; - us:statutes/26/62#adjusted_gross_income = all: 47 targets (Historic Table 2 and Table 1.1) read "All returns"; - age = 85_plus: 1 target (national Census PEP) reads "Age 85 and over". Like the other pinned-feed tests, it skips where the feed file is absent, as in CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l each (#1343) The pin moves from Chronicle 51aa40f to 9b91e8b: 51aa40f plus three label-only commits (branch feed/us-51aa40f-agi-age-labels), not Chronicle main. - AGI under_1: the week-47 package's "No adjusted gross income and deficit" becomes "No adjusted gross income" (chronicle#377's 6d74e42, without its build-bundle check). - AGI all: Historic Table 2 and Table 1.1's "All returns" becomes "All returns, total". Table 1.1 now states its IRS row header explicitly, so its row-header check still reads "All returns" in cell A10. - age 85_plus: national Census PEP's "Age 85 and over" becomes "Age 85 plus". Measured (experiments/us-feed-agi-age-labels/compare.json): the feed keeps its 40,178 aggregate_fact_keys and every value, key and constraint; 816 rows in six record sets change only in label fields (66 rows) and layout.record_set_spec_hash. Compiled at 2024 as the release does, the 33,250 targets keep their names, order and values; 50 change only in the hierarchy value_label and metadata ledger_layout_groupby_value_label (2 under_1, 47 all, 1 85_plus). Registry dde00e855af8 -> b8d571e91c22; national_state 6,102 targets, 3fad14f85468 -> 3aa2a0830e7d. Pin: facts 965a29ac... -> e477e04a..., scope f0901020... -> 8fedefb7... (only source_commit), 40,178 rows. Parity resources regenerated: only the feed name (consumer_facts_us_9b91e8b.jsonl) and digest change, 32 compiled / 52 reviewed. Test pins, the re-pin doc and a changelog fragment updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1343) Tests only. The label test added for #1343 compiles the pinned feed, so it skips in CI, and a later re-pin built on a Chronicle commit without the three label commits would bring the old labels back unnoticed. A re-pin must regenerate target_parity_feed_families.json from its feed (CI checks that the inventory restates the pinned digest), so the inventory is where CI can see the labels: - test_feed_inventory_lists_only_the_reviewed_label_variants requires the committed inventory to list, as dimension_value_label_variants, exactly the two values the feed still labels two ways (age_20 and age_21), and none of adjusted gross income under_1 or all or age 85_plus; - TestFeedLabelVariants checks the generator's listing on synthetic rows, reading both dimension_value_labels and layout.groupby_value_label. Both fail now: the inventory has no dimension_value_label_variants (KeyError) and the generator has no _dimension_value_label_variants (AttributeError). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/build_us_target_parity_manifest.py now writes, into target_parity_feed_families.json, dimension_value_label_variants: every (dimension, value id) the feed labels more than one way, with its labels, read from dimension_value_labels and layout.groupby_value_label as the ledger compiler reads them. Regenerated from consumer_facts_us_9b91e8b.jsonl (sha256 e477e04a...), it lists only age = age_20 and age_21; the manifest and the family counts are unchanged. A re-pin must regenerate the inventory from its feed, because CI checks that the inventory restates the pinned digest. So a re-pin built on a Chronicle commit without the three #1343 label commits now lists those values again and fails test_feed_inventory_lists_only_the_reviewed_label_variants in CI, where the compiled-target label test skips for want of the feed. The re-pin doc says so. 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.
Fixes #1343
Summary
The pinned US Chronicle feed labels three dimension values two ways, so the compiled US targets show one value id under two names. This PR re-pins the feed to a Chronicle commit that gives each value the one wording #1343 chose, and changes nothing else.
us:statutes/26/62#adjusted_gross_income=under_1us:statutes/26/62#adjusted_gross_income=allage=85_plusThe Chronicle commit
9b91e8bc61802e5fd9d5fa19a8f991828c1025f8on the new branchfeed/us-51aa40f-agi-age-labels: the current pin51aa40fplus three label-only commits, not Chronicle main.edb7cf1: the week-47 YAML change of Give each dimension value one Chronicle-declared label, keep the package's own wording beside it (consumer_fact.v5) chronicle#377 (6d74e42), and nothing else from that PR (not itsbuild-bundlecheck).59d9d06:soi-historic-table-2andsoi-table-1-1relabel theirallrows. Table 1.1's row had noexpected_row_header, so its row-header check compared the label itself with the IRS text in cell A10; the row now statesexpected_row_header: All returns, so the check still reads the same cell for the same text. Matching test changes at this base: two tests that pin Table 1.1'srecord_set_spec_hash, the checked-in consumer fact sample built from Table 1.1's first rows, and that sample's pinned digest.9b91e8b:census-pep-2024-national-age-sexrelabels its85_plusrow.Every package's checks of the publisher's text are unchanged: the week-47 column header, Historic Table 2's
AGI_STUB0, Table 1.1's row header, and Census PEP's row header 85 and single-year age sequence.soi-historic-table-2-state-broad-2022keeps "All returns" forstate=all(chronicle#267). That is thestatedimension, which no other feed package labels, and its 2,397 targets carry one label.Checks on the branch:
chronicle validate-package: valid, no warnings, for each changed package at each scope year (week 47 at 2024, Historic Table 2 at 2022, Table 1.1 at 2022 and 2023, national PEP at 2024).chronicle build-suite: valid with lineage coverage 1.0 and 0 acceptance errors for the same runs. The warnings are the same as at51aa40f.test_chronicle_soi_targets,_source_cells,_source_package,_suite,_harness,_consumer_contract,_core,_bundle,_facts_only,test_issue_265_non_uk_labels,test_etl_soi). The CI-only merged-bundle test was deselected; see "Unverified".Tag: none yet. Under the #940 convention it would be
microcosm-us-feed-1343-v1on9b91e8b, to be created after review.Red, then green
5769515: tests only.test_pinned_feed_targets_give_each_reviewed_value_one_labelcompiles the pinned feed as the release does and requires every target that selects each value to carry the chosen label. On the51aa40ffeed all three cases fail: 2 targets read "No adjusted gross income and deficit", 47 read "All returns", and 1 reads "Age 85 and over". The other feed-covering tests pass there.09b950e: the re-pin. With the new feed, all 245 feed-covering tests pass and none skip. That includes the three cases,test_us_chronicle_feed.py,test_release_target_parity.py, the whole oftest_us_fiscal_targets.py, and the pinned-feed tests intest_us_acs_local_release_tool,_acs_local_sparse_cd,_fiscal_refresh_builder,_release_gate_preflight,_soi_congressional_district_vintageand_soi_state_agi_bands, run withMICROCOSM_US_CHRONICLE_FACTSset.Like the other pinned-feed tests, the new test skips where the feed file is absent, as in CI. A reviewer with the feed can run it at
~/PolicyEngine/_buildh-runtime/inputs/consumer_facts_us_9b91e8b.jsonl.What changes in this PR
us/chronicle_feed.json:source_commit,buildtext,facts_sha256andscope_sha256.fact_row_countstays 40,178.us/chronicle_feed_scope.json: onlysource_commit.target_parity_feed_families.jsonandtarget_parity_manifest.json, regenerated withtools/build_us_target_parity_manifest.py: only the feed name andfeed_sha256change. There are still 32 compiled families, 52 reviewed exclusions and 81 feed families.tools/build_us_target_parity_manifest.py:DEFAULT_FEED_NAME._CHRONICLE_COMMITand_FACTS_SHA256intest_us_chronicle_feed.py;national_statesurface version intest_pinned_feed_national_state_surface_restores_the_fences, because the version hashes the hierarchy labels.docs/us-chronicle-feed-repin.md: a new section and the pin table.changelog.d/1343-us-feed-one-label-per-value.fixed.md.experiments/us-feed-agi-age-labels/compare_feeds.pyand its reportcompare.json.Digests
51aa40fd28e2ca81937752515e773d123fecfb719b91e8bc61802e5fd9d5fa19a8f991828c1025f8consumer_facts_us_51aa40f.jsonl, 40,178 rows, 169,038,757 bytesconsumer_facts_us_9b91e8b.jsonl, 40,178 rows, 169,039,583 bytesfacts_sha256965a29ac9458edb58a05184917ee4a19772fd3dc7b4588db6eb6da5803641aace477e04aa7c73209df2bcbf484f029a2357da8c2339217d1d0518f7a8a47bcbfscope_sha256f090102099b3d2c799a8f975a8156101dbb18925b526c3791a785f68944d020d8fedefb72789ad96f83f899090bd8f37cc8e0e1b81e6aebf9a32fd9e3e9a53c4dde00e855af8b8d571e91c22national_statesurface (6,102 targets)3fad14f854683aa2a0830e7dReproducibility:
tools/build_us_chronicle_feed.py --skip-artifactat51aa40freproduced965a29ac…byte for byte.9b91e8b, and at an earlier commit of the branch that differed only in Chronicle test files, it gave the same bytes,e477e04a….Only labels change
uv run python experiments/us-feed-agi-age-labels/compare_feeds.py <51aa40f feed> <9b91e8b feed> compare.json, compiled at 2024 as #940 did (packaged CD crosswalk, age targets, Medicaid substitutions):Feed rows, joined on
aggregate_fact_key:The same 40,178 keys are in both feeds. 816 rows change, and no field other than the ones below changes on any row.
dimension_value_labels[…adjusted_gross_income][under_1]eitc_by_agi.countand.amountdimension_value_labels[…adjusted_gross_income][all]ty2022.historic_table_2.us(55),ty2022.table_1_1(4),ty2023.table_1_1(4)dimension_value_labels[age][85_plus]census_pep.cy2024.national_resident_population_agelayout.groupby_value_labellayout.record_set_spec_hash(covers row labels)Label variants in the feed. Before: the three values, plus
age=age_20andage_21("Age 20" against "Female 20 years", and the same for 21, from Census population projections and ACS B01001). After: onlyage_20andage_21, which no compiled target selects.Compiled targets, compared field by field on
TargetSpec.to_dict():Both feeds give 33,250 targets, with the same names in the same order and the same values. 50 targets change, in exactly two fields each:
hierarchy.dimensions[…].value_label;metadata["ledger_layout_groupby_value_label"].Label variants in the compiled targets. Before: those three values. After: none, so no dimension value in the compiled targets has two labels.
The registry and surface versions move as listed above. The surface keeps its 6,102 targets.
compare.jsonlists every changed feed label, every record-set hash change and all 100 changed target fields.Interplay with #1189 and #1192
All three PRs rewrite the same pin files:
chronicle_feed.json, the scope file, both parity files,DEFAULT_FEED_NAME, thetest_us_chronicle_feed.pypins, and the doc. Whichever merges second conflicts in those files, and resolving the conflict as text is wrong: its feed must be rebuilt from a Chronicle commit that holds both changes.Their Chronicle bases:
9b91e8b=51aa40f+edb7cf1,59d9d06,9b91e8bcf9ece2=51aa40f+2744154(digit-text guard) +cf9ece2(BEA B4923C package)f98acf4=c5e5bf8+ the W-2 package fileThe commits touch disjoint files. Locally:
cf9ece2and ontof98acf4;cf9ece2's two commits, andf98acf4's one, cherry-pick cleanly onto9b91e8b.None of the other PRs' packages carries these dimension values.
If this PR merges first:
9b91e8bwith2744154andcf9ece2cherry-picked. It points its scope (637 + 3 pairs) at that commit, rebuilds, and compares withe477e04a…, not965a29ac…. It then regenerates the parity files and moves its pins.9b91e8b, or Produce ESI employer premiums scaled to BEA B4923C from restored ASEC policyholder fields (#454) #1189's combined commit if that merged).If #1189 (or #1192) merges first: this PR moves its three commits onto that PR's Chronicle commit, as a new branch such as
feed/us-cf9ece2-agi-age-labels. It rebuilds from main's scope, rerunscompare_feeds.pyagainst that PR's feed, expecting the same 66 label rows and 816 hash rows and nothing else, and re-measures the surface version. Thefeed/us-51aa40f-agi-age-labelsbranch would then go unused.The risk either way: a later re-pin built on a base without these commits silently restores the old labels. CI would not catch it, because
test_pinned_feed_targets_give_each_reviewed_value_one_labelskips without the feed. So whoever merges second must run the pinned-feed tests locally with the new feed.Recommended order: this PR first, then #1189, then #1192.
9b91e8bis a clean cherry-pick plus a rebuild.If #1189 is ready first, the reverse order works too, with the mechanical steps above.
Unverified
9b91e8b, because Chronicle'sci.ymlruns on every push. On the51aa40fbase, the same CI failed only intest_build_bundle_writes_merged_consumer_contract(run 37179848880, a count pin from before State top-tail income mass is uncalibrated: CO M+ AGI at 24% of SOI in buildp-acs-local (fails progressive-bracket scoring) #940), and I expect the same here. That test also pins the three cross-package label warnings, 9 warnings with these three keys. I did not change it, because it is not one of the packages' own tests, it already fails at the base, and it takes about 85 minutes.aa288c3) still has all three old labels. The draft chronicle#377 covers onlyunder_1, so the full re-pin onto main (Read restamped Chronicle facts at their data year before aging #1030) must carry thealland85_pluslabels or lose them.Review (2026-10-21)
No bug found in this PR or in the Chronicle branch
feed/us-51aa40f-agi-age-labels:tools/build_us_chronicle_feed.pyreproducesfacts_sha256e477e04a…andscope_sha2568fedefb7…byte for byte.compare_feeds.pyconfirms that only labels change: 50 national targets change onlyvalue_labelandledger_layout_groupby_value_label.expected_row_headerchecks the same IRS cell, A10.value_id;Added by the review: a check CI runs without the feed file. The pinned-feed label test skips in CI.
target_parity_feed_families.json, every dimension value the feed labels more than one way. On this feed that's onlyage_20andage_21.under_1,allor85_plusgain a second label again, or if any other value gains one without review.388699c9KeyError,AttributeError)2880b263For whichever of #1189 or #1192 merges after this:
9b91e8b;🤖 Generated with Claude Code