Skip to content

Add exact income-band intervals and boundary diagnostics - #1394

Merged
MaxGhenis merged 23 commits into
mainfrom
nzhub/g8r2b-intervals
Oct 29, 2026
Merged

MaxGhenis merged 23 commits into
mainfrom
nzhub/g8r2b-intervals

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Targets main and lands after #1382. The UK Budget hold on shared compile-module hashes, which applied because eleven kernel implementation hashes move (see Cross-country), ended at 2026-10-29 12:00Z. f700082 fixed the round-1 review, and its delta review approved it with wording nits (see Review). Head fca69c1: d27a8f5 merges #1382's fix4 head (Belgium OK'd it 10/26), and fca69c1 fixes the changelog nit. A batch delta review of the fix4 merges approved them with no findings (see Verification); the BE re-clear passed (see Landing).

What this does (G8-r2b)

Adds exact income-band intervals, the prepared indicators built from them, and fixed-weight boundary diagnostics. No target is activated: all 474 IRD rows and 235 P1 rows stay parked until G8-r2c.

  • Shared module, reference_intervals.py. Country data declares everything per table, and the module has no defaults for semantics:
    • entity, currency, columns and periods;
    • the first cut;
    • positive-band closure (left or right), nil band (present or absent) and negative-income policy.
    • Cuts are exact rationals over signed integer-cent inputs.
    • When a nil band is present, zero is nil under either closure. With a nil band and a zero first cut, the first positive band starts above zero, so no record is in two bands. Without a nil band, zero falls in the first band.
    • Validation refuses unresolved universes, malformed cuts and repeated scaling.
  • Scaling. r2a's scale_money_and_intervals transformation now scales each named interval table once, with its companions' selected factor. Fractional-cent cuts stay exact.
  • Output binding. In calibration_columns.py, interval outputs are their own kind beside predicate outputs, and name their entity explicitly. _prepare_roster_counts is untouched.
  • Transport.
    • compose.py: a calibration.prepare@1 node receives the profile view's exact effective interval companion, and refuses if it supplies a different one. Only a spec with a profile view that has intervals is affected, which today means NZ.
    • target_kernels.py, preparation:
      • recomputes indicators from each variant's cuts;
      • records interval input fingerprints in its evidence, only when bindings name interval outputs;
      • refuses an intervals parameter without a resolution receipt.
    • target_kernels.py, the problem kernel: re-derives the fingerprints, checks the interval hash, and adds fixed-weight boundary diagnostics to its metadata and receipt, never to targets.
  • NZ.
    • 237 national and 183 age bands are generated and checked against every feed label.
    • The national table scales in all three ageing profiles.
    • The canonical golden changes only identity fields.
  • Integration with Add feed-derived NZ reference ageing factors (G8-r2a) #1382's fix3: test_nz_default_factor_resolution_validates_after_declaration_expiry now passes the interval document that NZ's profiles require.

Invariants (tested)

  1. Classification is exact: scaled classification equals classification of the deflated source amount (property, with an independent Fraction oracle).
  2. Partition and conservation: included and excluded records partition the input. Counts and amounts are conserved across bands, including the below-first-cut bucket, with nil unchanged.
  3. Closure: the declared closure governs exact cuts and one cent either side; the alternative closure appears only in diagnostics.
  4. No rounding of aged cuts: fractional-cent cuts stay exact (mutants dollar_rounded_edge and cent_rounded_edge killed).
  5. Entity-generic: weights resolve through resolve_weights(entity) (mutant person_only_entity killed).
  6. Diagnostics never move targets: RHS values are unchanged (mutant change_rhs_for_diagnostics killed).
  7. Determinism and order: results are invariant under joint record-and-weight permutations, and a mismatched order refuses.
  8. No-interval paths are byte-stable: with no interval outputs, the prepare evidence and the problem's metadata and receipt bytes are unchanged (the review compared 36 payloads, base against head, byte for byte). Only the implementation-hash cache bust remains.
  9. With a nil band, zero belongs to nil only: under both closures, unscaled and scaled, a zero income is nil and never in a positive band (hub mutants restore_guard and nil_after_cuts killed).

