Repository navigation
Conversation
benefit_unit_rule.json cited concepts.py:880-919 and concepts.py lines 892-901 for the relationship pointers. #1120 shifted both ranges by one line on main, and #1134 (open) adds seven more lines above them: at its head, lines 892-901 are the partner pointer's text rather than the "always parent 1" sentence, and 880-919 stops before reference_person_id. The file also cited executor.py by line, and scenarios.json cited the harness as "ops main run.py:168", which moves with ops main. Cite the Relationships block, _pointer("parent_1_person_id"), the executor functions, and WEEKS_IN_MODEL_YEAR at ops ba6e7d6e instead. Add unpinned_python_line_citations: no NZ spec resource may cite a line of a Python source unless it pins that source at a commit (as as_rate_bridge.json pins the harness), with Hypothesis cases per refusal branch, plus checks that the cited pointers match the concepts source and that every dotted microcosm symbol the package names resolves. Re-pin the two resource hashes and the NZ spec fingerprint in the golden. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng line Port PR #1141's NZ citation guard to every country spec package as a shared validator (test_support/microcosm_build/spec_source_citations.py) and an engine-free test (test_spec_source_citations.py). The guard refuses a line citation of a file in this repository, pinned or not, and a line citation of any other source unless its string names the commit or the resource pins the file in a path/commit mapping. US: ecps_parity_known_gaps.json now cites asec_pool symbols, the PUF support tool's functions, the build script's --asec-h5 arguments and the Build J summary's keys; where #720's Census person-column restore had made a sentence false, it now names the columns the restore leaves out. The remaining us-data citations in source_stages.json and target_parity_manifest.json name archived commit 42ed5d45. UK: uk_data_target_parity.json (and its generator) names incumbent commit 8629dbbf; uk_population_targets.json names registry ref 12a1e028. Reading every cited range at its commit corrected six wrong pointers (SSI take-up, SCF net worth fit, hmrc_cgt.py 195, frs_only.py, _land.py 52-73, the salary-sacrifice drop). Re-pins the source_stages.json hash, the regenerated sources.yaml, the US spec and documentation hashes, three inventory EXPECTED_HASHES and us-f0-coverage.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pec-symbol-citations-us-uk
Main's 6c27a68 re-cut the US spec digest (d1df6b31 -> f76f921d) and the seed hashes. On the merged tree the US spec_sha256 is cf79472d (generator --check agrees), the three inventory digests this branch moves are unchanged, and us-f0-coverage.json is regenerated (41/41). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_nz_spec_package.py now imports nested_strings, line_citations, commit_pinned_sources and unpinned_line_citations from test_support/microcosm_build/spec_source_citations.py and keeps only its NZ-specific checks: the harness pin, the five replaced citations as regression vectors, and the relationship-pointer differential. The package-wide scan, the Hypothesis properties and the dotted-symbol resolution now run once for every country in test_spec_source_citations.py, which also asserts that the NZ and US dotted symbol citations are scanned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1122 adds an NZ resource whose format id is microcosm.axiom_input_closure.v1, which the dotted-symbol scan read as a Python symbol and failed to import. A dotted name now counts as a symbol citation only when its second component is a shard in this checkout (build, calibrate, data, diagnostics, fit, frame, graph). Every dotted name the packages carry today is under a shard, so the scanned sets are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Recognise a quoted or backticked file name and the `x.py: lines N`, `x.py, LN` and `x.py (LN)` locators; the Hypothesis spellings cover them. - A cited path of two or more components is this repository's when it is the tail of a source file here (`us_runtime/asec_pool.py`), not only when it resolves from the root, so a partial in-repo path pinned inline is still refused. - A path/commit mapping now needs the same sha form as an inline commit (7-40 lowercase hex with a digit and a letter); a decimal, a word or an upper-case value pins nothing. - The unmarried-partner build contract says Build J predates #720, and a test checks the summary's per-year relationship_recode_source. No package resource gains or loses a citation hit under the wider rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
21 of 52 tasks
This was referenced Oct 8, 2026
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.
Invariants
The guard is
test_spec_source_citations.py, with validators intest_support/microcosm_build/spec_source_citations.py. It scans every resource in every country spec package, meaning everybuild/<country>/directory with acountry_package.json(today am, be, nz, uk, us). JSON and YAML resources are parsed, and every string is scanned, mapping keys included. For those resources:in_repository_line_citations). A cited path counts as in-repository when it has two or more components and is the tail of a source file in this checkout, underpackages/,tools/,experiments/,test_support/ordocs/. Sotools/x.py,packages/microcosm-build/src/…,microcosm/graph/executor.pyand a partialus_runtime/asec_pool.pyall count. These sources are cited by symbol instead.unpinned_line_citations). A citation is pinned when one of these holds:commit <sha>,at <sha>,@<sha>or a GitHub/blob/<sha>/link, where<sha>is 7-40 lowercase hex digits with at least one digit and one letter, not running on into a file name;path/commitmapping for that file, at any depth, whose commit has the same sha form. As in Cite NZ spec sources by symbol, not line number #1141, pins match by file name across the whole resource, so one pin ofcps.pycovers everycps.pycitation in that resource, whichever repository it means.microcosm.<shard>.*name in a resource resolves through import plus getattr. Only names whose second component is a shard in this checkout count (build, calibrate, data, diagnostics, fit, frame, graph), so a format id such as Build benefit units from concept pointers and execute group encoding (NZ v0, G4) #1122'smicrocosm.axiom_input_closure.v1is not read as a symbol.Scope of each claim:
x.py:12,x.py:12-19,x.py:12,19,#L12,L12,, L12,(L12),line 12,, lines 12-19,: lines 12-19and(lines 12-19), plus the reverselines 12-19 of x.pyandline 12 in x.py. The file name may be quoted or backticked. A symbol between the file and its lines (x.py some_function, lines 12-19) is not recognised.concepts.pycannot be resolved, so only rule 2 covers it.Each rule has Hypothesis properties, at least one per refusal branch:
path/commitpin covers a citation, and so does an inline commit in any spelling, before or after the citation;path/commit.Why
The US and UK packages cited sources by line numbers that drift. The in-repository ones drifted under ordinary edits, and the external ones had no commit, so they drifted with the other repository's main. #1141 fixed this for NZ and added a guard for the NZ package only. Before this PR the guard flagged US 42 unpinned + 21 in-repository citations and UK 53 unpinned (NZ: 5, which #1141 fixes).
Changes
US,
ecps_parity_known_gaps.json(7hermetic_build_contractstrings andis_unmarried_partner_of_household_head.evidence.semantic_non_substitutes.derived_A_EXPRRP):asec_pool.py lines 61-75microcosm.build.us_runtime.asec_pool.load_asec_h5_tables(plus_prepare_year_inputwhere the restore matters)asec_pool.py lines 397-422microcosm.build.us_runtime.asec_pool._with_relationship_recodetools/build_us_puf_support_base.py lines 85-88, 647-687, 659-699, 748-755_parse_args (--asec-h5),_pooled_asec_sources_from_args,_asec_sources_from_args. Lines 748-755 were_load_frame, the--base-h5loader, which never touches--asec-h5, so that citation is dropped.buildj_base.sh lines 65-69/65-81/70-81 and 103-108--asec-h5 2024=, 2023=, and 2022=(and--puf-h5) arguments. Three of these ranges were already stale when written.base_j.summary.json lines 55-75/317-318base_source.sources[].sha256,puf_sha256, andbase_source.metadata.sources[].sharefor the equal shares. Lines 55-75 never held the shares.#720 (39b8e7b, 2026-09-23) made several of these sentences false as written on main, for example "reads the prebuilt person tables without refreshing omitted Census columns". The pool now restores 11 reviewed Census person columns. Each sentence now says which columns the restore leaves out (NOW_OWNGRP/HIPAID/GRPFTYP, FIN_VAL/FIN_YN/I_FINVAL, SRVS_VAL, PERRP/PECOHAB/A_FAMREL). Differential tests check those columns against
ASEC_CENSUS_PERSON_COLUMN_NAMES. They also check that the restore runs before the relationship fallback, that the fallback never emits code 13 (a Hypothesis property over synthetic households), and that the tool defines the functions the evidence names. No exclusion decision orreasonchanges.US,
source_stages.json→ regeneratedspec/sources.yaml:42ed5d45c56df80d754fbe24cce21cfeb8d05cbeand package-relative paths (datasets/cps/cps.py,parameters/take_up/wic_takeup.yaml,utils/randomness.py,datasets/cps/extended_cps.py).target_parity_manifest.jsonand its generator citeutils/loss.py:67-70 at 42ed5d45…. The quoted comment is at 67-70 there. At PR UK was_lisa: Lifetime ISA holdings from the WAS round-8 person tab (#1003) #1059's own squash commit it sits at 62-65.UK:
uk_data_target_parity.jsonand its generatoruk_runtime/data_target_parity.py: all 13 uk-data citations name the resource'sincumbent_commit,8629dbbfe82727278d47ee5ff09fd1da4acefa38. Each cited blob's sha256 matchesuk_data_target_inventory.json.uk_population_targets.json: 21 strings nameregistry_parity.pinned_ref,12a1e028afeef08d8b2d74ee03fd9de3a78b2dd3, withtargets/-qualified paths.Wrong pointers corrected. Each cited range was read at its commit, and these six pointed at other code:
ssi_take_upnotesssi_reportedanchor; the save is 759-766scf_wealthnotesSCF_PREDICTORS168-177hmrc_cgthmrc_cgt.py:195def _band_targets)datasets/imputations/frs_only.pyservices/services.py:137-148sources/_land.py:52-73exceptexcept Exceptionintargets/sources/hmrc_salary_sacrifice.pylines 34-109, which logs the error and returns only the contributions targetSmaller fixes:
prior_year_incomegains the predictor-definition rangeextended_cps.py 234-248, matching its sibling stage.obr.py:617-728to570-728to include_parse_tv_licence.Tests whose literal assertions moved. Four exclusion tests asserted
"buildj_base.sh lines 65-69". They now assert the content anchors and check thatbase_j.summary.jsonholds three 64-hexbase_source.sources[].sha256.Re-pins
Every byte edit to
source_stages.jsonmoves these (afaffae and 808ee8f moved parts of the same set):source_stages.jsonraw sha256 (sources.yamlstage_asset, generatorFROZEN_LEGACY_RESOURCE_SHA256,us_spec_bundle.py,test_us_bundle_core_contracts.py)e75217c0…41e8194a…spec_sha256(us-f0-coverage.json×2,test_us_multispine_pool_tool.py)f76f921d…(main after 6c27a68)cf79472d…documentation_sha256(us-f0-coverage.json)0931cbd3…b3d98ce9…EXPECTED_HASHES.source_manifestf4f8bfeb…4e0d2a60…EXPECTED_HASHES.late_resource_semanticscc34ba11…5d84124a…EXPECTED_HASHES.full_checkpoint3db095ce…9a86a977…us-f0-coverage.jsonpool-code observed sha61a5484e…934b244e…How they were produced:
sources.yamlwas regenerated withtools/generate_us_bundle_from_constants.py.--checkreported onlysources.yamlstale, and after merging main--checkpasses and printsspec_sha256=cf79472d….us-f0-coverage.jsonwas regenerated withtools/spec_engine_coverage.py: 41/41 inventory checks, and exactly the 10 predicted leaves moved.legacy_json, so only the unpinned UK package fingerprints move.Operational cost: the stacked US pool checkpoint identity binds the late producer resource semantics, which hash
source_stages.json's bytes. Existing stacked US pool stage checkpoints will therefore be treated as stale and rebuilt on the next build, as after any source-stage note edit. No behaviour or data changes.How this was verified
git log -Sand read the lines in us-data, uk-data or microcosm. Separate adversarial verifiers re-derived each proposal; all 49 proposed edits were confirmed, and one audit finding was refuted and dropped. That finding claimed the ESI "cannot execute" wording was wrong, but_validate_raw_cps_schemaraises first.Tests
Only targeted files, each run with
-p no:cacheprovider --basetemp=.hub-scratch/pytest -o tmp_path_retention_policy=failed(no full suite):test_no_incumbent_data_package_references_in_live_tree(the new test named the incumbent package; it now uses neutral paths).--checkpasses, andspec_engine_coverage.pyreports 41/41.ruff check .andruff format --checkare clean.Depends on #1141
The guard's NZ cases pass only with #1141's NZ fixes, so this branch merges #1141's head (
fba45621). Its five files show in this diff until #1141 merges. Do not merge this before #1141. This PR also moves #1141's NZ validators into the shared helper:test_nz_spec_package.pykeeps its NZ-specific checks and imports the rest. #1142 rewrites the same NZ citations, and the NZ hub agrees #1141 lands instead.Review
Round 1 was an independent Opus 5.5 review, run read-only with no shell (
~/reviews/microcosm-1146/review-r1.md). It approved with six non-blocking findings. 0a841e4 addresses them:: lines,, L12,(L12)). The symbol-between form is documented as out of scope.path/commitpin needs the inline sha form.reasonis left to the follow-up below.Follow-up (not in this PR)
Since #720, Census A_EXPRRP (whose reviewed domain includes code 13) is restored for the 2022 and 2023 inputs. So the
is_unmarried_partner_of_household_headgap'sreasonandsemantic_non_substitutes.A_EXPRRPread as stale. Whether the exclusion stands is a methodology call, so it is split into its own task rather than changed here.axiom: n/a: spec citation text, test-only validators and re-pins; no policy or rule change.
🤖 Generated with Claude Code