#321 B1: boot seam — detect embedded image before cold package construction, dispatch to old loader (Axis B / ADR 0025)
openPart of #318 (epic). Axis B, ADR 0025 D2/D3. Recommended first step (with B3).
Goal
Add the boot seam that detects an embedded image before cold package construction, but initially dispatch to today's reconstruction loader. Zero behavior change — this lands the ordering hook with nothing to regress.
Why first
The migration's crux is boot-order inversion (runtime adopts the image's world instead of cold-booting its own). Landing the seam first, still calling the old loader, de-risks everything downstream.
Approach / real work
- Move/extend the
FUNCLIMGtrailer probe so it runs before primordial package/symbol/keyword construction. - Ensure the minimal loader substrate is ordered ahead of world-adoption: syscalls, region mapping + validation, build-id/version gate, GC-metadata / region-table init, and a sane fallback when the image is stale/absent. This substrate mostly exists — the ordering is the work.
- On probe hit, call the existing reconstruction path (no new format yet).
Code anchors
src/cold/cold-loader.lisp:527ag-load-embedded-image-actionsrc/cold/cold-image.lispFUNCLIMG format;:338is-FUNCLIMG?- boot/primordial construction order (trace from cold-loader entry)
Acceptance gate
Byte-identical behavior to today: build/funcl-asdf boots the same, full suite
green incl. asdf load, self-host fixed point unchanged. Purely a seam.
Comments (2)
B1 landed — commit 2f9295c
Seam factored as ag-image-primordial-boot gated on *ag-image-adopt-world-p*
(defaults NIL = old reconstruction loader, byte-for-byte).
Verified clean:
- 8/8
make test-fast-shardedshards green tests/alexandria-load.shviaFUNCL=build/funcl(the IMAGE binary, i.e. the changed path): 17/17 files load, 8/8 smoke functions correct- image-baked
build/funclboots; keyword eq/member + arith + mapcar correct
Note / caveat for later: the ad-hoc (asdf:load-system "alexandria") via a
central-registry push + source-compile SPINS (infinite loop) — confirmed on
BASELINE (pre-B1) too, so pre-existing and unrelated. That path is NOT the
validated north-star (which is the FASL replay / ocicl.csv registry, cave#309).
Filed separately. Use the FASL path or alexandria-load.sh for the asdf gate on
subsequent stages, and always wrap probes in timeout.
Next: B3 (#323) — emit the relocation bitmap from GC slot descriptors.
Boot-order findings (from the B1 investigation)
Mapped the actual boot path so B5 has ground truth:
The outer seam already exists.
src/main.lisp:26(no-argv path) callsag-boot-embedded-funclimgbefore the cold-boot fallbackag-repl-loop. So the embedded image is already detected before the CWD-prelude boot.The overlay is inside the image path, not the dispatcher.
ag-boot-embedded-funclimg(repl.lisp:2217) →ag-image-reset-compiler-state(repl.lisp:2140) unconditionally callsag-bootstrap-standard-packages(:2157) — it cold-builds the primordial package/symbol/keyword world — and thenag-image-load-and-repl-installreconciles the image against it:ag-image-rebuild-symbol-pool-offsets(:2321)ag-image-rebuild-keyword-pool-offsets(:2326)ag-image-canonicalize-heap-keywords(:2333, cave#314)ag-image-rebuild-pkgsym-offsets(:2338)Those four are the reconcile path B6 (#326) deletes once B5 adopts.
Same
ag-image-reset-compiler-stateis shared by the explicitfuncl FILE.funclimgpath (ag-image-load-and-repl,:2264) — so the seam covers both image entries.Loader substrate ordering: GC/region init happens via
mmap-rwx-bv-at-vaddr+gc-register-pool-emissionsduring install (the.fco/heap sections), afterag-image-reset-compiler-state. For B5, world adoption must be installed before the reconcile steps run (they read the pools); the natural insertion point is the NIL arm ofag-image-primordial-boot.B1 landed
Seam factored as
ag-image-primordial-bootgated on*ag-image-adopt-world-p*(defaults NIL = old reconstruction loader, byte-for-byte). B5 flips the flag and installs the adopted world in the NIL arm; the four reconcile calls then become dead for B6. Validated:make buildclean, image-bakedbuild/funclboots and keywordeq/member+ compute all correct. Full sharded suite running.