Cross-country

  • Belgium OK'd every transport hunk (10/24). BE has no transport graph or profile view, so no BE output bytes move. The re-clear on this head follows once it's green.
  • Cache bust: 11 of the 32 kernel refs the hub probe enumerated move. The probe imported every microcosm package and the transport run registry at the base (2a64132) and at this head, and compared the implementation_hash() of every kernel instance it reached, 32 distinct refs:
    • the four kernels defined in target_kernels.py: calibration.prepare@1, targets.compile@1, targets.problem@1, takeup.compare@1;
    • seven kernels that hash target_kernels.py as a dependency: transport.create@1, transport.quantile_map@1, geography.support_from_facts@1, gates.battery@1, takeup.assign@1, takeup.gap@1, diagnostics.calibration@1.
    • The other 21 are unchanged.
    • Outside the enumeration: kernels the country runtimes and delegates instantiate dynamically, for example us.post_transfer.create@1, uk.full.target_compilation@1 and simulate.rules@1. The delta review hashed the first two, and neither shows another changed implementation.
    • The three engine-backed simulate kernels were read rather than run. With the built-in Axiom bindings they hash microcosm-frame modules, which this PR doesn't touch, plus their bound adapter classes.
  • What moves downstream. A node key binds its kernel's implementation hash and its inputs' artifact keys (graph/keys.py, node_key). So any graph, in any country, that runs one of these kernels recomputes that node and everything downstream of it once. Every node of a graph rooted at transport.create@1 recomputes. Outputs are shown unchanged for no-interval inputs only for prepare and problem (invariant 8). The seven dependency kernels' own modules are unchanged.

Review

Round 1 (GPT-6.1 Sol, at 75c2768): REQUEST_CHANGES. All three findings are fixed in f700082:

  • Major: test collection failed. The composed-graph interval config built Owned("person", "age") without its required dtype. It now passes "int64".
  • Major: a combination the brief allows was refused. The brief says that with a nil band and a zero first cut, the first positive band also requires z > 0. The validator instead refused left closure with nil present and a zero first cut. The guard is removed (_position already puts zero in nil first), the refusal test is replaced by acceptance tests, the two first=1 workarounds are gone, and the Hypothesis generator now draws the combination.
  • Minor: the cache-bust disclosure was understated. It is rewritten above from a probe of the 32 kernel refs the probe reaches, not only the four the review checked.

The review's other checks passed:

  • exactness against an independent Fraction oracle (54,792 comparisons);
  • partition and conservation, no semantic defaults, entity generality and output kind;
  • scaling once, and eight transport tamper refusals;
  • the no-interval byte differential, the NZ data and parking, and the fix3 integration.

Round 2 (GPT-6.1 Sol, delta 75c2768..f700082): APPROVE_WITH_NITS.

  • Both majors are fixed. The composed-graph interval tests collect and pass, and 107 interval tests pass. 79,110 independent classifications agree, including left closure with a nil band and a zero first cut. The scaled diagnostics, transport, generator coverage and in-memory counterexamples also pass.
  • The cache-bust impact is verified: all eleven changed kernels, and the downstream recompute.
  • Its minor finding was that "every kernel" overstated the probe. That is fixed above: the claim now covers the 32 enumerated refs and names the dynamically instantiated kernels outside them.
  • Its nit was that "zero is nil" holds only when a nil band is present. That is fixed above, and in the changelog at fca69c1.
  • The test_transport_target_kernels.py selection was UNCHECKED, because the fleet disk hold blocked pytest; in-memory prepare and problem probes pass. Ruff, format, the diff checks and both NZ generators pass.
  • Once disk allowed (2026-10-25), the hub ran test_transport_target_kernels.py at f700082 under pytest, in full, at -n 0: 67 passed. It passes again after the fix4 merge (see Verification).

