Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
df1893c
Start #578 increment 2 progress ledger
MaxGhenis Jul 30, 2026
089fe96
Record increment 2 wiring design
MaxGhenis Jul 31, 2026
e0d1f6e
Add ordered multispine pool runtime seam
MaxGhenis Jul 31, 2026
bc2c197
Add bounded PUF donor artifact loader
MaxGhenis Jul 31, 2026
13d84fd
Add pool-safe seed and simulation stages
MaxGhenis Jul 31, 2026
7f9426e
Retire legacy ACS builder behind shared H5 I/O
MaxGhenis Jul 31, 2026
36fc800
Preserve raw values in ACS transfer
MaxGhenis Jul 31, 2026
a083dae
Add bounded ASEC checkpoint loader
MaxGhenis Jul 31, 2026
18ef73e
Receipt disposable simulation defaults
MaxGhenis Jul 31, 2026
c47e216
Complete deterministic pool derivations
MaxGhenis Jul 31, 2026
f5d80b5
Document and guard multispine pool ordering
MaxGhenis Jul 31, 2026
f42eaed
Reject retired late assembly in pool graph
MaxGhenis Jul 31, 2026
8e3b35a
Wire SHA-pinned multispine pool builder
MaxGhenis Jul 31, 2026
5e4f560
Bind pool assembly and tail receipts
MaxGhenis Jul 31, 2026
b4ea478
Harmonize ACS source lineage for assembly
MaxGhenis Jul 31, 2026
8a5ab94
Test multispine pool build boundary
MaxGhenis Jul 31, 2026
f9a3e1b
Bind resumable QRF to verified pool inputs
MaxGhenis Jul 31, 2026
136ea1e
Exercise real transfer through pool gate
MaxGhenis Jul 31, 2026
f3cc1dc
Record increment 2 validation handoff
MaxGhenis Jul 31, 2026
c4c9734
Keep PROGRESS.md at origin/main (root journals stay out of PRs)
MaxGhenis Jul 31, 2026
a20e847
Bind the ported provenance schema in the multispine stage test
MaxGhenis Jul 31, 2026
b6c3046
Start PR 583 hold remediation journal
MaxGhenis Jul 31, 2026
884c255
Catch pandas string reads in spine-blindness guard
MaxGhenis Jul 31, 2026
957ea8e
Checkpoint pandas guard remediation
MaxGhenis Jul 31, 2026
b75f352
Make multispine publication interruption-safe
MaxGhenis Jul 31, 2026
58de86f
Checkpoint interruption-safe publication
MaxGhenis Jul 31, 2026
f8bcb3b
Restore deprecated ACS local-release builder
MaxGhenis Jul 31, 2026
cb5f863
Checkpoint legacy release compatibility
MaxGhenis Jul 31, 2026
5b930ab
Make multispine lineage assembly-first
MaxGhenis Jul 31, 2026
a9baed9
Checkpoint final validation
MaxGhenis Jul 31, 2026
b421bfa
Bind raw artifact to source construction
MaxGhenis Jul 31, 2026
307174a
Checkpoint adversarial audit
MaxGhenis Jul 31, 2026
c94fe06
Keep PROGRESS.md at origin/main
MaxGhenis Jul 31, 2026
31356f2
Round 2: the guard resolves static indirection and fails closed on op…
MaxGhenis Jul 31, 2026
19a7a1d
Round 3: wildcards, hidden args, shadows, and mutations are all opaque
MaxGhenis Jul 31, 2026
4fa8c11
Start PR 583 round-4 guard journal
MaxGhenis Jul 31, 2026
972a22b
Fail closed on opaque column subscripts
MaxGhenis Jul 31, 2026
d836881
Propagate static column choices through iteration
MaxGhenis Jul 31, 2026
a88fef1
Resolve complete static format fields
MaxGhenis Jul 31, 2026
9bf61b0
Apply strict pandas checks through method aliases
MaxGhenis Jul 31, 2026
91b41ea
Fail closed on late-bound closure values
MaxGhenis Jul 31, 2026
ecea64e
Pin the complete spine-blindness guard contract
MaxGhenis Jul 31, 2026
a0421e9
Preserve strictness through composed method aliases
MaxGhenis Jul 31, 2026
7da96e6
Resolve composed static format fields
MaxGhenis Jul 31, 2026
4df316a
Count late writes across closure boundaries
MaxGhenis Jul 31, 2026
a2e4d87
Propagate every static string iterable form
MaxGhenis Jul 31, 2026
1f7405e
Join conditional selector states conservatively
MaxGhenis Jul 31, 2026
7fa05a4
Record validation and format the completed guard
MaxGhenis Jul 31, 2026
b219b21
Finalize PR 583 handoff journal
MaxGhenis Jul 31, 2026
03350e6
Start PR 583 fix-3 completion journal
MaxGhenis Jul 31, 2026
ddb40d5
Close spine guard with contraband literals
MaxGhenis Jul 31, 2026
4d78471
Harden universal contraband traversal
MaxGhenis Jul 31, 2026
cceb797
Record PR 583 fix-3 certification
MaxGhenis Jul 31, 2026
3a404e8
Keep PROGRESS.md at origin/main
MaxGhenis Jul 31, 2026
dd63858
Start PR 583 final guard journal
MaxGhenis Jul 31, 2026
5b685de
Reframe and close PR 583 guard scope
MaxGhenis Jul 31, 2026
ae7fbc1
Record PR 583 value preservation checks
MaxGhenis Jul 31, 2026
92f97f4
Record PR 583 final suite receipt
MaxGhenis Jul 31, 2026
cb058c0
Keep PROGRESS.md at origin/main after fix 4
MaxGhenis Jul 31, 2026
142e133
Round 6: qualified factory aliases and pair-unpacking loops enter scope
MaxGhenis Jul 31, 2026
53fc85c
Round 7: module-local scope stated; dict.items and starred rows enter it
MaxGhenis Jul 31, 2026
22d7771
Round 8: any-position stars and constructed dict entries enter scope
MaxGhenis Jul 31, 2026
9e9acf5
Round 9: unpropagatable geometry over guarded fragments fails closed
MaxGhenis Jul 31, 2026
87a8fc8
Start PR 583 round 10 fix journal
MaxGhenis Jul 31, 2026
7218dae
Add round 10 spine guard regression repros
MaxGhenis Jul 31, 2026
6c8b38f
Close static iteration propagation gaps
MaxGhenis Jul 31, 2026
2b9b54c
Align spine guard contract with iteration mechanics
MaxGhenis Jul 31, 2026
35b28d3
Add partial-binding precision regressions
MaxGhenis Jul 31, 2026
e031aba
Preserve precision in partial static bindings
MaxGhenis Jul 31, 2026
56a68d8
Add static view composition regressions
MaxGhenis Jul 31, 2026
0d0d39a
Compose partial structures through static dict views
MaxGhenis Jul 31, 2026
bf10f33
Record round 10 validation receipts
MaxGhenis Jul 31, 2026
93b0b8d
Restore root progress journal
MaxGhenis Jul 31, 2026
b32f20e
Round 11: opaque-over-string positions are incomplete; static stars s…
MaxGhenis Jul 31, 2026
6d903a6
Round 12: string material is always visible — structures propagate, n…
MaxGhenis Jul 31, 2026
1d43981
Start PR 583 round 13 fix journal
MaxGhenis Jul 31, 2026
1c4cb62
Backfill round 12 nested structure mirrors
MaxGhenis Jul 31, 2026
1e89916
Add round 13 structure resolver regressions
MaxGhenis Jul 31, 2026
942030f
Unify static iteration structure resolution
MaxGhenis Jul 31, 2026
e8abe85
Record round 13 validation receipts
MaxGhenis Jul 31, 2026
4c2e068
Restore root progress journal
MaxGhenis Jul 31, 2026
1340c0c
Round 14: starred dict views route through the shared iteration resolver
MaxGhenis Jul 31, 2026
d8554fd
Round 15: dict(view) nestings share the resolver; partial scalars sta…
MaxGhenis Jul 31, 2026
cc6b31e
Round 16: comprehension layers share the resolver and keep partiality
MaxGhenis Jul 31, 2026
6d9018e
Round 17: structural identity layers and partial sets classify
MaxGhenis Jul 31, 2026
0bad771
Round 18: identity dict comprehensions classify; repair the round-17 …
MaxGhenis Jul 31, 2026
944e77f
Start PR 583 round 19 fix journal
MaxGhenis Jul 31, 2026
e8985c9
Round 19: bound identity layers share iteration resolution
MaxGhenis Jul 31, 2026
75c82e9
Restore root progress journal
MaxGhenis Jul 31, 2026
31d6a93
Handle keys views, builtin wrappers, and filtered comprehensions
MaxGhenis Jul 31, 2026
f086fcd
Add round 20 iteration family regression matrices
MaxGhenis Jul 31, 2026
c978800
Strengthen wrapper table and filtered overcatch tests
MaxGhenis Jul 31, 2026
d0de889
Classify iteration wrappers by the membership principle
MaxGhenis Jul 31, 2026
36092dd
Exercise the membership principle across wrapper matrices
MaxGhenis Jul 31, 2026
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
10 changes: 10 additions & 0 deletions changelog.d/578-multispine-pool-build.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Add a SHA-pinned, pre-calibration US multispine pool builder that consumes a
dedicated operator-untouched ASEC raw-stage artifact, assembles ASEC and ACS
before PUF cloning and the full source-blind operator chain, publishes nullable
input-only artifacts through a run-bound invalidate-then-publish protocol, and
runs the fixed spine-agreement gate over the complete pool transfer charter,
including categorical joint checks, as its terminal stage; the readiness
loader verifies the manifest, H5, and diagnostics as one publication, the
deprecated ACS local-release builder remains executable until increment 4,
and this code increment has synthetic fixture coverage but does not certify a
full-data build.
177 changes: 141 additions & 36 deletions docs/us-multispine-operator-ordering.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# US multispine operator ordering

