Skip to content

Reference translation: sidecar emission + consumer-side translate/canonicalize (bundle v2)#6

Merged
jack-champagne merged 3 commits into
masterfrom
feat/reference-translation
Jul 5, 2026
Merged

Reference translation: sidecar emission + consumer-side translate/canonicalize (bundle v2)#6
jack-champagne merged 3 commits into
masterfrom
feat/reference-translation

Conversation

@jack-champagne

@jack-champagne jack-champagne commented Jul 4, 2026

Copy link
Copy Markdown
Member

Reference translation — sidecar emission + consumer-side translate/canonicalize (bundle v2)

Productizes the validated bundle-v2 research pipeline (Piccolissimo
experiments/bundle-v2-tracer, legs 4-5) into a JSD product API: re-point a
private package image's cross-image references at a consumer's own rebuild of
its dependencies, using live reflection on both sides instead of the
research matcher's blob-archaeology.

Stacked on #5 (feat/identity-stamp). This branch (feat/reference-translation)
is cut from feat/identity-stamp and reuses its restamp internals
(stamp_identity!'s embedded-checksum + .ji-trailer-CRC rewrite,
dry_verify, verify_closure). Merge #5 first, then this. The diff shown
against master will include #5's commits until #5 lands.

What ships

Each pointer crossing into another loaded image is an inline 8-byte reloc word
(5<<61) | (depsidx<<40) | (byte_offset÷8) (staticdata.c:1204/2170 @ v1.12.6).
Refs into the sysimage (depsidx == 0, ~98.8%) are stable across depots and need
no translation; only refs into separately-precompiled pkgimage deps shift.

  • emit_sidecar(images; …)Sidecar (builder): parse every external reloc
    word, skip depsidx==0, and for each pkgimage-dep ref resolve the target to the
    live object in the builder's own loaded deps (jl_linkage_blobs base + offset)
    and emit a semantic RefDescriptor.
  • translate!(image_copy, sidecar; …)TranslationReport (consumer): resolve
    each descriptor against the consumer's rebuilt deps, compute the new offset,
    rewrite the word (integrity-checked), restamp the checksums.
  • canonicalize!(mods…)CanonicalizeReport (post-load): the leg5 type-hash
    repair — re-intern private method sigs and re-insert genuinely-broken dispatch
    entries. Health-gated + idempotent (see fix below).
  • load_translated(image, sidecar; …): one-shot chain — translate! → header
    remap-to-loaded-deps → verify_closure/load_package_imagecanonicalize!.
  • write_sidecar / read_sidecar: persist a Sidecar (stdlib Serialization).

RefDescriptor kinds

A target is described as, in priority order: a named entity
(:module/:binding/:type/:typename/:function); a nearest-named :anchor

  • deterministic field path; or — for anonymous objects with no build-stable
    path
    (their reaching path runs through build-volatile type-cache order, leg5
    RESULTS §6) — an order-independent content descriptor:
  • :svec_content — an anonymous SimpleVector (format-spec / method-sig /
    type-cache svec: svec('e'), svec(Val{'f'}), svec(Bool,…)). Described by its
    per-element content (types + isbits/Symbol/String leaves, serialized). The
    consumer reconstructs the elements and locates the live in-blob svec whose content
    matches structurally (mutual subtyping for type elements — interning-
    independent, so non-interned Tuple types compare equal).
  • :const_data — a const-region String, matched by scanning the consumer
    dep's const region for the object's byte image [len:8][bytes][NUL].
  • :type_content — an anonymous Union / un-named UnionAll /
    parameterization, matched by structural type equality over the blob's type objects.
  • :method — a Method object, resolved by (defining module, name, structural signature) via _methods_by_ftype.

rank/cohort pin the correct member when structurally-identical duplicates share
the blob (blob-offset order within the equal-content cohort). Every content
descriptor is self-checked at emit against its own round-tripped payload, so a
target that is not faithfully content-describable (e.g. a svec with free type
variables) fails cheaply at emit rather than mis-resolving on the consumer. If a
target matches none of the above, emit_sidecar errors loudly (builder-side failure
is cheap; a consumer-side one is not).

