Skip to content

Commit fdb25b6

Browse files
MaxGhenisclaude
andcommitted
Always enable the ACS donor (rent, real_estate_taxes imputation)
The ACS donor provider supplies the rent and real_estate_taxes source imputation that eCPS also draws from ACS. It was gated by include_acs, so the no-ACS / "eCPS-shaped" build variants dropped it and exported rent=$0 (the nation/census/rent target read $0 against a ~$735B baseline). Decouple the ACS donor from include_acs / include_donor_surveys so it is always enabled. ACS as a population spine ("multispine") remains a separate, not-yet-enabled control. Update the CLI help text and the two provider- assembly tests that encoded the old can-disable behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 14c114a commit fdb25b6

3 files changed

Lines changed: 30 additions & 19 deletions

File tree

src/microplex_us/pipelines/pe_us_data_rebuild.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,22 @@ def default_policyengine_us_data_rebuild_source_providers(
155155
social_security_split_strategy=SOCIAL_SECURITY_SPLIT_STRATEGY_PE_QRF,
156156
),
157157
]
158-
resolved_include_acs = include_donor_surveys if include_acs is None else include_acs
159158
resolved_include_sipp = (
160159
include_donor_surveys if include_sipp is None else include_sipp
161160
)
162161
resolved_include_scf = include_donor_surveys if include_scf is None else include_scf
163-
if resolved_include_acs:
164-
providers.append(
165-
ACSSourceProvider(
166-
year=int(acs_year),
167-
policyengine_us_data_repo=policyengine_us_data_repo,
168-
policyengine_us_data_python=policyengine_us_data_python,
169-
)
162+
# The ACS donor is always enabled. It supplies the rent and real_estate_taxes
163+
# source imputation that eCPS also draws from ACS, so omitting it leaves those
164+
# variables at zero. ACS as a population spine ("multispine") is a separate,
165+
# independently controlled feature that is not enabled here; ``include_acs`` is
166+
# retained for backward compatibility and no longer disables the donor.
167+
providers.append(
168+
ACSSourceProvider(
169+
year=int(acs_year),
170+
policyengine_us_data_repo=policyengine_us_data_repo,
171+
policyengine_us_data_python=policyengine_us_data_python,
170172
)
173+
)
171174
if resolved_include_sipp:
172175
providers.extend(
173176
[

src/microplex_us/pipelines/pe_us_data_rebuild_checkpoint.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,8 +2130,9 @@ def main(argv: list[str] | None = None) -> None:
21302130
action=argparse.BooleanOptionalAction,
21312131
default=None,
21322132
help=(
2133-
"Include the ACS donor provider. Defaults to --include-donor-surveys; "
2134-
"use --no-include-acs for an eCPS-shaped run that keeps SIPP/SCF."
2133+
"Deprecated/no-op for the ACS donor: the ACS donor (rent, "
2134+
"real_estate_taxes) is always enabled, matching eCPS. Retained for "
2135+
"backward compatibility. ACS as a population spine is a separate control."
21352136
),
21362137
)
21372138
parser.add_argument(

tests/pipelines/test_pe_us_data_rebuild.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,21 @@ def test_default_policyengine_us_data_rebuild_source_providers_use_pe_style_bund
145145
assert isinstance(providers[5], SCFSourceProvider)
146146

147147

148-
def test_default_policyengine_us_data_rebuild_source_providers_can_disable_donor_surveys() -> (
148+
def test_default_policyengine_us_data_rebuild_source_providers_keeps_acs_when_donor_surveys_disabled() -> (
149149
None
150150
):
151+
# include_donor_surveys=False disables the SIPP/SCF donors, but the ACS donor is
152+
# always enabled (it supplies the rent / real_estate_taxes imputation), so it
153+
# remains alongside the CPS spine and PUF.
151154
providers = default_policyengine_us_data_rebuild_source_providers(
152155
include_donor_surveys=False,
153156
cps_download=False,
154157
)
155158

156-
assert len(providers) == 2
159+
assert len(providers) == 3
157160
assert isinstance(providers[0], CPSASECSourceProvider)
158161
assert isinstance(providers[1], PUFSourceProvider)
162+
assert isinstance(providers[2], ACSSourceProvider)
159163

160164

161165
def test_default_policyengine_us_data_rebuild_source_providers_can_include_donor_surveys() -> (
@@ -177,24 +181,27 @@ def test_default_policyengine_us_data_rebuild_source_providers_can_include_donor
177181
assert isinstance(providers[5], SCFSourceProvider)
178182

179183

180-
def test_default_policyengine_us_data_rebuild_source_providers_can_disable_only_acs() -> (
184+
def test_default_policyengine_us_data_rebuild_source_providers_always_includes_acs_donor() -> (
181185
None
182186
):
187+
# The ACS donor is mandatory: it supplies the rent / real_estate_taxes source
188+
# imputation (as eCPS does), so it is present even when include_acs=False. That
189+
# flag no longer disables the donor.
183190
providers = default_policyengine_us_data_rebuild_source_providers(
184191
include_donor_surveys=True,
185192
include_acs=False,
186193
cps_download=False,
187194
)
188195

189-
assert len(providers) == 5
196+
assert len(providers) == 6
190197
assert isinstance(providers[0], CPSASECSourceProvider)
191198
assert isinstance(providers[1], PUFSourceProvider)
192-
assert isinstance(providers[2], SIPPSourceProvider)
193-
assert providers[2].block == "tips"
199+
assert isinstance(providers[2], ACSSourceProvider)
194200
assert isinstance(providers[3], SIPPSourceProvider)
195-
assert providers[3].block == "assets"
196-
assert isinstance(providers[4], SCFSourceProvider)
197-
assert not any(isinstance(provider, ACSSourceProvider) for provider in providers)
201+
assert providers[3].block == "tips"
202+
assert isinstance(providers[4], SIPPSourceProvider)
203+
assert providers[4].block == "assets"
204+
assert isinstance(providers[5], SCFSourceProvider)
198205

199206

200207
def test_build_policyengine_us_data_rebuild_pipeline_returns_configured_pipeline() -> (

0 commit comments

Comments
 (0)