This note records the build ordering visible in
`tools/build_us_puf_support_base.py`,
`tools/build_us_acs_multispine_base.py`, and their directly called US runtime
modules. It defines the seam introduced by populace#395; it does not certify
the distributions of an output artifact.
This note records the executable pool ordering in
`tools/build_us_multispine_pool.py` and the serial lineage it replaces. The
assembly and agreement contracts originated in populace#581; populace#578
increment 2 wires them into a build path. This documentation and its fixture
tests do not certify a full-data output artifact.

## Current ordering
## Retired serial ordering

The current lineage is two serial builds. The first build produces an
operated ASEC-by-PUF-detail donor. The second build creates ACS records,
transfers inputs from that donor, and only then appends ACS.
The earlier lineage used two serial builds. The first build produced an
operated ASEC-by-PUF-detail donor. The second build created ACS records,
transferred inputs from that donor, and only then appended ACS.

### `build_us_puf_support_base.py`

Expand All @@ -35,8 +35,8 @@ stages.

### `build_us_acs_multispine_base.py`

The ACS builder takes that exported H5 as `--base-h5`. Its runtime call graph
is:
The former ACS builder took that exported H5 as `--base-h5`. Its runtime call
graph was:

1. Load and validate the dense ASEC-by-PUF-detail base and declared transfer
coverage.
Expand All @@ -55,14 +55,114 @@ is:
Calibration is downstream of this tool. Simulation is not run by either
builder in this call graph.