New types in types.jl: RefDescriptor (with payload/rank/cohort),
RefTarget, ImageSidecar, Sidecar, TranslationReport, CanonicalizeReport.
docs/src/api.md updated.

Results / validation (julia +1.12.6, frozen twin depots)

Altissimo (emit vs depot A → translate! vs depot B, compared to leg5's
proven maps_Altissimo new_off):

  • emit describes 43/43 targets, zero emit failures (12 type, 10 binding, 10
    svec_content, 5 module, 2 function, 2 typename, 2 const_data);
  • resolve-side agreement with leg5's proven offsets: 43/43 = 100%, incl. all 10
    anonymous svecs + 2 const strings;
  • translate! end-to-end: 253 words checked, 18 rewritten, 235 unchanged, 43
    resolved, 0 failed, ok=true — matching leg5 exactly.

Piccolissimo (the closing gap generalized): emit describes 244/244 targets,
0 failures (adds :type_content ×2 and :method ×3); translate! rewrites
1012 words (= leg5), 0 failures; 243/243 resolvable public-dep targets agree
with leg5's ground truth (the single "difference" is a cohort of two structurally-
identical svec(ComplexF64, 1) — semantically equivalent; rank-1 pick).

Full production flow (stretch) — PASS. Emit ONE 43 KB sidecar for both privates
on depot A (11.8 s); on a pure consumer depot (private-free clone of depot B,
zero builder-depot dependency access at consume time), load_translated both
images purely from that sidecar (translate A 1.7 s / P 3.3 s), then the H-gate
smoke solve: Ipopt f1 = 0.9761, Altissimo-backend f1 = 0.9921 — bit-for-bit the
leg1/leg5 values. canonicalize re-inserted 36 broken dispatch entries (= leg5).

  • Full JSD suite green on julia +1.12.6: 336 / 336 (was 293; +43 for the new
    content-descriptor tests). New test/test_translate.jl items (5) pure-Julia codec
    / structural-matcher / cohort-rank / const-scan / sidecar round-trip of the new
    kinds, and (6) a toolchain-gated round-trip on a Val/Char-parameterized image
    (which bakes anonymous method-sig svecs + a const String) — describe → resolve on
    its own live blob.

Notable fixes over the leg5 prototype

  • Idempotent AND correct canonicalize!. The type-hash repair must rebuild a
    broken method sig's (non-interned) Tuple so its baked hash is recomputed in the
    consumer's nonce universe — but rebuilding every sig is non-idempotent (fresh
    pointer each run) and re-inserting healthy entries causes spurious ambiguities. Fix:
    gate the repair on brokenness detected by a fresh-hash dispatch probe
    (_methods_by_ftype on the reconstructed sig — probing with the method's own
    stale-hashed sig would falsely report health by matching the stale-stored entry).
    A repaired method becomes findable under its consumer-hash sig, so the next pass
    skips it → idempotent, and only the genuinely-broken 36 (Piccolissimo) are touched.
  • Multi-private load chains. _remap_to_loaded! and translate!'s dep lookup now
    consult Base.loaded_precompiles (not just loaded_modules), so a downstream
    private (Piccolissimo) sees an upstream private (a translated Altissimo, loaded via
    load_package_image and registered only in loaded_precompiles) and remaps its
    header to Altissimo's new restamped build-id — avoiding a mixed-lineage
    closure-check failure.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V9jVcSYDNXtbBGfcAEPwvh

jack-champagne and others added 3 commits July 4, 2026 21:51
… (bundle v2)

Productize the bundle-v2 pipeline (Piccolissimo experiments/bundle-v2-tracer,
legs 4-5) into a JSD product API using live reflection on both sides instead of
the research matcher's blob-archaeology:

