Files
fruix/docs/reports/postphase10-runtime-prefix-shims-freebsd.md

5.5 KiB

Post-Phase-10: removed runtime dependence on /tmp Guile/Shepherd compatibility-prefix shims

Date: 2026-04-02

Goal

After validating both the rc.d bridge path and the new Shepherd-as-PID-1 path, the next priority was the remaining runtime-artifact problem:

  • the guest still carried activation-time /tmp/... compatibility symlinks for locally built Guile, guile-extra, and Shepherd prefixes
  • those shims were compensating for baked-in historical paths in staged runtime artifacts

The goal of this subphase was narrower than fully rebuilding Guile/Shepherd in a store-native way. The immediate target was:

  • remove the guest's runtime dependence on those /tmp compatibility-prefix symlinks,
  • keep both validated boot modes working,
  • and prove that Guile can still load the relevant modules from the store-backed runtime layout without those /tmp aliases.

Result

This subphase succeeded.

The generated guest no longer needs activation to create:

  • /tmp/guile-freebsd-validate-install
  • /tmp/guile-gnutls-freebsd-validate-install
  • /tmp/shepherd-freebsd-validate-install

Those shims are now absent in the booted guest, while both of these boot paths still pass on the real XCP-ng VM:

  1. freebsd-init+rc.d-shepherd
  2. shepherd-pid1

In both cases, the guest now also passes an explicit in-guest Guile module smoke test using the staged store paths and without the /tmp prefix aliases.

What changed

modules/fruix/system/freebsd.scm no longer emits activation logic that recreates the old /tmp/... prefix trees.

That means the guest is no longer depending on those aliases as part of ordinary first boot.

2. The staged runtime prefixes are sanitized as they are materialized into /frx/store

The prefix materializer now post-processes the copied runtime trees so the most relevant runtime-facing Scheme modules no longer require those /tmp prefix aliases.

This required a new prefix-materializer revision and deterministic post-copy sanitation.

3. Guile-extra runtime fixes

The staged guile-extra runtime now:

  • patches fibers/config.scm so it can use GUILE_EXTENSIONS_PATH instead of falling back to the old /tmp/guile-gnutls-freebsd-validate-install/... path
  • patches gnutls.scm so it can fall back to GUILE_EXTENSIONS_PATH
  • removes stale compiled cache files that still embedded the old prefix values and would otherwise override the corrected source modules:
    • fibers/config.go
    • gnutls.go

4. Shepherd runtime fixes

The staged Shepherd runtime now:

  • patches share/guile/site/3.0/shepherd/config.scm to use real runtime-facing paths instead of the old temporary install prefix:
    • Prefix-dir => /frx
    • %localstatedir => /var
    • %runstatedir => /var/run
    • %sysconfdir => /etc
    • %localedir => /usr/share/locale
    • %pkglibdir => /usr/local/lib/shepherd
  • removes the stale compiled cache file that still embedded the old prefix values:
    • shepherd/config.go

5. Real-VM validation harnesses now assert shim absence directly

The main real-VM validation scripts now check that the old /tmp compatibility-prefix trees are absent in the guest:

  • tests/system/run-phase9-xcpng-boot.sh
  • tests/system/run-phase11-shepherd-pid1-xcpng.sh

They also run an in-guest Guile module smoke test using the store-backed runtime environment and require:

  • guile_module_smoke=ok

Validation

Real VM, freebsd-init+rc.d-shepherd

Passing run:

  • PASS phase9-xcpng-boot
  • workdir: /tmp/noshim-phase9-smoke-1775143001

Key metadata:

compat_prefix_shims=absent
guile_module_smoke=ok
ready_marker=ready
shepherd_status=running
sshd_status=running

Real VM, shepherd-pid1

Passing run:

  • PASS phase11-shepherd-pid1-xcpng
  • workdir: /tmp/noshim-phase11-smoke-1775142712

Key metadata:

compat_prefix_shims=absent
guile_module_smoke=ok
ready_marker=ready
shepherd_pid=1
shepherd_status=running
sshd_status=running

Manual guest confirmation

A direct SSH probe on the real guest confirmed that all three historical /tmp compatibility prefixes are absent while Guile can still load:

  • (fibers config)
  • (gnutls)
  • (shepherd config)

with output including:

ABSENT:/tmp/guile-freebsd-validate-install
ABSENT:/tmp/guile-gnutls-freebsd-validate-install
ABSENT:/tmp/shepherd-freebsd-validate-install
1.4.2
/var/run

Assessment

This removes an important transitional runtime crutch.

Fruix is no longer merely booting despite historical /tmp prefix aliases; it now boots and runs Guile/Shepherd services from the staged store-backed runtime arrangement without those guest-side compatibility symlinks.

Remaining limitation

This does not mean every historical prefix string has disappeared from every staged artifact.

Some compiled binaries and libraries still contain old build/install strings internally, especially in places such as:

  • libguile
  • libtool metadata
  • pkg-config metadata
  • extension shared objects built upstream with the original prefixes

However, the important practical milestone is that the guest no longer depends on /tmp compatibility-prefix symlinks at runtime.

The next, deeper cleanup would be to eliminate the remaining baked prefix strings from the runtime artifacts themselves by moving the local Guile/guile-extra/Shepherd build/install flow closer to a genuinely store-native prefix from the start, rather than relying on post-copy sanitation.