The important ordering fact is structural: ACS receives model-input
The important ordering flaw is structural: ACS receives model-input
transfers from a donor after the donor has crossed the ASEC-only operator
sequence. Appending the transferred ACS records later does not cause those
operators to run over the combined population.

## Current provenance axes

The current lineage uses two related metadata schemes:
`build_us_acs_multispine_base.py` remains a deprecated but executable
compatibility path until populace#578 increment 4 retires the ACS local-release
overlay. The public command warns and delegates to the preserved implementation
under `tools/_legacy`; its summary and reviewed-null receipts remain the inputs
expected by `build_us_acs_local_release.py`. New multispine work uses the pool
builder below, but the supported legacy release recipe is not left half-working.

## Executable increment-2 pool build

`build_us_multispine_pool.py` consumes only explicit local files and their
declared SHA-256 values:

- the dedicated `populace_us_asec_raw_stage` artifact emitted alongside the
producer's `source_construction` checkpoint. Its stage tag is
`raw_source_mapping` and its operator status is `operator_untouched`;
- the ACS household and person PUMS archives, whose caller-supplied hashes
must also match the checked-in ACS source manifest;
- the canonical ACS 2022 rent donor used by the post-assembly housing
operator; and
- the processed PUF H5 and source-year PUF CSV used by the existing donor
loader.