- emit_sidecar(images): parse external reloc words, skip depsidx==0 (sysimage,
  ~98.8%), resolve each pkgimage-dep target to the live builder object via
  jl_linkage_blobs, emit a semantic RefDescriptor (module/binding/type/typename/
  function or a nearest-named-owner anchor+field-path). Loud emit-time failure
  on an undescribable target.
- translate!(image_copy, sidecar): resolve descriptors to live consumer objects,
  compute new offsets (jl_value_ptr - blob_base), rewrite ref words (integrity-
  checked), restamp checksums (reusing the #5 stamp_identity! restamp path).
- canonicalize!(mods...): leg5 type-hash repair (re-intern private method sigs
  through live constructors, re-insert only broken dispatch entries). Idempotent
  (Tuple wrappers are not interned, so only rebuild when a parameter's identity
  actually changed -- fixes non-convergence in the leg5 prototype).
- load_translated: translate -> remap-to-loaded-deps -> load -> canonicalize.
- write_sidecar/read_sidecar (Serialization).

New types (types.jl): RefDescriptor, RefTarget, ImageSidecar, Sidecar,
TranslationReport, CanonicalizeReport. docs/src/api.md updated.

Stacked on feat/identity-stamp (PR #5): reuses its restamp internals; branch
from it, merge #5 first.

Tests (test/test_translate.jl): toy round-trip (leg5 inversion -- build User->Dep
in depot A, emit; rebuild Dep in depot B, translate/load/call, assert value),
descriptor-kind coverage (binding/type/function/svec-anchor + emit-time loud
failure), canonicalize! idempotence, reloc-word codec + sidecar serialization.
Full suite green on julia +1.12.6 (293/293).

Integration smoke (local): real Altissimo image, emit against depotA / resolve
against depotB -- 31/41 mapped non-const targets described, 100% (31/31)
agreement with leg5's proven maps_Altissimo.tsv new_off, 0 disagreements.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9jVcSYDNXtbBGfcAEPwvh
…ymous svecs + const-data

Close the sidecar coverage gap: the anonymous SimpleVectors (format-spec /
method-sig / type-cache svecs — svec('e'), svec(Val{'f'}), svec(Bool,...)) and
interned const-data Strings that have no name and no build-stable field path to a
named owner (type-cache iteration order is per-build volatile — leg5 RESULTS §6).
These are exactly the targets whose blob offsets shift between builds, so they
must be describable for a sidecar-only production translate. emit_sidecar
previously errored loudly on them (correct interim); now it describes them.

New RefDescriptor kinds (types.jl):
- :svec_content — describe an anonymous svec ORDER-INDEPENDENTLY by its element
  content (each a Type or an isbits/Symbol/String leaf), serialized into the
  descriptor. The consumer reconstructs the element values and locates the live
  in-blob svec whose content matches structurally (mutual subtyping for type
  elements — interning-independent, so non-interned Tuple types compare equal).
- :const_data — describe a const-region String by its value; the consumer scans
  the dep's const region for the String's byte image [len:8][bytes][NUL].
- rank/cohort pin the right member when structurally-identical duplicates share
  the blob (blob-offset order within the equal-content cohort).

Mechanics (translate.jl):
- _dep_so_path locates a loaded dep's own .so (via find_all_in_cache_path +
  build-id match) so the consumer can enumerate the dep blob's objects (gctag
  boundaries) / const region for content matching.
- emit's content describers self-check against the ROUND-TRIPPED payload, so a
  target that is not faithfully content-describable (e.g. a svec with free type
  variables) fails cheaply at emit rather than mis-resolving on the consumer.
- translate! now requires every recorded dep (a content svec's element types can
  name any of them) and routes content descriptors through _resolve_new_offset,
  which searches the consumer dep blob instead of computing jl_value_ptr - base.