Verification

  • Lane (GPT-6.1 Sol, at d28817f, before the rebase): 8 files, 1,624 passed.
  • Hub at 75c2768 plus the dtype fix:
    • all 18 baseline files pass, one process each. They include test_reference_profiles.py 120, test_transport_composed_graph.py 166, test_transport_entitlement_graph.py 67, test_nz_spec_package.py 1,201 and test_ledger_targets.py 451.
    • 12 of 12 mutants killed, each with a passing same-file control and byte-verified restoration: left_closed_cut, dollar_rounded_edge, cent_rounded_edge, drop_nil_band, all_person_universe, unknown_universe_as_false, double_applied_factor, change_rhs_for_diagnostics, omit_helper_source_hash, reuse_s0_indicators, person_only_entity, default_closure.
    • ci_test_plan.py verify, graph_acceptance_burndown.py --verify and both NZ generators' --check exit 0.
  • Hub at f700082:
    • test_reference_intervals.py 107, test_nz_reference_intervals.py 14, test_transport_target_kernels.py 67 and test_transport_composed_graph.py 166 passed;
    • mutants restore_guard and nil_after_cuts killed (three new tests red, control green); left_closed_cut and default_closure rerun and still kill;
    • ruff check and format, and git diff --check, are clean.
  • Hub at fca69c1, after the fix4 merge, one file per process at -n 0: test_country_spec.py 136, test_nz_spec_package.py 1,201, test_transport_target_kernels.py 67, test_transport_composed_graph.py 172, test_nz_reference_intervals.py 14, test_reference_intervals.py 107 and test_spec_engine_country_bundles.py 21 passed.
  • Delta review of f700082 (GPT-6.1 Sol): APPROVE_WITH_NITS (see Review).
  • Qualify the changelog's "zero is nil" with "when a nil band is present" (fca69c1).
  • Merge Add feed-derived NZ reference ageing factors (G8-r2a) #1382's fix4 head (d27a8f5). Belgium OK'd it; the merged transport/cli.py is c4ddcb4's blob (6f42b3b0) and the only transport file the merge changes. The NZ golden conflicted and was regenerated from the merged tree; per-key attribution shows no mismatches. Reruns above.
  • Batch delta review of the fix4 merges (GPT-6.1 Sol, at db02ae8 on Normalize donor money with exact declared factors #1395, which contains this head): APPROVE, no findings. It rebuilt each merge with git merge-tree (only the conflicted NZ golden differs), attributed the golden key by key, checked Belgium's two conditions and the wording commits, and ran test_country_spec.py 136, test_nz_money_normalization.py 17 and the 12 currency-check tests of test_transport_composed_graph.py.
  • BE re-clear on the landing head (see Landing).

Landing (2026-10-29)

Merge order

#1375 → #1382 → this → #1395 (w2a, money normalization, stacked here) → w1 → S5 (#1392) → w2b.

🤖 Generated with Claude Code

MaxGhenis and others added 6 commits October 24, 2026 02:38
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>
Add a shared reference_intervals module: per-table declared semantics
(band closure, nil band, negative-income policy) with no defaults, exact
rational cuts on signed integer-cent inputs, classification, scaling and
diagnostics. Interval tables scale once with their companions' selected
factor, keeping fractional-cent cuts exact.

Bind interval outputs as their own kind in calibration_columns, beside
predicate outputs, and leave roster preparation untouched. Preparation
receives the exact effective interval companion, recomputes indicators
from each variant's cuts and records input fingerprints; the problem
kernel re-derives them and adds fixed-weight boundary diagnostics to its
metadata, never to targets.

Declare NZ's 237 national and 183 age bands, checked against every feed
label, and scale the national table in all three ageing profiles. All 474
IRD and 235 P1 rows stay parked. fix3's expiry test now passes the
interval document NZ's profiles require.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address the r2b review (GPT-6.1 Sol, 75c2768).

- Remove the validator guard that refused positive_band_closure "left"
  with a nil band and a zero first lower cut. Zero is nil under either
  closure (_position checks nil before any cut), so the first positive
  band is 0 < z < upper and nothing belongs to two bands. The refusal
  forced a one-cent stand-in cut, which moves membership after scaling:
  at factor two, one cent fell below the first cut.
- Replace the refusal test with acceptance tests: classification at the
  unscaled and twice-scaled cuts, and boundary diagnostics with zero in
  nil under the declared and alternative closures. Drop the two first=1
  workarounds, and let the Hypothesis table generator draw the
  combination.
- Give the composed-graph interval config's Owned output its required
  dtype; without it the whole test file failed collection.
- Correct the changelog's refusal sentence.

Verified: test_reference_intervals 107, test_nz_reference_intervals 14,
test_transport_target_kernels 67 and test_transport_composed_graph 166
passed. Restoring the guard, and checking nil after the cuts, each turn
the three new tests red with the control green. All 12 r2b mutants were
killed with the dtype fix in place; left_closed_cut and default_closure,
whose test file this changes, were rerun after it and still kill. ruff,
format and git diff --check are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 25, 2026
The hub's validation after rebasing onto #1394 found three failures the
lane's pre-rebase runs could not see.

- money_normalization.json cited local files by line number, which
  test_nz_spec_package refuses. The donor-period evidence now names the
  symbols (the PERIOD constant, _dataset_from_frame,
  PolicyEngineUSEngine._write_and_verify). A new test parses both files
  and checks each cited fact against the code. Mutants that change
  PERIOD, pass a literal time_period, or drop the int cast each fail it.
- The rulespec-pin plant edited currency_bridge.json's source record,
  which w2a moved into money_normalization.json. The plant now edits the
  IRS rate's citation there, so the planted revision is caught again.
- The v2 receipt digests were produced before #1394 added the interval
  document. The test now passes reference_intervals.json and pins the
  digests that #1394's 75c2768 produces; they are unchanged at f700082
  and at w2a.

The country-spec golden was regenerated for the new
money_normalization.json bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…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>
MaxGhenis and others added 3 commits October 25, 2026 12:10
#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>
#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>
Zero is nil only when the table declares a nil band (_position checks
nil_present first). Without one, a zero record with a zero first cut falls
below the first cut under right closure and into the first band under left
closure, so the unqualified sentence overstated it.

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
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>
@MaxGhenis
MaxGhenis changed the base branch from nzhub/g8r2a-factors to main October 29, 2026 12:12
MaxGhenis and others added 3 commits October 29, 2026 08:12
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>
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>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
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>
MaxGhenis and others added 2 commits October 29, 2026 08:26
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>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 29, 2026 09:55
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>
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>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
Brings b36c702 (via #1394) 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>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
Brings b36c702 (via #1394) 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>
MaxGhenis and others added 4 commits October 29, 2026 10:14
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>
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>
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>
Brings 7cd1d26 (via #1382) into this branch: ledger_artifact joins UK_TARGET_COMPILE_MODULE_NAMES instead of EXCLUDED_DIRECT_IMPORTS, so an edit to the fact decoder re-keys both UK target kernels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
Brings 7cd1d26 (via #1394) into this branch: ledger_artifact joins UK_TARGET_COMPILE_MODULE_NAMES instead of EXCLUDED_DIRECT_IMPORTS, so an edit to the fact decoder re-keys both UK target kernels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 29, 2026
Brings 7cd1d26 (via #1394) into this branch: ledger_artifact joins UK_TARGET_COMPILE_MODULE_NAMES instead of EXCLUDED_DIRECT_IMPORTS, so an edit to the fact decoder re-keys both UK target kernels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 29, 2026 16:39
@MaxGhenis
MaxGhenis merged commit 1f2ee55 into main Oct 29, 2026
10 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merged by the NZ hub (session local_e407a527) at ae1f24b with --merge. Gates: gh pr checks exit 0; MERGEABLE; not draft; no CHANGES_REQUESTED review. Reviewed head: ae1f24b. Independent delta review of the ledger_artifact listing across all five stack heads: APPROVE_WITH_NITS (Opus 5.5 in session), jobs/review-microcosm-fix5list/out-opus.md. BE re-clear clean at this head (jobs/be-reclear-1029e).

@MaxGhenis
MaxGhenis deleted the nzhub/g8r2b-intervals branch October 29, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant