Repository navigation
Add feed-derived NZ reference ageing factors (G8-r2a) - #1382
Merged
Merged
Conversation
G8-r2a. Adds the projected_period_average_ratio@1 factor operation (reference_factors.py) and wires its selected factors into the shared reference-profile resolver, composition preflight and target compilation. - Operands are the authenticated Ledger JSON tokens (LexicalFloat keeps the token on a slotted float subclass; integers stay int). Factors are exact rationals with a certified root enclosure, rounded once (half-even) to six decimals and carried as p/10**6. - reference_aging.json declares the six operational factors (IRD TY2024 low/central/high 1.115056/1.117109/1.119158; P1 1.026690/1.028580/1.030467) and the 1.086069 diagnostic, each with a receipt bound to the seven-field Chronicle feed identity. Factors need re-declaration after the September QES observation (validity ends 2026-11-03). - The resolver takes factor_context; selected factors enter a version-2 selection identity, money companions take one common linear_combination weight, counts are unchanged, and non-empty interval rosters refuse until r2b. - Composition checks selected factors against the declared feed pin; compilation replays every selected factor against the loaded artifact and refuses a self-consistent forged factor or an unauthenticated source commit. reference_factors joins _COMPILE_MODULES. - S0-S5 and V3 use the central factor, V1 low, V2 high, V4 central plus the small-household residual. All 474 IRD rows stay parked on B4 measurement. Tests: 24 engine-free files, 2,832 passed and 5 skipped (UK feed not configured), one file per run. Eleven mutants killed, each by a named test. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes the #1382 review (Sol r1) and the UK hub's loader notes. - Factor application: each transformed row's role (money or count) now comes from the selected profile's companion roster, not the rehashable action label. Money rows must carry exactly the verified singleton linear_combination; count rows keep their original operation, operands and kind. Both reviewer tampering cases refuse at the resolver and at compilation. - Lexical floats: load_ledger_consumer_artifact(lexical_floats=False) by default returns builtin floats again. Only compile replay with selected factors and the NZ ageing generator opt in; a static test pins those call sites. - _strict_scalar_equal treats LexicalFloat as float; bool, int and float stay distinct. - Oracle: exact roots return a zero-width enclosure and ambiguous bounds are refined; the (32, 1, 0, 2, 4) tie is an explicit example. - RuleSpec scan: only the seven Chronicle identity fields are exempt. - Factor schedules: frequency 1-12 and digits 0-18, so exact receipts stay serializable. Tests: 24 engine-free files, 3,024 passed and 5 skipped (UK feed not configured), one file per run; six new mutants killed. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1d5fff4 embedded the selected declarations and the whole base reference document in every v2 resolution receipt, which travels in each compile and prepare node's params: the NZ default receipt grew to 4.07 MB canonical. Those documents were trusted only through hashes in the selection identity, so a compact record bound the same way is as strong. - v2 receipts carry factor_companions: per roster name, its role, factor, profile and source value semantics (474 names, 392 KB). factor_companions_sha256 and transformed_names join the v2 selection identity. - Roles still come from the bound record, never the action label; money operands and count semantics are checked as before. - The NZ default receipt is now 1.67 MB canonical, capped by a test at 2.6 MB. v1 receipt bytes are unchanged and pinned. Tests: 15 files, 2,508 passed and 5 skipped; three mutants killed. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Belgium's Sol review of 4f77038 found two latent regressions in validate_reference_resolution: a receipt without transformed_names raised KeyError, and an unnamed unresolved row raised KeyError where base accepted it. transformed_names is now checked as a list of strings, and roster-name bookkeeping runs only with factor evidence. The docstring states the trust boundary: checks assume a trusted selection identity; selected factors are anchored by replay against the authenticated feed. The resolver property test suppresses only too_slow: an integer draw took 31 s under host load in review. Tests: test_legacy_receipt_without_transformed_names_refuses_as_a_value_error and test_unnamed_unresolved_rows_still_validate_without_factor_evidence; each goes red (KeyError) with its fix reverted. test_reference_profiles.py 74 passed, test_transport_target_kernels.py 52, test_nz_target_references.py 50. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Factor validation compared date.today() with each declaration's validity window. Every NZ factor declares valid_until 2026-11-03, so main's CI would have failed for every PR from 2026-11-04. Validation is now a pure function of declaration and feed: declared_on <= as_of and valid_from <= as_of <= valid_until. require_current_factors(selected, *, today) has no default for today. The transport CLI calls it once, for --resume auto|forbid, with today's UTC date, before preparation can run CREATE. --resume require replays a stored graph and is exempt. No kernel reads the clock. The CLI checks every factor the default and scenario profile views select, through compose.reference_profile_views, the walk activation now shares, so a spec without scenarios checks its default view alone (Belgium's review). An end-to-end test replays a warm store under --resume require after the factor expires: rc 0, no kernel runs, and the stored export's bytes unchanged. From the d28817f review (findings 1-4): resolution transformations must map names to objects, resolved and factor rows need nonempty names, and a v2 unresolved duplicate companion refuses. Unresolved unnamed v1 rows still validate. The expired-factor mutation in test_reference_factors now expires before its as_of, so the retained as_of check refuses it. Tests (hub, one file per process, normal priority): 15 files, 2,077 passed and 5 skipped (the UK feed cases). Clock runs at 2026-11-05: test_nz_reference_aging 18 and test_reference_profiles 97 passed. Whole CLI test file with the CLI clock at 2100-01-01: 163 passed. Mutants killed, 8 of 8: the clock back in validation, the currency check on replay, no currency check, run entry walking other views than activation, the local date, and review mutants M3, M6 and M7. Receipts, effective intervals and factor contexts are byte-identical to d28817f (8 payloads, re-checked on this tree). Co-Authored-By: GPT-6.1 Sol <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 24, 2026
…a factor prepare_transport_build now runs the run-entry currency check itself, after it validates the resume policy and before activation. Every library caller that starts a new run (auto or forbid) therefore refuses an expired selected factor, not only the CLI; require still reaches stored work. main drops its own call, and execute_transport_graph stays clock-free: its docstring says a caller that composes a graph itself owns the check. New tests cover library callers under auto and forbid for the default and scenario views, the require exemption, and resume validation before the currency check. The warm-store replay test now compiles a factor-bound target surface. A test-local targets.compile@1 node on nz.open reads the factor references and the pinned factor feed, and is a CLI terminal endpoint, so the warm run executes it. The test spies the factor replay and checks it ran once against the facts of the pinned feed. After the factor expires, require runs no kernel or replay, keeps the export bytes and serves the compiler from the store under the same key; auto refuses on the factor before preparation work. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#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
#1394 now carries #1382's head (c4ddcb4), whose fix moved the factor-currency check into prepare_transport_build in build/transport/cli.py. The merged cli.py is c4ddcb4's blob; no #1395 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
#1394 now carries #1382's head (c4ddcb4), whose fix moved the factor-currency check into prepare_transport_build in build/transport/cli.py. The merged cli.py is c4ddcb4's blob; no #1398 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
#1395 now carries #1382's head (c4ddcb4), whose fix moved the factor-currency check into prepare_transport_build in build/transport/cli.py, and #1395's two wording fixes. The merged cli.py is c4ddcb4's blob; no #1397 commit touches it. The merge is clean, and the NZ golden it takes from #1395 regenerates byte for byte from the merged tree. 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
Two tests imported microcosm_build.reference_factors as a top-level module. The hub's local runs put test_support on PYTHONPATH, so they passed there, but CI imports it as test_support.microcosm_build and stopped engine-free at collection once this stack first ran against main. Every other test in the repo uses the test_support prefix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
Resolves the one conflict in test_reference_profiles.py: keep this branch's two fixtures and #1382's test_support import path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1d5fff4 made `ledger_targets` import `LexicalFloat` from `ledger_artifact`, and `ledger_targets` is a UK target compile module. CI's `test_every_direct_import_of_a_listed_module_is_listed_or_excluded` then failed: every direct import of a listed module must be listed or excluded. The import feeds one type check: `_strict_scalar_equal` reads an opt-in lexical float as `float`. Only the transport factor compiler opts in, which `test_lexical_float_opt_in_is_limited_to_factor_consumers` pins; the UK kernels load plain floats, so no UK value is ever a `LexicalFloat`, and the loaded facts are node inputs hashed by content. That matches the existing exclusions for imports that never move a value, and it keeps the UK kernels' hashed module set as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
added a commit
that referenced
this pull request
Oct 29, 2026
Brings b36c702 into this branch: ledger_artifact joins EXCLUDED_DIRECT_IMPORTS with its reason, so test_every_direct_import_of_a_listed_module_is_listed_or_excluded passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Both UK target kernels decode their ledger facts inside run, through full_targets -> load_ledger_consumer_artifact -> _load_fact_rows. The decoded floats feed listed compilers, but source keys hash the raw file bytes and source_hash covers only the modules the kernels pass it, so an edit to the decoder left both UK implementation hashes unchanged (the delta review moved a national target by changing only the default decimal parser). List the module instead of excluding it; its one microcosm.build import, chronicle_epoch, stays excluded, and its reason now names ledger_artifact's schema gate and epoch labels too. This adds no cache invalidation of its own: this branch already edits ledger_targets.py and ledger_artifact.py, so it re-keys every UK target node either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 29, 2026 16:39
Contributor
Author
|
Merged by the NZ hub (session local_e407a527) at 7cd1d26 with --merge. Gates: |
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.
Targets
main. #1375 merged on 2026-10-29 at 6af97bf, and the UK hold on compile-hash changes ended at 12:00Z that day. Landing record: see Landing (2026-10-29) below.G8-r2a: feed-derived ageing factors for the NZ reference profiles. The PR adds one factor operation,
projected_period_average_ratio@1(reference_factors.py), and wires its selected factors through the sharedresolve_reference_profiles, the composition preflight andtargets.compile@1/takeup.compare@1.Commits:
prepare_transport_buildruns the currency check itself, so library callers that start a new run refuse an expired factor too; the warm-store replay test now compiles a factor-bound target surface.main(fddbc70) through update-branch.test_support, as CI does, and sort them as ruff does.What changes
Exact operands.
load_ledger_consumer_artifact(..., lexical_floats=False)still returns builtin floats by default. Two callers opt in, and a static test pins both call sites:With
lexical_floats=True, floats load asLexicalFloat, a slottedfloatsubclass that keeps its JSON token. The factor operation proves each token reproduces the float before using the exact decimal. A plain-float operand refuses.Exact factors. Each factor is the ratio of projected period averages in exact rationals. A certified enclosure brackets the root; exact roots get a zero-width enclosure. The factor is rounded once (half-even) to six decimals and carried as
p/10**6. Schedules are bounded (frequency 1–12, digits 0–18), so exact receipts stay serializable.NZ declarations (
nz/reference_aging.json, generated bytools/generate_nz_reference_aging.py):valid_until). A September-quarter observation re-anchors the projection, and the old factor refuses until it is re-declared.declared_on <= as_ofandvalid_from <= as_of <= valid_until, so the same inputs validate the same way on any date. Whether a declaration is still current is checked once, at run entry (see Transport).Resolver.
resolve_reference_profiles(..., factor_context=None).factor_companions: per roster name, its role (money or count), factor, profile and source value semantics. Its hash andtransformed_namesjoin the selection identity.linear_combinationweight equal to the verified factor. Count companions keep their original operation and operands.interval_table_idsrefuses until r2b.Transport.
chronicle_feed.jsonpin, without feed I/O.reference_factorsjoins_COMPILE_MODULES.--resume auto|forbid, the CLI checks every factor that the default and scenario profile views select against today's UTC date, before preparation can run CREATE.require_current_factors(selected, *, today)has no default fortoday. The views come fromcompose.reference_profile_views, the walk activation also uses, so a spec without scenarios checks its default view alone.--resume requirereplays a stored graph and is exempt. No kernel reads the clock.Scenarios.
Still parked. All 474 IRD rows stay parked: ageing is satisfied, but B4 measurement and coverage closure are outstanding. No donor normalization is declared.
Shared-code impact (UK, Belgium)
float). UK and Belgian code never opt in. The NZ opt-in load adds 40,247 bytes, tokens included, across 525 floats, with canonical bytes identical.ledger_targets._strict_scalar_equal:LexicalFloatcompares asfloat.bool,intandfloatstay distinct._COMPILE_MODULESgainsreference_factors, so compile-node implementation hashes move for every country. This is a cache bust; it is the reason for the 10/29 hold.UK_TARGET_COMPILE_MODULE_NAMESgainsledger_artifact(7cd1d26; see Landing), and this PR editsledger_targets.py, already listed. Both UK target kernels' implementation hashes move, which re-keys every UK target node once.compose.py: 71–74, 392–393, 400–402, 404–437 and 579.cli.py: 17–20, 31, 40, 69, 644–665, 667–671 and 692.target_kernels.py: 56, 75, 77, 280, 296, 402–407, 409–432 and 524.Known edges (no current path)
yaml.safe_dumprejectsLexicalFloat(Belgium hub tested this).marshalrejects it (ValueError), and so doesyaml.safe_dump(RepresenterError); both were reproduced by the d28817f review.orjsonrejects it too, as the UK hub reported; that one was not reproduced, because orjson is not installed in the review environment.Invariants and checks
Test IDs are relative to
packages/microcosm-build/tests/engine_free/shared/.test_ledger_artifact.py::test_default_float_loading_returns_exact_builtin_float,::test_real_nz_lexical_opt_in_preserves_canonical_bytesand::test_lexical_float_opt_in_is_limited_to_factor_consumers;test_transport_target_kernels.py::test_no_factor_compilation_is_identical_with_or_without_lexical_loading.test_reference_factors.py::test_certified_rounding_and_root_bounds_match_independent_fraction_oracle(with the explicit (32, 1, 0, 2, 4) example) and::test_independent_oracle_refines_ambiguous_rounding.test_nz_reference_aging.py::test_all_six_factors_and_observed_diagnostic_are_exactand::test_generated_aging_resource_reproduces_pinned_feed_and_all_receipts.test_reference_factors.py::test_observed_preferred_requires_redeclaration_and_reanchors_projectionandtest_nz_reference_aging.py::test_september_observation_reanchors_and_requires_reviewed_redeclaration.test_reference_profiles.py::test_rehashed_factor_application_cannot_bypass_companion_role,::test_rehashed_forged_companion_role_requires_the_bound_selection_identity,::test_rehashed_action_label_cannot_change_money_into_a_countand::test_count_preserves_original_weighted_operation_and_refuses_changed_weight;test_transport_target_kernels.py::test_compile_replay_refuses_rehashed_factor_application_tampering.test_reference_profiles.py::test_factor_scales_money_once_keeps_counts_and_measurement_prerequisiteandtest_nz_target_references.py::test_resolved_money_uses_the_verified_factor_once_and_count_values_are_unchanged.test_transport_target_kernels.py.test_ledger_targets.py::test_strict_scalar_equal_treats_lexical_floats_as_floatsand::test_float_dimension_pin_compiles_loaded_fact.test_reference_profiles.py, covering the compact shape under 2.6 MB and the pinned v1 digest.test_nz_target_references.py::test_ageing_profiles_have_237_explicit_companions_and_keep_b4_parkedand::test_v4_changes_only_the_residual_knob_and_prior_variants_keep_their_meaning;test_reference_profiles.py::test_factor_evidence_and_unselected_profile_locality.test_nz_spec_package.py::TestRulespecPin::test_chronicle_identity_scope_preserves_rulespec_mentions.test_reference_factors.py::test_unsupported_exact_receipt_schedule_refuses_at_declaration.test_nz_reference_aging.py::test_packaged_factor_context_validation_ignores_the_wall_clockandtest_reference_profiles.py::test_nz_default_factor_resolution_validates_after_declaration_expiry; the hub rerunstest_nz_reference_aging.pyandtest_reference_profiles.pywith the clock at 2026-11-05, and the wholetest_transport_composed_graph.pywith the CLI clock at 2100-01-01.test_nz_reference_aging.py::test_factor_currency_uses_inclusive_declared_boundaries,test_reference_factors.py::test_currency_check_without_selected_factors_is_a_noop, and intest_transport_composed_graph.py:::test_cli_main_refuses_expired_factors_before_create,::test_cli_factor_currency_decision_allows_historical_replayand::test_cli_require_replays_a_warm_store_after_selected_factors_expire(a warm store replays at 2100 with no kernel call, whileautorefuses and writes nothing).scenarioswith the same error. Tests:test_transport_composed_graph.py::test_cli_run_date_is_the_utc_dateand::test_cli_currency_check_walks_the_views_activation_walks.ValueError. Tests:test_reference_profiles.py::test_malformed_resolution_shapes_refuse_as_value_errors,::test_unnamed_unresolved_factor_rows_refuse_as_value_errorsand::test_duplicate_unresolved_factor_companion_refuses.Verification (lane-reported unless marked hub)
skip_compile_replayitself.test_reference_profiles.py74,test_transport_target_kernels.py52 andtest_nz_target_references.py50 passed. Two mutants killed: reverting either fix turns its new test red with KeyError.test_nz_reference_aging.py18 andtest_reference_profiles.py97 passed. Whole CLI test file with the CLI clock at 2100-01-01: 163 passed. Mutants killed: 8 of 8, each for the intended reason. Receipts, effective intervals and factor contexts are byte-identical to d28817f (8 payloads, re-checked on the committed tree).ci_test_plan.py verify,graph_acceptance_burndown.py --verify,git diff --checkand both generators'--checkpassed at each head.Independent review
Sol round 1 (a30c377): REQUEST_CHANGES.
UK hub (a30c377): SAFE WITH NOTES. All notes are addressed by the opt-in loader and strict-equality fix; a delta check is pending.
Belgium hub (a30c377): transport cleared, and BE outputs byte-identical. A delta check is pending.
Sol delta review of 1d5fff4 and 4f77038: APPROVE_WITH_NITS at 4f77038. It ran 2,356 tests (5 expected skips) and observed 215 mutation failures across all 84 changed test functions, with no survivors. Its three nits are addressed above: the trust-boundary qualification, the source-text limit and the orjson attribution.
Belgium hub Sol review (4f77038): BE-INERT. Its latent finding Re-base epic: frame.place, sparse solve, target registry, gates + rotated holdout, US stage plan, wheels CI #5 is fixed in d28817f.
UK hub delta check (4f77038): safe for UK outputs; 112 passed and 5 skipped.
Opus delta review of d28817f (job 20261024-101711): APPROVE_WITH_NITS, Needs Max: no.
Belgium hub, fix round 3 transport hunks (before commit): OK to commit once two asks were done. Ask 1 (defect): run entry walked scenarios without activation's guard, so a spec with reference profiles and no
scenarioswould refuse at the CLI only; run entry and activation now sharecompose.reference_profile_views. Ask 2: an end-to-end replay test throughmain(... --resume require)on a warm store, which thecurrency_check_on_replaymutant targets. Its nit, the UTC date, is taken (cli._today()). Its second round (10/24 about 6:10pm ET) OK'd the compose.py and cli.py hunks as they stand. Its optional nit is taken: the replay test'sis_file()check proved nothing, because the cold run had already written the export. Underrequirethe CLI reads back the stored export and never rewrites it, so the test now compares the export's bytes before and after the replay. Belgium re-clears BE (five dumps and its suites) at the pushed head.Sol delta review of 2a64132 (job 20261024-180703): REQUEST_CHANGES. fix4 (495db83) addresses both findings:
cli.main, so the exportedprepare_transport_build→execute_transport_graphroute skipped it. The fix runs the check first inprepare_transport_build, before activation, the registry, the CREATE inventory and CREATE;requirestays exempt. Execution and composition stay clock-free. The hub's tests pass (16 currency tests), and three mutants are killed. Belgium OK'd thecli.pyhunk on 2026-10-24 (about 9:45pm ET): BE declares no reference profiles, so the check reads nothing, and BE still refuses at activation.targets.compile@1node, and the test spies the factor replay (test-only).requirenever computes missing work; Part B refusals areValueError; and the valid receipt bytes and pinned digests are unchanged.Sol delta review of fix4 (c4ddcb4, job 20261025-151022): REQUEST_CHANGES for incomplete verification only. P3 resolved and P2 partly resolved; M1 and M3 killed; M6 interrupted and M7 not run.
Hub controls (c4ddcb4, 2026-10-26): M2, M4, M5, M6 and M7 all killed for their stated reasons; the positive control passed 14 of 14.
Sol continuation review (c4ddcb4, job 20261025-212859): APPROVE_WITH_NITS, Needs Max: no. It ran M6 and M7 itself (both killed) and audited the hub's controls. Two non-blocking nits:
execute_transport_graphand standalone inventory stay exported. Their docstring assigns the currency check to any caller that composes a graph itself; no checked-in production caller skips it. Making them internal is a separate change that needs Belgium's sign-off.test_nz_spec_package.py:1380(from Add the New Zealand spec package for the graph build (NZ v0, G2) #1119) can fail Hypothesis'stoo_slowhealth check on a loaded host. This PR doesn't touch it; Add receipt contract v2 and selection-aware reference preflight #1397 (84c2082) suppressesHealthCheck.too_slowon that property.Delta review of the CI import fix (2026-10-29, job 20261029-083505): APPROVE, no findings, across Add feed-derived NZ reference ageing factors (G8-r2a) #1382, Add exact income-band intervals and boundary diagnostics #1394, Normalize donor money with exact declared factors #1395, Add receipt contract v2 and selection-aware reference preflight #1397 and Reconcile regional Census family-type counts under d1932 #1398. Merging b157bb9 into
maindiffers from merging c4ddcb4 only in the fixture import lines of the two test files.Landing (2026-10-29)
mainafter Allocate Census residuals through shared reference profiles #1375 landed, so it ran CI for the first time. Stacked PRs never ran it.test_reference_factors.pyandtest_reference_profiles.pyimportedmicrocosm_build.reference_factorsas a top-level module. The hub's local runs had puttest_supportonPYTHONPATH, which hid the bad path; CI imports it only astest_support.microcosm_build. 64daa4f fixes the import and b157bb9 sorts it; the hub's runner no longer addstest_supporttoPYTHONPATH.test_uk_target_compile_modules.py::test_every_direct_import_of_a_listed_module_is_listed_or_excluded: 1d5fff4 madeledger_targets, a UK target compile module, importLexicalFloatfromledger_artifact. b36c702 first addedledger_artifacttoEXCLUDED_DIRECT_IMPORTS.mainafter Allocate Census residuals through shared reference profiles #1375's landing. It changes no file, but Allocate Census residuals through shared reference profiles #1375 landed as 6af97bf, so this branch had two merge bases withmain; GitHub marked the PR conflicting and ran no CI until this merge gave it one.run, throughfull_targets→load_ledger_consumer_artifact→_load_fact_rows, andsource_hashcovers only the modules a kernel passes it. Changing only the decoder's default parser moved a national target (325,054,437,305.83 → 325,054,437,306.58) while both UK implementation hashes stayed put. The gap predates this PR, but the exclusion would have exempted it on the record.ledger_artifactinUK_TARGET_COMPILE_MODULE_NAMESinstead.microcosm.buildimport,chronicle_epoch, stays excluded. That entry's reason now also namesledger_artifact's uses, the consumer schema gate and the epoch labels; none of them moves a fact value.ledger_targets.py, a listed module, so it re-keys every UK target node either way.test_uk_solve_scope.py(126),test_ledger_artifact.py(55),test_chronicle_epoch.py(74) andtest_transport_target_kernels.py(52).ledger_artifactfrom the tuple turns the coverage guard red. Each stacked PR's merge changes onlytarget_compile_modules.py(blob 642a1e912 on all five heads). The four test files (259 passed, 2 skipped for want of an NZ Chronicle artifact), ruff, the plan check and the burndown pass at Add feed-derived NZ reference ageing factors (G8-r2a) #1382, Add receipt contract v2 and selection-aware reference preflight #1397 and Reconcile regional Census family-type counts under d1932 #1398. Two nits: pinledger_artifactin both kernel-hash tests, so the listing doesn't rest onledger_targets' incidentalLexicalFloatimport (a follow-up PR after the stack lands); and 7cd1d26's message credits the re-key toledger_artifact.pyas well, when only theledger_targets.pyedit was hashed. Two gaps that predate this PR, which the follow-up triages:chronicle_epoch's epoch labels reach node artifacts without moving a kernel hash, and other modules onfull_targets' path go unhashed.gh pr checksexit 0; run 40896742895): 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 at 7cd1d26 againstmainat 846b48a, 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.valid_until2026-11-03. From 2026-11-04, new NZ transport runs refuse until the NZ hub re-declares the factors from Stats NZ's next quarterly release;requirereplay stays exempt.Wall-clock fix (found by the hub 2026-10-24; fixed in 2a64132)
reference_factors.py:236compareddate.today()with each declaration'svalid_untilinside validation, and every NZ factor declaresvalid_until2026-11-03. With the clock patched,test_nz_reference_aging.pypassed 13 on the real clock and at 2026-11-03 but failed 11 at 2026-11-05, andtest_reference_profiles.pyfailed 1. Merged as it was, it would have failed main's CI for every PR from 2026-11-04.today(Transport, above). Replay is exempt, as the Belgium hub asked.Open scope
🤖 Generated with Claude Code