Repository navigation
Allocate Census residuals through shared reference profiles - #1375
Merged
Merged
Conversation
Implement d1886 Census household-size and tenure allocation through the shared
allocated_residual_by_ratio operation and one resolve_reference_profiles API.
Keep regional residuals local, preserve independent national diagnostics, add
MAR and small-household profiles plus V4, and prepare all 136 size indicators.
Verification below identifies every invariant and its checking tests. Final
execution counts and named-mutant evidence follow.
All test IDs below are relative to:
packages/microcosm-build/tests/engine_free/shared/
Design section 6 invariants and their checks:
1. Regional closure: both size profiles and allocated tenure close to each
region's published Census household total, then that total times its ERP
ratio, using fsum with rel_tol=1e-12 and abs_tol=1e-7. Retain fractional
targets and each region's own computed residual.
- test_nz_target_references.py::test_inventory_asserts_exact_regional_residual_table
- test_nz_target_references.py::test_real_artifact_regional_closure_shares_and_sensitivity
- test_nz_target_references.py::test_scaled_tenure_values_are_fractional_exact_bridges_and_national_diagnostics_are_separate
- test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once
2. MAR shares: allocated cross-products preserve stated shares, including
zero-valued leaves.
- test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once
- test_nz_target_references.py::test_real_artifact_regional_closure_shares_and_sensitivity
3. Sensitivity recipients: only stated sizes 1 and 2 receive additions, in
their stated proportions; total size counts stay fixed. Tenure remains
proportional across all three source atoms in both residual profiles.
- test_ledger_allocated_residual.py::test_sensitivity_exact_recipients_and_increment_ratio
- test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
- test_nz_target_references.py::test_real_artifact_regional_closure_shares_and_sensitivity
4. Sensitivity comparison: against MAR, sizes 3-8 lose their MAR additions;
against stated counts under the same ERP scaling, they remain unchanged.
- test_ledger_allocated_residual.py::test_sensitivity_exact_recipients_and_increment_ratio
- test_nz_target_references.py::test_sensitivity_removes_mar_additions_from_sizes_three_to_eight
5. ERP commutation: A(qx,qT,E)=qA(x,T,E); apply the paired growth ratio once.
The exact-rational oracle also checks generated output-group partitions.
- test_ledger_allocated_residual.py::test_exact_rational_oracle_for_partitions_recipients_groups_and_growth
- test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once
- test_nz_target_references.py::test_all_17_erp_ratios_match_the_reviewed_source_table
- test_nz_target_references.py::test_real_artifact_regional_closure_shares_and_sensitivity
6. Grouping: allocating tenure atoms and then grouping source categories 1+3
equals allocating the owned group directly; category 3 stays in the exact
atomic partition. Facts reused in growth roles are counted once per role.
- test_ledger_allocated_residual.py::test_grouping_preserves_the_third_atomic_member
- test_ledger_allocated_residual.py::test_growth_roles_may_reuse_total_or_atom_without_double_counting
- test_ledger_allocated_residual.py::test_exact_rational_oracle_for_partitions_recipients_groups_and_growth
7. Region separation: keep all 17 Census regions, preserve geography 99 and
its explicit national-growth proxy, and make unrelated regions inert.
Never substitute national residuals for local residuals or equate 99 to
territorial authority 999. The regional size/tenure residual sums remain
61,713/429; independent national diagnostics remain 61,725/426.
- test_nz_target_references.py::test_inventory_has_exact_contract_counts_and_named_parking_reasons
- test_nz_target_references.py::test_inventory_asserts_exact_regional_residual_table
- test_nz_target_references.py::test_published_regional_totals_and_national_totals_remain_independent_diagnostics
- test_nz_target_references.py::test_region_99_is_a_separate_national_growth_proxy_and_ta_999_has_no_erp
- test_ledger_allocated_residual.py::test_explicit_proxy_preserves_output_geography
- test_ledger_allocated_residual.py::test_prefilter_keeps_every_auxiliary_selector_and_unrelated_rows_are_inert
8. Source preservation: selectors contain no observations; source facts and
raw published totals/leaf sums/discrepancies remain unchanged. Inventory
receipts explicitly classify residuals and allocated outputs as computed.
- test_ledger_allocated_residual.py::test_receipt_labels_keys_and_preserves_base_geography_and_raw_facts
- test_nz_target_references.py::test_source_discrepancies_remain_unreconciled_and_no_totals_enter_the_fit
- test_reference_profiles.py::test_observed_values_cannot_enter_effective_references
- test_reference_profiles.py::test_unselected_profiles_cannot_carry_observed_values
9. Preparation: validate household/member identities and memberships, refuse
duplicates, missing identities, orphans and empty households, and derive
usual-resident household roster counts. The 136 region-by-size indicators
partition each valid household exactly once; size 8 includes 9+ members.
Prepared columns cannot overwrite the validated roster count.
- test_calibration_columns.py::test_household_size_indicators_partition_all_regions_and_include_nine_people
- test_calibration_columns.py::test_household_roster_refuses_invalid_membership
- test_calibration_columns.py::test_prepared_columns_cannot_overwrite_a_validated_roster_count
- test_calibration_columns.py::test_all_active_calibration_bindings_enter_the_small_frame_matrix
10. Profile identity: references, intervals, preparation and problem bindings
use one selection identity and exact effective-document hashes. Preserve
full raw-resource identity while projecting effective documents to the
compiler's strict country/schema_version/hierarchy/target_references keys.
Bind the prepared column inventory, values and identity axis as well.
- test_reference_profiles.py::test_resolution_is_pure_and_binds_effective_documents
- test_reference_profiles.py::test_effective_document_projects_resource_headers_and_binds_full_base
- test_nz_target_references.py::test_full_nz_resource_resolves_directly_to_the_strict_compiler_document
- test_transport_target_kernels.py::test_profile_compilation_checks_actual_reference_document_hash
- test_transport_target_kernels.py::test_preparation_and_resolution_evidence_bind_the_problem
- test_transport_target_kernels.py::test_problem_refuses_stale_interval_or_preparation_profile
- test_transport_target_kernels.py::test_decode_resolved_surface_requires_the_resolution_receipt
- test_transport_target_kernels.py::test_decode_surface_refuses_stale_resolution_evidence
- test_transport_target_kernels.py::test_preparation_requires_its_effective_interval_companion
- test_transport_composed_graph.py::test_preflight_and_composition_use_the_same_resolved_reference_view
- test_transport_composed_graph.py::test_preflight_checks_the_selected_variant_reference_status
Additional section 6 properties and refusal contracts:
- Hypothesis compares nonnegative counts, recipient subsets, output-group
partitions and valid growth ratios with an exact Fraction oracle. It covers
zero leaves, zero residual, grouping, input reordering and unrelated-region
facts, with generated invalid cases exercising both normal selector
resolution and direct pre-resolved compilation.
Checking IDs:
test_ledger_allocated_residual.py::test_exact_rational_oracle_for_partitions_recipients_groups_and_growth
test_ledger_allocated_residual.py::test_generated_invalid_partition_rosters_refuse
- Exact typed atomic membership goes beyond cardinality: reject missing,
duplicate, substituted, string/float-coerced and out-of-partition members;
reject total-in-partition, wrong universes, changed source snapshots,
periods/vintages, negative/nonfinite facts and incomplete selectors.
Checking IDs:
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths
test_ledger_allocated_residual.py::test_declared_base_roster_must_match_its_count_and_partition
test_ledger_allocated_residual.py::test_constructor_rejects_base_roster_members_outside_partition
test_ledger_allocated_residual.py::test_partition_dimension_filters_cannot_change_the_total_universe
test_ledger_allocated_residual.py::test_only_exact_typed_category_equalities_are_removed_from_universe
test_ledger_allocated_residual.py::test_total_and_atoms_require_same_typed_shared_dimension_values
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands
test_ledger_allocated_residual.py::test_future_count_period_cannot_bypass_consumer_period_policy
test_ledger_allocated_residual.py::test_generated_invalid_partition_rosters_refuse
- Negative residuals always refuse; no clipping and no signed reconciliation.
Zero residual with zero recipient mass is an explicit identity branch;
positive residual with zero recipient mass refuses.
Checking IDs:
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity
test_ledger_allocated_residual.py::test_positive_residual_with_zero_recipient_mass_refuses
- Growth operands come as one complete pair with matching source series and
periods, positive denominator and a ratio in (0.5,2]. Cross-geography growth
requires an explicit proxy while the output keeps its base geography.
Checking IDs:
test_ledger_allocated_residual.py::test_growth_operand_refusals_on_both_paths
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands
test_ledger_allocated_residual.py::test_explicit_proxy_preserves_output_geography
- Raw size and tenure rows cannot compile unresolved or be promoted through
activation_status alone. Only a transformation satisfying the declared
prerequisite activates the row; unrelated prerequisites remain parked.
Checking IDs:
test_ledger_allocated_residual.py::test_raw_reference_profile_requirement_cannot_be_promoted_by_status
test_nz_target_references.py::test_raw_tenure_and_size_cannot_bypass_profile_resolution
test_nz_target_references.py::test_raw_tenure_refuses_even_when_all_real_operands_are_present
test_reference_profiles.py::test_transformation_must_satisfy_its_declared_profile_prerequisite
test_reference_profiles.py::test_unsatisfied_prerequisites_remain_parked_after_transformation
- One country-neutral resolver selects explicit reference-name lists, applies
disjoint transformations deterministically, refuses unknown/unavailable
selections, missing names, duplicate/overlapping transformations, unsupported
factors/interval transformations, repeated resolution and stale evidence.
Unselected-profile edits leave selected identities unchanged. The independent
aging_index dimension is reserved: central is explicitly deferred; low/high
remain unavailable until G8-r2 supplies the ageing transformations.
Checking IDs:
test_reference_profiles.py::test_unknown_or_unavailable_profiles_refuse
test_reference_profiles.py::test_invalid_transformations_refuse
test_reference_profiles.py::test_resolution_is_pure_and_binds_effective_documents
test_reference_profiles.py::test_stale_effective_documents_and_receipts_refuse
test_reference_profiles.py::test_unrelated_profiles_do_not_change_effective_identity
test_reference_profiles.py::test_disjoint_transformations_are_deterministic
test_nz_target_references.py::test_v4_changes_only_the_residual_knob_and_prior_variants_keep_their_meaning
- Shared arithmetic/profile tests use synthetic consumer declarations. Country
packages remain spec-only, with no Python entrypoints; transport retains its
country-name/runtime and float-literal guards. Country values live in spec
JSON, and no country-specific solver or frozen kernel is changed.
Checking IDs and inspection:
test_transport_target_kernels.py::test_kernels_declare_honest_country_neutral_contracts
test_transport_graph.py::test_transport_modules_import_no_country_runtime_and_name_no_country
test_transport_graph.py::test_transport_modules_carry_no_float_literal
test_transport_composed_graph.py::test_transport_python_has_no_policy_literal_or_remote_path
test_spec_only_country_packages.py::test__given_country_packages__then_no_python_files_are_present
test_spec_only_country_packages.py::test__given_country_specs__then_no_python_entrypoints_are_declared
Static diff inspection covers the frozen-file exclusion and shared modules.
Parked-target and scenario scope:
- Raw calibration counts are 64 active, 170 requiring profile resolution and
539 otherwise parked; effective MAR and small-household documents have 234
active and 539 parked references. A read-only HEAD row-payload comparison
retains the other 603 calibration rows, all 318 precal rows and all 6 holdout
rows. Families, IRD, receipt assignments, NZ Super and VP remain parked.
Checking IDs:
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
test_nz_target_references.py::test_every_parked_row_refuses_direct_compilation
test_nz_target_references.py::test_grouped_tenure_family_multiplicities_and_parked_definitions
test_nz_target_references.py::test_receipt_snapshots_are_split_and_stratified_inputs_stay_parked
test_calibration_columns.py::test_family_multiplicity_is_a_measure_while_nucleus_activation_stays_blocked
- V1/V2 keep low/high ageing; V3 keeps beneficiary assignment; V4 changes only
residual allocation to small_households. Gates and reporting include V4.
Checking IDs:
test_nz_target_references.py::test_v4_changes_only_the_residual_knob_and_prior_variants_keep_their_meaning
test_nz_spec_package.py::TestScenarios::test_committed_grid_satisfies_the_scenario_contract
Feed, regeneration, disclosures and golden:
- Keep the Chronicle 8f4cfd573c0d6f580d9c51cd67e8f449a42ed174 feed pin. Recompute
the design's exact regional residual table from its Census rows. QES/PREFU
rows stay unused. Regenerate with tools/generate_nz_target_references.py and
verify --check against NZ_CHRONICLE_ARTIFACT.
Checking IDs:
test_nz_target_references.py::test_generation_reproduces_committed_resources_with_exact_feed_identity
test_nz_target_references.py::test_inventory_asserts_exact_regional_residual_table
test_nz_target_references.py::test_changed_feed_identity_refuses_authoring_before_reference_compilation
test_transport_target_kernels.py::test_target_kernels_enforce_full_feed_pin
- Disclose MAR, locally computed residuals, the national/regional differences,
proportional tenure including family trusts, V4's recipients, fractional
targets, one ERP bridge and the separate region-99 proxy. Preserve raw
diagnostics and per-region/profile receipts with tolerance and provenance.
Checking IDs and inspection:
test_nz_target_references.py::test_source_discrepancies_remain_unreconciled_and_no_totals_enter_the_fit
test_nz_target_references.py::test_published_regional_totals_and_national_totals_remain_independent_diagnostics
Static inspection of generator disclosure, reference_inventory.json,
docs/nz-calibration-targets.md and docs/nz-take-up-engine-plan.md.
- Regenerate nz_country_spec.json with
canonical_json_bytes(_loaded_spec_summary("nz")). Only fingerprint,
resource_hashes and resources move: eight existing resource hashes change,
reference_profiles.json adds one hash and one resource-list entry, and the
fingerprint becomes d970b6e900b7f5d455a86158718703444ac91c15d49b2203720fc2bdf2baba7d.
Checking ID:
test_country_spec.py::TestGoldenCountrySpecs::test_loaded_spec_matches_the_golden_file_byte_for_byte[nz]
Reviewer mutants: all 18 killed; 25 expected failed checks and 41 passing
controls across final mutant runs. Each mutation was restored. Actual red IDs:
- wrong_recipients_23: 1 failed, 1 passed in 25.50s
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
- allocation_denominator_total: 2 failed, 1 passed in 1.42s
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[False]
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[True]
- small_denominator_all_leaves: 1 failed, 1 passed in 1.45s
test_ledger_allocated_residual.py::test_sensitivity_exact_recipients_and_increment_ratio
- drop_tenure_trust_3: 1 failed, 1 passed in 1.05s
test_ledger_allocated_residual.py::test_grouping_preserves_the_third_atomic_member
- national_residual_per_region: 1 failed, 1 passed in 6.03s
test_nz_target_references.py::test_generation_reproduces_committed_resources_with_exact_feed_identity
- total_in_partition: 1 failed, 1 passed in 0.21s
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands[total_in_partition]
- duplicate_replaces_missing_atom: 1 failed, 1 passed in 0.18s
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths[substituted-True]
- coerce_member_type: 1 failed, 1 passed in 0.75s
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths[float-True]
- clip_negative_residual: 2 failed, 1 passed in 0.76s
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping[False]
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping[True]
- zero_residual_divide_by_zero: 2 failed, 1 passed in 2.61s
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity[False]
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity[True]
- erp_applied_twice: 1 failed, 2 passed in 1.34s
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[True]
- drop_region_99: 1 failed, 1 passed in 0.86s
test_nz_target_references.py::test_inventory_has_exact_contract_counts_and_named_parking_reasons
- region_99_relocated_to_NZ: 1 failed, 1 passed in 2.71s
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
- prune_auxiliary_selectors: 1 failed, 1 passed in 1.38s
test_ledger_allocated_residual.py::test_prefilter_keeps_every_auxiliary_selector_and_unrelated_rows_are_inert
- raw_tenure_bypasses_profile: 1 failed, 1 passed in 5.62s
test_nz_target_references.py::test_raw_tenure_refuses_even_when_all_real_operands_are_present
- stale_interval_or_preparation_profile: 1 failed, 1 passed in 5.13s
test_transport_target_kernels.py::test_problem_refuses_stale_interval_or_preparation_profile[selection]
- observed_value_in_reference: 5 failed, 23 passed in 1.18s
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[value]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[values]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[observed]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[observed_value]
test_reference_profiles.py::test_unselected_profiles_cannot_carry_observed_values
- size_8_means_exactly_8: 1 failed, 1 passed in 3.10s
test_calibration_columns.py::test_household_size_indicators_partition_all_regions_and_include_nine_people
Final execution evidence: 2,470 passed across 16 targeted files, with five
optional UK feed/authentication checks skipped (CHRONICLE_UK_FACTS unavailable).
- test_calibration_columns.py: 39 passed
- test_country_spec.py: 136 passed
- test_ledger_allocated_residual.py: 89 passed
- test_ledger_grouped_roll_forward.py: 52 passed
- test_ledger_targets.py: 436 passed
- test_nz_spec_package.py: 1192 passed
- test_nz_target_references.py: 46 passed
- test_reference_profiles.py: 28 passed
- test_spec_engine_country_bundles.py: 21 passed
- test_spec_only_country_packages.py: 18 passed
- test_transport_composed_graph.py: 145 passed
- test_transport_gate_bindings.py: 126 passed
- test_transport_graph.py: 15 passed
- test_transport_target_kernels.py: 33 passed
- test_uk_ledger_targets.py: 64 passed
- test_uk_target_references.py: 30 passed, 5 skipped
Generator --check: exit 0 against Chronicle 8f4cfd573c0d6f580d9c51cd67e8f449a42ed174.
Ruff check: all checks passed on 18 changed Python files.
Ruff format --check: 18 files already formatted.
tools/ci_test_plan.py verify: verification=ok.
git diff --check: exit 0.
Final scope audit: 31 implementation files;
no frozen-source edits; zero float literals
in the 19 transport Python modules. Golden resource hashes all match.
HEAD row audit: exactly 136 size + 34 tenure rows changed; other 603
calibration rows, all 318 precal rows and all 6 holdout rows unchanged.
The exact legacy NZ resource-list assertion now includes reference_profiles.json
(test_spec_engine_country_bundles.py:237; corrected full run 21 passed).
The spec-only guard admits canonical Ledger recipient keys only in exact
typed partition rosters pinned by member selectors; 18 passed including
two positive and eight refusal cases for this narrow data-field support.
Corrected validation history is retained: initial Hypothesis too_slow health
check (1 failed, 66 passed) was corrected without dropping any examples or
assertions; final allocation file passed 89. Initial resource-list assertion
was 1 failed, 20 passed, followed by 21 passed. The duplicate-atom mutant
initially survived because its count change triggered a separate guard;
the fixture now preserves counts, its rerun is red, and the full 89 pass.
Changelog: changelog.d/nz-census-residual-profiles.added.md.
Production NZ graph assembly and B5 ageing remain separate; one resolver
API is the extension point.
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reported_cell_support_target_a gate now requires ten scenarios (S0-S5, V1-V4), so its tracked-target flags number 43 cells x 10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address the #1375 review (GPT-6.1 Sol, REQUEST_CHANGES at 12b590a): - Allocation fact resolution deduplicated by aggregate_fact_key alone, so a growth fact reusing an atom's key could replace a validated atom on the direct compile path (186.56 became 104.88). It now keeps a fact reused across operand roles but refuses a different fact sharing the key. The review's counterexample runs on both compile paths; with the check disabled the direct case fails. - The commutation property now scales the Census total independently as q*T rather than from scaled leaves. Scaling commutes with allocation in exact arithmetic; in floating point a zero residual can round to either sign, and the negative case still refuses without clipping. Two explicit examples (counts 1, 2 at q=0.55 and 0.58) pin both signs. - The low-level activation guard documents that resolution markers are trusted declarations there; receipt validation and transport authenticate a resolved document. - The NZ plan's status no longer says the gates await D1; it names the d1376 thresholds and says production fit evidence does not exist yet. Tests (-n 0, one file per run): test_ledger_allocated_residual.py 91 passed; test_ledger_targets.py 436; test_nz_target_references.py 46; test_reference_profiles.py 28; test_transport_target_kernels.py 33; test_country_spec.py 136; test_uk_ledger_targets.py 64. ruff check and format clean; git diff --check clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The #1375 delta review (GPT-6.1 Sol, REQUEST_CHANGES at 8d2d7a0) found a second way past 8d2d7a0's check. Atoms whose keys matched a base fact were dropped before the content comparison, so a base selector pinned to a different record that reused atom 1's key (value 66, not 72) displaced the validated atom on the direct compile path: 76.8 became 72.33. Every base, atom, total and growth fact now enters the content-aware comparison, so a distinct fact sharing any selected key refuses, while a genuine same-fact reuse across roles still compiles. The reviewer's counterexample is a test on both compile paths; restoring the old atom filter turns its direct case red, and the four genuine-reuse controls still pass. Tests (-n 0, one file per run): test_ledger_allocated_residual.py 93 passed; test_ledger_targets.py 436; test_nz_target_references.py 46. ruff check and format clean; git diff --check clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 24, 2026
#1393 added atomic_geography_support.json and changed country_package.json, geography_spine.json and spec/sources.yaml, so the NZ golden conflicted. The golden was regenerated from the merged tree with the test's own summary function. Keys only this branch changed keep its values, keys only main changed take main's, and the fingerprint, resource list and country_package.json hash are the merged tree's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 25, 2026
#1375 merged main (#1393), which added atomic_geography_support.json and changed country_package.json, so the NZ golden conflicted. The golden was regenerated from the merged tree with the test's own summary function. Keys only one side changed keep that side's values; the fingerprint, the resource list and the country_package.json hash, which both sides changed, are the merged tree's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 26, 2026
#1382's fix moved the factor-currency check into prepare_transport_build in build/transport/cli.py, after the resume check and before activation validation. This carries that change, and #1375's merge of main beneath it, up the NZ stack. The merged cli.py is c4ddcb4's blob; no #1394 commit touches it. The NZ golden conflicted: both sides changed the fingerprint, the resource list and the country_package.json hash. It was regenerated from the merged tree with the test's own summary function. Keys only one side changed keep that side's values; the three both-changed keys are the merged tree's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 26, 2026
The region-99 support note in the generator, calibration_bindings.json and the calibration-targets doc said G8-m2 (#1393) was not in this stack's base. The merge of #1394's head brought in #1382's fix4 head, which carries #1375's merge of main, so #1393 (4e31e42) is now an ancestor. Drop the dependency clause; the support statement itself is unchanged. calibration_bindings.json is regenerated with the generator, and the NZ golden follows its hash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 26, 2026
MaxGhenis
marked this pull request as ready for review
October 29, 2026 13:28
Contributor
Author
|
Merged by the NZ hub (session local_e407a527) at 6af97bf with --merge. Gates: |
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
main now holds #1375 as 6af97bf/846b48a9, so this branch had two merge bases with main (fddbc70 and 840d933). Git merges them cleanly, but GitHub marked the PR conflicting and ran no CI. This merge gives one merge base; its tree equals `git merge-tree --write-tree origin/main b36c702`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
main now holds #1375 as 6af97bf/846b48a9, so this branch had two merge bases with main (fddbc70 and 840d933). Git merges them cleanly, but GitHub marked the PR conflicting and ran no CI. This merge gives one merge base; its tree equals `git merge-tree --write-tree origin/main 6d1252a`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
main now holds #1375 as 6af97bf/846b48a9, so this branch had two merge bases with main (fddbc70 and 840d933). Git merges them cleanly, but GitHub marked the PR conflicting and ran no CI. This merge gives one merge base; its tree equals `git merge-tree --write-tree origin/main e35612f`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
main now holds #1375 as 6af97bf/846b48a9, so this branch had two merge bases with main (fddbc70 and 840d933). Git merges them cleanly, but GitHub marked the PR conflicting and ran no CI. This merge gives one merge base; its tree equals `git merge-tree --write-tree origin/main d1b513c`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
main now holds #1375 as 6af97bf/846b48a9, so this branch had two merge bases with main (fddbc70 and 840d933). Git merges them cleanly, but GitHub marked the PR conflicting and ran no CI. This merge gives one merge base; its tree equals `git merge-tree --write-tree origin/main 8853469`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implement d1886 Census household-size and tenure allocation through the shared
allocated_residual_by_ratio operation and one resolve_reference_profiles API.
Keep regional residuals local, preserve independent national diagnostics, add
MAR and small-household profiles plus V4, and prepare all 136 size indicators.
Verification below identifies every invariant and its checking tests. Final
execution counts and named-mutant evidence follow.
All test IDs below are relative to:
packages/microcosm-build/tests/engine_free/shared/
Design section 6 invariants and their checks:
Regional closure: both size profiles and allocated tenure close to each
region's published Census household total, then that total times its ERP
ratio, using fsum with rel_tol=1e-12 and abs_tol=1e-7. Retain fractional
targets and each region's own computed residual.
MAR shares: allocated cross-products preserve stated shares, including
zero-valued leaves.
Sensitivity recipients: only stated sizes 1 and 2 receive additions, in
their stated proportions; total size counts stay fixed. Tenure remains
proportional across all three source atoms in both residual profiles.
Sensitivity comparison: against MAR, sizes 3-8 lose their MAR additions;
against stated counts under the same ERP scaling, they remain unchanged.
ERP commutation: A(qx,qT,E)=qA(x,T,E) in exact arithmetic; apply the paired
growth ratio once. In floating point an independently scaled total can leave
a rounding residual of either sign; a negative one still refuses, never
clips (explicit examples at counts 1, 2 and q=0.55, 0.58). The
exact-rational oracle also checks generated output-group partitions.
Grouping: allocating tenure atoms and then grouping source categories 1+3
equals allocating the owned group directly; category 3 stays in the exact
atomic partition. Facts reused in growth roles are counted once per role.
Region separation: keep all 17 Census regions, preserve geography 99 and
its explicit national-growth proxy, and make unrelated regions inert.
Never substitute national residuals for local residuals or equate 99 to
territorial authority 999. The regional size/tenure residual sums remain
61,713/429; independent national diagnostics remain 61,725/426.
Source preservation: selectors contain no observations; source facts and
raw published totals/leaf sums/discrepancies remain unchanged. Inventory
receipts explicitly classify residuals and allocated outputs as computed.
Preparation: validate household/member identities and memberships, refuse
duplicates, missing identities, orphans and empty households, and derive
usual-resident household roster counts. The 136 region-by-size indicators
partition each valid household exactly once; size 8 includes 9+ members.
Prepared columns cannot overwrite the validated roster count.
Profile identity: references, intervals, preparation and problem bindings
use one selection identity and exact effective-document hashes. Preserve
full raw-resource identity while projecting effective documents to the
compiler's strict country/schema_version/hierarchy/target_references keys.
Bind the prepared column inventory, values and identity axis as well.
Additional section 6 properties and refusal contracts:
Hypothesis compares nonnegative counts, recipient subsets, output-group
partitions and valid growth ratios with an exact Fraction oracle. It covers
zero leaves, zero residual, grouping, input reordering and unrelated-region
facts, with generated invalid cases exercising both normal selector
resolution and direct pre-resolved compilation.
Checking IDs:
test_ledger_allocated_residual.py::test_exact_rational_oracle_for_partitions_recipients_groups_and_growth
test_ledger_allocated_residual.py::test_generated_invalid_partition_rosters_refuse
Exact typed atomic membership goes beyond cardinality: reject missing,
duplicate, substituted, string/float-coerced and out-of-partition members;
reject total-in-partition, wrong universes, changed source snapshots,
periods/vintages, negative/nonfinite facts and incomplete selectors.
Checking IDs:
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths
test_ledger_allocated_residual.py::test_declared_base_roster_must_match_its_count_and_partition
test_ledger_allocated_residual.py::test_constructor_rejects_base_roster_members_outside_partition
test_ledger_allocated_residual.py::test_partition_dimension_filters_cannot_change_the_total_universe
test_ledger_allocated_residual.py::test_only_exact_typed_category_equalities_are_removed_from_universe
test_ledger_allocated_residual.py::test_total_and_atoms_require_same_typed_shared_dimension_values
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands
test_ledger_allocated_residual.py::test_future_count_period_cannot_bypass_consumer_period_policy
test_ledger_allocated_residual.py::test_generated_invalid_partition_rosters_refuse
Negative residuals always refuse; no clipping and no signed reconciliation.
Zero residual with zero recipient mass is an explicit identity branch;
positive residual with zero recipient mass refuses.
Checking IDs:
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity
test_ledger_allocated_residual.py::test_positive_residual_with_zero_recipient_mass_refuses
Growth operands come as one complete pair with matching source series and
periods, positive denominator and a ratio in (0.5,2]. Cross-geography growth
requires an explicit proxy while the output keeps its base geography.
Checking IDs:
test_ledger_allocated_residual.py::test_growth_operand_refusals_on_both_paths
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands
test_ledger_allocated_residual.py::test_explicit_proxy_preserves_output_geography
Raw size and tenure rows cannot compile unresolved or be promoted through
activation_status alone. Only a transformation satisfying the declared
prerequisite activates the row; unrelated prerequisites remain parked.
Checking IDs:
test_ledger_allocated_residual.py::test_raw_reference_profile_requirement_cannot_be_promoted_by_status
test_nz_target_references.py::test_raw_tenure_and_size_cannot_bypass_profile_resolution
test_nz_target_references.py::test_raw_tenure_refuses_even_when_all_real_operands_are_present
test_reference_profiles.py::test_transformation_must_satisfy_its_declared_profile_prerequisite
test_reference_profiles.py::test_unsatisfied_prerequisites_remain_parked_after_transformation
One country-neutral resolver selects explicit reference-name lists, applies
disjoint transformations deterministically, refuses unknown/unavailable
selections, missing names, duplicate/overlapping transformations, unsupported
factors/interval transformations, repeated resolution and stale evidence.
Unselected-profile edits leave selected identities unchanged. The independent
aging_index dimension is reserved: central is explicitly deferred; low/high
remain unavailable until G8-r2 supplies the ageing transformations.
Checking IDs:
test_reference_profiles.py::test_unknown_or_unavailable_profiles_refuse
test_reference_profiles.py::test_invalid_transformations_refuse
test_reference_profiles.py::test_resolution_is_pure_and_binds_effective_documents
test_reference_profiles.py::test_stale_effective_documents_and_receipts_refuse
test_reference_profiles.py::test_unrelated_profiles_do_not_change_effective_identity
test_reference_profiles.py::test_disjoint_transformations_are_deterministic
test_nz_target_references.py::test_v4_changes_only_the_residual_knob_and_prior_variants_keep_their_meaning
Shared arithmetic/profile tests use synthetic consumer declarations. Country
packages remain spec-only, with no Python entrypoints; transport retains its
country-name/runtime and float-literal guards. Country values live in spec
JSON, and no country-specific solver or frozen kernel is changed.
Checking IDs and inspection:
test_transport_target_kernels.py::test_kernels_declare_honest_country_neutral_contracts
test_transport_graph.py::test_transport_modules_import_no_country_runtime_and_name_no_country
test_transport_graph.py::test_transport_modules_carry_no_float_literal
test_transport_composed_graph.py::test_transport_python_has_no_policy_literal_or_remote_path
test_spec_only_country_packages.py::test__given_country_packages__then_no_python_files_are_present
test_spec_only_country_packages.py::test__given_country_specs__then_no_python_entrypoints_are_declared
Static diff inspection covers the frozen-file exclusion and shared modules.
Parked-target and scenario scope:
Raw calibration counts are 64 active, 170 requiring profile resolution and
539 otherwise parked; effective MAR and small-household documents have 234
active and 539 parked references. A read-only HEAD row-payload comparison
retains the other 603 calibration rows, all 318 precal rows and all 6 holdout
rows. Families, IRD, receipt assignments, NZ Super and VP remain parked.
Checking IDs:
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
test_nz_target_references.py::test_every_parked_row_refuses_direct_compilation
test_nz_target_references.py::test_grouped_tenure_family_multiplicities_and_parked_definitions
test_nz_target_references.py::test_receipt_snapshots_are_split_and_stratified_inputs_stay_parked
test_calibration_columns.py::test_family_multiplicity_is_a_measure_while_nucleus_activation_stays_blocked
V1/V2 keep low/high ageing; V3 keeps beneficiary assignment; V4 changes only
residual allocation to small_households. Gates and reporting include V4.
Checking IDs:
test_nz_target_references.py::test_v4_changes_only_the_residual_knob_and_prior_variants_keep_their_meaning
test_nz_spec_package.py::TestScenarios::test_committed_grid_satisfies_the_scenario_contract
Feed, regeneration, disclosures and golden:
Keep the Chronicle 8f4cfd573c0d6f580d9c51cd67e8f449a42ed174 feed pin. Recompute
the design's exact regional residual table from its Census rows. QES/PREFU
rows stay unused. Regenerate with tools/generate_nz_target_references.py and
verify --check against NZ_CHRONICLE_ARTIFACT.
Checking IDs:
test_nz_target_references.py::test_generation_reproduces_committed_resources_with_exact_feed_identity
test_nz_target_references.py::test_inventory_asserts_exact_regional_residual_table
test_nz_target_references.py::test_changed_feed_identity_refuses_authoring_before_reference_compilation
test_transport_target_kernels.py::test_target_kernels_enforce_full_feed_pin
Disclose MAR, locally computed residuals, the national/regional differences,
proportional tenure including family trusts, V4's recipients, fractional
targets, one ERP bridge and the separate region-99 proxy. Preserve raw
diagnostics and per-region/profile receipts with tolerance and provenance.
Checking IDs and inspection:
test_nz_target_references.py::test_source_discrepancies_remain_unreconciled_and_no_totals_enter_the_fit
test_nz_target_references.py::test_published_regional_totals_and_national_totals_remain_independent_diagnostics
Static inspection of generator disclosure, reference_inventory.json,
docs/nz-calibration-targets.md and docs/nz-take-up-engine-plan.md.
Regenerate nz_country_spec.json with
canonical_json_bytes(_loaded_spec_summary("nz")). Only fingerprint,
resource_hashes and resources move: eight existing resource hashes change,
reference_profiles.json adds one hash and one resource-list entry, and the
fingerprint becomes d970b6e900b7f5d455a86158718703444ac91c15d49b2203720fc2bdf2baba7d.
Checking ID:
test_country_spec.py::TestGoldenCountrySpecs::test_loaded_spec_matches_the_golden_file_byte_for_byte[nz]
Build-lane evidence below is lane-reported: its logs are kept in the NZ hub's
job archive, not in this checkout. The independent review section further
down re-ran the current behaviour separately.
Reviewer mutants: all 18 killed; 25 expected failed checks and 41 passing
controls across final mutant runs. Each mutation was restored. Actual red IDs:
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[False]
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[True]
test_ledger_allocated_residual.py::test_sensitivity_exact_recipients_and_increment_ratio
test_ledger_allocated_residual.py::test_grouping_preserves_the_third_atomic_member
test_nz_target_references.py::test_generation_reproduces_committed_resources_with_exact_feed_identity
test_ledger_allocated_residual.py::test_reference_contract_refuses_unpaired_or_malformed_operands[total_in_partition]
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths[substituted-True]
test_ledger_allocated_residual.py::test_refuses_invalid_atomic_partitions_on_both_compilation_paths[float-True]
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping[False]
test_ledger_allocated_residual.py::test_negative_residual_is_refused_without_clipping[True]
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity[False]
test_ledger_allocated_residual.py::test_zero_residual_with_zero_recipient_mass_is_identity[True]
test_ledger_allocated_residual.py::test_mar_closes_preserves_shares_zero_leaves_and_applies_growth_once[True]
test_nz_target_references.py::test_inventory_has_exact_contract_counts_and_named_parking_reasons
test_nz_target_references.py::test_residual_profiles_have_exact_recipient_rosters_and_preserve_other_targets
test_ledger_allocated_residual.py::test_prefilter_keeps_every_auxiliary_selector_and_unrelated_rows_are_inert
test_nz_target_references.py::test_raw_tenure_refuses_even_when_all_real_operands_are_present
test_transport_target_kernels.py::test_problem_refuses_stale_interval_or_preparation_profile[selection]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[value]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[values]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[observed]
test_reference_profiles.py::test_observed_values_cannot_enter_effective_references[observed_value]
test_reference_profiles.py::test_unselected_profiles_cannot_carry_observed_values
test_calibration_columns.py::test_household_size_indicators_partition_all_regions_and_include_nine_people
Final execution evidence: 2,470 passed across 16 targeted files, with five
optional UK feed/authentication checks skipped (CHRONICLE_UK_FACTS unavailable).
Generator --check: exit 0 against Chronicle 8f4cfd573c0d6f580d9c51cd67e8f449a42ed174.
Ruff check: all checks passed on 18 changed Python files.
Ruff format --check: 18 files already formatted.
tools/ci_test_plan.py verify: verification=ok.
git diff --check: exit 0.
Final scope audit: 31 implementation files;
no frozen-source edits; zero float literals
in the 19 transport Python modules. Golden resource hashes all match.
HEAD row audit: exactly 136 size + 34 tenure rows changed; other 603
calibration rows, all 318 precal rows and all 6 holdout rows unchanged.
The exact legacy NZ resource-list assertion now includes reference_profiles.json
(test_spec_engine_country_bundles.py:237; corrected full run 21 passed).
The spec-only guard admits canonical Ledger recipient keys only in exact
typed partition rosters pinned by member selectors; 18 passed including
two positive and eight refusal cases for this narrow data-field support.
Corrected validation history is retained: initial Hypothesis too_slow health
check (1 failed, 66 passed) was corrected without dropping any examples or
assertions; final allocation file passed 89. Initial resource-list assertion
was 1 failed, 20 passed, followed by 21 passed. The duplicate-atom mutant
initially survived because its count change triggered a separate guard;
the fixture now preserves counts, its rerun is red, and the full 89 pass.
Changelog: changelog.d/nz-census-residual-profiles.added.md.
Production NZ graph assembly and B5 ageing remain separate; one resolver
API is the extension point.
Independent review
GPT-6.1 Sol reviewed 12b590a (REQUEST_CHANGES), re-running every touched
test file at -n 0: 2,470 passed, 5 skipped. Under targeted regressions,
187 expected failures and 33 passing controls. It also ran an independent
source audit of 340 transformations and 68 regional receipts against
Chronicle 8f4cfd57.
Its findings and how 8d2d7a0 addresses them:
an atom's key could replace it on the direct compile path. Now refused;
the counterexample is a test on both paths and goes red without the fix.
scales the total independently, and the claim above is qualified for
floating point.
trusted-declaration boundary; receipt validation and transport
authenticate resolved documents.
A delta review of 8d2d7a0 (REQUEST_CHANGES) confirmed findings 1–4 closed
(603 tests passed; 4 expected mutant failures) and found a second collision:
atoms whose keys matched a base fact were dropped before the content
comparison, so a base selector pinned to a different record that reused an
atom's key displaced it on the direct path (76.8 became 72.33). 10ee4a5
puts every base, atom, total and growth fact through the content-aware
comparison; the counterexample is a test on both paths, red on the direct
path without the fix, and genuine same-fact reuse still compiles. A second
delta review of 10ee4a5 returned APPROVE_WITH_NITS. It ran a 379-case
collision matrix across every role pair and both compile paths: every
distinct-fact collision refuses, and genuine role reuse and unselected
colliding facts compile unchanged. All 575 tests in the three touched
files pass, and the new test fails under mutation. Its one nit: the
external clearances can't be proved from this checkout. They are labelled
hub-reported above, and their receipts stay with the merge gate.
After that review, main was merged in at 840d933 to take #1393 (NZ joint
geography). Only the NZ golden conflicted. It was regenerated from the merged
tree with the test's own summary function: keys only this branch changed keep
their values, keys only main changed take main's, and the fingerprint,
resource list and country_package.json hash are the merged tree's. CI reruns
on the merge, and all ten checks pass at 840d933.
A merge delta review of 840d933 (GPT-6.1 Sol) returned APPROVE_WITH_NITS:
resources, no duplicate keys, and both sides' bundle-test assertions
kept.
byte-identical.
production compiles, US county parents, compatibility recertification and
ESI. They give identical outputs. The UK, US and BE package fingerprints
equal main's.
atomic geography rows preserve every TA total, and both residual profiles
compile 234 active targets.
ledger_targets.pyis still the onlymember this PR changes. Six UK kernel hashes move. That is why the merge
waits for the UK hold.
Its nits are no source change: keep the external clearance receipts, honor
the hold, and rerun the local regression files a fleet disk hold cut short.
CI's full suite passed on the same head.
The hub reran those files at 840d933 on 2026-10-25, one at a time at
-n 0. All 15 passed (2,216 tests). With the review's owntest_country_spec.py(136), all 16 requested files pass locally.test_nz_joint_geography.pyskips its 11 pinned-source replays withoutstaged sources. With
NZ_AS_AREA_SOURCESandNZ_JOINT_GEOGRAPHY_SOURCESset, the file passes 33 of 33.present: 5 in
test_uk_target_references.pyand 1 intest_uk_council_tax_targets.py.Landing (2026-10-29)
main, so each of those PRs runs CI on its own cumulative tree.main(fddbc70) into this branch as 6af97bf. Merging 6af97bf intomaingives the same tree as merging the reviewed head 840d933 (git merge-tree --write-tree), so the review covers the tree that lands.git diff --name-only 12b590a1 6af97bfestill lists no transport source file.gh pr checksexit 0): engine-free, engine-uk and engine-us on Python 3.13 and 3.14, integration-uk, lint, select-countries and wheels.dump_be.pyand its three BE suites (test_spec_engine_country_bundles.py,test_country_spec.py,test_spec_only_country_packages.py) at this head, alone and merged with Belgium's open Rewrite the Belgian country package for donor transport #1369 (dc157a7). The BE dump matchesmain's byte for byte; with Rewrite the Belgian country package for donor transport #1369 merged in, it matchesmainplus Rewrite the Belgian country package for donor transport #1369. The BE golden comparison holds in both, and all three suites pass with Rewrite the Belgian country package for donor transport #1369 merged in.Invariants, acceptance and tests
See commit messages.
Shared files and owners
packages/microcosm-build/src/microcosm/build/transport/(5 files: new country-neutralcalibration.prepare@1kernel, reference-profile view in compose/entitlement, optionalreference_resolutionon target surfaces): shared with the Belgium session. Hub-reported: the Belgium hub cleared them at 12b590a on 2026-10-23 (S2-d check-in rule; cross-session record held by the NZ hub, outside this repo). Checkable here:git diff --name-only 12b590a1..HEADlists no transport source file.ledger_targets.py,calibration_columns.py, newreference_profiles.py: country-neutral shared modules. UK/US/BE specs declare noreference_profilesresource, so their reference views are unchanged; hub-reported: the UK hub ran its real-feed checks and returned SAFE on 2026-10-23 (its review is held by the UK hub, outside this repo). Merge waited until 2026-10-29 12:00 UTC at the UK hub's request:ledger_targets.pyis in the UK compile-module hash list, so a change recomputes the cached UK graph during the UK Budget hold. That hold has ended.Part of the Microcosm NZ v0 graph plan (Max ruling d962). Built by the NZ hub on a Subfleet build lane (model named in the commit trailer); the hub verified scope (no frozen graph files, uk_runtime/us_runtime or frame/kernels.py touched) before committing.
🤖 Generated with Claude Code