# Phase 13.3: booted Fruix using native store-built FreeBSD base artifacts Date: 2026-04-03 ## Goal Phase 13.3 was the first end-to-end boot validation of the new native FreeBSD base path. The target was a Fruix system/image that boots using: - native `/usr/src`-built kernel output in `/frx/store` - native `/usr/src`-built world output in `/frx/store` - host-staged bootloader only, as the remaining explicit transitional boundary Validation still followed the established strategy: - local QEMU/UEFI/TCG - real XCP-ng on the approved VM/VDI path ## Issues found and fixed ### 1. The old fixed 256 MiB root filesystem image was too small The first native-base image attempt failed during `makefs` with: ```text size of .../image-rootfs is larger than the maxsize of 268435456 ``` That was expected once the image started carrying a native world instead of the earlier curated host-copy runtime slice. To fix this cleanly, Fruix image generation gained an explicit root filesystem size parameter: - `scripts/fruix.scm` now accepts: - `--root-size SIZE` - image metadata now emits: - `root_size=...` - `tests/system/run-phase8-system-image.sh` now accepts: - `ROOT_SIZE` and records the reported root size in metadata For the native-base boot validation, the working values were: - local QEMU: - `ROOT_SIZE=6g` - `DISK_CAPACITY=8g` - real XCP-ng: - `ROOT_SIZE=6g` - disk capacity kept matched to the fixed 30 GiB VDI as before ### 2. `materialize-bhyve-image` needed to propagate native-base metadata After adding the new `native_base_*` metadata path, the first native image run hit a Scheme error because `materialize-bhyve-image` still returned: - `host-base-stores` - `fruix-runtime-stores` but not: - `native-base-stores` That was corrected so image-generation results now carry the native-base store set too. ## Harness updates ### Reused/extended existing Phase 11 boot harnesses - `tests/system/run-phase11-shepherd-pid1-qemu.sh` - now accepts `OS_TEMPLATE` like the XCP-ng PID1 harness already did - `tests/system/run-phase8-system-image.sh` - now records: - `native_base_store_count` - `native_base_stores` - `root_size` ### Added native-base boot wrappers New wrappers: - `tests/system/run-phase13-native-base-qemu.sh` - `tests/system/run-phase13-native-base-xcpng.sh` These wrappers reuse the already-validated PID1 boot path but require the image metadata to confirm that the booted system really uses the intended Phase-13 base split: - `native_base_store_count=2` - native kernel present - native world present - `host_base_store_count=1` - host base reduced to bootloader only ## Validation ### Local QEMU / UEFI / TCG Passing run: - `PASS phase13-native-base-qemu` - workdir: `/tmp/phase13-3-qemu3-1775174863` Key metadata: ```text disk_capacity=8g root_size=6g native_base_store_count=2 host_base_store_count=1 shepherd_pid=1 sshd_status=running native_base_boot=ok ``` The wrapped underlying Phase 11 PID1 harness also confirmed the full guest runtime path: - ready marker present - `/run/current-system` correct - Shepherd socket present - Shepherd PID is `1` - `sshd` running - activation completed successfully - `/etc/login.conf` regular + databases present ### Real XCP-ng VM Passing run: - `PASS phase13-native-base-xcpng` - workdir: `/tmp/phase13-3-xcpng-1775175086` Key metadata: ```text vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289 vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743 guest_ip=192.168.213.62 root_size=6g native_base_store_count=2 host_base_store_count=1 shepherd_pid=1 sshd_status=running compat_prefix_shims=absent guile_module_smoke=ok native_base_boot=ok ``` The dynamic VHD upload remained workable even with the larger native-world image payload, though naturally much larger than the earlier minimal image path: - upload size: `4740784128` bytes (~4.42 GiB) ## What booted The validated native-base system closure used: - native kernel store: - `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE` - native world store: - `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE` - remaining host base store: - `/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE` That means Phase 13 has now crossed its main success boundary: - the kernel is native - the core world runtime is native - the system actually boots from those outputs ## Assessment Phase 13 is complete. Fruix has now moved from: - building a FreeBSD system from curated host copies into: - building kernel/world artifacts from `/usr/src` into `/frx/store`, then booting a declarative Fruix system from those outputs. The remaining major transitional boundary is now much narrower and explicit: - host-staged bootloader/boot assets remain - native kernel + native core world runtime are already in place That is a real architectural shift, not just more documentation. ## Next recommended step Proceed to Phase 14: 1. replace the remaining host-copy boot assets first 2. then keep reducing the older host-staged FreeBSD base slice around the now-working native world/kernel path 3. revisit cleaner runtime vs. development splits once the boot asset transition is done