The raw artifact is a second producer output, not a relabeling of
`pre_clone_enrichment`. It contains pooled ASEC unit structure and measured raw
columns. The only enrichment allowed there is faithful source mapping:
`LKWEEKS` and `ED_VAL` are restored by exact, pinned Census identity joins.
No `weeks_unemployed`, `educational_assistance`, carried-income split,
eligibility, pregnancy, take-up, childcare, retirement, or immigration output
is present. The producer still emits its historical enriched checkpoint and
final H5 for the sparse/dense single-spine release lineage; their operator
sequence and bytes are unchanged.

The dedicated raw artifact is produced by the checkpointed producer recipe
(`--stage all --checkpoint-dir ...`) at
`<checkpoint-dir>/asec_raw_stage.checkpoint.h5`. The legacy monolithic recipe
continues to produce only its historical release outputs.

The tool does not download any source. It verifies all file pins and validates
the raw artifact kind, stage, frame identity, operator status, and complete
operator-output absence before loading the peer frames. Measured ACS mappings
are allowed only when named by the ACS native-input receipt. It then runs this
fixed sequence:

1. `assemble_spines({"asec": ..., "acs": ...})` creates the first shared
population state and binds the immutable assembly receipt.
2. `clone_us_frame_for_puf_support(...)` applies the PUF-detail clone to the
whole assembled pool. Clone-index provenance, not source-spine identity,
controls later PUF-detail routing.
3. CPS-carried predictor inputs are derived after assembly on rows with the
required measured CPS source fields. The pool wrapper validates the complete
assembly receipt first, then gives the historical CPS kernel an ephemeral
`PERIDNUM`-available structural projection. That projection deliberately
carries neither the full-pool assembly receipt nor its mass history. Only
the kernel's declared output family is merged back into the still-receipted
full pool. Unavailable peer rows remain nullable; no operator uses
source-channel identity to choose behavior.
4. The primary PUF QRF chain and capital-gains tail transfer run over the
combined frame. The remaining historical ASEC input families then run in
their declared order on source-evidenced rows: prior-year income,
relationship and Medicare inputs, housing, eligibility, pregnancy, WIC,
housing-assistance support transfer, child support, disability benefits,
workers compensation, weeks unemployed, childcare, adult care, energy
subsidy, retirement contributions/distributions, immigration, and
education inputs.
5. The pool-specific ACS transfer plan fills only still-null peer cells from
those post-assembly results. Existing measured/native cells remain
byte-for-byte unchanged, and transfer receipts record fitted and imputed
rows.
6. Schedule-D and QBI deterministic reconciliation run over that same pool.
7. The seed stage preserves existing take-up values, applies the sourced
TANF and EITC mechanisms, and explicitly receipts live engine defaults
used for unresolved, non-transfer-owned take-up inputs. Those defaults
are not described as fitted or administrative mechanisms.
8. SSI is materialized only on an ephemeral agreement view in fixed
household batches. Any engine defaults required solely for that
calculation are separately receipted; formula output is not written into
the input pool.
9. The spine-agreement gate is terminal. Its immutable pool registry is built
from the complete pool-specific transfer plan plus derived, take-up, and SSI
surfaces. Numeric columns retain the fixed incidence and conditional-
quantile tolerances. Categorical columns use a fixed weighted total-
variation-distance ceiling of `0.25`; the immigration fields are also
checked jointly so matching marginals cannot conceal incompatible pairs.
The gate batches all failures and controls the manifest's simulation-ready
status.

The output H5 is a nullable, input-only, pre-calibration pool. Its companion
manifest carries input pins, the assembly receipt, per-source and per-clone
counts, operator receipts, and the complete agreement result. Publication
first atomically replaces any prior manifest with a non-ready tombstone, then
stages the H5 and diagnostics under one publication run ID and renames them,
and finally writes the readiness manifest. The manifest records the H5 and
diagnostics run IDs and SHA-256 digests. The readiness loader requires a green
manifest whose run ID and digests match the H5 metadata and diagnostics
payload. An interrupted, substituted, or failed publication therefore
self-reports not ready even beside stale files. A failed agreement gate writes
diagnostics and a non-ready final manifest and exits nonzero. Calibration is
deliberately absent; the downstream k-ladder
may consume only a pool whose terminal agreement result passed.

## Provenance axes

The retired lineage used two related metadata schemes:

- PUF support cloning adds, on every entity,
`*_source_id`, `*_support_channel`, and
Expand All @@ -77,13 +177,13 @@ The current lineage uses two related metadata schemes:
including the target family, donor spine/channel, predictors, seeds,
weight kind, recipient patterns, and unmodeled-row count.

Those fields currently mix two concepts: the population source that carried
a record and the PUF-detail copy created by an operator. The new seam keeps
those concepts separate.
Those fields mixed two concepts: the population source that carried a record
and the PUF-detail copy created by an operator. The assembly seam keeps those
concepts separate.

## Canonical target ordering
## Canonical executable ordering

The target US multispine build order is:
The US multispine build order is:

```text
source ingestion and faithful schema harmonization
Expand All @@ -94,15 +194,22 @@ source ingestion and faithful schema harmonization
-> seed take-up and other stochastic inputs
-> simulate
-> spine-agreement gate
-> calibrate
-> emit input-only pool and receipts
```

Calibration is a downstream consumer boundary, not a stage in this tool.

`assemble_spines(...)` is the boundary between source preparation and
population operators. It receives nullable, schema-compatible peer frames
and produces one combined frame before cloning, fitted transfer, derivation,
seeded assignment, simulation, or calibration. Downstream operator
seeded assignment, simulation, or calibration. Downstream pool-stage
entrypoints receive that combined frame and operate on measured
characteristics without selecting behavior by source spine.
characteristics without selecting behavior by source spine. A historical
source kernel that requires CPS-only raw fields receives an ephemeral
availability projection after the combined-frame boundary is validated. Such
a projection is not published or described as a full-pool lineage state; its
declared outputs are merged back into the combined frame, whose immutable
assembly receipt remains the authority.

ASEC and ACS are peer household spines. A future household source can join
the same assembly contract. PUF tax detail is not a peer spine: it remains a
Expand Down Expand Up @@ -149,8 +256,11 @@ marital-unit, and benefit-unit naming variants. It recognizes direct,
aliased-helper, dynamic-subscript, `getattr`, and `*_spine_source_id` reads.
Every US runtime module is classified as a reviewed population operator or an
explicit non-operator/provenance owner, so a new unclassified module fails the
guard. `transfer_acs_inputs` selects fit donors by the centrally derived clone
role; assembled source-channel names never determine donor eligibility.
guard. A second fail-closed scan starts at `build_us_multispine_pool.py` and
covers the tool plus its transitive US-runtime import graph under the same
owner registry. `transfer_acs_inputs` selects fit donors by the centrally
derived clone role; assembled source-channel names never determine donor
eligibility.

