Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
488 changes: 366 additions & 122 deletions packages/populace-build/src/populace/build/us/target_parity_manifest.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,11 @@
us_release_reform_coverage_probes,
)
from populace.build.us_runtime.release_target_parity import (
SSI_RECIPIENT_RED_LINE_FAMILIES,
RED_LINE_COMPILED_FAMILIES,
US_TARGET_PARITY_FEED_FAMILIES_RESOURCE,
US_TARGET_PARITY_MANIFEST_RESOURCE,
TargetFamily,
TargetFence,
TargetParityManifest,
assert_target_parity_manifest_current,
load_target_parity_feed_families,
Expand Down Expand Up @@ -1617,10 +1618,11 @@
"us_release_input_coverage_required_columns",
"us_release_input_coverage_reviewed_exclusions",
"us_release_reform_coverage_probes",
"SSI_RECIPIENT_RED_LINE_FAMILIES",
"RED_LINE_COMPILED_FAMILIES",
"US_TARGET_PARITY_FEED_FAMILIES_RESOURCE",
"US_TARGET_PARITY_MANIFEST_RESOURCE",
"TargetFamily",
"TargetFence",
"TargetParityManifest",
"assert_target_parity_manifest_current",
"load_target_parity_feed_families",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@
"cms_medicare",
{"target_role": "medicare_part_b_premium_total"},
),
# Household net worth: the retired us-data/eCPS pipeline calibrated a
# national wealth control (loss.py "net_worth", PR #282). Per-household
# net_worth is SCF-imputed and fixed, so the weighted sum is linear in the
# reweighting weights — a valid direct-sum target that pins the post-reweight
# aggregate the input-stage SCF imputation does not. Federal Reserve Z.1
# series BOGZ1FL192090005Q (households & nonprofits net worth).
("federal_reserve", "amount_outstanding", "fl152090005"): (
"net_worth",
"federal_reserve",
{"target_role": "household_net_worth"},
),
}


Expand Down Expand Up @@ -506,6 +517,17 @@
"fact_aggregation": "time_mean",
},
),
# LIHEAP recipient households: the retired us-data/eCPS pipeline calibrated
# the ACF national recipient-household count (loss.py
# _add_liheap_targets_from_db, PR #688) as an indicator sum of the model's
# energy-subsidy receipt over SPM units — the exact SNAP-caseload pattern.
# Only the recipient COUNT is targeted; LIHEAP dollars stay deferred (the
# ACF component split is not a clean model concept, us-data PR #688).
("hhs_acf_liheap", "households_served"): (
"spm_unit_energy_subsidy",
"hhs_acf_liheap",
{"target_role": "liheap_households"},
),
}


Expand Down Expand Up @@ -2045,6 +2067,8 @@ def _reference_from_ledger_fact(
)
if source_name == "ssa":
return _ssa_ssi_reference_from_fact(fact, target_period=target_period)
if source_name == "bea":
return _bea_reference_from_fact(fact, target_period=target_period)
if source_name == "jct":
return None
return _direct_reference_from_fact(fact, target_period=target_period)
Expand Down Expand Up @@ -2446,6 +2470,98 @@ def _ssa_ssi_reference_from_fact(
)


# BEA all-population (nonfiler-inclusive) income targets the retired us-data/
# eCPS pipeline calibrated to (us-data utils/loss.py
# BEA_NIPA_DIRECT_SUM_TARGETS, PR #994). Only the national wage and proprietors'
# income series are direct-sum targets here: us-data explicitly declined the
# NIPA interest/dividend totals because they include imputed interest,
# pension-plan dividends, and trust flows that are not a close microdata concept
# (PR #1059), and its state wage target (PR #1034) requires a place-of-work ->
# residence definitional adjustment the feed's raw SAINC4 line-50 facts cannot
# reproduce, so state wages are a documented reviewed exclusion. Every other BEA
# series in the feed is a ledger reference fact, not a calibration target.
_BEA_NATIONAL_WAGES_RECORD_SET = "bea_nipa.total_wages_salaries"
_BEA_NATIONAL_PROPRIETORS_RECORD_SET = "bea_nipa.proprietors_income"
#: The engine-computed counterparts us-data mapped these NIPA totals to.
_BEA_WAGES_BASE_VARIABLE = "employment_income_before_lsr"
_BEA_PROPRIETORS_BASE_VARIABLES = (
"self_employment_income_before_lsr",
"sstb_self_employment_income_before_lsr",
"farm_operations_income",
"partnership_s_corp_income",
)
BEA_NIPA_WAGES_TARGET_ROLE = "nipa_wages_and_salaries"
BEA_NIPA_PROPRIETORS_TARGET_ROLE = "nipa_proprietors_income"


def _bea_reference_from_fact(
fact: object,
*,
target_period: int | str,
) -> LedgerTargetReference | None:
"""Compile a BEA (``source_name == "bea"``) fact into a US target.

Follows the retired us-data/eCPS mapping exactly (us-data
utils/loss.py ``BEA_NIPA_DIRECT_SUM_TARGETS``, PR #994):

- ``bea_nipa.total_wages_salaries`` (BEA NIPA Table 2.1 gross wages and
salaries for all workers, **including nonfilers**; FRED A034RC) →
economy-wide engine ``employment_income_before_lsr``, national. This is
the ~$12.4T wage universe that filed tax returns and CPS-reported wages
(~$4T in the base microdata) systematically undercount — the nonfiler /
unreported-wage coverage gap the target was added to close (PR #994).
- ``bea_nipa.proprietors_income`` (BEA NIPA Table 2.1 proprietors' income
with IVA and CCAdj, all persons; FRED A041RC) → the same additive
expression us-data used: Schedule C non-SSTB and SSTB self-employment
income before labor-supply responses, farm operations income, and active
partnership/S-corp income, national.

Only these two national record sets compile; every other BEA series returns
``None`` (a reviewed exclusion in the target-parity manifest, whose fence
records the NIPA interest/dividend decline and the state-wage
residence-adjustment gap).
"""
record_set_id = _normalized_record_set_id(_str_at(fact, "layout", "record_set_id"))
if _geography_level(fact) != "country":
return None

if record_set_id == _BEA_NATIONAL_WAGES_RECORD_SET:
base_variable: str | tuple[str, ...] = _BEA_WAGES_BASE_VARIABLE
target_role = BEA_NIPA_WAGES_TARGET_ROLE
elif record_set_id == _BEA_NATIONAL_PROPRIETORS_RECORD_SET:
base_variable = _BEA_PROPRIETORS_BASE_VARIABLES
target_role = BEA_NIPA_PROPRIETORS_TARGET_ROLE
else:
return None

source_record_id = _source_record_id(fact)
if not source_record_id:
return None

metadata = {
"materializer": "policyengine_variable",
"measure_mode": "sum",
"target_role": target_role,
"source_measure_id": _measure_id(fact),
"source_period": str(_period_value(fact)),
"target_period": str(target_period),
}
if isinstance(base_variable, tuple):
metadata["base_variables"] = ",".join(base_variable)
else:
metadata["base_variable"] = base_variable
return LedgerTargetReference(
name=source_record_id,
ledger_source_record_id=source_record_id,
entity="household",
measure=source_record_id,
period=target_period,
family="bea",
signed=_numeric_value(fact) < 0,
metadata=metadata,
)


