From ade6d6aad44c0e3300c8317c29631d0a643cd991 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Thu, 13 Aug 2026 23:28:38 -0400 Subject: [PATCH 1/2] Hold the #600 enrollment leaves out of the ACS plan until a #600-era release certifies (#512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The buildp refresh's donor-coverage gate correctly refused the certified buildp release: receives_wic, is_tanf_enrolled, and receives_snap were added to the pool and the declared ACS transfer plan by #600 three days AFTER buildp certified, so the newest certified donor cannot supply them (it carries only the runtime-owned takes_up_* draws). The plan stays honest to the certified lineage, with restore markers for the moment a #600-era release lands — the donor gate enforces the contract in both directions. Co-Authored-By: Claude Fable 5 --- .../build/us_runtime/acs_transfer.py | 19 ++++++++++++------- .../tests/test_us_acs_transfer.py | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/acs_transfer.py b/packages/microcosm-build/src/microcosm/build/us_runtime/acs_transfer.py index 09e2c90e9..2b98a9dc9 100644 --- a/packages/microcosm-build/src/microcosm/build/us_runtime/acs_transfer.py +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/acs_transfer.py @@ -367,10 +367,13 @@ def acs_transfer_execution_contract_identity( "is_disabled", "is_full_time_college_student", "is_pregnant", - # WICYN's adult-female reporter is only a physical carrier for an - # SPM-unit receipt fact. Engine consumers are separately guarded - # to aggregate receives_wic at SPM-unit grain (microcosm#591). - "receives_wic", + # NOT YET: receives_wic (WICYN's adult-female reporter as the + # physical carrier for an SPM-unit receipt fact, microcosm#591). + # The #600 enrollment leaves postdate the newest certified + # release (buildp, 2026-07-28), so the certified donor cannot + # supply them and the donor-coverage gate would refuse the whole + # build. Restore receives_wic here the moment a #600-era release + # certifies — the gate holds the plan honest in both directions. ), "model_required_discrete": ("own_children_in_household",), }, @@ -394,9 +397,11 @@ def acs_transfer_execution_contract_identity( # Housing-assistance receipt is source-observed in the raw pool. Other # takes_up_* leaves are runtime-owned draws and are not donor targets. "benefit_participation": ("takes_up_housing_assistance_if_eligible",), - # Reported TANF/SNAP receipt is produced from annual ASEC amounts before - # cloning and transferred like the person-level required booleans. - "model_required_boolean": ("is_tanf_enrolled", "receives_snap"), + # NOT YET: is_tanf_enrolled + receives_snap (reported TANF/SNAP + # receipt from annual ASEC amounts, microcosm#591/#600). Like + # receives_wic above, these postdate the newest certified release + # (buildp) and the certified donor carries only the runtime-owned + # takes_up_* draws; restore both when a #600-era release certifies. "model_required_numeric": ("spm_unit_pre_subsidy_childcare_expenses",), }, } diff --git a/packages/microcosm-build/tests/test_us_acs_transfer.py b/packages/microcosm-build/tests/test_us_acs_transfer.py index ff4c7fc68..3f9d40a04 100644 --- a/packages/microcosm-build/tests/test_us_acs_transfer.py +++ b/packages/microcosm-build/tests/test_us_acs_transfer.py @@ -739,7 +739,18 @@ def test_declared_families_are_independent_of_release_coverage_surface() -> None } ) assert "has_esi" in production_declared["person"]["model_required_boolean"] - assert "receives_wic" in production_declared["person"]["model_required_boolean"] + # The #600 enrollment leaves (receives_wic, is_tanf_enrolled, + # receives_snap) postdate the newest certified release; the plan stays + # honest to the certified donor until a #600-era release certifies. + declared_targets = { + target + for entity_families in production_declared.values() + for targets in entity_families.values() + for target in targets + } + assert declared_targets.isdisjoint( + {"receives_wic", "is_tanf_enrolled", "receives_snap"} + ) def test_declared_plan_carries_the_23_stage_base_surface() -> None: @@ -780,9 +791,10 @@ def test_declared_plan_carries_the_23_stage_base_surface() -> None: "second_home_mortgage_origination_year", } ) - assert declared_acs_transfer_target_families()["spm_unit"][ + assert ( "model_required_boolean" - ] == ("is_tanf_enrolled", "receives_snap") + not in (declared_acs_transfer_target_families()["spm_unit"]) + ) def test_explicit_transfer_adds_requested_model_inputs( From 592ae5d67a615c6d8afcf4e09da4cb3288b6088b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 18 Aug 2026 22:02:48 -0400 Subject: [PATCH 2/2] Derive the release campaign letter from the pinned donor lineage (#512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The buildp refresh minted 'buildo-acs-local-…' because the id prefix was a constant naming the tool line's birth campaign; the campaign letter is lineage doctrine, so it now derives from the donor release id pinned in the staging summary (buildp donor -> populace-us-2024-buildp-acs-local / namespace buildp_acs_local), falling back to buildo only when no donor identity is pinned. Co-Authored-By: Claude Fable 5 --- .../tests/test_us_acs_local_release_tool.py | 12 +++++-- tools/build_us_acs_local_release.py | 32 ++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/microcosm-build/tests/test_us_acs_local_release_tool.py b/packages/microcosm-build/tests/test_us_acs_local_release_tool.py index c8b38c910..cfb4cacb5 100644 --- a/packages/microcosm-build/tests/test_us_acs_local_release_tool.py +++ b/packages/microcosm-build/tests/test_us_acs_local_release_tool.py @@ -163,10 +163,16 @@ def test_parse_args_enforces_stage_requirements(tmp_path: Path) -> None: assert args.gate_report == tmp_path / "ckpt" / "gate_summary.json" -def test_release_id_prefix_and_manifest_constants() -> None: +def test_release_naming_derives_from_the_donor_campaign() -> None: + """The campaign letter names the donor lineage, not the tool's birthday.""" + module = _load_tool_module() - assert module.RELEASE_ID_PREFIX == "populace-us-2024-buildo-acs-local" - assert module.RELEASE_NAMESPACE == "buildo_acs_local" + buildp = {"release_id": "populace-us-2024-buildp-sparse-rmloss100-x"} + assert module.release_id_prefix(buildp) == "populace-us-2024-buildp-acs-local" + assert module.release_namespace(buildp) == "buildp_acs_local" + # No pinned donor identity falls back to the tool line's birth campaign. + assert module.release_id_prefix(None) == "populace-us-2024-buildo-acs-local" + assert module.release_namespace({}) == "buildo_acs_local" assert module.ARTIFACT_FILENAME == "populace_us_2024_acs_local.h5" assert module.HF_REPO_ID == "policyengine/populace-us" diff --git a/tools/build_us_acs_local_release.py b/tools/build_us_acs_local_release.py index f597cf8c4..f4deffd0a 100644 --- a/tools/build_us_acs_local_release.py +++ b/tools/build_us_acs_local_release.py @@ -48,6 +48,7 @@ import gc import hashlib import json +import re import resource import shutil import subprocess @@ -68,8 +69,29 @@ sys.path.insert(0, str(_TOOLS_DIR)) PERIOD = 2024 -RELEASE_NAMESPACE = "buildo_acs_local" -RELEASE_ID_PREFIX = "populace-us-2024-buildo-acs-local" +# The campaign letter names the donor lineage, so it derives from the +# pinned donor release id at package time (falling back to the letter this +# tool line was born under only when no donor identity is pinned). +_FALLBACK_CAMPAIGN = "buildo" +_CAMPAIGN_TOKEN_RE = re.compile(r"-(build[a-z0-9]+)-") + + +def release_campaign(donor_release: dict | None) -> str: + """The campaign token of the pinned donor release (e.g. ``buildp``).""" + + release_id = (donor_release or {}).get("release_id") or "" + match = _CAMPAIGN_TOKEN_RE.search(release_id) + return match.group(1) if match else _FALLBACK_CAMPAIGN + + +def release_namespace(donor_release: dict | None) -> str: + return f"{release_campaign(donor_release)}_acs_local" + + +def release_id_prefix(donor_release: dict | None) -> str: + return f"populace-us-2024-{release_campaign(donor_release)}-acs-local" + + ARTIFACT_NAME = "populace_us_2024_acs_local" ARTIFACT_FILENAME = f"{ARTIFACT_NAME}.h5" HF_REPO_ID = "policyengine/populace-us" @@ -1614,9 +1636,10 @@ def do_package(args) -> dict: "Refusing to package: the finalized summary is not simulation_ready." ) + donor_release = (staging_summary.get("base") or {}).get("donor_release") code = _repo_code_identity(args.allow_dirty) timestamp = datetime.now(UTC).strftime("%Y%m%dT%H%M%SZ") - release_id = f"{RELEASE_ID_PREFIX}-{code['sha']}-{timestamp}" + release_id = f"{release_id_prefix(donor_release)}-{code['sha']}-{timestamp}" release_dir = args.out / "releases" / release_id release_dir.mkdir(parents=True, exist_ok=True) @@ -1672,7 +1695,6 @@ def _version(package: str) -> str: except Exception: return "unknown" - donor_release = (staging_summary.get("base") or {}).get("donor_release") refresh_recipe = { "note": ( "When the next certified default publishes (e.g. the microcosm#508 " @@ -1802,7 +1824,7 @@ def _artifact(path_name: str, kind: str, local: Path) -> dict: "default_datasets": {}, "dataset_role": "non_default_local_area", "is_default": False, - "namespace": RELEASE_NAMESPACE, + "namespace": release_namespace(donor_release), "build": { "build_id": release_id, "built_at": datetime.now(UTC).isoformat(),