# Phase 14.3: split native FreeBSD boot, runtime, and development artifacts Date: 2026-04-03 ## Goal Phase 14.3 finished the Phase 14 cleanup work by replacing the temporary broad-world reuse with narrower native artifacts and by making the runtime/development boundary explicit in code. The target was: - no host-staged FreeBSD base stores in the validated path - no need to keep the broad `freebsd-native-world` artifact in the final validated system closure - explicit native boot and runtime slices - clearer development-profile boundaries ## Implementation ### New native packages Added in `modules/fruix/packages/freebsd.scm`: - `freebsd-native-bootloader` - `freebsd-native-headers` Also refined: - `freebsd-native-runtime` ### Narrower native runtime slice `freebsd-native-runtime` now prunes more obviously non-runtime content, including at least: - `boot` - `rescue` - `usr/include` - `usr/lib/debug` - `usr/lib32` - `usr/obj` - `usr/src` - `usr/share/doc` - `usr/share/examples` - `usr/share/info` - `usr/share/man` - `usr/share/mk` - `usr/tests` This shrank the runtime output substantially and made the runtime/development distinction much cleaner. ### Native bootloader slice `freebsd-native-bootloader` is now a native world-derived slice that keeps only the validated boot assets Fruix currently needs: - `boot/loader` - `boot/loader.efi` - `boot/device.hints` - `boot/defaults` - `boot/lua` ### Native headers slice `freebsd-native-headers` now captures the development-facing header/mk boundary explicitly: - `usr/include` - `usr/share/mk` ### Build-system support for sliced native outputs `modules/fruix/system/freebsd.scm` gained support for `keep-paths` on native world-derived packages. That means a native package can now: - install full world/distribution into a staging tree - keep only selected subtrees/files for its final store output - still participate in the same `/usr/src`-based identity/build-root story Native output metadata now records both: - `keep-paths` - `prune-paths` ## New package-set boundaries Added explicit package sets: - `%freebsd-native-system-packages` - currently centered on `freebsd-native-runtime` - `%freebsd-native-development-profile-packages` - `freebsd-native-runtime` - `freebsd-native-headers` - explicit toolchain/dev helpers that remain separate artifacts This makes the boundary clearer: - runtime world output - headers artifact - toolchain artifact(s) - optional development profile composition ## Final validated Phase 14 system model The final Phase 14 PID1 system template now uses: - `#:kernel freebsd-native-kernel` - `#:bootloader freebsd-native-bootloader` - `#:base-packages %freebsd-native-system-packages` That means the validated system closure now contains: - native kernel - native bootloader slice - native runtime slice - Fruix runtime stores and no longer needs the broad `freebsd-native-world` artifact in the final system closure. ## New files Added: - `tests/system/phase14-native-split-pid1-operating-system.scm.in` - `tests/system/run-phase14-native-split-qemu.sh` - `tests/system/run-phase14-native-split-xcpng.sh` - `tests/system/run-phase14-native-development-split.sh` ## Validation ### Development split validation Passing run: - `PASS phase14-native-development-split` - workdir: `/tmp/phase14-3-dev5-1775191195` Confirmed: ```text bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE headers_store=/frx/store/aab09122d37962e6d479c17172ce4b8ea85e5ff33c98aa76424ada2fa1a82617-freebsd-native-headers-15.0-STABLE native_system_packages=freebsd-native-runtime native_development_packages=freebsd-native-runtime,freebsd-native-headers,freebsd-clang-toolchain,freebsd-gmake,freebsd-autotools,freebsd-openssl,freebsd-zlib,freebsd-sh,freebsd-bash runtime_vs_development_split=ok ``` The harness also confirmed: - native bootloader slice contains only expected boot assets - native headers slice contains headers/mk files - native headers slice does not contain `/boot` or runtime binaries ### Local QEMU / UEFI / TCG Passing run: - `PASS phase14-native-split-qemu` - workdir: `/tmp/phase14-3-qemu-1775191337` Confirmed: ```text disk_capacity=8g root_size=6g bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE native_base_store_count=3 host_base_store_count=0 shepherd_pid=1 sshd_status=running native_split_boot=ok ``` ### Real XCP-ng VM Passing run: - `PASS phase14-native-split-xcpng` - workdir: `/tmp/phase14-3-xcpng-1775191743` Confirmed: ```text vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289 vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743 guest_ip=192.168.213.62 root_size=6g bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE native_base_store_count=3 host_base_store_count=0 shepherd_pid=1 sshd_status=running compat_prefix_shims=absent guile_module_smoke=ok native_split_boot=ok ``` Notably, after the narrower native split, the XCP-ng upload size dropped back down dramatically: - dynamic VHD upload: `1560725504` bytes (~1.45 GiB) That is much better than the temporary broad-world + runtime duplication in Phase 14.2. ## Result Phase 14 is complete. Fruix now has a validated, host-base-free FreeBSD system path built from native artifacts in `/frx/store`: - `freebsd-native-kernel` - `freebsd-native-bootloader` - `freebsd-native-runtime` with a clearer development boundary via: - `freebsd-native-headers` - `%freebsd-native-development-profile-packages` This completes the Phase 14 objective of incrementally replacing the host-copy FreeBSD base layer for the validated boot/runtime path. ## Next step Proceed to Phase 15: 1. make the FreeBSD base version a declarative input 2. demonstrate side-by-side base versions in `/frx/store` 3. establish rebuild/redeploy/rollback across those base versions