def _direct_reference_from_fact(
fact: object,
*,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@
"COMPILED_STATUS",
"REVIEWED_EXCLUSION_STATUS",
"SOURCE_ABSENT_CLASSIFICATION",
"SSI_RECIPIENT_RED_LINE_FAMILIES",
"RED_LINE_COMPILED_FAMILIES",
"TargetFamily",
"TargetFence",
"TargetParityManifest",
"assert_target_parity_manifest_current",
"load_target_parity_feed_families",
Expand All @@ -88,13 +89,23 @@
#: declared families exempt from the feed-surface reconciliation.
SOURCE_ABSENT_CLASSIFICATION = "source_absent"

#: The core SSA SSI recipient family. Per this contract it must ship
#: ``compiled`` with no reviewed exclusion — the whole point of the register is
#: that the family the retired pipeline calibrated (``nation/ssa/ssi_recipients``)
#: can never again be silently dropped. The anti-rot check refuses to let it be
#: downgraded, mirroring the #368 SSI countable-resource asset red line on the
#: input-coverage side.
SSI_RECIPIENT_RED_LINE_FAMILIES = ("ssa_supplement.ssi_recipients",)
#: Families that must ship ``compiled`` with no reviewed exclusion — the whole
#: point of the register is that the administrative targets the retired pipeline
#: calibrated can never again be silently dropped. The anti-rot check refuses to
#: let any of them be downgraded, mirroring the #368 SSI countable-resource asset
#: red line on the input-coverage side.
#:
#: - ``ssa_supplement.ssi_recipients``: the SSA SSI recipient count
#: (``nation/ssa/ssi_recipients``).
#: - ``bea_nipa.total_wages_salaries``: the BEA NIPA all-population wage total
#: (``nation/bea/nipa_wages_and_salaries``, PR #994) — economy-wide wages
#: including nonfilers, the ~$12.4T universe that tax-return / CPS-reported
#: wages undercount by two-thirds. Silent loss of it is the exact failure the
#: Chesterton's-fence audit surfaced.
RED_LINE_COMPILED_FAMILIES = (
"ssa_supplement.ssi_recipients",
"bea_nipa.total_wages_salaries",
)


def _is_target_period_token(value: str) -> bool:
Expand Down Expand Up @@ -144,6 +155,42 @@ def us_target_family_id(source_record_id: str) -> str:
return namespace


@dataclass(frozen=True)
class TargetFence:
"""The Chesterton's-fence record behind one reviewed exclusion.

A category label (``macro_control_total``, ``not_modeled``, ``superseded``)
is not a sufficient reason to drop a target the retired pipeline calibrated
to. Before an exclusion may stand it must recover *why the fence was built*:
the target's origin, the failure mode it guarded, and the purpose-informed
basis for not rebuilding it here. An unexplained fence gets rebuilt (wired),
not removed.

Attributes:
origin: Where the fence came from — the introducing (and, where
relevant, removing) ``us-data`` PR/commit, or the
explicit finding ``"not a us-data calibration target"`` when the feed
fact was never a target (a ledger reference fact).
purpose: The failure mode the target guarded, quoting the PR/issue
rationale verbatim where one exists, or stating ``"no discoverable
rationale in PR #N"`` (then the exclusion must justify itself on
mechanics), or ``"n/a"`` for a fact that was never a target.
verdict_basis: The purpose-informed reason the exclusion stands — a
named compiled family that subsumes it, an architecture change that
retires the need (with a code/PR cite), or a deferral with the
specific blocker. Never a bare category label.
"""

origin: str
purpose: str
verdict_basis: str

def __post_init__(self) -> None:
for field_name in ("origin", "purpose", "verdict_basis"):
if not getattr(self, field_name):
raise ValueError(f"TargetFence.{field_name} is required.")


@dataclass(frozen=True)
class TargetFamily:
"""One declared target-parity family.
Expand All @@ -155,13 +202,16 @@ class TargetFamily:
classification: For a reviewed exclusion, the exclusion kind
(``survey_derived``, ``macro_control_total``, ``non_linear``,
``off_by_default``, ``superseded``, ``source_absent``,
``deferred``, ``input_side``, ``not_modeled``). Empty for a
compiled family.
``deferred``, ``input_side``, ``not_modeled``, ``not_a_target``).
A classification is now a label ON TOP of the fence narrative, not a
reason by itself. Empty for a compiled family.
reason: Why the gap is accepted — required for a reviewed exclusion.
evidence: The concrete fact/mechanism the reason names (a sample
``source_record_id``, a code constant, a compiled sibling family).
Required for a reviewed exclusion — an undocumented exclusion is a
silent omission with extra steps.
Required for a reviewed exclusion.
fence: The Chesterton's-fence record (origin, purpose, verdict_basis).
REQUIRED for every reviewed exclusion — a category label alone is no
longer a sufficient reason to drop a us-data-era target.
issue: Optional tracking issue owning the gap's closure.
note: Optional free-text annotation.
"""
Expand All @@ -171,6 +221,7 @@ class TargetFamily:
classification: str = ""
reason: str = ""
evidence: str = ""
fence: TargetFence | None = None
issue: str = ""
note: str = ""

Expand All @@ -197,6 +248,12 @@ def __post_init__(self) -> None:
f"{self.name}: a reviewed exclusion needs evidence naming the "
"concrete fact or mechanism behind the reason."
)
if self.fence is None:
raise ValueError(
f"{self.name}: a reviewed exclusion needs a fence "
"{origin, purpose, verdict_basis} — a category label is not a "
"sufficient reason to drop a us-data-era calibration target."
)