Validated on the real Altissimo image (frozen twin depots, julia 1.12.6):
- emit vs depotA: 43/43 targets described, ZERO emit failures (was 31/41
  non-const). Breakdown: 12 type, 10 binding, 10 svec_content, 5 module, 2
  function, 2 typename, 2 const_data.
- translate! vs depotB: every target's resolved new offset AGREES with leg5's
  ground-truth map (43/43, incl. all 10 svecs + 2 const strings); words
  checked=253, rewritten=18, unchanged=235, resolved=43, failed=0, ok=true —
  matching leg5 exactly.

Tests (test_translate.jl): a pure-Julia item covering the codec, structural
matchers, cohort-rank selection, const-region byte scan, and sidecar round-trip
of the new kinds; plus a toolchain-gated item that builds a Val/Char-parameterized
package (which bakes anonymous method-sig svecs + a const String) and round-trips
each content target through describe -> resolve on its own live blob.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9jVcSYDNXtbBGfcAEPwvh
…scriptors, health-gated canonicalize!, multi-private load chains

Completes the full production flow (translated-load of the whole bundle purely from
an emitted sidecar) discovered while proving the svec descriptors at Piccolissimo
scale.

Two more order-independent descriptor kinds (the remaining anonymous targets in
Piccolissimo's 244; same content-match philosophy as :svec_content):
- :type_content — an anonymous Union / un-named UnionAll / parameterization,
  located by structural type equality (mutual subtyping) over the dep blob's type
  objects, rank-disambiguated.
- :method — a Method object, resolved by (defining-module path, name, structural
  signature) via _methods_by_ftype.
emit_sidecar now describes Piccolissimo 244/244 (was 239/244) and Altissimo 43/43,
zero failures.

canonicalize! — idempotent AND correct. The leg5 type-hash repair must rebuild a
broken method sig's non-interned Tuple so its baked hash is recomputed in the
consumer's nonce universe. The previous conditional-rebuild left a broken sig
whose params were pointer-correct but whose baked hash was stale (Piccolissimo's
AltissimoOptions solve! → paradoxical MethodError). Fix: gate repair on brokenness
detected by a fresh-hash dispatch probe — _methods_by_ftype on the RECONSTRUCTED
sig (probing with the method's own stale-hashed sig falsely reports health by
matching the stale-stored table entry). Repaired methods become findable under
their consumer-hash sig, so the next pass skips them → idempotent; only the 36
genuinely-broken Piccolissimo entries are re-inserted (= leg5).

Multi-private load chains: _remap_to_loaded! and translate!'s dep lookup now consult
Base.loaded_precompiles (not just loaded_modules), so a downstream private
(Piccolissimo) sees an upstream private (a translated Altissimo, loaded via
load_package_image → registered only in loaded_precompiles) and remaps its header to
Altissimo's NEW restamped build-id, avoiding a mixed-lineage closure-check failure.
Added loader helper _loaded_module_by_pid.

Full production flow validated (julia 1.12.6, pure private-free consumer depot,
ZERO builder-depot dependency access at consume time): emit one 43 KB sidecar for
both privates (11.8 s); load_translated both from that sidecar alone (translate
Altissimo 1.7 s / Piccolissimo 3.3 s; 18 + 1012 words rewritten = leg5); H-gate
smoke solve Ipopt f1=0.9761, Altissimo-backend f1=0.9921 — bit-for-bit leg1/leg5.

Test item 6 updated for the new _resolve_new_offset(t, root, ctx) arity; full suite
green (336/336).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9jVcSYDNXtbBGfcAEPwvh
@jack-champagne
jack-champagne force-pushed the feat/reference-translation branch from 8aa7d23 to ef329d2 Compare July 5, 2026 01:51
@jack-champagne
jack-champagne changed the base branch from feat/identity-stamp to master July 5, 2026 01:51
@jack-champagne
jack-champagne marked this pull request as ready for review July 5, 2026 01:51
@jack-champagne
jack-champagne merged commit e0839ac into master Jul 5, 2026
1 of 2 checks passed
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