From ff8ee35f79de50351e7e889b3f80afaf10714ca5 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Thu, 15 Oct 2026 10:40:38 -0400 Subject: [PATCH] Test a frozen cited source at another hash; name the tier files The Opus 5.5 review that gated #540 (an independent agent with a shell, standing in while the Codex lanes were held) approved at b274f424 and left two notes, both closed here: - Every frozen-load test froze an empty set of cited-source hashes, so a loader that compared only the cited files' names, not their hashes, passed the whole U2 set. A new test freezes one cited setup file at one hash and rehashes it at another: it refuses before any family record is parsed, and fails under that names-only comparison. - The exposure log's line for the delta-review commit omitted the two tier files it rewrote, and the replay onto master, whose commits each rewrote them, was not recorded. Both are now named. Section 19 records it; the spec is re-pinned. Tier counts recounted by whole-suite collection (+1 unit: 8,957; total 15,387). Co-Authored-By: Claude Opus 5.5 --- data/external/track_u2/u1_identity.json | 2 +- docs/design/boomers2004_1946_55_comparison.md | 1 + docs/design/u2_m1b_exposure.md | 4 ++- tests/README-tiers.md | 4 +-- tests/tier_counts.json | 2 +- tests/track_u2/test_u2_loader.py | 36 +++++++++++++++++++ 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/data/external/track_u2/u1_identity.json b/data/external/track_u2/u1_identity.json index 153e66f90..c4d5f5d16 100644 --- a/data/external/track_u2/u1_identity.json +++ b/data/external/track_u2/u1_identity.json @@ -60,7 +60,7 @@ "draft_3_commit": "f7412e00cdcdba6ee1156b74fa93039f5329cb8f", "draft_3_git_blob": "e07ee0d589d20f3b6d100e5d4ce173f9a653f5e9", "version": "u2-draft-4", - "sha256": "7b1350ff7099405282c50bad27bd90d5d2aad38f07f391d1b459840d56b03269", + "sha256": "22f66d0269958c330b5ff7a7239c10345577092bccf1d70c06512bd2c27b06a0", "cited_lines_sha256": { "74": "7b299c9e4473fd51d04bdfec51af83268e517181ab734d3e76ccd1c744f6daa9", "75": "44454cc04e6a50863035d69ccb53edec175b4ad70a19d8877437901d2deb8428", diff --git a/docs/design/boomers2004_1946_55_comparison.md b/docs/design/boomers2004_1946_55_comparison.md index 4519dd0ed..b7f6664cc 100644 --- a/docs/design/boomers2004_1946_55_comparison.md +++ b/docs/design/boomers2004_1946_55_comparison.md @@ -1873,6 +1873,7 @@ Revision verification comprised the two touched test files and `tests/track_u2/t - Wording: the six registries that record the independent adjudication no longer end their note with the six code-88 records staying TO VERIFY pending d745; each says Max confirmed 1a–1c on 2026-10-12 and that the 1c commit resolved them. The package docstring names 1a–1c among d637's ratified amendments. - After the reviews of the d745, 1a, 1b, 1c-builder, 1c and wording commits (GPT-6.1 Sol, Subfleet jobs `20261012-101531-d637-review-d745`, `-review-a1a`, `20261012-101532-d637-review-a1b`, `20261012-102316-d637-review-b1c`, `20261012-104946-d637-review-a1c` and `20261012-105640-d637-review-w745`; 1b APPROVE, the rest REQUEST CHANGES, the 1c review with one blocking finding): a frozen load must pass the committed pre-registration record, and any other refuses before any PSID path is resolved, so a fabricated record cannot stand in for the authorization an unfrozen load needs; while a frozen load reads, opening a file under the PSID directory that the record does not freeze refuses before the file is read. Every required prose field of a ruled entry must be a nonblank string; 1a pins each code's annuity, marital and birth-support conventions; 1b refuses any adjudication record, null included; the d637 differential counts a field added as null as a change. A new invented variant puts a code-88 cohabitor who is itself a U0 target (born 1951, observed in 2019) in a family with OFUM Social Security and SSI: it keeps the OFUM role and its recorded marriage and, in U4, the family income basis and the OFUM SSI cap. Stale wording in `rows.py`, the dry run, the master record and the exposure log is corrected. - After the delta review of those answers (GPT-6.1 Sol, Subfleet job `20261014-055752-d637-review-r745b`; APPROVE with three test-coverage notes): the open-time refusal of an unfrozen file is tested on each reader's own opener (a family file, a setup file, the individual file read through pandas); a frozen load whose cited setup files and codebooks differ from the record refuses before any family record is parsed, now under test; and the code-88 cohort target's test also makes the OFUM SSI cap the binding bound. Tests only. +- After the merged-head review of #540 (an Opus 5.5 review with a shell, gating while the Codex lanes were held; APPROVE with two notes): a frozen load whose cited setup file is the same file at another hash now refuses under test, where a comparison of the files' names alone would have passed; the exposure log names the tier files each commit rewrote. Tests and records only. - No count, statistic or outcome was computed, no model or estimator was run on real data, and no file on the restricted list was opened for reading. Reading and exposure are appended to `docs/design/u2_m1b_exposure.md`. ## 20. Ratification and execution record diff --git a/docs/design/u2_m1b_exposure.md b/docs/design/u2_m1b_exposure.md index 7509cb5bf..25e7339bb 100644 --- a/docs/design/u2_m1b_exposure.md +++ b/docs/design/u2_m1b_exposure.md @@ -414,7 +414,9 @@ The U2 tests ran with the PSID root staged. They read staged PSID documentation - Amendment 1c: `roles.json` (the six code-88 records and the d637 record), `income.json` (amendment 2's ten `use_restriction` sentences) and `u1_identity.json`; the specification's §17 item 2, §19 and §20 step 4; the master record (the summary, the code-88 and spouse age/sex blocker rows, the d637 section and sixteen per-route rows); `u2_source_registry.py` (1c's scope), `sources.py` (the roles and income byte pins and docstrings), `loader.py` (the structural-pass authorization), `invented.py` (two variant notes), `scripts/track_u2_structure.py` and `scripts/track_u2_component_diagnostics.py` (`--authorized-by`), `scripts/track_u2_dry_run.py` and `scripts/run_track_u2_registered.py` (checks and docstrings); `tests/track_u2/test_adjudication_applied.py`, `test_source_registries.py`, `test_u2_mappings.py`, `test_u2_roles.py`, `test_u2_scripts.py` and `test_u2_loader.py`; and this section. - Wording after d745: the six `independent_adjudication` notes (`income.json`, `wealth.json`, `pension.json`, `roles.json`, `support.json`, `weights.json`) and `u1_identity.json`; the specification's §19; `sources.py` (six byte pins and three docstring and comment paragraphs rewrapped) and the package docstring; `tests/track_u2/test_u2_mappings.py`; and this section. - Answers to the d745 and 1a–1c reviews: `loader.py` (the committed-record check and the unfrozen-open guard), `u2_source_registry.py` (typed prose fields, 1a's governed role conventions, 1b's absent adjudication), `invented.py` (one variant appended), `rows.py` and `scripts/track_u2_dry_run.py` (docstrings), and `u1_identity.json`; the specification's §19; the master record (the d637 section's introduction); `tests/track_u2/test_adjudication_applied.py`, `test_source_registries.py`, `test_u2_loader.py`, `test_u2_mappings.py`, `test_u2_roles.py` and `test_u2_scripts.py`; and this section. -- Delta-review notes: `tests/track_u2/test_u2_loader.py` and `test_u2_roles.py`; the specification's §19 and `u1_identity.json`; and this section. +- Delta-review notes: `tests/track_u2/test_u2_loader.py` and `test_u2_roles.py`; `tests/tier_counts.json` and `tests/README-tiers.md`; the specification's §19 and `u1_identity.json`; and this section. +- The replay onto master after #524 (`24da3c61..75354b89`): each commit also rewrites `tests/tier_counts.json` and `tests/README-tiers.md` from a collection of its own tree. +- After the merged-head review of #540: `tests/track_u2/test_u2_loader.py` (one test), `tests/tier_counts.json` and `tests/README-tiers.md`; the specification's §19 and `u1_identity.json`; and this section. - Outside the repository: the registry and master-record edit scripts and the review records, copied to `EV/rulings-records-20261011/`. No U1 file, engine file, `gates.yaml` or `runs/*.json` was edited. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 2aa5b04bf..676cb4056 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 8,956 | +| `unit` | 8,957 | | `artifact` | 4,201 | | `integration_psid` | 1,401 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **15,386** | +| **Total** | **15,387** | diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 3d5868aa6..067c126a7 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 8956, + "unit": 8957, "artifact": 4201, "integration_psid": 1401, "reproduction_legacy": 520, diff --git a/tests/track_u2/test_u2_loader.py b/tests/track_u2/test_u2_loader.py index bcbc1e8a8..781d2bb65 100644 --- a/tests/track_u2/test_u2_loader.py +++ b/tests/track_u2/test_u2_loader.py @@ -983,6 +983,42 @@ def test_frozen_cited_sources_must_match( assert parsed == [] +def test_a_frozen_cited_source_with_changed_bytes_refuses( + tmp_path, u2_inputs, committed_registries, evidence +): + """The same cited file, frozen at one hash and rehashed at another, + refuses before any family record is parsed: a comparison of the cited + files' names alone would pass it (review of #540 at b274f424, nit + 1).""" + + _stage(tmp_path, u2_inputs, committed_registries) + cited = "PSID/family/2019/FAM2019ER.sps" + pinned = {**evidence, "cited_sources_sha256": {cited: "b" * 64}} + parsed = [] + patch = pytest.MonkeyPatch() + original = loader.read_family_records + patch.setattr( + loader, + "read_family_records", + lambda handle, wave, gate: parsed.append(wave) + or original(handle, wave, gate), + ) + try: + with pytest.raises( + loader.U2FrozenIdentityMismatch, + match="cited setup files and codebooks differ", + ): + _load( + tmp_path, + u2_inputs, + evidence=pinned, + source_hashes={cited: "a" * 64}, + ) + finally: + patch.undo() + assert parsed == [] + + def test_a_frozen_load_needs_the_committed_record( tmp_path, evidence, monkeypatch ):