Assembly accepts only integer-typed, nonnegative structural source IDs and
names the source spine and offending IDs on failure. PUF cloning revalidates
Expand Down Expand Up @@ -217,15 +327,10 @@ This ordering makes the gate diagnostic of the shared operator surface:
calibration cannot hide a disagreement, and no per-spine target, loss term,
seed, or tolerance may be introduced to shape a passing result.

## Increment-1 compatibility boundary

This increment adds an opt-in assembly seam, operator contracts, structural
enforcement, and the agreement-gate specification. It does not rewire
`build_us_puf_support_base.py`,
`build_us_acs_multispine_base.py`, or current sparse/dense release tools to
the new sequence. Their current call paths and artifact behavior remain the
compatibility lineage until a later increment explicitly adopts the seam.
## Increment-2 validation boundary

The seam is the foundation for the broader populace#578 build shape,
including one suite per country and the US full-geography/exact-k work. Those
release changes are outside this increment.
This increment makes the assembly seam executable and covers it with small,
synthetic two-spine fixtures. It does not execute or certify a full-data
build, download a source dataset, calibrate the pool, select k, or change the
current sparse/dense release artifacts. Those data-scale and release steps
remain downstream of this code increment.
26 changes: 26 additions & 0 deletions packages/populace-build/src/populace/build/us_runtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@
us_alimony_stage_spec,
us_alimony_summary,
)
from populace.build.us_runtime.asec_checkpoint import (
ASEC_RAW_STAGE_ARTIFACT_KIND,
ASEC_RAW_STAGE_CHECKPOINT_FILENAME,
ASEC_RAW_STAGE_OPERATOR_STATUS,
ASEC_RAW_STAGE_SCHEMA_VERSION,
ASEC_RAW_STAGE_STAGE,
load_asec_pre_clone_checkpoint,
load_asec_raw_stage_checkpoint,
)
from populace.build.us_runtime.asec_pool import (
AsecSource,
build_pooled_asec_unit_frame,
Expand Down Expand Up @@ -409,6 +418,10 @@
nonzero_share,
us_nonzero_shares,
)
from populace.build.us_runtime.operator_boundary import (
PRE_ASSEMBLY_OPERATOR_OUTPUT_FAMILIES,
assert_operator_free_source_frame,
)
from populace.build.us_runtime.org_wages import (
BLS_STATE_UNION_REPRESENTATION_RATE_2024,
FLSA_EXECUTIVE_ADMINISTRATIVE_PROFESSIONAL_OCCUPATION_CODES,
Expand Down Expand Up @@ -516,6 +529,7 @@
validate_puf_capital_gains_tail_manifest,
write_puf_capital_gains_tail_manifest,
)
from populace.build.us_runtime.puf_donor_io import load_puf_tax_unit_donor
from populace.build.us_runtime.puf_e01000_reconciliation import (
PUF_E01000_RECONCILIATION_SCHEMA_VERSION,
build_puf_e01000_reconciliation_basis,
Expand Down Expand Up @@ -857,6 +871,7 @@
us_source_operation_handlers,
)
from populace.build.us_runtime.spine_agreement import (
DEFAULT_CATEGORICAL_TOTAL_VARIATION_TOLERANCE,
DEFAULT_INCIDENCE_RATIO_BOUNDS,
DEFAULT_QUANTILE_ENVELOPE_TOLERANCE,
DEFAULT_SPINE_AGREEMENT_QUANTILES,
Expand Down Expand Up @@ -1041,6 +1056,11 @@
from populace.frame import Frame

__all__ = [
"ASEC_RAW_STAGE_ARTIFACT_KIND",
"ASEC_RAW_STAGE_CHECKPOINT_FILENAME",
"ASEC_RAW_STAGE_OPERATOR_STATUS",
"ASEC_RAW_STAGE_SCHEMA_VERSION",
"ASEC_RAW_STAGE_STAGE",
"BuildConfig",
"AsecSource",
"BASE_ASEC_SUPPORT_CHANNEL",
Expand Down Expand Up @@ -1774,12 +1794,14 @@
"PUF_SOURCE_YEAR",
"PUF_SOURCE_YEAR_AGI_REQUIRED_COLUMNS",
"PUF_SYNTHETIC_RECID_START",
"PRE_ASSEMBLY_OPERATOR_OUTPUT_FAMILIES",
"US_PUF_SUPPORT_FIT_NAME",
"US_PUF_SUPPORT_STAGE_NAME",
"US_STATE_INCOME_TAX_TARGET_SPECS",
"US_STATE_INCOME_TAX_TARGET_REFERENCES",
"compile_us_fiscal_target_registry",
"assign_congressional_districts_to_households",
"assert_operator_free_source_frame",
"build_pooled_asec_unit_frame",
"clone_us_frame_for_puf_support",
"congressional_district_assignment_summary",
Expand All @@ -1795,6 +1817,9 @@
"load_default_reform_specs",
"load_congressional_district_vintage_crosswalk",
"load_default_congressional_district_vintage_crosswalk",
"load_asec_pre_clone_checkpoint",
"load_asec_raw_stage_checkpoint",
"load_puf_tax_unit_donor",
"normalize_district_code",
"parse_baf_cd_layer",
"parse_national_cd_bef_districts",
Expand Down Expand Up @@ -1861,6 +1886,7 @@
"us_register_consistency_gate",
"us_register_contradictions",
"write_us_source_coverage_diagnostics",
"DEFAULT_CATEGORICAL_TOTAL_VARIATION_TOLERANCE",
"DEFAULT_INCIDENCE_RATIO_BOUNDS",
"DEFAULT_QUANTILE_ENVELOPE_TOLERANCE",
"DEFAULT_SPINE_AGREEMENT_QUANTILES",
Expand Down
21 changes: 12 additions & 9 deletions packages/populace-build/src/populace/build/us_runtime/acs_pums.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
ACS input-mapping stage applies the Census adjustment factors and records
which PolicyEngine inputs are native versus transferred.

Raw ``SERIALNO`` remains on the household table. Person lineage uses the
stable, sorted household ID assigned from that key, string-valued ``SPORDER``,
and a sequential row ID. Those generated fields match the ASEC source-frame
lineage dtypes required by pre-operator spine assembly without rewriting a
measured Census value.

Full national archives contain multiple CSV members. Each member is read in
bounded chunks, but the final selected-column tables necessarily materialize:
the returned :class:`~populace.frame.Frame` itself is the dense base-pool
Expand Down Expand Up @@ -264,15 +270,12 @@ def build_acs_pums_unit_frame(
person["household_id"] = person["household_id"].astype("int64")
person = _with_structural_columns(person)
person["source_year"] = source.vintage
person["source_household_id"] = person["SERIALNO"].astype(str)
person["source_person_id"] = _required_integer(person, "SPORDER")
person["source_row_id"] = (
ACS_2024_1YR_SPINE
+ ":"
+ person["SERIALNO"].astype(str)
+ ":"
+ person["SPORDER"].astype("int64").astype(str)
)
person["source_household_id"] = person["household_id"].to_numpy(dtype=np.int64)
person["source_person_id"] = pd.Series(
_required_integer(person, "SPORDER"),
index=person.index,
).astype(str)
person["source_row_id"] = np.arange(len(person), dtype=np.int64)

household_weights = _household_weights(household, person)
# SERIALNO belongs on the household table in the returned Frame. Its
Expand Down
Loading
Loading