@property
def is_source_absent(self) -> bool:
Expand Down Expand Up @@ -317,13 +374,26 @@ def load_target_parity_manifest(
for name, entry in sorted(raw_families.items()):
if not isinstance(entry, Mapping):
raise ValueError(f"{resource}: family {name!r} must be a JSON object.")
raw_fence = entry.get("fence")
fence: TargetFence | None = None
if raw_fence is not None:
if not isinstance(raw_fence, Mapping):
raise ValueError(
f"{resource}: family {name!r} 'fence' must be a JSON object."
)
fence = TargetFence(
origin=str(raw_fence.get("origin", "")),
purpose=str(raw_fence.get("purpose", "")),
verdict_basis=str(raw_fence.get("verdict_basis", "")),
)
families.append(
TargetFamily(
name=str(name),
status=str(entry.get("status", "")),
classification=str(entry.get("classification", "")),
reason=str(entry.get("reason", "")),
evidence=str(entry.get("evidence", "")),
fence=fence,
issue=str(entry.get("issue", "")),
note=str(entry.get("note", "")),
)
Expand Down Expand Up @@ -449,7 +519,7 @@ def assert_target_parity_manifest_current(
is drift and must be reconciled by regenerating the manifest.
- The manifest's ``reference.feed_sha256`` must match the inventory's, so
the two artifacts describe the same pinned feed.
- The core SSA SSI recipient family must stay ``compiled`` with no reviewed
- The red-line families must stay ``compiled`` with no reviewed
exclusion — the red line this contract exists for cannot be quietly undone.
- When a compiled registry is supplied, every ``compiled`` family must be
present in it, every ``reviewed_exclusion`` family must be absent from it,
Expand Down Expand Up @@ -492,16 +562,16 @@ def assert_target_parity_manifest_current(
f"{inventory_sha!r}; regenerate both from the same pinned feed."
)

for family in SSI_RECIPIENT_RED_LINE_FAMILIES:
for family in RED_LINE_COMPILED_FAMILIES:
entry = manifest.by_name.get(family)
if entry is None:
failures.append(
f"{family}: core SSA SSI recipient family must be declared and "
"compiled (the target-parity red line)."
f"{family}: red-line administrative target family must be declared "
"and compiled (the target-parity red line)."
)
elif entry.status != COMPILED_STATUS:
failures.append(
f"{family}: core SSA SSI recipient family must stay status="
f"{family}: red-line administrative target family must stay status="
f"{COMPILED_STATUS!r}, not {entry.status!r} — it can never be "
"quietly downgraded to a reviewed exclusion."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@
"cbo_qualified_dividend_income": "qualified_dividend_income",
"cbo_net_capital_gain": "net_capital_gain",
"cbo_net_business_income": "net_business_income",
# BEA NIPA all-population income targets (nonfiler-inclusive) age by their
# own CBO income-by-source series so a cy2023 source level is projected to
# the build year on the matching concept, not the AGI default. The cy2024
# NIPA wage level needs no aging (source == build period).
"nipa_wages_and_salaries": "wages_and_salaries",
"bea_state_wages": "wages_and_salaries",
"nipa_proprietors_income": "net_business_income",
}


Expand Down
Loading
Loading