Reference translation: sidecar emission + consumer-side translate/canonicalize (bundle v2)#6
Merged
Merged
Conversation
… (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
force-pushed
the
feat/reference-translation
branch
from
July 5, 2026 01:51
8aa7d23 to
ef329d2
Compare
jack-champagne
marked this pull request as ready for review
July 5, 2026 01:51
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.
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 aprivate 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.
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 needno translation; only refs into separately-precompiled pkgimage deps shift.
emit_sidecar(images; …)→Sidecar(builder): parse every external relocword, skip
depsidx==0, and for each pkgimage-dep ref resolve the target to thelive object in the builder's own loaded deps (
jl_linkage_blobsbase + offset)and emit a semantic
RefDescriptor.translate!(image_copy, sidecar; …)→TranslationReport(consumer): resolveeach 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-hashrepair — 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!→ headerremap-to-loaded-deps →
verify_closure/load_package_image→canonicalize!.write_sidecar/read_sidecar: persist aSidecar(stdlibSerialization).RefDescriptor kinds
A target is described as, in priority order: a named entity
(
:module/:binding/:type/:typename/:function); a nearest-named:anchorpath (their reaching path runs through build-volatile type-cache order, leg5
RESULTS §6) — an order-independent content descriptor:
:svec_content— an anonymousSimpleVector(format-spec / method-sig /type-cache svec:
svec('e'),svec(Val{'f'}),svec(Bool,…)). Described by itsper-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
Tupletypes compare equal).:const_data— a const-regionString, matched by scanning the consumerdep's const region for the object's byte image
[len:8][bytes][NUL].:type_content— an anonymousUnion/ un-namedUnionAll/parameterization, matched by structural type equality over the blob's type objects.
:method— aMethodobject, resolved by(defining module, name, structural signature)via_methods_by_ftype.rank/cohortpin the correct member when structurally-identical duplicates sharethe 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_sidecarerrors loudly (builder-side failureis cheap; a consumer-side one is not).
New types in
types.jl:RefDescriptor(withpayload/rank/cohort),RefTarget,ImageSidecar,Sidecar,TranslationReport,CanonicalizeReport.docs/src/api.mdupdated.Results / validation (julia +1.12.6, frozen twin depots)
Altissimo (
emitvs depot A →translate!vs depot B, compared to leg5'sproven
maps_Altissimonew_off):svec_content, 5 module, 2 function, 2 typename, 2 const_data);
anonymous svecs + 2 const strings;
translate!end-to-end: 253 words checked, 18 rewritten, 235 unchanged, 43resolved, 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!rewrites1012 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_translatedbothimages 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).
content-descriptor tests). New
test/test_translate.jlitems (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
canonicalize!. The type-hash repair must rebuild abroken method sig's (non-interned)
Tupleso its baked hash is recomputed in theconsumer'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_ftypeon the reconstructed sig — probing with the method's ownstale-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.
_remap_to_loaded!andtranslate!'s dep lookup nowconsult
Base.loaded_precompiles(not justloaded_modules), so a downstreamprivate (Piccolissimo) sees an upstream private (a translated Altissimo, loaded via
load_package_imageand registered only inloaded_precompiles) and remaps itsheader to Altissimo's new restamped build-id — avoiding a mixed-lineage
closure-check failure.
🤖 Generated with Claude Code
https://claude.ai/code/session_01V9jVcSYDNXtbBGfcAEPwvh