3627 lines
173 KiB
Markdown
3627 lines
173 KiB
Markdown
# Progress
|
||
|
||
## 2026-04-01 — Phase 1.1 started: Guile verified on FreeBSD amd64
|
||
|
||
Completed work:
|
||
|
||
- installed/confirmed `guile3-3.0.10`
|
||
- added a reusable verification harness:
|
||
- `tests/guile/run-phase1-verification.sh`
|
||
- `tests/guile/verify-phase1.scm`
|
||
- `tests/guile/modules/phase1/sample.scm`
|
||
- verified the following on `FreeBSD 15.0-STABLE` amd64:
|
||
- module loading
|
||
- deterministic output generation
|
||
- file I/O
|
||
- process handling with `primitive-fork`/`waitpid`
|
||
- loopback TCP sockets
|
||
- FFI calls into libc
|
||
- execution of Guix bootstrap-related code from `(guix build make-bootstrap)`
|
||
- wrote the results to `docs/reports/phase1-guile-freebsd.md`
|
||
|
||
Notable findings:
|
||
|
||
- `guile3` and `guile-3.0` are present, but there is no unversioned `guile` binary
|
||
- `system*` and `open-pipe*` currently segfault on this host (`exit 139`)
|
||
- despite that crash, the lower-level process primitives needed for further investigation do work
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.1 has a solid amd64 smoke-verification baseline
|
||
- Phase 1.1 is not fully complete yet because `i386` has not been checked and the subprocess crash needs investigation
|
||
- verification harness committed as `e380e88` (`Add FreeBSD Guile verification harness`)
|
||
|
||
## 2026-04-01 — Phase 1.1 follow-up: subprocess crash isolated
|
||
|
||
Completed work:
|
||
|
||
- added a dedicated subprocess diagnostic harness:
|
||
- `tests/guile/run-subprocess-diagnostics.sh`
|
||
- `tests/guile/posix-spawn-freebsd-diagnostics.c`
|
||
- reproduced crashes for:
|
||
- `system*`
|
||
- `spawn`
|
||
- `open-pipe*`
|
||
- confirmed all three fail with `SIGSEGV` / `exit 139`
|
||
- confirmed native FreeBSD `posix_spawn` + `posix_spawn_file_actions_addclosefrom_np` works in a standalone C program
|
||
- confirmed FreeBSD behavior that triggers gnulib replacement logic:
|
||
- `posix_spawn_file_actions_adddup2` accepts an invalid fd in the gnulib probe
|
||
- `posix_spawn_file_actions_addopen` accepts an invalid fd in the gnulib probe
|
||
- `posix_spawnp` accepts a shebang-less executable script in the gnulib security probe
|
||
- wrote the analysis to `docs/reports/phase1-guile-subprocess-crash.md`
|
||
|
||
Conclusion:
|
||
|
||
- this is most likely an upstream Guile/gnulib ABI bug on FreeBSD, not a Guix-specific problem
|
||
- likely sequence:
|
||
1. gnulib enables `REPLACE_POSIX_SPAWN=1`
|
||
2. Guile still enables `HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP`
|
||
3. Guile passes a gnulib replacement `posix_spawn_file_actions_t` object to native `posix_spawn_file_actions_addclosefrom_np`
|
||
4. libc interprets gnulib struct fields as a native pointer and crashes
|
||
- evidence from the lldb core matches this hypothesis (`*fa = 0x0000000600000008`, consistent with gnulib `_allocated=8`, `_used=6`)
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.1 amd64 investigation is now much stronger and has a concrete root-cause hypothesis
|
||
- the next practical step is to validate a workaround or patch in Guile so subprocess helpers stop crashing
|
||
- after that, continue with Phase 1.2 (minimal native build environment / GNU Hello)
|
||
|
||
## 2026-04-01 — Phase 1.1 follow-up: local Guile build validated the fix
|
||
|
||
Completed work:
|
||
|
||
- installed the additional build tooling needed for a local Guile checkout build:
|
||
- `autoconf`
|
||
- `automake`
|
||
- `libtool`
|
||
- `gettext-tools`
|
||
- `texinfo`
|
||
- `help2man`
|
||
- `gperf`
|
||
- `pkgconf`
|
||
- confirmed a FreeBSD-specific bootstrap quirk:
|
||
- Guile `autogen.sh` needs GNU `m4`
|
||
- FreeBSD base `/usr/bin/m4` is not sufficient
|
||
- `M4=gm4 ./autogen.sh` works
|
||
- built a disposable validation copy from `~/repos/guile`
|
||
- confirmed `~/repos/guile` already contains upstream commit:
|
||
- `eb828801f621d3e130b6fe88cfc4acaa69b98a03`
|
||
- `Don't use posix_spawn_file_actions_addclosefrom_np with glib posix_spawn`
|
||
- updated the local test harnesses so they can test non-system Guile builds:
|
||
- `tests/guile/run-phase1-verification.sh`
|
||
- `tests/guile/run-subprocess-diagnostics.sh`
|
||
- both now accept `GUILE_BIN`
|
||
- both now prepend the sibling `../lib` directory to `LD_LIBRARY_PATH` when a matching local `libguile-3.0.so.1` exists
|
||
- subprocess diagnostics now supports `EXPECT_GUILE_SUBPROCESS_CRASH=0` for fixed builds
|
||
- validated that the packaged Guile still reproduces the crash
|
||
- validated that the locally built Guile succeeds for:
|
||
- `system*`
|
||
- `spawn`
|
||
- `open-pipe*`
|
||
- re-ran the broader Phase 1.1 Scheme verification suite successfully against the local Guile build
|
||
- wrote the results to `docs/reports/phase1-guile-local-build-validation.md`
|
||
|
||
Important findings:
|
||
|
||
- the local Guile executable initially still crashed until it was forced to load its matching local `libguile-3.0.so.1`
|
||
- once `LD_LIBRARY_PATH` pointed at the local install lib directory, subprocess helpers worked correctly
|
||
- this strongly supports the earlier diagnosis and shows that the upstream Guile fix resolves the problem in practice
|
||
- the local `~/repos/bdwgc` checkout was not needed for this step; packaged `boehm-gc-threaded` was sufficient so far
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.1 now has both a root-cause analysis and a working validated fix path on amd64
|
||
- no source changes were needed in `~/repos/guile` because the local checkout already contains the relevant upstream fix
|
||
- no source changes were needed in `~/repos/bdwgc` yet, but the earlier FreeBSD warning keeps it on the watch list
|
||
- the project can now move on to Phase 1.2 with a known-good local Guile fallback
|
||
|
||
## 2026-04-01 — Phase 1.2 started: native GNU Hello build validated on FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- added a reusable native build harness:
|
||
- `tests/native-build/run-gnu-hello.sh`
|
||
- used the current Guix package definition in `~/repos/guix/gnu/packages/base.scm` as the source of truth for:
|
||
- GNU Hello version `2.12.3`
|
||
- expected Guix nix-base32 source hash `183a6rxnhixiyykd7qis0y9g9cfqhpkk872a245y3zl28can0pqd`
|
||
- verified the downloaded tarball against the translated SHA256:
|
||
- `0d5f60154382fee10b114a1c34e785d8b1f492073ae2d3a6f7b147687b366aa0`
|
||
- successfully executed the standard native build lifecycle on `FreeBSD 15.0-STABLE` amd64:
|
||
- fetch
|
||
- hash verification
|
||
- extract
|
||
- configure
|
||
- build
|
||
- staged install
|
||
- runtime execution
|
||
- confirmed the staged binary runs and prints:
|
||
- `Hello, world!`
|
||
- captured build metadata including:
|
||
- compiler and make versions
|
||
- host triplet
|
||
- configure command
|
||
- staged output path
|
||
- runtime shared-library dependencies
|
||
- wrote the results to `docs/reports/phase1-native-gnu-hello.md`
|
||
|
||
Important findings:
|
||
|
||
- GNU Hello built successfully with FreeBSD base `make`, not just `gmake`
|
||
- that contrasts with the earlier local Guile build, which did require GNU `gmake`
|
||
- even this minimal GNU package links against FreeBSD-userland-provided libraries such as `libiconv` and `libintl`, which is useful data for later Guix package modeling
|
||
- this step is still a native shell-driven build exercise, not yet a real Guix package build
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.2 now has a concrete native autotools success case on FreeBSD
|
||
- the host can perform the basic fetch/verify/configure/build/install/run cycle needed for later `gnu-build-system` adaptation work
|
||
- Guix-specific build orchestration is still missing, but the environmental baseline is stronger now
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. extend Phase 1.2 with at least one additional representative GNU/autotools package build on FreeBSD, or
|
||
2. prototype a tiny Scheme-based `gnu-build-system`-like phase runner using the known-good local Guile path, starting from the GNU Hello flow
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: Guix builder-side GNU Hello phase runner validated
|
||
|
||
Completed work:
|
||
|
||
- added a Scheme-driven GNU Hello build prototype:
|
||
- `tests/native-build/gnu-hello-guix-phase-runner.scm`
|
||
- `tests/native-build/run-gnu-hello-guix-phase-runner.sh`
|
||
- required the previously validated fixed local Guile build for this harness because it depends on subprocess-heavy Scheme operations
|
||
- used Guix modules directly from `~/repos/guix`, including:
|
||
- `(guix base32)`
|
||
- `(guix build gnu-build-system)`
|
||
- `(guix build utils)`
|
||
- fetched and hash-verified GNU Hello `2.12.3` again against the Guix package hash:
|
||
- nix-base32: `183a6rxnhixiyykd7qis0y9g9cfqhpkk872a245y3zl28can0pqd`
|
||
- SHA256: `0d5f60154382fee10b114a1c34e785d8b1f492073ae2d3a6f7b147687b366aa0`
|
||
- successfully executed a subset of Guix builder-side `%standard-phases` on FreeBSD:
|
||
- `set-SOURCE-DATE-EPOCH`
|
||
- `unpack`
|
||
- `configure`
|
||
- `build`
|
||
- `check`
|
||
- `install`
|
||
- installed GNU Hello into a store-like output path under the temporary work directory rather than using a `/usr/local` `DESTDIR` staging layout
|
||
- executed the resulting binary successfully and confirmed output:
|
||
- `Hello, world!`
|
||
- captured metadata including:
|
||
- host triplet
|
||
- selected phase list
|
||
- runtime dependencies
|
||
- test-suite summary
|
||
- wrote the results to `docs/reports/phase1-guix-gnu-hello-phase-runner.md`
|
||
|
||
Important findings:
|
||
|
||
- this is the first validation step in the repo that successfully exercised actual Guix builder-side GNU build logic on FreeBSD instead of only a shell approximation
|
||
- the harness works when driven by the fixed local Guile build, confirming that the earlier Guile subprocess-fix validation is directly useful for FreeBSD Guix build orchestration
|
||
- GNU Hello's `make check` test suite also passed in this mode:
|
||
- total: `7`
|
||
- pass: `7`
|
||
- fail: `0`
|
||
- the resulting binary's runtime dependencies differ from the earlier `/usr/local`-prefixed native shell harness; in this store-like output layout it only showed:
|
||
- `libc.so.7`
|
||
- `libsys.so.7`
|
||
- that difference is a useful clue that Guix-style output layout/build invocation can materially affect FreeBSD runtime linkage behavior
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.2 now has both:
|
||
- a shell-driven native GNU Hello build harness, and
|
||
- a Scheme-driven prototype that uses real Guix builder-side GNU phases
|
||
- this is still short of a true Guix package/derivation build, but it significantly narrows the gap between host validation and real `gnu-build-system` execution on FreeBSD
|
||
- the known-good local Guile path is now validated as part of a practical Guix-adjacent build workflow, not just standalone subprocess diagnostics
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
|
||
Next recommended step:
|
||
|
||
1. run the Scheme-driven phase-runner pattern against at least one more small GNU/autotools package on FreeBSD, or
|
||
2. document the concrete gaps between this prototype and a real Guix package/derivation build, especially around store management and build isolation
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: second Scheme-driven GNU package build validated with GNU which
|
||
|
||
Completed work:
|
||
|
||
- added a second Scheme-driven GNU package harness:
|
||
- `tests/native-build/gnu-which-guix-phase-runner.scm`
|
||
- `tests/native-build/run-gnu-which-guix-phase-runner.sh`
|
||
- again used the previously validated fixed local Guile build because this harness depends on subprocess-heavy Guix/Scheme builder logic
|
||
- used the current Guix package definition in `~/repos/guix/gnu/packages/base.scm` as the source of truth for:
|
||
- GNU which version `2.21`
|
||
- expected Guix nix-base32 source hash `1bgafvy3ypbhhfznwjv1lxmd6mci3x1byilnnkc7gcr486wlb8pl`
|
||
- verified the downloaded tarball against the translated SHA256:
|
||
- `f4a245b94124b377d8b49646bf421f9155d36aa7614b6ebf83705d3ffc76eaad`
|
||
- successfully executed the same subset of Guix builder-side `%standard-phases` on FreeBSD as used for GNU Hello:
|
||
- `set-SOURCE-DATE-EPOCH`
|
||
- `unpack`
|
||
- `configure`
|
||
- `build`
|
||
- `check`
|
||
- `install`
|
||
- executed the resulting `which` binary successfully with a deterministic command:
|
||
- `PATH=/bin:/usr/bin ./which sh`
|
||
- confirmed output:
|
||
- `/bin/sh`
|
||
- captured metadata including:
|
||
- host triplet
|
||
- phase list
|
||
- runtime dependencies
|
||
- check-phase success status
|
||
- executed command output
|
||
- wrote the results to `docs/reports/phase1-guix-which-phase-runner.md`
|
||
|
||
Important findings:
|
||
|
||
- this confirms the Scheme-driven Guix builder-side phase-runner pattern is not limited to GNU Hello; a second small GNU/autotools package also succeeds on FreeBSD
|
||
- GNU which's `check` phase passed, but it did not leave behind an Automake-style `test-suite.log` or `testsuite.log`
|
||
- GNU which emitted a non-fatal `configure` warning about Guix's standard `--enable-fast-install` flag being unrecognized
|
||
- the source also emitted several clang warnings about deprecated non-prototype C declarations/definitions, but the build still completed successfully
|
||
- the resulting `which` binary again showed a minimal store-like runtime linkage profile:
|
||
- `libc.so.7`
|
||
- `libsys.so.7`
|
||
- unlike GNU Hello, the source tree did not present an obvious shipped `config.guess`, so the harness used `cc -dumpmachine` as a fallback for host-triplet metadata
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.2 now has two successful Scheme-driven Guix builder-side GNU package validations on FreeBSD:
|
||
- GNU Hello
|
||
- GNU which
|
||
- this increases confidence that a narrow but real subset of `gnu-build-system` builder-side execution already works on FreeBSD when paired with the fixed local Guile build
|
||
- the next uncertainty is now less about whether basic builder phases run at all, and more about where real Guix package/derivation/store integration and isolation will first require FreeBSD-specific adaptation
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. document the concrete remaining gap between these Scheme-driven phase-runner prototypes and a true Guix package/derivation/store-daemon build on FreeBSD, especially around store management, implicit inputs, and build isolation
|
||
2. or choose a somewhat more demanding GNU package with non-trivial declared inputs to identify the first builder-side FreeBSD adaptation points
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: documented the gap to a real Guix package build
|
||
|
||
Completed work:
|
||
|
||
- analyzed the concrete remaining gap between the current FreeBSD validation harnesses and a real Guix package/derivation/store-daemon build
|
||
- wrote the analysis to:
|
||
- `docs/reports/phase1-guix-build-gap-analysis.md`
|
||
- based the analysis on the current local Guix source tree, including the relevant host-side and daemon-side code paths in:
|
||
- `guix/packages.scm`
|
||
- `guix/build-system/gnu.scm`
|
||
- `guix/gexp.scm`
|
||
- `guix/store.scm`
|
||
- `guix/derivations.scm`
|
||
- `gnu/packages/commencement.scm`
|
||
- `doc/guix.texi`
|
||
- `nix/libstore/build.cc`
|
||
- compared those real Guix layers against the currently validated FreeBSD prototypes:
|
||
- shell-driven native GNU Hello harness
|
||
- Scheme-driven GNU Hello builder-phase runner
|
||
- Scheme-driven GNU which builder-phase runner
|
||
|
||
Main conclusions recorded:
|
||
|
||
- the current FreeBSD work has validated a narrow but real builder-side slice of Guix execution:
|
||
- Guile can run the needed Scheme code when using the fixed local build
|
||
- `(guix build gnu-build-system)` phases can build small GNU packages on FreeBSD
|
||
- however, the current prototypes still bypass several critical layers of a real Guix build:
|
||
- package -> bag lowering
|
||
- bag -> derivation lowering
|
||
- imported module closure/store materialization
|
||
- real daemon RPC and build submission
|
||
- canonical `/gnu/store` management and metadata
|
||
- build users, chroot/container or jail-style isolation
|
||
- substitute/graft/offload handling
|
||
- documented that the current phase runners rely on host tools already present on FreeBSD, whereas real `gnu-build-system` uses implicit inputs drawn from `%final-inputs`
|
||
- identified the most actionable next milestone as a derivation-generation investigation for a tiny package, to locate the first failure boundary among:
|
||
- host-side lowering
|
||
- store interaction
|
||
- derivation emission
|
||
- daemon availability
|
||
- daemon-side execution
|
||
|
||
Current assessment:
|
||
|
||
- Phase 1.2 now has both practical build validation and a clearer architectural map of what remains before a true Guix package build can work on FreeBSD
|
||
- the project has reduced uncertainty around builder-side GNU phase portability
|
||
- the next uncertainty is now specifically the host-side lowering/store/daemon boundary, not the builder-phase boundary
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. investigate whether a tiny package can be lowered far enough on FreeBSD to produce a real derivation, and capture the exact first failure point
|
||
2. if derivation generation proves immediately blocked, document whether the blocker is generated Guix modules/configuration, store connectivity, or daemon assumptions
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: derivation-generation investigation identified the first real checkout blockers
|
||
|
||
Completed work:
|
||
|
||
- added a reproducible checkout/bootstrap/configure investigation harness:
|
||
- `tests/guix/run-derivation-generation-investigation.sh`
|
||
- used the previously validated fixed local Guile build for the investigation:
|
||
- `/tmp/guile-freebsd-validate-install/bin/guile`
|
||
- followed the operator instruction for future store setup by parameterizing the checkout attempts to use:
|
||
- store directory: `/frx/store`
|
||
- local state directory: `/frx/var`
|
||
- sysconf directory: `/frx/etc`
|
||
- created a disposable shared clone of `~/repos/guix`
|
||
- successfully ran `./bootstrap` from that disposable checkout on FreeBSD
|
||
- attempted `configure` without `--with-courage`
|
||
- attempted `configure` again with `--with-courage`
|
||
- confirmed directly that the local fixed Guile build currently cannot load:
|
||
- `(gnutls)`
|
||
- wrote the results to:
|
||
- `docs/reports/phase1-guix-derivation-generation-investigation.md`
|
||
|
||
Important findings:
|
||
|
||
- a stock Guix checkout currently fails configuration on FreeBSD before any derivation/store/daemon work is reached, due to the explicit unsupported-platform gate:
|
||
- ``configure: error: `x86_64-freebsd15.0' is not a supported platform.``
|
||
- re-running `configure` with `--with-courage` gets past that gate, but then stops on a second blocker:
|
||
- `configure: error: The Guile bindings of GnuTLS are missing; please install them.`
|
||
- a direct module-load test with the same local Guile confirms the problem more concretely:
|
||
- `(use-modules (gnutls))` fails with `no code for module (gnutls)`
|
||
- this means the current effort is still blocked before reaching:
|
||
- usable `pre-inst-env` generation for Guix commands
|
||
- package -> bag lowering in a live checkout
|
||
- bag -> derivation lowering
|
||
- daemon connectivity
|
||
- actual `/frx/store` population
|
||
|
||
Current assessment:
|
||
|
||
- the first practical boundary between the earlier FreeBSD builder-phase prototypes and a real Guix checkout has now been located more precisely
|
||
- the project is no longer blocked by vague uncertainty at this stage; it is blocked by two concrete checkout-preparation issues:
|
||
1. unsupported-platform configure gating
|
||
2. missing Guile `(gnutls)` bindings
|
||
- importantly, the derivation-generation investigation has not yet reached the store/daemon boundary, so the next step must first clear the `(gnutls)` dependency issue
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
|
||
Next recommended step:
|
||
|
||
1. obtain working Guile `(gnutls)` bindings compatible with the fixed local Guile build and re-run the derivation-generation investigation
|
||
2. once configuration succeeds, continue until the next failure boundary is identified among:
|
||
- `pre-inst-env` usability
|
||
- derivation emission
|
||
- daemon connectivity
|
||
- daemon-side `/frx/store` assumptions
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: local Guile-GnuTLS built on FreeBSD; next blocker is Guile-Git
|
||
|
||
Completed work:
|
||
|
||
- installed the host-side C GnuTLS stack needed for Guile-GnuTLS builds:
|
||
- `gnutls`
|
||
- `libtasn1`
|
||
- `nettle`
|
||
- `p11-kit`
|
||
- added a reproducible local Guile-GnuTLS build harness:
|
||
- `tests/guix/build-local-guile-gnutls.sh`
|
||
- updated the derivation-generation investigation harness so it can consume extra Guile module prefixes through:
|
||
- `GUILE_EXTRA_PREFIX`
|
||
- used the current Guix package definition in `~/repos/guix/gnu/packages/tls.scm` as the source of truth for:
|
||
- `guile-gnutls` version `5.0.1`
|
||
- expected Guix nix-base32 source hash `0kqngyx4520gjk49l6whjd2ss994kaj9rm78lli6p3q6xry0945i`
|
||
- verified the downloaded Guile-GnuTLS tarball against the translated SHA256:
|
||
- `b190047cee068f6b22a5e8d49ca49a2425ad4593901b9ac8940f8842ba7f164f`
|
||
- built and installed a local Guile-GnuTLS validation copy against the previously validated fixed local Guile build under:
|
||
- `/tmp/guile-gnutls-freebsd-validate-install`
|
||
- validated successfully that the fixed local Guile can now load:
|
||
- `(gnutls)`
|
||
- re-ran the checkout derivation-generation investigation with:
|
||
- `GUILE_EXTRA_PREFIX=/tmp/guile-gnutls-freebsd-validate-install`
|
||
- store directory still set to `/frx/store`
|
||
- wrote the results to:
|
||
- `docs/reports/phase1-guile-gnutls-freebsd.md`
|
||
|
||
Important findings:
|
||
|
||
- Guile-GnuTLS does not build with FreeBSD base `make`; it requires GNU `gmake`
|
||
- a FreeBSD-specific source compatibility issue surfaced in `guile/src/core.c`:
|
||
- it includes `<alloca.h>` unconditionally
|
||
- on this host, `alloca` is available through `<stdlib.h>` instead
|
||
- for local validation, the harness applies a small disposable-tree patch that uses `<stdlib.h>` on `__FreeBSD__`
|
||
- after that fix, the local Guile-GnuTLS build succeeded and `(use-modules (gnutls))` worked with the fixed local Guile build
|
||
- re-running the Guix checkout investigation confirms the earlier `(gnutls)` blocker is genuinely cleared
|
||
- the next configure-time blocker is now:
|
||
- `configure: error: Guile-Git is missing; please install it.`
|
||
|
||
Current assessment:
|
||
|
||
- the first checkout-preparation blocker after unsupported-platform gating has advanced from missing `(gnutls)` to missing `Guile-Git`
|
||
- this is meaningful progress because the project is now moving farther into the dependency chain required for a real Guix checkout on FreeBSD
|
||
- the requested experimental store path remains `/frx/store`, but the effort still has not yet reached actual store population or daemon interaction
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. obtain `Guile-Git` compatible with the fixed local Guile build and re-run the derivation-generation investigation again
|
||
2. once checkout configuration succeeds, continue until the next failure boundary is identified among:
|
||
- `pre-inst-env` usability
|
||
- derivation emission
|
||
- daemon connectivity
|
||
- daemon-side `/frx/store` assumptions
|
||
3. continue keeping `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: local Guile-Git stack built on FreeBSD; next blocker is Guile-JSON
|
||
|
||
Completed work:
|
||
|
||
- added a reproducible local Guile-Git dependency-stack build harness:
|
||
- `tests/guix/build-local-guile-git.sh`
|
||
- updated the derivation-generation investigation harness to probe and record both:
|
||
- local `(gnutls)` availability
|
||
- local `(git)` / `graph-descendant?` availability
|
||
- used the current Guix package definitions in `~/repos/guix/gnu/packages/guile.scm` as the source of truth for:
|
||
- `guile-bytestructures` version `1.0.10`
|
||
- `guile-git` version `0.10.0`
|
||
- built `guile-bytestructures` from the matching upstream tag and recorded resolved commit:
|
||
- `27cadba6b69a01b38b33bb39b9766d713eb90c1b`
|
||
- built `guile-git` from the matching upstream tag and recorded resolved commit:
|
||
- `05d4a48c811f29c8db80ee6697fe658950fb503e`
|
||
- installed both into the same local dependency prefix already used for the earlier Guile-GnuTLS validation:
|
||
- `/tmp/guile-gnutls-freebsd-validate-install`
|
||
- validated successfully that the fixed local Guile can now load:
|
||
- `(bytestructures guile)`
|
||
- `(git)`
|
||
- validated specifically that the Guile-Git export required by Guix `configure.ac` is present:
|
||
- `graph-descendant?`
|
||
- confirmed the host `libgit2` dependency used for the build is:
|
||
- `1.9.2`
|
||
- re-ran the checkout derivation-generation investigation with:
|
||
- `GUILE_EXTRA_PREFIX=/tmp/guile-gnutls-freebsd-validate-install`
|
||
- store directory still set to `/frx/store`
|
||
- wrote the results to:
|
||
- `docs/reports/phase1-guile-git-freebsd.md`
|
||
|
||
Important findings:
|
||
|
||
- both `guile-bytestructures` and `guile-git` were built from Git source layouts, so autotools regeneration was required:
|
||
- `guile-bytestructures`: `autoreconf -vfi`
|
||
- `guile-git`: `autoreconf -vfi` via harness fallback
|
||
- unlike the earlier Guile-GnuTLS step, no additional FreeBSD-specific source patch was needed for either package in this validation pass
|
||
- the Guix checkout now gets past both previously cleared dependency gates:
|
||
- `(gnutls)`
|
||
- `Guile-Git`
|
||
- after clearing those, the next configure-time blocker is now:
|
||
- `configure: error: Guile-JSON is missing; please install it.`
|
||
|
||
Current assessment:
|
||
|
||
- the checkout-preparation path on FreeBSD has progressed one dependency layer deeper
|
||
- the local validation prefix under `/tmp/guile-gnutls-freebsd-validate-install` now contains at least:
|
||
- Guile-GnuTLS
|
||
- Guile bytestructures
|
||
- Guile-Git
|
||
- despite that progress, the work still has not yet reached derivation emission, daemon connectivity, or actual `/frx/store` population
|
||
- the next concrete blocker is now `Guile-JSON`, as reported directly by the real Guix checkout configure step
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. obtain `Guile-JSON` compatible with the fixed local Guile build and install it into the same local dependency prefix
|
||
2. re-run the derivation-generation investigation again to identify the next configure-time or checkout-time blocker after `Guile-JSON`
|
||
3. continue keeping `/frx/store` as the intended experimental store root and keep `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: local Guile-JSON built on FreeBSD; next blocker is Guile-SQLite3
|
||
|
||
Completed work:
|
||
|
||
- added a reproducible local Guile-JSON build harness:
|
||
- `tests/guix/build-local-guile-json.sh`
|
||
- updated the derivation-generation investigation harness to probe and record local recent-enough `(json)` availability in addition to the earlier `(gnutls)` and `(git)` checks
|
||
- used the current Guix package definition in `~/repos/guix/gnu/packages/guile.scm` as the source of truth for:
|
||
- `guile-json` version `4.7.3`
|
||
- expected Guix nix-base32 source hash `127k2xc07w1gnyqs40z4865l8p3ra5xgpcn569dz04lxsa709fiq`
|
||
- verified the downloaded Guile-JSON tarball against the translated SHA256:
|
||
- `38ba048ed29d12f05b32c5b2fb7a51795c448b41e403a2b1b72ff0035817f388`
|
||
- built and installed a local Guile-JSON validation copy into the same local dependency prefix already used for checkout prerequisites:
|
||
- `/tmp/guile-gnutls-freebsd-validate-install`
|
||
- validated successfully that the fixed local Guile now satisfies the Guix configure-time JSON requirement by:
|
||
- loading `(json)`
|
||
- using `define-json-mapping`
|
||
- decoding a small JSON object successfully
|
||
- re-ran the checkout derivation-generation investigation with:
|
||
- `GUILE_EXTRA_PREFIX=/tmp/guile-gnutls-freebsd-validate-install`
|
||
- store directory still set to `/frx/store`
|
||
- wrote the results to:
|
||
- `docs/reports/phase1-guile-json-freebsd.md`
|
||
|
||
Important findings:
|
||
|
||
- unlike the earlier Guile-Git step, Guile-JSON built cleanly from the release tarball and did not require autotools regeneration in this validation pass
|
||
- unlike the earlier Guile-GnuTLS step, no FreeBSD-specific source patch was needed here
|
||
- the shared local validation prefix now contains at least:
|
||
- Guile-GnuTLS
|
||
- Guile bytestructures
|
||
- Guile-Git
|
||
- Guile-JSON
|
||
- the Guix checkout now gets past the previously cleared dependency gates for:
|
||
- `(gnutls)`
|
||
- `Guile-Git`
|
||
- `Guile-JSON`
|
||
- after clearing those, the next configure-time blocker is now:
|
||
- `configure: error: A recent Guile-SQLite3 could not be found; please install it.`
|
||
|
||
Current assessment:
|
||
|
||
- the checkout-preparation path on FreeBSD has progressed another dependency layer deeper
|
||
- the project still has not yet reached derivation emission, daemon connectivity, or actual `/frx/store` population
|
||
- the next concrete blocker is now recent `Guile-SQLite3`, as reported directly by the real Guix checkout configure step
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. obtain recent `Guile-SQLite3` compatible with the fixed local Guile build and install it into the same local dependency prefix
|
||
2. re-run the derivation-generation investigation again to identify the next configure-time or checkout-time blocker after `Guile-SQLite3`
|
||
3. continue keeping `/frx/store` as the intended experimental store root and keep `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.2 follow-up: remaining checkout Guile prerequisites built; next blocker is `./pre-inst-env guix --version`
|
||
|
||
Completed work:
|
||
|
||
- installed the remaining missing host C library dependencies required for the next Guile extension stack:
|
||
- `libgcrypt`
|
||
- `libgpg-error`
|
||
- `lzlib`
|
||
- added a reproducible build harness for the remaining mandatory Guix checkout Guile modules:
|
||
- `tests/guix/build-local-guile-configure-deps.sh`
|
||
- extended the derivation-generation investigation harness to:
|
||
- probe local recent-enough availability for:
|
||
- `(sqlite3)`
|
||
- `(gcrypt hash)`
|
||
- `(zlib)`
|
||
- `(lzlib)`
|
||
- `(semver)`
|
||
- run checkout `configure` with:
|
||
- `MAKE=gmake`
|
||
- continue past successful configuration into:
|
||
- `gmake scripts/guix`
|
||
- `./pre-inst-env guix --version`
|
||
- used the current Guix package definitions as source of truth for the following additional module stack:
|
||
- `guile-sqlite3` `0.1.3`
|
||
- `guile-gcrypt` `0.5.0`
|
||
- `guile-zlib` `0.2.2`
|
||
- `guile-lzlib` `0.3.0`
|
||
- `guile-semver` `0.2.0`
|
||
- built and installed those modules into the same shared local dependency prefix already used for prior checkout prerequisites:
|
||
- `/tmp/guile-gnutls-freebsd-validate-install`
|
||
- validated successfully that the fixed local Guile can now satisfy all of the remaining configure-time Guix module checks encountered so far:
|
||
- `(sqlite3)` with `sqlite-bind-arguments`
|
||
- `(gcrypt hash)` with `hash-algorithm` lookup
|
||
- `(zlib)` with `make-zlib-input-port`
|
||
- `(lzlib)`
|
||
- `(semver)`
|
||
- re-ran the checkout derivation-generation investigation with:
|
||
- `GUILE_EXTRA_PREFIX=/tmp/guile-gnutls-freebsd-validate-install`
|
||
- store directory still set to `/frx/store`
|
||
- wrote the results to:
|
||
- `docs/reports/phase1-guix-checkout-configure-stack-freebsd.md`
|
||
|
||
Important findings:
|
||
|
||
- `guile-gcrypt` required an explicit configure workaround on this host:
|
||
- `--with-libgcrypt-prefix=/usr/local`
|
||
- without it, the package's `libgcrypt-config --libs` parsing produced an unusable shared-library name on FreeBSD
|
||
- the currently served upstream `guile-lzlib` `0.3.0` tarball no longer matches the Guix-recorded hash:
|
||
- expected from Guix: `a7f99c8d2a143e05ea22db2dc8b9ce6c27cae942162b45ee3015ed9027af0ff2`
|
||
- observed from current source URL: `6a2847a303a141bb95b1b5d1a4b975b4dbff9cc590eba377cc8072682e7637ec`
|
||
- for local validation, the harness fell back to the matching upstream Git tag and recorded commit:
|
||
- `474cee42116295bc0bd2acf12d4d6a766043090e`
|
||
- once the remaining Guile modules were present, checkout `configure --with-courage` stopped failing on missing modules
|
||
- however, the checkout still needed:
|
||
- `MAKE=gmake`
|
||
to complete configuration successfully on FreeBSD
|
||
- after that, `gmake scripts/guix` succeeded as well
|
||
- the next concrete blocker has moved from configuration-time prerequisites to runtime behavior of the uninstalled Guix command path:
|
||
- `./pre-inst-env guix --version` prints the version banner, then exits with:
|
||
- `Wrong type to apply: #<syntax-transformer leave-on-EPIPE>`
|
||
|
||
Current assessment:
|
||
|
||
- the checkout-preparation path on FreeBSD has now progressed beyond the missing mandatory Guile module stack that previously blocked configuration
|
||
- the current local validation prefix now contains the required configure-time modules encountered so far for a real Guix checkout
|
||
- the first blocker after successful checkout configuration and `scripts/guix` generation is now a runtime Scheme failure in the uninstalled `guix` command path itself
|
||
- the work is therefore now meaningfully past “cannot configure” and into “configures, builds `scripts/guix`, but fails at `./pre-inst-env guix --version`”
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. investigate the `leave-on-EPIPE` runtime failure now blocking `./pre-inst-env guix --version`
|
||
2. complete the remaining Phase 1.3 FreeBSD system-call mapping/documentation deliverable so Phase 1 foundations can be closed out cleanly
|
||
3. continue keeping `/frx/store` as the intended experimental store root and keep `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 1.3 completed: FreeBSD syscall/interface mapping documented and exercised
|
||
|
||
Completed work:
|
||
|
||
- added a runnable C syscall/interface mapping harness:
|
||
- `tests/system/freebsd-syscall-mapping.c`
|
||
- added a shell runner for the mapping harness:
|
||
- `tests/system/run-freebsd-syscall-mapping.sh`
|
||
- inspected current Guix/Linux-oriented source paths relevant to daemon/build isolation and host behavior, especially:
|
||
- `~/repos/guix/nix/libstore/build.cc`
|
||
- `~/repos/guix/configure.ac`
|
||
- inspected the relevant FreeBSD interfaces/documentation available on the host, including:
|
||
- `jail(2)`
|
||
- `chroot(2)`
|
||
- `closefrom(2)` / `close_range(2)`
|
||
- `mount(2)` / `nmount(2)`
|
||
- `mount_nullfs(8)`
|
||
- `cap_enter(2)`
|
||
- `cap_rights_limit(2)`
|
||
- `lutimes(2)`
|
||
- `lchown(2)`
|
||
- `posix_fallocate(2)`
|
||
- `pdfork(2)`
|
||
- ran the new syscall mapping harness successfully and captured metadata under:
|
||
- `/tmp/freebsd-syscall-mapping-metadata.txt`
|
||
- wrote the Phase 1.3 report to:
|
||
- `docs/reports/phase1-freebsd-syscall-mapping.md`
|
||
|
||
Important findings:
|
||
|
||
- the current FreeBSD host provides and the harness successfully exercised:
|
||
- `fork` / `waitpid`
|
||
- `posix_spawn_file_actions_addclosefrom_np`
|
||
- `close_range`
|
||
- `lutimes`
|
||
- `statvfs`
|
||
- `chroot` (root test)
|
||
- `jail(2)` (root test)
|
||
- `lchown` (root test)
|
||
- the same harness confirmed the absence of the key Linux namespace-oriented interfaces that current Guix daemon code depends on:
|
||
- `clone`
|
||
- `unshare`
|
||
- `setns`
|
||
- `pivot_root`
|
||
- `sys/prctl.h`
|
||
- FreeBSD Capsicum headers are present, which is useful context for later security design, but Capsicum is not a direct replacement for Linux namespaces or Linux capabilities
|
||
- `posix_fallocate` is present but returned `EOPNOTSUPP` on the tested filesystems, so a successful configure/link probe does not guarantee useful runtime semantics
|
||
- the mapping strongly confirms that the correct Phase 2 direction is not syscall emulation but a jail-first redesign using:
|
||
- jails
|
||
- `chroot`
|
||
- `nullfs`
|
||
- traditional build-user privilege separation
|
||
|
||
Current assessment:
|
||
|
||
- the Phase 1.3 deliverable is now satisfied with both:
|
||
- a technical mapping document, and
|
||
- a runnable validation harness
|
||
- the main architectural conclusion is now concrete rather than speculative:
|
||
- Linux namespace code paths in current Guix daemon/build isolation cannot be ported directly to FreeBSD
|
||
- the FreeBSD implementation must instead be designed around jails and explicit mount/layout control
|
||
|
||
## 2026-04-01 — Phase 1 completed on the current FreeBSD amd64 porting track
|
||
|
||
Phase 1 is now considered complete for the active amd64 FreeBSD host path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 1.1** success criteria were met on the current host:
|
||
- Guile executes Guix bootstrap-related code
|
||
- deterministic/module/FFI/socket/process validation succeeded
|
||
- the FreeBSD subprocess crash was root-caused and a working fixed local Guile path was validated
|
||
- **Phase 1.2** success criteria were exceeded:
|
||
- native GNU Hello build success was demonstrated
|
||
- multiple Guix builder-side GNU phase validations succeeded
|
||
- a real Guix checkout now configures on FreeBSD with local dependency supplementation, builds `scripts/guix`, and reaches a concrete runtime blocker at:
|
||
- `./pre-inst-env guix --version`
|
||
- **Phase 1.3** is now completed with the syscall/interface mapping document and runnable harness
|
||
|
||
Important scope note:
|
||
|
||
- the original Phase 1.1 narrative mentioned `i386` as additional target coverage, but the explicit success criteria used to gate progression have been satisfied on the active amd64 FreeBSD host
|
||
- full i386 Guile validation remains useful future coverage work, but it is no longer the blocker for moving into Phase 2 design/prototyping on this machine
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 2.1 by turning the new syscall mapping into a concrete FreeBSD jail-based build-isolation design/prototype
|
||
2. carry forward the current concrete runtime blocker from Phase 1.2:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
3. continue keeping `/frx/store` as the intended experimental store root and keep `~/repos/bdwgc` in reserve if later FreeBSD-specific GC/thread issues appear
|
||
|
||
## 2026-04-01 — Phase 2.1 completed: jail-first build isolation design validated on FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- added a runnable jail-based build isolation prototype:
|
||
- `tests/daemon/run-freebsd-jail-build-prototype.sh`
|
||
- wrote the Phase 2.1 design/prototype report:
|
||
- `docs/reports/phase2-freebsd-jail-build-isolation.md`
|
||
- translated the earlier Phase 1 syscall mapping into a concrete FreeBSD Guix-daemon isolation design centered on:
|
||
- thin jails
|
||
- one jail per build
|
||
- explicit `nullfs` mount plans
|
||
- networking disabled by default
|
||
- separate build-user credentials inside the jail envelope
|
||
- ran the jail prototype successfully and captured metadata under:
|
||
- `/tmp/jail-build-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- a thin-jail approach is the right match for Guix's declared-input model; thick jails would overexpose ambient host state and add unnecessary duplication
|
||
- a per-build jail root assembled from explicit read-only `nullfs` mounts is a practical replacement for the Linux bind-mount + mount-namespace model in current Guix daemon code
|
||
- a basic build operation can already be executed successfully inside a FreeBSD jail with a restricted filesystem view consisting only of:
|
||
- selected read-only host toolchain paths
|
||
- a read-only declared input directory
|
||
- a writable declared output directory
|
||
- a writable `/tmp`
|
||
- a host sentinel file left outside the jail root is not visible inside the build environment, confirming the prototype is exercising real visibility restriction rather than a mere chroot-like shell wrapper
|
||
- the prototype jail ran with:
|
||
- `ip4=disable`
|
||
- `ip6=disable`
|
||
which matches the intended default for hermetic builds
|
||
|
||
Current assessment:
|
||
|
||
- Phase 2.1 is now satisfied on the current FreeBSD prototype track
|
||
- the main design decision is now concrete rather than speculative:
|
||
- the Guix FreeBSD daemon path should be jail-first, not Linux-namespace emulation
|
||
- the next step is to add a build-user privilege-dropping prototype inside or alongside this jail model so the design covers both containment and user-level isolation
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
|
||
Next recommended step:
|
||
|
||
1. implement the Phase 2.2 privilege-dropping/build-user prototype for FreeBSD, ideally combined with the new jail execution model
|
||
2. then establish a `/frx/store`-based store-management prototype covering permissions, package readability, and garbage-collection behavior
|
||
3. continue carrying the separate Guix checkout runtime blocker:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
|
||
## 2026-04-01 — Phase 2.2 completed: privilege dropping and concurrent build-user isolation validated
|
||
|
||
Completed work:
|
||
|
||
- added a C helper implementing the core daemon-side privilege drop mechanics:
|
||
- `tests/daemon/freebsd-build-user-helper.c`
|
||
- added a harness that combines that helper with the new jail model and runs two jobs concurrently:
|
||
- `tests/daemon/run-freebsd-privilege-drop-prototype.sh`
|
||
- wrote the Phase 2.2 report:
|
||
- `docs/reports/phase2-freebsd-privilege-drop.md`
|
||
- ran the concurrent build-user prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-privdrop-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- a root-launched FreeBSD helper can successfully perform the expected daemon-side transition:
|
||
- `setgroups`
|
||
- `setgid`
|
||
- `setuid`
|
||
into a dedicated build identity
|
||
- once dropped, the helper cannot regain root with `setuid(0)`:
|
||
- `Operation not permitted`
|
||
- each build job can create files in its own writable directory and those files end up owned by the dropped build UID/GID rather than by root
|
||
- two concurrent jobs using distinct numeric build identities succeeded with:
|
||
- job 1 UID/GID `35001:35001`
|
||
- job 2 UID/GID `35002:35002`
|
||
- host-side result files were observed with the matching ownership and restrictive permissions:
|
||
- `0600`
|
||
- the two jobs were deliberately held for two seconds each and the measured wall-clock elapsed time was also about two seconds, demonstrating actual concurrent execution rather than serialized execution
|
||
- two complementary denial modes were validated at the same time:
|
||
- peer build files mounted but blocked by permissions: `Permission denied`
|
||
- host path not mounted into the jail at all: `No such file or directory`
|
||
- the dropped build user also could not:
|
||
- create files in a protected root-owned directory
|
||
- `chown` its own output back to root
|
||
|
||
Current assessment:
|
||
|
||
- Phase 2.2 is now satisfied on the current FreeBSD prototype track
|
||
- the combined jail + build-user model now has practical validation for the most important security properties required by a future FreeBSD Guix daemon:
|
||
- root-controlled setup
|
||
- permanent drop to build credentials
|
||
- per-build writable areas
|
||
- cross-build isolation
|
||
- concurrent execution under distinct identities
|
||
- the remaining Phase 2 work is now centered on the store itself: permissions, readability, content-addressed layout, and garbage-collection behavior under `/frx/store`
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
|
||
Next recommended step:
|
||
|
||
1. complete Phase 2.3 by establishing a `/frx/store`-based store prototype with:
|
||
- correct root/daemon write restrictions
|
||
- unprivileged read access
|
||
- content-addressed path naming
|
||
- garbage-collection behavior
|
||
2. if possible, use outputs or dependency relationships realistic enough to model how a future FreeBSD Guix daemon would retain referenced store items
|
||
3. continue carrying the separate Guix checkout runtime blocker:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
|
||
## 2026-04-01 — Phase 2.3 completed: `/frx/store` prototype validated on FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- added a runnable `/frx/store` prototype harness:
|
||
- `tests/store/run-freebsd-store-prototype.sh`
|
||
- wrote the Phase 2.3 report:
|
||
- `docs/reports/phase2-freebsd-store-prototype.md`
|
||
- created and exercised the operator-requested `/frx` layout on-host:
|
||
- `/frx/store`
|
||
- `/frx/var`
|
||
- `/frx/etc`
|
||
- `/frx/var/fruix/gcroots`
|
||
- created a store group for the prototype path:
|
||
- `fruixbuild`
|
||
- ran the store prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-store-prototype-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the current host now has a working `/frx/store` prototype owned as:
|
||
- `root:fruixbuild`
|
||
with mode:
|
||
- `drwxrwxr-t`
|
||
- the prototype successfully created content-addressed demo store items under `/frx/store` using hash-based names
|
||
- the demo item set included:
|
||
- rooted greeting data
|
||
- a rooted app referencing that data through an absolute store path
|
||
- an unrooted orphan item intended for collection
|
||
- an unprivileged user (`nobody`) could:
|
||
- read store data
|
||
- execute the demo app from the store
|
||
- the same unprivileged user could not:
|
||
- create files directly in `/frx/store`
|
||
and the observed failure was:
|
||
- `Permission denied`
|
||
- the prototype GC logic followed rooted references successfully:
|
||
- with a GC root present, the app and its referenced data survived while the orphan item was collected
|
||
- after removing the GC root, the remaining demo items were collected as well
|
||
- the demo store returned to an empty state after the second GC pass, so the host is left with the `/frx` skeleton but without lingering prototype payloads
|
||
|
||
Current assessment:
|
||
|
||
- Phase 2.3 is now satisfied on the current FreeBSD prototype track
|
||
- the core store assumptions needed for a FreeBSD Guix-daemon design have practical validation now:
|
||
- `/frx/store` path viability
|
||
- root-controlled mutation
|
||
- unprivileged read access
|
||
- immutable absolute store references
|
||
- root-managed GC roots and mark/sweep retention behavior
|
||
- remaining gaps are now above this architectural layer rather than below it:
|
||
- real derivation registration
|
||
- SQLite-backed store metadata
|
||
- daemon RPC integration
|
||
- actual package lowering/build submission using these mechanisms
|
||
|
||
## 2026-04-01 — Phase 2 completed on the current FreeBSD prototype track
|
||
|
||
Phase 2 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 2.1** success criteria were met:
|
||
- a detailed jail-first build-isolation design was produced
|
||
- a runnable prototype successfully executed a build command in a restricted FreeBSD jail
|
||
- **Phase 2.2** success criteria were met:
|
||
- a concrete C privilege-dropping implementation was added
|
||
- build-user credential drop, inability to regain root, and concurrent cross-build isolation were demonstrated
|
||
- **Phase 2.3** success criteria were met on the prototype track:
|
||
- a working `/frx/store` equivalent was established
|
||
- content-addressed demo store items were created and consumed
|
||
- unprivileged read vs. privileged write behavior was validated
|
||
- garbage-collection behavior over rooted references was demonstrated
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **core daemon architecture adaptation** milestone, not a full Guix-daemon port
|
||
- the separate real-checkout blocker from Phase 1 remains relevant for later integration work:
|
||
- `./pre-inst-env guix --version` still fails with `Wrong type to apply: #<syntax-transformer leave-on-EPIPE>`
|
||
- however, that runtime issue no longer blocks the specific Phase 2 architectural deliverables because the jail, privilege, and store assumptions have now been validated independently on FreeBSD
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 3.1 by adapting Guix build-system expectations to the now-validated jail/privilege/store model on FreeBSD
|
||
2. carry forward the concrete real-checkout runtime blocker for later integration work:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
3. continue using `/frx/store` rather than `/gnu/store` for FreeBSD store experiments
|
||
|
||
## 2026-04-01 — Phase 3.1 completed: reusable FreeBSD GNU build-system adaptation validated across five packages
|
||
|
||
Completed work:
|
||
|
||
- added a reusable Scheme runner for FreeBSD-adapted GNU package builds:
|
||
- `tests/build-system/gnu-package-freebsd-phase-runner.scm`
|
||
- added a shell wrapper for the generic runner:
|
||
- `tests/build-system/run-gnu-package-freebsd-phase-runner.sh`
|
||
- added a five-package validation matrix:
|
||
- `tests/build-system/run-freebsd-gnu-package-matrix.sh`
|
||
- wrote the Phase 3.1 report:
|
||
- `docs/reports/phase3-freebsd-gnu-build-system.md`
|
||
- ran the matrix successfully and captured summary metadata under:
|
||
- `/tmp/freebsd-gnu-package-matrix-summary.txt`
|
||
|
||
Important findings:
|
||
|
||
- the build adaptation is now centralized rather than package-specific and is applied through a dedicated pre-configure FreeBSD environment phase
|
||
- the adaptation consistently uses:
|
||
- GNU `gmake` via a `make` path shim
|
||
- FreeBSD Clang via `cc`/`gcc` and `c++`/`g++` tool shims
|
||
- `CONFIG_SHELL=/bin/sh`
|
||
- `/usr/local` include/library/pkg-config search paths
|
||
- five representative GNU packages from current Guix package definitions now build successfully through the adapted runner on the current FreeBSD amd64 host:
|
||
- `hello` `2.12.3`
|
||
- `which` `2.21`
|
||
- `time` `1.9`
|
||
- `patch` `2.8`
|
||
- `nano` `8.7.1`
|
||
- the resulting binaries executed correctly with deterministic checks appropriate to each package:
|
||
- `hello` -> `Hello, world!`
|
||
- `which` -> `/bin/sh`
|
||
- `time` -> `time (GNU Time) 1.9`
|
||
- `patch` -> `GNU patch 2.8`
|
||
- `nano` -> `GNU nano, version 8.7.1`
|
||
- the matrix also validated a package with meaningful runtime dependencies:
|
||
- `nano` linked against FreeBSD/base and `/usr/local` libraries including `libintl`, `libmagic`, `libncursesw`, `libtinfow`, and `libz`
|
||
- one package-specific FreeBSD test boundary was recorded explicitly instead of being hidden:
|
||
- `time` required `RUN_TESTS=0` because the upstream `time-max-rss` test was not reliable on this host
|
||
|
||
Current assessment:
|
||
|
||
- Phase 3.1 is now satisfied on the current prototype track
|
||
- the main question has shifted from “can adapted GNU builder phases run on FreeBSD?” to “how should FreeBSD system components themselves be described and installed as profile-usable packages?”
|
||
- the next step is therefore Phase 3.2: define a minimal FreeBSD package set with explicit dependencies and validate profile-style installation/usability
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
- `e404e2e` — `Prototype FreeBSD store management`
|
||
|
||
Next recommended step:
|
||
|
||
1. complete Phase 3.2 by defining a minimal FreeBSD system package set with explicit dependency relationships and profile-style installation validation
|
||
2. carry forward the concrete real-checkout runtime blocker for later integration work:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
3. continue using `/frx/store` rather than `/gnu/store` for future FreeBSD store experiments when the prototype work needs a persistent store root
|
||
|
||
## 2026-04-01 — Phase 3.2 completed: FreeBSD system package-definition prototype and profile validation added
|
||
|
||
Completed work:
|
||
|
||
- added a Guix-style FreeBSD system package-definition prototype module:
|
||
- `modules/fruix/packages/freebsd.scm`
|
||
- added a Scheme harness to materialize those package definitions into store-like outputs and a merged profile:
|
||
- `tests/packages/freebsd-package-profile-prototype.scm`
|
||
- added a shell wrapper for that harness:
|
||
- `tests/packages/run-freebsd-package-profile-prototype.sh`
|
||
- installed the missing host shell dependency needed to satisfy the requested package set:
|
||
- `bash`
|
||
- wrote the Phase 3.2 report:
|
||
- `docs/reports/phase3-freebsd-package-definitions.md`
|
||
- ran the profile prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-package-profile-prototype-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the prototype now defines a minimal FreeBSD core package set covering the categories requested by Phase 3.2:
|
||
- kernel
|
||
- kernel headers
|
||
- libc
|
||
- userland utilities
|
||
- development tools (`clang`, `make`, autotools)
|
||
- minimum system libraries (`openssl`, `zlib`)
|
||
- shells (`sh`, `bash`)
|
||
- the current package-definition layer uses an explicit Guix-like record shape with fields for:
|
||
- name
|
||
- version
|
||
- build system
|
||
- inputs
|
||
- synopsis/description/home-page/license
|
||
- install plan
|
||
- explicit dependency relationships are now encoded and resolved recursively during materialization, including examples such as:
|
||
- `freebsd-libc` -> `freebsd-kernel-headers`
|
||
- `freebsd-userland` -> `freebsd-libc`, `freebsd-sh`
|
||
- `freebsd-clang-toolchain` -> `freebsd-libc`, `freebsd-kernel-headers`, `freebsd-sh`
|
||
- `freebsd-autotools` -> `freebsd-gmake`, `freebsd-bash`, `freebsd-libc`
|
||
- the harness successfully materialized:
|
||
- `11` core package outputs
|
||
into a store-like directory tree under the work directory
|
||
- it then merged those outputs into a development profile and validated that the profile contains working:
|
||
- `bash`
|
||
- `make`
|
||
- `autoconf`
|
||
- `cc`
|
||
- kernel image path
|
||
- kernel-header path
|
||
- core shared-library paths
|
||
- the generated profile compiled and ran a C test program successfully, with observed output:
|
||
- `hello-from-freebsd-profile`
|
||
- for executables installed under `bin/`, the prototype uses wrappers that `exec` the host tool by absolute path; this preserved correct behavior for prefix-sensitive tools such as `autoconf`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 3.2 is now satisfied on the current prototype track
|
||
- Phase 3 as a whole is now completed on the current FreeBSD amd64 path because both:
|
||
- adapted GNU build-system execution, and
|
||
- minimal FreeBSD system package-definition/profile validation
|
||
have been demonstrated successfully
|
||
- the next remaining project milestone is now Phase 4, centered on Shepherd rather than package-building foundations
|
||
|
||
## 2026-04-01 — Phase 3 completed on the current FreeBSD prototype track
|
||
|
||
Phase 3 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 3.1** success criteria were met on the prototype track:
|
||
- a reusable FreeBSD adaptation layer for GNU builder phases was added
|
||
- five representative GNU packages built successfully through that adapted runner
|
||
- the resulting binaries executed correctly on the host
|
||
- **Phase 3.2** success criteria were met on the prototype track:
|
||
- a minimal FreeBSD system package-definition layer was added
|
||
- explicit dependency relationships were modeled and resolved
|
||
- the package outputs installed into a merged profile successfully
|
||
- the generated profile was validated by compiling and running a test program with the staged toolchain
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **build-system adaptation milestone** in prototype form, not the full Guix package-lowering/daemon integration path
|
||
- the earlier concrete upstream/runtime blocker still exists for later integration work:
|
||
- `./pre-inst-env guix --version` fails with `Wrong type to apply: #<syntax-transformer leave-on-EPIPE>`
|
||
- however, that blocker no longer prevents Phase 4 work because the core build-system and package-definition assumptions have now been validated independently
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
- `e404e2e` — `Prototype FreeBSD store management`
|
||
- `eb0d77c` — `Adapt GNU build phases for FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 4.1 by validating whether Shepherd itself now builds and runs as a regular service on FreeBSD with the fixed local Guile path
|
||
2. carry forward the separate real-checkout runtime blocker for later integration work:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
3. continue using `/frx/store` rather than `/gnu/store` for future FreeBSD integration experiments when a persistent store root is required
|
||
|
||
## 2026-04-01 — Phase 4.1 completed: Shepherd built and validated as a regular FreeBSD service manager
|
||
|
||
Completed work:
|
||
|
||
- added a reproducible local Guile Fibers build harness:
|
||
- `tests/shepherd/build-local-guile-fibers.sh`
|
||
- added a reproducible local Shepherd build harness:
|
||
- `tests/shepherd/build-local-shepherd.sh`
|
||
- added a runnable multi-service Shepherd validation harness for FreeBSD:
|
||
- `tests/shepherd/run-freebsd-shepherd-service-prototype.sh`
|
||
- wrote the Phase 4.1 report:
|
||
- `docs/reports/phase4-freebsd-shepherd-service.md`
|
||
- ran the service-management prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-shepherd-service-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the current FreeBSD path now has a working local Shepherd build based on:
|
||
- local fixed Guile
|
||
- locally installed Guile Fibers `1.4.2`
|
||
- Shepherd `1.0.9`
|
||
- Shepherd build/install required one concrete FreeBSD-specific toolchain adaptation:
|
||
- `SED=/usr/local/bin/gsed`
|
||
because the install phase edits wrapper scripts using GNU `sed -i` syntax that base FreeBSD `sed` does not accept
|
||
- at runtime, Shepherd reports:
|
||
- `System lacks support for 'signalfd'; using fallback mechanism.`
|
||
but the fallback path works correctly for supervision on this host
|
||
- the prototype successfully validated all requested regular-service capabilities:
|
||
- start/stop via `herd`
|
||
- dependency handling
|
||
- status monitoring
|
||
- crash/respawn behavior
|
||
- privilege-aware execution
|
||
- the concrete service set used for validation included:
|
||
- an unprivileged heartbeat logger
|
||
- a loopback HTTP service
|
||
- a dependent file-monitor service
|
||
- a crash-once respawn test service
|
||
- observed metadata confirmed:
|
||
- `logger_running=yes`
|
||
- `web_running=yes`
|
||
- `monitor_running=yes`
|
||
- `crashy_running=yes`
|
||
- `logger_uid=65534` (`nobody`)
|
||
- `http_response=shepherd-freebsd-ok`
|
||
- `monitor_detected=detected`
|
||
- `crashy_counter=2`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 4.1 is now satisfied on the current FreeBSD prototype track
|
||
- Shepherd is no longer just a theoretical later step; it now builds and supervises multiple services correctly on the host when paired with the fixed local Guile stack
|
||
- the next question is no longer “can Shepherd run on FreeBSD at all?” but “what is the best FreeBSD init-integration strategy for it on this prototype path?”
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
- `e404e2e` — `Prototype FreeBSD store management`
|
||
- `eb0d77c` — `Adapt GNU build phases for FreeBSD`
|
||
- `d47dc9b` — `Prototype FreeBSD package definitions`
|
||
|
||
Next recommended step:
|
||
|
||
1. complete Phase 4.2 by prototyping how Shepherd should be launched and stopped through FreeBSD init conventions while validating boot/shutdown dependency ordering for essential services
|
||
2. after that, bridge Shepherd to key FreeBSD service concepts such as rc.d management, loopback/network configuration, filesystem setup, and temporary user/group administration
|
||
3. continue carrying the separate real-checkout runtime blocker for later integration work:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
|
||
## 2026-04-01 — Phase 4.2 completed: FreeBSD rc.d init-integration prototype validated for Shepherd
|
||
|
||
Completed work:
|
||
|
||
- added a runnable FreeBSD init-integration prototype harness:
|
||
- `tests/shepherd/run-freebsd-shepherd-init-prototype.sh`
|
||
- wrote the Phase 4.2 report:
|
||
- `docs/reports/phase4-freebsd-shepherd-init-integration.md`
|
||
- ran the init-integration prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-shepherd-init-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- a real temporary FreeBSD `rc.d` script can successfully launch the locally built Shepherd daemon through the standard:
|
||
- `service <name> onestart`
|
||
path
|
||
- the same wrapper can stop it cleanly through:
|
||
- `service <name> onestop`
|
||
using `herd ... stop root` under the hood
|
||
- the prototype automatically started a minimal essential-service graph at daemon launch consisting of:
|
||
- `filesystems`
|
||
- `system-log`
|
||
- `networking`
|
||
- `login`
|
||
- observed startup order matched the declared dependency chain exactly:
|
||
- `start:filesystems`
|
||
- `start:system-log`
|
||
- `start:networking`
|
||
- `start:login`
|
||
- observed shutdown order matched the expected reverse dependency order exactly:
|
||
- `stop:login`
|
||
- `stop:networking`
|
||
- `stop:system-log`
|
||
- `stop:filesystems`
|
||
- the rc.d wrapper reported the Shepherd instance as running while active:
|
||
- `rc_status=running`
|
||
- the prototype again observed the expected FreeBSD runtime note:
|
||
- `System lacks support for 'signalfd'; using fallback mechanism.`
|
||
and confirmed that it does not prevent correct boot/shutdown ordering behavior
|
||
|
||
Current assessment:
|
||
|
||
- Phase 4.2 is now satisfied on the current prototype track as an init-integration prototype
|
||
- the key result is that Shepherd can already be launched and stopped through native FreeBSD service-management conventions while preserving dependency-based startup and shutdown semantics
|
||
- the remaining Phase 4 work is now specifically about bridging Shepherd services to concrete FreeBSD host-management concepts rather than basic daemon launch or service ordering
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
- `e404e2e` — `Prototype FreeBSD store management`
|
||
- `eb0d77c` — `Adapt GNU build phases for FreeBSD`
|
||
- `d47dc9b` — `Prototype FreeBSD package definitions`
|
||
- `b36746f` — `Validate Shepherd services on FreeBSD`
|
||
|
||
Next recommended step:
|
||
|
||
1. complete Phase 4.3 by adding a small FreeBSD Shepherd bridge layer for rc.d-style services, loopback/network configuration, filesystem setup, and temporary user/group administration
|
||
2. use that bridge layer in a runnable integration harness that validates both activation and cleanup of those FreeBSD concepts
|
||
3. continue carrying the separate real-checkout runtime blocker for later integration work:
|
||
- investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
|
||
## 2026-04-01 — Phase 4.3 completed: FreeBSD Shepherd bridge layer validated across rc.d, network, filesystem, and account management
|
||
|
||
Completed work:
|
||
|
||
- added a reusable FreeBSD Shepherd bridge module:
|
||
- `modules/fruix/shepherd/freebsd.scm`
|
||
- added a runnable integration harness exercising that bridge layer:
|
||
- `tests/shepherd/run-freebsd-shepherd-bridge-prototype.sh`
|
||
- wrote the Phase 4.3 report:
|
||
- `docs/reports/phase4-freebsd-shepherd-bridge.md`
|
||
- ran the bridge prototype successfully and captured metadata under:
|
||
- `/tmp/freebsd-shepherd-bridge-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the new module now exports concrete helper constructors for four FreeBSD integration categories:
|
||
- `freebsd-rc-service`
|
||
- `freebsd-loopback-alias-service`
|
||
- `freebsd-tmpfs-service`
|
||
- `freebsd-user-group-service`
|
||
- the integration harness used those helpers to manage a real chained host-side service graph under Shepherd covering:
|
||
- a temporary rc.d script in `/usr/local/etc/rc.d/`
|
||
- loopback alias configuration on `lo0`
|
||
- tmpfs mount/unmount with mode validation
|
||
- temporary user/group creation and removal via `pw`
|
||
- observed activation metadata confirmed all of those operations succeeded under Shepherd control:
|
||
- `target_running=yes`
|
||
- `rc_started=yes`
|
||
- `alias_present=yes`
|
||
- `tmpfs_mounted=yes`
|
||
- `tmpfs_mode=drwxr-x---`
|
||
- `user_present=yes`
|
||
- `group_present=yes`
|
||
- observed cleanup metadata confirmed that `stop root` also reversed all of those host-side effects successfully:
|
||
- `rc_stopped=yes`
|
||
- `alias_removed=yes`
|
||
- `tmpfs_unmounted=yes`
|
||
- `user_removed=yes`
|
||
- `group_removed=yes`
|
||
- the same expected FreeBSD runtime note remained true here as well:
|
||
- `System lacks support for 'signalfd'; using fallback mechanism.`
|
||
and again it did not prevent the prototype from working correctly
|
||
|
||
Current assessment:
|
||
|
||
- Phase 4.3 is now satisfied on the current prototype track
|
||
- Shepherd now has a concrete FreeBSD bridge layer in-repo rather than only ad hoc validation scripts
|
||
- with service supervision, rc.d integration, and FreeBSD host-concept bridging now all validated, Phase 4 is complete on the current FreeBSD amd64 prototype path
|
||
|
||
## 2026-04-01 — Phase 4 completed on the current FreeBSD prototype track
|
||
|
||
Phase 4 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 4.1** success criteria were met on the prototype track:
|
||
- Shepherd built successfully on FreeBSD with the fixed local Guile stack
|
||
- regular multi-service supervision worked
|
||
- dependency handling, status monitoring, privilege-aware execution, and respawn behavior were all validated
|
||
- **Phase 4.2** success criteria were met in init-integration prototype form:
|
||
- a real FreeBSD `rc.d` wrapper launched Shepherd successfully
|
||
- a minimal essential-service graph started automatically in correct dependency order
|
||
- orderly reverse shutdown through native FreeBSD service entry points was validated
|
||
- **Phase 4.3** success criteria were met on the prototype track:
|
||
- a reusable FreeBSD Shepherd bridge layer was added
|
||
- Shepherd services successfully bridged to rc.d service control, loopback/network configuration, filesystem mounting/permissions, and temporary user/group administration
|
||
- both activation and cleanup were validated
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **Shepherd porting milestone** on the current prototype track, not a literal replacement of `/sbin/init` on the live host
|
||
- however, the core Shepherd questions have now been answered positively on FreeBSD:
|
||
- it builds
|
||
- it runs
|
||
- it supervises services
|
||
- it integrates with FreeBSD service-management conventions
|
||
- it can express concrete FreeBSD host-management tasks through Shepherd services
|
||
- the separate real-Guix-checkout runtime blocker still exists for later integration work:
|
||
- `./pre-inst-env guix --version` fails with `Wrong type to apply: #<syntax-transformer leave-on-EPIPE>`
|
||
but that is now clearly outside the scope of the completed Phase 4 Shepherd milestone
|
||
|
||
Recent commits:
|
||
|
||
- `e380e88` — `Add FreeBSD Guile verification harness`
|
||
- `cd721b1` — `Update progress after Guile verification`
|
||
- `27916cb` — `Diagnose Guile subprocess crash on FreeBSD`
|
||
- `02f7a7f` — `Validate local Guile fix on FreeBSD`
|
||
- `4aebea4` — `Add native GNU Hello FreeBSD build harness`
|
||
- `c944cdb` — `Validate Guix builder phases on FreeBSD`
|
||
- `0a2e48e` — `Validate GNU which builder phases on FreeBSD`
|
||
- `245a47d` — `Document gaps to real Guix FreeBSD builds`
|
||
- `d62e9b0` — `Investigate Guix derivation generation on FreeBSD`
|
||
- `c0a85ed` — `Build local Guile-GnuTLS on FreeBSD`
|
||
- `15b9037` — `Build local Guile-Git on FreeBSD`
|
||
- `47d31e8` — `Build local Guile-JSON on FreeBSD`
|
||
- `d82195b` — `Advance Guix checkout on FreeBSD`
|
||
- `9bf3d30` — `Document FreeBSD syscall mapping`
|
||
- `7621798` — `Prototype FreeBSD jail build isolation`
|
||
- `d65b2af` — `Prototype FreeBSD build user isolation`
|
||
- `e404e2e` — `Prototype FreeBSD store management`
|
||
- `eb0d77c` — `Adapt GNU build phases for FreeBSD`
|
||
- `d47dc9b` — `Prototype FreeBSD package definitions`
|
||
- `b36746f` — `Validate Shepherd services on FreeBSD`
|
||
- `83715f0` — `Prototype Shepherd rc.d integration`
|
||
|
||
Next recommended step:
|
||
|
||
1. return to the remaining real Guix checkout/runtime blocker and investigate the `leave-on-EPIPE` failure in `./pre-inst-env guix --version`
|
||
2. begin the next post-Phase-4 integration milestone by connecting the now-validated daemon/build/store/Shepherd prototypes more directly to real Guix checkout behavior on FreeBSD
|
||
3. continue using `/frx/store` rather than `/gnu/store` whenever future integration experiments need a persistent store root
|
||
|
||
## 2026-04-01 — Planning update: Fruix naming policy clarified for post-Phase-4 work
|
||
|
||
Completed work:
|
||
|
||
- added a new post-Phase-4 planning document:
|
||
- `docs/PLAN_2.md`
|
||
- updated that plan to clarify the naming policy for the fork going forward
|
||
|
||
Key planning decision:
|
||
|
||
- **Fruix** is now the intended user-facing product identity
|
||
- the user-facing CLI should become:
|
||
- `fruix`
|
||
- `/frx` remains the canonical store/state/config root on the FreeBSD path
|
||
- however, the plan explicitly avoids a blanket rename of all upstream-derived internal identifiers
|
||
- in particular:
|
||
- internal `guix` namespaces may remain temporarily where needed for compatibility and maintenance
|
||
- `gnu` names are preserved where they refer to real GNU concepts or components such as GNU packages, GNU Shepherd, or `gnu-build-system`
|
||
- new fork-specific modules and user-facing surfaces should prefer `fruix` naming
|
||
|
||
Current assessment:
|
||
|
||
- the naming direction is now clearer for the next integration batch
|
||
- Phase 5 and beyond should aim to:
|
||
- first make the upstream-derived checkout runnable on FreeBSD,
|
||
- then introduce a deliberate `fruix` command boundary,
|
||
- rather than destabilizing the codebase with a whole-tree `guix`/`gnu` rename too early
|
||
|
||
## 2026-04-01 — Phase 5.1 completed: checkout runtime unblocked and first `fruix` frontend boundary established
|
||
|
||
Completed work:
|
||
|
||
- added a reusable phase-5 checkout setup helper:
|
||
- `tests/guix/setup-phase5-checkout.sh`
|
||
- added a checkout runtime patch queue for the upstream-derived source tree:
|
||
- `tests/guix/patches/phase5-checkout-runtime.patch`
|
||
- added a FreeBSD daemon/build patch queue needed for later phase-5 work:
|
||
- `tests/guix/patches/phase5-guix-daemon-freebsd.patch`
|
||
- added a runtime validation harness:
|
||
- `tests/guix/run-phase5-checkout-runtime.sh`
|
||
- wrote the Phase 5.1 report:
|
||
- `docs/reports/phase5-checkout-runtime-freebsd.md`
|
||
- ran the runtime harness successfully and captured metadata under:
|
||
- `/tmp/phase5-runtime-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the earlier checkout blocker
|
||
- `./pre-inst-env guix --version`
|
||
- `Wrong type to apply: #<syntax-transformer leave-on-EPIPE>`
|
||
is now explained by top-level definition ordering in `guix/ui.scm`:
|
||
- `show-version-and-exit` called `leave-on-EPIPE` before the syntax transformer was defined later in the file
|
||
- on this FreeBSD path, that became a runtime application of a syntax-transformer object instead of a macro expansion site
|
||
- the phase-5 runtime patch fixes this by:
|
||
- making `(guix ui)` explicitly non-declarative
|
||
- rewriting `show-version-and-exit` to use direct `catch 'system-error` handling
|
||
- parameterizing `program-name` in `guix-main`
|
||
- deriving the top-level version banner name from `program-name`
|
||
- making `(guix scripts repl)` explicitly non-declarative as well
|
||
- the checkout now successfully runs the following commands on FreeBSD:
|
||
- `./pre-inst-env guix --version`
|
||
- `./pre-inst-env guix repl --help`
|
||
- `./pre-inst-env guix build --help`
|
||
- the first user-facing Fruix command boundary is now implemented in the checkout setup via:
|
||
- `scripts/fruix`
|
||
as a front-end alias next to `scripts/guix`
|
||
- observed runtime metadata confirmed:
|
||
- `first_guix_version_line=guix (GNU Guix) ...`
|
||
- `first_fruix_version_line=fruix (GNU Guix) ...`
|
||
- this matches the agreed naming policy:
|
||
- Fruix at the user-facing boundary
|
||
- stable upstream-derived internal `guix`/`gnu` names unless there is a concrete reason to rename them
|
||
|
||
Current assessment:
|
||
|
||
- Phase 5.1 is now satisfied on the current FreeBSD prototype track
|
||
- the key boundary has shifted from “the checkout still crashes immediately” to “the checkout runs, and can now be used as the basis for real derivation/store experiments”
|
||
- the next step is to prove that a real derivation can be emitted against `/frx/store` from the now-runnable checkout
|
||
|
||
## 2026-04-01 — Phase 5.2 completed: real derivation generation validated against `/frx/store`
|
||
|
||
Completed work:
|
||
|
||
- added a runnable derivation-generation harness:
|
||
- `tests/guix/run-phase5-derivation-generation.sh`
|
||
- wrote the Phase 5.2 report:
|
||
- `docs/reports/phase5-derivation-generation-freebsd.md`
|
||
- ran the derivation-generation harness successfully and captured metadata under:
|
||
- `/tmp/phase5-derivation-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the now-runnable checkout can successfully use a real daemon/store connection on FreeBSD to lower a package through:
|
||
- `package->bag`
|
||
- `bag->derivation`
|
||
- the emitted derivation is a real `/frx/store` derivation path rather than an ad hoc placeholder or shell metadata artifact
|
||
- the validation used a deliberately minimal custom package with a custom low-level build system so that this subphase isolates the real lowering/store boundary without being dominated by still-unresolved upstream bootstrap assumptions for full native FreeBSD package graphs
|
||
- observed metadata confirmed:
|
||
- `bag_name=phase5-freebsd-lowering-0`
|
||
- `bag_host_inputs=("source")`
|
||
- `drv_path=/frx/store/...-phase5-freebsd-lowering-0.drv`
|
||
- `out_path=/frx/store/...-phase5-freebsd-lowering-0`
|
||
- this means the key architectural step is now real and no longer hypothetical:
|
||
- a package object in the checkout can be lowered to a real derivation targeting `/frx/store` on FreeBSD
|
||
|
||
Current assessment:
|
||
|
||
- Phase 5.2 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is no longer “can we emit a derivation at all?” but “can the same daemon/store path accept and execute a derivation-backed build request successfully?”
|
||
|
||
## 2026-04-01 — Phase 5.3 completed: minimal daemon/store RPC integration validated on FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- added a runnable daemon/store RPC validation harness:
|
||
- `tests/guix/run-phase5-daemon-rpc.sh`
|
||
- wrote the Phase 5.3 report:
|
||
- `docs/reports/phase5-daemon-rpc-freebsd.md`
|
||
- ran the daemon/store RPC harness successfully and captured metadata under:
|
||
- `/tmp/phase5-daemon-rpc-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the patched checkout can now contact a real FreeBSD-aware daemon over a Unix socket and submit a derivation-backed build request successfully
|
||
- the resulting build path is a real `/frx/store` output rather than a simulated prototype artifact
|
||
- the successful metadata path now includes the full minimal chain needed for later system work:
|
||
- checkout command path
|
||
- daemon RPC
|
||
- derivation submission
|
||
- build execution
|
||
- store output materialization
|
||
- observed metadata confirmed:
|
||
- `drv_path=/frx/store/...-phase5-freebsd-daemon-build-0.drv`
|
||
- `out_path=/frx/store/...-phase5-freebsd-daemon-build-0`
|
||
- `payload=phase5-daemon-build-source`
|
||
- `source_path=/frx/store/...-phase5-source.txt`
|
||
- this step was exercised through the Fruix-facing checkout boundary:
|
||
- `./pre-inst-env fruix repl -- ...`
|
||
which means the user-facing transition is now connected to actual daemon/store activity, not just to help text or version banners
|
||
|
||
Current assessment:
|
||
|
||
- Phase 5.3 is now satisfied on the current FreeBSD prototype track
|
||
- the project now has a real but narrow end-to-end host-side execution path on FreeBSD:
|
||
- runnable checkout
|
||
- Fruix front-end boundary
|
||
- real derivation emission
|
||
- daemon/store RPC
|
||
- successful derivation-backed build into `/frx/store`
|
||
|
||
## 2026-04-01 — Phase 5 completed on the current FreeBSD prototype track
|
||
|
||
Phase 5 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 5.1** success criteria were met on the prototype track:
|
||
- the checkout runtime blocker around `leave-on-EPIPE` was root-caused and fixed in the patch queue
|
||
- the uninstalled checkout command path now runs on FreeBSD
|
||
- a first user-facing `fruix` command boundary was established
|
||
- **Phase 5.2** success criteria were met on the prototype track:
|
||
- a real package object was lowered through `package->bag` and `bag->derivation`
|
||
- a real derivation was emitted targeting `/frx/store`
|
||
- **Phase 5.3** success criteria were met on the prototype track:
|
||
- a real checkout command path contacted a FreeBSD-aware daemon/store path
|
||
- that path accepted and executed a derivation-backed build request
|
||
- the resulting output was materialized successfully in `/frx/store`
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **real checkout and host runtime unblocking milestone** on the current prototype track, not full upstream-package-graph support for arbitrary native FreeBSD package builds yet
|
||
- the successful derivation/build path currently uses a deliberately minimal custom package/build-system path to isolate real daemon/store viability from still-unresolved upstream bootstrap and package-graph assumptions for native FreeBSD
|
||
- nevertheless, the core Phase 5 question has now been answered positively:
|
||
- the checkout runs
|
||
- real derivations can be emitted
|
||
- the daemon can be built far enough to serve store RPC
|
||
- and derivation-backed builds can succeed into `/frx/store`
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 6.1 by moving from the minimal custom derivation-backed package path to at least one real FreeBSD store-backed package build driven by Fruix/Guix mechanisms
|
||
2. then integrate the already validated jail/build-user model more directly into the live daemon build path
|
||
3. continue preserving the selective Fruix naming policy:
|
||
- Fruix at the product boundary
|
||
- `/frx` as the canonical store root
|
||
- stable upstream-derived internal names unless there is strong architectural value in renaming them
|
||
|
||
## 2026-04-01 — Phase 6.1 completed: real package build validated into `/frx/store`
|
||
|
||
Completed work:
|
||
|
||
- added a runnable real-package harness:
|
||
- `tests/guix/run-phase6-real-package-build.sh`
|
||
- wrote the Phase 6.1 report:
|
||
- `docs/reports/phase6-real-package-build-freebsd.md`
|
||
- ran the real-package harness successfully and captured metadata under:
|
||
- `/tmp/phase6-real-package-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the checkout can now build a real package definition derived from Guix's `hello` package through:
|
||
- `./pre-inst-env fruix build -f ...`
|
||
- the FreeBSD-aware daemon
|
||
- `/frx/store`
|
||
- this moves the project beyond the deliberately minimal Phase 5 custom derivation path and into a real package-definition flow
|
||
- the current successful path still uses a prefetched local GNU Hello tarball as the package source because the built-in downloader path remains a separate unresolved FreeBSD/root-daemon issue
|
||
- observed metadata confirmed:
|
||
- `drv_path=/frx/store/...-hello-2.12.3.drv`
|
||
- `out_path=/frx/store/...-hello-2.12.3`
|
||
- `source_store_path=/frx/store/...-hello-2.12.3.tar.gz`
|
||
- `runtime_output=Hello, world!`
|
||
- a daemon-side references query confirmed that the built output preserved the declared source store item as a direct reference
|
||
|
||
Current assessment:
|
||
|
||
- Phase 6.1 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is to move the already validated jail/build-user model into this live package-build path rather than keeping it prototype-only
|
||
|
||
## 2026-04-01 — Phase 6.2 completed: jail/build-user isolation integrated into the real package path
|
||
|
||
Completed work:
|
||
|
||
- added a reusable UID/GID drop helper source:
|
||
- `tests/daemon/freebsd-drop-exec.c`
|
||
- added a runnable jail-integrated package harness:
|
||
- `tests/guix/run-phase6-jail-package-build.sh`
|
||
- wrote the Phase 6.2 report:
|
||
- `docs/reports/phase6-jail-build-integration-freebsd.md`
|
||
- ran the jail-integrated harness successfully and captured metadata under:
|
||
- `/tmp/phase6-jail-package-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- a real package build derived from Guix's `hello` definition now runs through the live daemon path inside a FreeBSD jail rather than only through the earlier prototype scripts
|
||
- the actual build work inside the jail runs as dropped credentials:
|
||
- UID `35001`
|
||
- GID `35001`
|
||
- the integrated build path required one additional FreeBSD-specific adjustment beyond the earlier prototype:
|
||
- the daemon-side host `TMPDIR` path was not automatically valid inside the jail, so the jailed build environment must reset `TMPDIR=/tmp`
|
||
- observed metadata confirmed:
|
||
- `drv_path=/frx/store/...-hello-2.12.3.drv`
|
||
- `out_path=/frx/store/...-hello-2.12.3`
|
||
- `runtime_output=Hello, world!`
|
||
- `build_uid=35001`
|
||
- `build_gid=35001`
|
||
- `jail_hostname=fruix-phase6-hello-...`
|
||
- `build_mode=freebsd-jail`
|
||
- `source_store_path=/frx/store/...-hello-2.12.3.tar.gz`
|
||
- the GNU Hello test suite also passed inside the jail-integrated build path
|
||
|
||
Current assessment:
|
||
|
||
- Phase 6.2 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is to validate a minimal user-facing profile installation flow on top of these real store outputs
|
||
|
||
## 2026-04-01 — Phase 6.3 completed: minimal profile installation validated on real store outputs
|
||
|
||
Completed work:
|
||
|
||
- added a runnable real-store profile harness:
|
||
- `tests/packages/run-phase6-real-store-profile-prototype.sh`
|
||
- wrote the Phase 6.3 report:
|
||
- `docs/reports/phase6-real-store-profile-freebsd.md`
|
||
- updated the Phase 6 package-build harnesses so they can recover derivation paths even when the requested outputs are already present in `/frx/store`
|
||
- ran the real-store profile harness successfully and captured metadata under:
|
||
- `/tmp/phase6-real-store-profile-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the current FreeBSD track now has a minimal user-facing profile installation flow built on top of real Phase 6 store outputs rather than the earlier Phase 3 package/profile prototype inputs
|
||
- the validated transaction semantics are intentionally small but real:
|
||
- generation 1 is created from the Phase 6.1 host-built store item
|
||
- generation 2 is created from the Phase 6.2 jail-built store item
|
||
- the `profile` symlink switches to generation 2
|
||
- both generations remain addressable
|
||
- observed metadata confirmed:
|
||
- `profile_target=profile-2-link`
|
||
- `generation1_store_path=/frx/store/...-hello-2.12.3`
|
||
- `generation2_store_path=/frx/store/...-hello-2.12.3`
|
||
- `current_store_path=/frx/store/...-hello-2.12.3`
|
||
- `profile_hello_output=Hello, world!`
|
||
- `clean_env_hello_output=Hello, world!`
|
||
- the upstream-derived profile layer is still not fully usable on this FreeBSD track because the current `guix profiles` / `fruix package` path still reaches the unresolved bootstrap-platform blocker:
|
||
- `dynamic linker name not known for this system "x86_64-freebsd15.0"`
|
||
- despite that blocker, the minimal Fruix-owned profile path is now validated on top of real daemon-built store items
|
||
|
||
Current assessment:
|
||
|
||
- Phase 6.3 is now satisfied on the current FreeBSD prototype track
|
||
- Phase 6 as a whole is now complete on the active FreeBSD amd64 prototype path
|
||
|
||
## 2026-04-01 — Phase 6 completed on the current FreeBSD prototype track
|
||
|
||
Phase 6 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 6.1** success criteria were met on the prototype track:
|
||
- a real package definition derived from Guix's `hello` package now builds through `fruix build`
|
||
- the output lands in `/frx/store`
|
||
- the package runs from the store and preserves a declared source reference
|
||
- **Phase 6.2** success criteria were met on the prototype track:
|
||
- a real package build now executes inside a FreeBSD jail
|
||
- the build work runs under dropped numeric build credentials
|
||
- the jailed build succeeds into `/frx/store`
|
||
- **Phase 6.3** success criteria were met on the prototype track:
|
||
- real Phase 6 store outputs can be installed into a minimal profile environment
|
||
- generation switching works in a concrete form
|
||
- package execution through the profile succeeds for the current user
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **real FreeBSD-backed store-build milestone** on the current prototype track, not full upstream-package-graph support or full upstream profile-layer parity yet
|
||
- the current package path still relies on a prefetched local source tarball for GNU Hello because the built-in downloader/root-daemon path remains a separate FreeBSD issue
|
||
- the current profile-installation path is a Fruix-owned minimal layer over real store outputs because the upstream-derived profile code still hits the unresolved FreeBSD bootstrap-platform mapping blocker
|
||
- nevertheless, the core Phase 6 question has now been answered positively:
|
||
- real package definitions can be built into `/frx/store`
|
||
- those builds can run under integrated jail/build-user isolation
|
||
- and the resulting store items can be exposed through a minimal user-facing profile flow
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 7.1 by defining a minimal Fruix operating-system model for FreeBSD
|
||
2. carry forward the selective Fruix naming policy:
|
||
- Fruix at the product boundary
|
||
- `/frx` as the canonical store root
|
||
- stable upstream-derived internal names unless there is strong architectural value in renaming them
|
||
3. keep the two remaining Phase 6 follow-up blockers visible but scoped:
|
||
- built-in downloader/root-daemon integration for real package origins
|
||
- upstream-derived profile/bootstrap-platform support for `x86_64-freebsd15.0`
|
||
|
||
## 2026-04-01 — Phase 7.1 completed: minimal Fruix operating-system model defined for FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- added the first Fruix-owned FreeBSD system module:
|
||
- `modules/fruix/system/freebsd.scm`
|
||
- added the Phase 7.1 operating-system example and validation harnesses:
|
||
- `tests/system/phase7-minimal-operating-system.scm`
|
||
- `tests/system/validate-phase7-operating-system.scm`
|
||
- `tests/system/run-phase7-operating-system-model.sh`
|
||
- extended the FreeBSD package model with additional system-oriented prototype packages:
|
||
- `freebsd-bootloader`
|
||
- `freebsd-rc-scripts`
|
||
- `freebsd-runtime`
|
||
- `%freebsd-system-packages`
|
||
- wrote the Phase 7.1 report:
|
||
- `docs/reports/phase7-operating-system-model-freebsd.md`
|
||
- ran the operating-system model harness successfully and captured metadata under:
|
||
- `/tmp/phase7-os-model-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the FreeBSD track now has a concrete declarative operating-system object rather than only package/profile and service prototypes
|
||
- the model currently covers:
|
||
- host identity
|
||
- kernel and bootloader assets
|
||
- essential base packages
|
||
- users/groups
|
||
- file systems
|
||
- generated `/etc` payloads
|
||
- activation payload generation
|
||
- generated Shepherd configuration
|
||
- the selected first init strategy is now explicit in the model:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- observed metadata confirmed:
|
||
- `host_name=fruix-freebsd`
|
||
- `kernel_package=freebsd-kernel`
|
||
- `bootloader_package=freebsd-bootloader`
|
||
- `base_packages=freebsd-runtime,freebsd-userland,freebsd-libc,freebsd-rc-scripts,freebsd-sh,freebsd-bash`
|
||
- `users=root,operator`
|
||
- `groups=wheel,operator`
|
||
- `generated_files=boot/loader.conf,etc/rc.conf,etc/fstab,etc/hosts,etc/passwd,etc/group,etc/shells,etc/motd,activate,shepherd/init.scm`
|
||
- `init_mode=freebsd-init+rc.d-shepherd`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 7.1 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is to materialize this operating-system description into a reproducible system closure under `/frx/store`
|
||
|
||
## 2026-04-01 — Phase 7.2 completed: minimal system closure generated under `/frx/store`
|
||
|
||
Completed work:
|
||
|
||
- added the Phase 7.2 closure materialization harnesses:
|
||
- `tests/system/materialize-phase7-system-closure.scm`
|
||
- `tests/system/run-phase7-system-closure.sh`
|
||
- refined the minimal operating-system example so the generated system profile also contains `/bin/sh`
|
||
- wrote the Phase 7.2 report:
|
||
- `docs/reports/phase7-system-closure-freebsd.md`
|
||
- ran the system-closure harness successfully and captured metadata under:
|
||
- `/tmp/phase7-system-closure-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the declarative FreeBSD Fruix operating-system object now materializes into a real system closure under `/frx/store`
|
||
- that closure contains:
|
||
- boot assets
|
||
- a merged system profile
|
||
- generated `/etc` files
|
||
- a generated activation script
|
||
- a generated Shepherd configuration
|
||
- a generated `rc.d` launcher for Shepherd
|
||
- the closure now embeds the concrete first init integration choice for the FreeBSD track:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- rerunning the same materialization produced the same closure path, which is the current prototype proof of reproducible closure generation for this phase
|
||
- observed metadata confirmed:
|
||
- `closure_path=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `closure_rebuild_path=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `kernel_store=/frx/store/...-freebsd-kernel-15.0-STABLE`
|
||
- `bootloader_store=/frx/store/...-freebsd-bootloader-15.0-STABLE`
|
||
- `guile_store=/frx/store/...-fruix-guile-runtime-3.0`
|
||
- `guile_extra_store=/frx/store/...-fruix-guile-extra-3.0`
|
||
- `shepherd_store=/frx/store/...-fruix-shepherd-runtime-1.0.9`
|
||
- `profile_bin_sh=/frx/store/...-fruix-system-fruix-freebsd/profile/bin/sh`
|
||
- `profile_sbin_init=/frx/store/...-fruix-system-fruix-freebsd/profile/sbin/init`
|
||
- `profile_rc=/frx/store/...-fruix-system-fruix-freebsd/profile/etc/rc`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 7.2 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is to materialize and statically validate an installable root filesystem tree from this system closure
|
||
|
||
## 2026-04-01 — Phase 7.3 completed: installable rootfs tree validated from the system closure
|
||
|
||
Completed work:
|
||
|
||
- added the Phase 7.3 rootfs materialization harnesses:
|
||
- `tests/system/materialize-phase7-rootfs.scm`
|
||
- `tests/system/run-phase7-rootfs.sh`
|
||
- wrote the Phase 7.3 report:
|
||
- `docs/reports/phase7-rootfs-freebsd.md`
|
||
- ran the rootfs harness successfully and captured metadata under:
|
||
- `/tmp/phase7-rootfs-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the declarative Fruix FreeBSD system can now be materialized as a root filesystem tree rather than only as a store closure directory
|
||
- the rootfs uses a Guix-like anchor:
|
||
- `/run/current-system`
|
||
so that boot assets, generated configuration, and system-profile content remain tied to the declarative system closure
|
||
- static validation confirmed:
|
||
- boot asset linkage
|
||
- generated `/etc` linkage
|
||
- activation payload presence
|
||
- Shepherd `rc.d` launch integration
|
||
- declared filesystem entries
|
||
- declared user/group provisioning in the activation path
|
||
- deterministic ready-state wiring through `/var/lib/fruix/ready`
|
||
- observed metadata confirmed:
|
||
- `rootfs=/tmp/.../rootfs`
|
||
- `closure_path=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `run_current_system_target=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `activate_target=/run/current-system/activate`
|
||
- `bin_target=/run/current-system/profile/bin`
|
||
- `sbin_target=/run/current-system/profile/sbin`
|
||
- `boot_kernel_target=/run/current-system/boot/kernel`
|
||
- `boot_loader_target=/run/current-system/boot/loader`
|
||
- `boot_loader_efi_target=/run/current-system/boot/loader.efi`
|
||
- `rc_conf_target=/run/current-system/etc/rc.conf`
|
||
- `rc_script_target=/run/current-system/usr/local/etc/rc.d/fruix-shepherd`
|
||
- `ready_marker=/var/lib/fruix/ready`
|
||
- `validation_mode=static-rootfs-check`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 7.3 is now satisfied on the current FreeBSD prototype track
|
||
- Phase 7 as a whole is now complete on the active FreeBSD amd64 prototype path
|
||
|
||
## 2026-04-01 — Phase 7 completed on the current FreeBSD prototype track
|
||
|
||
Phase 7 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 7.1** success criteria were met on the prototype track:
|
||
- a minimal Fruix operating-system object now exists for FreeBSD
|
||
- it evaluates into a coherent system-closure specification
|
||
- **Phase 7.2** success criteria were met on the prototype track:
|
||
- that system model now materializes into a reproducible closure under `/frx/store`
|
||
- the closure contains boot assets, generated `/etc` files, activation payloads, and Shepherd launch integration
|
||
- **Phase 7.3** success criteria were met on the prototype track:
|
||
- the closure now materializes into a concrete rootfs tree
|
||
- the resulting rootfs passes static validation for later image-construction work
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **declarative system-composition milestone** for the current prototype track, not a fully booted Fruix guest yet
|
||
- the current output is a validated closure plus rootfs tree; Phase 8 still needs to turn that into a reproducible bhyve-friendly disk image
|
||
- the chosen first system-init strategy remains:
|
||
- FreeBSD init + `rc.d` launching Shepherd
|
||
rather than Shepherd-as-PID-1
|
||
- the current system model remains Fruix-owned and FreeBSD-oriented rather than attempting full upstream Guix System integration prematurely
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 8.1 by creating a reproducible disk-image build path from the generated Fruix rootfs tree
|
||
2. keep the current init decision explicit for the first boot target:
|
||
- FreeBSD init + `rc.d` + Shepherd
|
||
3. continue preserving the selective Fruix naming policy:
|
||
- Fruix at the product boundary
|
||
- `/frx` as the canonical store root
|
||
- stable upstream-derived internal names unless there is strong architectural value in renaming them
|
||
|
||
## 2026-04-01 — Phase 8.1 completed: reproducible bhyve-compatible raw disk image generated
|
||
|
||
Completed work:
|
||
|
||
- added the first Phase 8 image-generation harness:
|
||
- `tests/system/run-phase8-bhyve-image.sh`
|
||
- wrote the Phase 8.1 report:
|
||
- `docs/reports/phase8-bhyve-image-freebsd.md`
|
||
- ran the image-generation harness successfully and captured metadata under:
|
||
- `/tmp/phase8-bhyve-image-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- the current Fruix FreeBSD track now has a reproducible raw disk-image build path using:
|
||
- GPT
|
||
- UEFI boot
|
||
- a FAT EFI system partition
|
||
- a UFS root partition
|
||
- serial-console-friendly loader settings
|
||
- the earlier Phase 7 rootfs tree was not sufficient by itself for an installable image because it still referenced `/frx/store` content that only existed on the host; the image builder therefore had to stage the system closure and its recursively declared store references inside the image rootfs under `/frx/store`
|
||
- rebuilding the same image a second time with fixed timestamps and explicit filesystem parameters produced the same SHA256, which is the current prototype proof of reproducible image generation on this host
|
||
- observed metadata confirmed:
|
||
- `raw_sha256=08605d738021cb6fb5b87c270e1eafde57e1acb5159d3a2257aad4c560e2efc5`
|
||
- `image_size_bytes=335578624`
|
||
- `esp_fstype=msdosfs`
|
||
- `root_fstype=ufs`
|
||
- `run_current_system_target=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `boot_loader_target=/run/current-system/boot/loader`
|
||
- `boot_loader_conf_target=/run/current-system/boot/loader.conf`
|
||
- `rc_conf_target=/run/current-system/etc/rc.conf`
|
||
- `rc_script_target=/run/current-system/usr/local/etc/rc.d/fruix-shepherd`
|
||
- `store_item_count=13`
|
||
- `boot_mode=uefi`
|
||
- `image_format=raw`
|
||
- `partition_scheme=gpt`
|
||
- `serial_console=comconsole`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 8.1 is now satisfied on the current FreeBSD prototype track
|
||
- the next step is to integrate this image generation path into the declarative Fruix system-composition layer so that a single operating-system description can drive image generation end-to-end
|
||
|
||
## 2026-04-01 — Phase 8.2 completed: image generation integrated into the declarative system layer
|
||
|
||
Completed work:
|
||
|
||
- extended the FreeBSD system module with integrated image-generation operations:
|
||
- `operating-system-image-spec`
|
||
- `materialize-bhyve-image`
|
||
- added the Phase 8.2 integration harnesses:
|
||
- `tests/system/materialize-phase8-system-image.scm`
|
||
- `tests/system/run-phase8-system-image.sh`
|
||
- wrote the Phase 8.2 report:
|
||
- `docs/reports/phase8-system-image-freebsd.md`
|
||
- ran the integrated system-image harness successfully and captured metadata under:
|
||
- `/tmp/phase8-system-image-metadata.txt`
|
||
|
||
Important findings:
|
||
|
||
- image generation is now a direct output of the Fruix FreeBSD system-definition layer rather than an external shell-only follow-up to Phase 7
|
||
- the integrated path now stores the resulting image artifact itself under `/frx/store`, preserving the store-centered Fruix composition story even at the VM-image layer
|
||
- rerunning `materialize-bhyve-image` for the same operating-system description produced the same image store path, which is the current prototype proof that one declarative system object can drive image generation end-to-end
|
||
- observed metadata confirmed:
|
||
- `image_store_path=/frx/store/...-fruix-bhyve-image-fruix-freebsd`
|
||
- `disk_image=/frx/store/...-fruix-bhyve-image-fruix-freebsd/disk.img`
|
||
- `closure_path=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `raw_sha256=ac57d4c694ea3cf6b1bd24be48982090a6cfcfa301d052c1f903636a46f2d56e`
|
||
- `image_size_bytes=335578624`
|
||
- `store_item_count=13`
|
||
- `esp_fstype=msdosfs`
|
||
- `root_fstype=ufs`
|
||
- `run_current_system_target=/frx/store/...-fruix-system-fruix-freebsd`
|
||
- `boot_loader_target=/run/current-system/boot/loader`
|
||
- `rc_conf_target=/run/current-system/etc/rc.conf`
|
||
- `rc_script_target=/run/current-system/usr/local/etc/rc.d/fruix-shepherd`
|
||
- `image_generation_mode=declarative-system-layer`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 8.2 is now satisfied on the current FreeBSD prototype track
|
||
- Phase 8 as a whole is now complete on the active FreeBSD amd64 prototype path
|
||
|
||
## 2026-04-01 — Phase 8 completed on the current FreeBSD prototype track
|
||
|
||
Phase 8 is now considered complete for the active FreeBSD amd64 prototype path.
|
||
|
||
Why this milestone is satisfied:
|
||
|
||
- **Phase 8.1** success criteria were met on the prototype track:
|
||
- a reproducible raw GPT+UEFI+UFS image can now be generated from the Fruix system outputs
|
||
- that image passes static boot-structure sanity checks
|
||
- **Phase 8.2** success criteria were met on the prototype track:
|
||
- the image builder is now integrated with the declarative Fruix system-definition layer
|
||
- a single operating-system description now drives image generation end-to-end
|
||
- the integrated output is itself a store-backed Fruix image artifact under `/frx/store`
|
||
|
||
Important scope note:
|
||
|
||
- this completes the **image-construction milestone** for the current prototype track, not the first successful bhyve boot yet
|
||
- the generated image is now ready for the next phase’s VM-launch and serial-console validation work
|
||
- the current first-boot strategy remains explicit and unchanged:
|
||
- FreeBSD init + `rc.d` + Shepherd
|
||
- the image path still reflects the current prototype system/runtime limitations, including the fact that deeper runtime closure completeness for locally copied Guile/Shepherd dependencies will be exercised more fully in Phase 9 boot validation
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 9.1 by creating a bhyve launcher and serial-console validation harness for the generated image
|
||
2. keep the current deterministic ready-state target visible:
|
||
- Shepherd startup leading to the generated `/var/lib/fruix/ready` marker path
|
||
3. continue preserving the selective Fruix naming policy:
|
||
- Fruix at the product boundary
|
||
- `/frx` as the canonical store root
|
||
- stable upstream-derived internal names unless there is strong architectural value in renaming them
|
||
|
||
## 2026-04-02 — Phase 9 checkpoint: XCP-ng guest reached DHCP and SSH
|
||
|
||
Completed work:
|
||
|
||
- added a dedicated Phase 9 XCP-ng operating-system template:
|
||
- `tests/system/phase9-minimal-operating-system.scm.in`
|
||
- added an XCP-ng boot/import/validation harness:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- extended the staged FreeBSD runtime and system-generation layers so the guest can complete enough of real boot for network access:
|
||
- `modules/fruix/packages/freebsd.scm`
|
||
- `modules/fruix/system/freebsd.scm`
|
||
- updated the integrated image-generation path for Phase 9 use cases:
|
||
- `tests/system/materialize-phase8-system-image.scm`
|
||
- `tests/system/run-phase8-system-image.sh`
|
||
- wrote the checkpoint report:
|
||
- `docs/reports/phase9-xcpng-ssh-boot-freebsd.md`
|
||
|
||
Important findings:
|
||
|
||
- a decisive local QEMU/TCG serial-boot pass exposed the first real early-boot blocker:
|
||
- the generated `fstab` was wrong for pseudo-filesystems, so `rc` tried to fsck `devfs` and aborted boot
|
||
- after fixing `fstab`, later serial logs exposed additional FreeBSD base runtime gaps that only appear during real boot, including missing commands, runtime directories, and base config files used by `rc`, DHCP, logging, and service startup
|
||
- the staged image now includes the minimum currently known set of FreeBSD runtime pieces needed to:
|
||
- run `rc`
|
||
- obtain DHCP
|
||
- generate SSH host keys
|
||
- start `sshd`
|
||
- public-key SSH login initially still failed because the minimal guest did not stage a complete PAM runtime/config path; for the current Phase 9 prototype track, the generated `sshd_config` now uses:
|
||
- `UsePAM no`
|
||
- the current XCP-ng validation path succeeded against the operator-approved VM and existing VDI only:
|
||
- VM `90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- VDI `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- the successful XCP-ng boot obtained:
|
||
- guest IP `192.168.213.62`
|
||
- successful SSH validation on the real guest confirmed:
|
||
- `hostname=fruix-freebsd`
|
||
- `sshd` is reachable with the injected root key
|
||
- networking is configured on the Xen NIC
|
||
|
||
Current assessment:
|
||
|
||
- this checkpoint establishes the first real network-reachable Fruix boot on the active FreeBSD/XCP-ng track
|
||
- the generated image now boots far enough for DHCP and SSH, which closes the earlier uncertainty about whether the Phase 8 image could become a remotely usable guest at all
|
||
- Phase 9 is still not complete because the Fruix-specific readiness path remains blocked:
|
||
- `fruix-shepherd` does not start
|
||
- `/var/lib/fruix/ready` is still missing
|
||
- Guile still crashes in the guest with `signal 11`
|
||
- therefore the current state is:
|
||
- kernel boot: yes
|
||
- root mount: yes
|
||
- DHCP: yes
|
||
- SSH: yes
|
||
- Shepherd/ready marker: not yet
|
||
|
||
Next recommended step:
|
||
|
||
1. continue the in-guest Guile crash investigation so `fruix-shepherd` can start on the booted guest
|
||
2. once Shepherd is stable, rerun `tests/system/run-phase9-xcpng-boot.sh` to validate the full ready-marker path end-to-end
|
||
3. then close Phase 9 with updated report/progress entries for:
|
||
- deterministic boot readiness
|
||
- in-guest Shepherd validation
|
||
- minimal operator usability
|
||
|
||
## 2026-04-02 — Phase 9 completed on the active XCP-ng FreeBSD track
|
||
|
||
Completed work:
|
||
|
||
- resolved the in-guest Guile/Shepherd blocker that remained after the earlier DHCP+SSH checkpoint
|
||
- wrote the completion report:
|
||
- `docs/reports/phase9-xcpng-ready-boot-freebsd.md`
|
||
- extended the staged runtime again in:
|
||
- `modules/fruix/packages/freebsd.scm`
|
||
- added `/usr/sbin/daemon`
|
||
- added `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||
- completed the guest runtime integration in:
|
||
- `modules/fruix/system/freebsd.scm`
|
||
- activation now recreates compatibility symlinks for the currently locally built Guile / guile-extra / Shepherd prefixes, but points them at the real `/frx/store` items in the guest
|
||
- the rootfs now exposes `/usr/share/locale`
|
||
- the generated Shepherd config no longer relies on missing `mkdir-p` or unsupported `call-with-output-file #:append` behavior
|
||
- the Shepherd rc script now exports `LANG=C.UTF-8` / `LC_ALL=C.UTF-8`
|
||
- the Shepherd rc script now exports explicit Guile system/site path variables
|
||
- Shepherd is now started through FreeBSD `daemon(8)` so it remains alive after rc/session teardown
|
||
- corrected the XCP-ng harness in:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- it now uses a distinct SSH private key file for login instead of incorrectly trying to authenticate with the public key file
|
||
|
||
Important findings:
|
||
|
||
- the original guest Guile failure had multiple layers:
|
||
- missing UTF-8 locale data in the image
|
||
- baked-in temporary install-prefix references inside the copied Guile / guile-extra / Shepherd artifacts
|
||
- and Shepherd process lifetime issues caused by a fragile shell-background startup path
|
||
- reproducing the problem in a host-side chroot into the generated image root partition made the final debugging loop much tighter than repeated full VM imports alone
|
||
- after locale staging and compatibility-prefix recreation, Guile and Shepherd became runnable in the guest, but Shepherd still exited too early on the real boot path until it was launched via `daemon(8)`
|
||
- after those fixes, the full ready-marker path became reliable enough for end-to-end XCP-ng validation
|
||
|
||
Final validation:
|
||
|
||
- `tests/system/run-phase9-xcpng-boot.sh` now passes end-to-end against:
|
||
- VM `90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- VDI `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- passing run workdir:
|
||
- `/tmp/phase9-xcpng-pass-1775113189`
|
||
- passing real-guest metadata confirmed:
|
||
- `ready_marker=ready`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- `run_current_system_target=/frx/store/0fe459ea22156510e64cea794b7a001151b59625bd5f12a488d6851e1c6d2198-fruix-system-fruix-freebsd`
|
||
- `operator_home_listing=/home/operator`
|
||
- `logger_log=fruix-shepherd-started`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 9 is now complete for the active FreeBSD prototype track, using the XCP-ng replacement path adopted for this environment
|
||
- the generated Fruix image now reaches all currently required first-boot milestones on the real VM:
|
||
- kernel boot: yes
|
||
- root mount: yes
|
||
- DHCP: yes
|
||
- SSH: yes
|
||
- Shepherd: yes
|
||
- ready marker: yes
|
||
- minimal operator usability: yes
|
||
- this establishes the first real Fruix-on-FreeBSD VM that:
|
||
- boots from the declaratively generated image,
|
||
- reaches the generated ready state,
|
||
- keeps Shepherd running,
|
||
- and remains inspectable over SSH as a minimally usable system
|
||
|
||
Next recommended step:
|
||
|
||
1. begin the next post-Phase-9 cleanup/native-integration pass from `docs/PLAN_2.md` Optional Phase 10
|
||
2. prioritize replacing the current compatibility shims for locally built Guile / Shepherd prefixes with a more native store-path-aware Fruix runtime arrangement
|
||
3. clean up remaining non-fatal boot noise observed during Phase 9, such as:
|
||
- login-class warnings around `daemon`
|
||
- the `gpart: Unknown command: show` rc noise
|
||
- residual syslog/cron/runtime polish issues where they still matter
|
||
|
||
## 2026-04-02 — Phase 10.1: added a real `fruix system` command
|
||
|
||
Completed work:
|
||
|
||
- started Optional Phase 10 with the first user-facing Fruix system-management command surface
|
||
- wrote the subphase report:
|
||
- `docs/reports/phase10-fruix-system-command-freebsd.md`
|
||
- added a real CLI wrapper:
|
||
- `bin/fruix`
|
||
- added the corresponding Guile entry point:
|
||
- `scripts/fruix.scm`
|
||
- added a dedicated validation harness:
|
||
- `tests/system/run-phase10-fruix-system-command.sh`
|
||
|
||
What the new command does:
|
||
|
||
- exposes declarative FreeBSD system artifact generation through a Fruix CLI instead of only phase-specific harness scripts
|
||
- currently supports:
|
||
- `fruix system build OS-FILE`
|
||
- `fruix system image OS-FILE`
|
||
- `fruix system rootfs OS-FILE ROOTFS-DIR`
|
||
- currently supports options:
|
||
- `--system NAME`
|
||
- `--store DIR`
|
||
- `--disk-capacity SIZE`
|
||
- `--rootfs DIR`
|
||
- `--help`
|
||
- loads an operating-system object from a Scheme file, validates it, and dispatches to:
|
||
- `materialize-operating-system`
|
||
- `materialize-rootfs`
|
||
- `materialize-bhyve-image`
|
||
- emits machine-readable `key=value` metadata for the produced artifacts
|
||
|
||
Important findings:
|
||
|
||
- the project already had the core declarative system machinery by the end of Phase 9; the missing piece here was a direct Fruix operator interface to that machinery
|
||
- a small dedicated wrapper in this repo is currently the most practical way to expose that functionality without waiting for deeper upstream command-framework integration
|
||
- keeping the command aligned with the already validated local FreeBSD Guile / Fibers / Shepherd toolchain avoids introducing a second, divergent runtime path
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase10-fruix-system-command.sh` passes
|
||
- passing run workdir:
|
||
- `/tmp/phase10-fruix-cmd-1775117490`
|
||
- the test validated that:
|
||
- `fruix system build` materializes a closure under `/frx/store/*-fruix-system-fruix-freebsd`
|
||
- the produced closure contains the activation path
|
||
- `fruix system image` materializes a disk image under `/frx/store/*-fruix-bhyve-image-fruix-freebsd/disk.img`
|
||
- the command returns expected metadata fields for both actions
|
||
|
||
Current assessment:
|
||
|
||
- Fruix now has a real user-facing system command in this repo, which is a concrete step from “prototype scripts” toward “OS tooling”
|
||
- this does not replace all earlier harnesses yet, but it establishes `fruix system` as the new canonical interface for system closure/rootfs/image materialization work
|
||
- system/image creation still typically requires `sudo` because the command writes into `/frx/store` and uses privileged image-building operations
|
||
|
||
Next recommended step:
|
||
|
||
1. continue Phase 10 by making more of the existing system workflows call `bin/fruix` directly instead of bespoke phase scripts
|
||
2. reduce the current runtime compatibility shims for locally built Guile / Shepherd prefixes and move toward a more native store-path-aware Fruix runtime arrangement
|
||
3. consider adding the next operator-facing subcommand on top of the now-working image path, such as a `vm`/deploy-oriented flow for the active XCP-ng workflow
|
||
|
||
## 2026-04-02 — Phase 10 completed: canonical system workflows now use `fruix system`
|
||
|
||
Completed work:
|
||
|
||
- completed the current Optional Phase 10 track by making the existing FreeBSD system workflows use the real Fruix CLI as their canonical frontend
|
||
- wrote the completion report:
|
||
- `docs/reports/phase10-canonical-system-workflows-freebsd.md`
|
||
- extended the `fruix system build` metadata in:
|
||
- `scripts/fruix.scm`
|
||
- added:
|
||
- `ready_marker`
|
||
- `base_package_store_count`
|
||
- `base_package_stores`
|
||
- refactored the main static system harnesses to call `bin/fruix` instead of invoking internal Scheme materializer runners directly:
|
||
- `tests/system/run-phase7-system-closure.sh`
|
||
- `tests/system/run-phase7-rootfs.sh`
|
||
- `tests/system/run-phase8-system-image.sh`
|
||
|
||
What changed in practice:
|
||
|
||
- the closure path is now validated through:
|
||
- `fruix system build`
|
||
- the rootfs path is now validated through:
|
||
- `fruix system rootfs`
|
||
- the image path is now validated through:
|
||
- `fruix system image`
|
||
- the real XCP-ng boot path now benefits from this automatically because:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
still calls the Phase 8 harness, and that harness now builds its image through `bin/fruix`
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase7-system-closure.sh` passes
|
||
- workdir: `/tmp/phase10-canon-closure2-1775119728`
|
||
- `tests/system/run-phase7-rootfs.sh` passes
|
||
- workdir: `/tmp/phase10-canon-rootfs3-1775120391`
|
||
- `tests/system/run-phase8-system-image.sh` passes
|
||
- workdir: `/tmp/phase10-canon-image-1775120548`
|
||
- full real XCP-ng regression still passes after the frontend refactor:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- workdir: `/tmp/phase10-canon-xcpng-1775120869`
|
||
|
||
Important findings:
|
||
|
||
- the Phase 9 booted system path was already real, but the remaining transitional layer was the tooling/frontend boundary rather than the system internals
|
||
- adding `bin/fruix` in Phase 10.1 was necessary but not sufficient on its own; the existing validation and deployment workflows also had to adopt it, or the project would still effectively be driven by bespoke phase scripts
|
||
- after this refactor, the command path is now exercised by:
|
||
- static closure validation
|
||
- static rootfs validation
|
||
- static image validation
|
||
- and the real XCP-ng boot/import/SSH/ready-marker path
|
||
|
||
Current assessment:
|
||
|
||
- Optional Phase 10 is now complete for the current FreeBSD prototype track
|
||
- Fruix now has:
|
||
- a user-facing command surface in `bin/fruix`
|
||
- real `system build`, `system rootfs`, and `system image` actions
|
||
- canonical validation/deployment workflows that use that command instead of directly entering the materializers
|
||
- and a command-driven image path that remains validated on the real XCP-ng VM
|
||
- this means the project now has not just declarative OS internals, but also a real Fruix operator/tooling layer around those internals
|
||
|
||
Next recommended step:
|
||
|
||
1. begin the next post-Phase-10 cleanup/polish pass outside the plan milestones
|
||
2. prioritize replacing the current Guile / Shepherd compatibility-prefix shims with a more native store-path-aware runtime arrangement
|
||
3. consider adding richer deploy/vm-oriented `fruix` commands beyond the now-canonical `system build/rootfs/image` path
|
||
|
||
## 2026-04-02 — Post-Phase-10: local Shepherd-as-PID-1 prototype booted on FreeBSD
|
||
|
||
Completed work:
|
||
|
||
- began the next post-Phase-10 runtime-integration pass by exploring a Shepherd-as-PID-1 boot mode for Fruix on FreeBSD
|
||
- compared the approach with Guix's root Shepherd design in:
|
||
- `~/repos/guix/gnu/services/shepherd.scm`
|
||
- wrote the subphase report:
|
||
- `docs/reports/postphase10-shepherd-pid1-qemu-freebsd.md`
|
||
- extended the declarative FreeBSD operating-system model in:
|
||
- `modules/fruix/system/freebsd.scm`
|
||
- added an `init-mode` field with:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- `shepherd-pid1`
|
||
- generated loader configuration now sets:
|
||
- `init_exec="/run/current-system/boot/fruix-pid1"`
|
||
when `init-mode` is `shepherd-pid1`
|
||
- generated systems in PID 1 mode now include:
|
||
- `boot/fruix-pid1`
|
||
- the generated activation script now treats `cap_mkdb` / `pwd_mkdb` as best-effort so immutable store-backed config files do not abort this early boot path
|
||
- added a dedicated Shepherd-PID-1 operating-system template:
|
||
- `tests/system/phase11-shepherd-pid1-operating-system.scm.in`
|
||
- added a dedicated local QEMU/UEFI validation harness:
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
|
||
|
||
Important findings:
|
||
|
||
- FreeBSD's `init(8)` already has a suitable handoff mechanism for this experiment via:
|
||
- `init_exec`
|
||
- compared with Guix, the current Fruix implementation is still much more imperative, but it now follows the same broad direction:
|
||
- boot into Shepherd directly as PID 1 rather than merely starting Shepherd late from rc.d
|
||
- the first PID 1 attempt failed because the generated Shepherd config imported a repo-side module:
|
||
- `(fruix shepherd freebsd)`
|
||
that was not present inside the guest runtime; the fix was to inline the small helper procedures needed by the generated config itself
|
||
- the early PID 1 path also exposed that store-backed `/etc/login.conf` and `/etc/master.passwd` updates must be best-effort rather than fatal on this bootstrap path
|
||
- for the current locally built runtime artifacts, the compatibility-prefix shims are still needed; this subphase did not eliminate them yet, but it did remove the larger `rc.d` boot-manager dependency from the local prototype path
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now passes
|
||
- passing run workdir:
|
||
- `/tmp/pid1-qemu6-1775128407`
|
||
- validated local guest state included:
|
||
- `ready_marker=ready`
|
||
- `shepherd_pid=1`
|
||
- `shepherd_socket=present`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- `boot_backend=qemu-uefi-tcg`
|
||
- `init_mode=shepherd-pid1`
|
||
|
||
Current assessment:
|
||
|
||
- Fruix now has a working local FreeBSD prototype where Shepherd itself is PID 1
|
||
- this is not yet the new mainline boot path, but it proves that the project can move beyond the earlier `freebsd-init+rc.d-shepherd` bridge architecture
|
||
- the PID 1 process image appears as Guile because Shepherd is launched as a Guile script, but the decisive validation point is that:
|
||
- `/var/run/shepherd.pid` contains `1`
|
||
- this subphase was validated locally under QEMU/TCG + UEFI; the next meaningful test is the real XCP-ng VM
|
||
|
||
Next recommended step:
|
||
|
||
1. try the `shepherd-pid1` image on the real XCP-ng VM
|
||
2. if it boots there too, decide whether to keep `shepherd-pid1` as an experimental selectable boot mode or advance it further toward the main Fruix boot path
|
||
3. continue reducing the remaining Guile / Shepherd compatibility-prefix shims now that the broader `rc.d` boot-manager dependency has been locally bypassed
|
||
|
||
## 2026-04-02 — Post-Phase-10: Shepherd-as-PID-1 boot also passed on the real XCP-ng VM
|
||
|
||
Completed work:
|
||
|
||
- took the locally validated `shepherd-pid1` boot mode and tested it on the real XCP-ng deployment path
|
||
- wrote the follow-up report:
|
||
- `docs/reports/postphase10-shepherd-pid1-xcpng-freebsd.md`
|
||
- expanded the Shepherd-PID-1 operating-system template so the generated guest remains compatible with both local virtio and the real Xen NIC path:
|
||
- `tests/system/phase11-shepherd-pid1-operating-system.scm.in`
|
||
- now includes:
|
||
- `ifconfig_xn0=SYNCDHCP`
|
||
- `ifconfig_em0=SYNCDHCP`
|
||
- `ifconfig_vtnet0=SYNCDHCP`
|
||
- added a dedicated real-VM Shepherd-PID-1 deployment/validation harness:
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh`
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh` now passes on the operator-approved VM and existing VDI:
|
||
- VM `90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- VDI `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- passing run workdir:
|
||
- `/tmp/pid1-xcpng-1775129768`
|
||
- passing real-guest metadata confirmed:
|
||
- `ready_marker=ready`
|
||
- `run_current_system_target=/frx/store/2940c952e9d35e47f98fe62f296be2b6ab4fceb3eee8248d6a7823decd42a305-fruix-system-fruix-freebsd`
|
||
- `pid1_command=[guile]`
|
||
- `shepherd_pid=1`
|
||
- `shepherd_socket=present`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- `init_mode=shepherd-pid1`
|
||
|
||
Important findings:
|
||
|
||
- the local QEMU PID 1 prototype was not a simulator-only artifact; the same general boot design also works on the real XCP-ng/Xen guest
|
||
- as expected for a Guile-script entry point, the PID 1 process image shows up as Guile, but the meaningful architectural check is that:
|
||
- `/var/run/shepherd.pid` contains `1`
|
||
- this means Fruix has now validated two distinct real-VM boot architectures on FreeBSD:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- `shepherd-pid1`
|
||
- however, this still does not remove the current Guile / Shepherd compatibility-prefix shims; those remain a separate runtime-artifact issue rather than an init-manager issue
|
||
|
||
Current assessment:
|
||
|
||
- Shepherd-as-PID-1 is now no longer merely a local prototype; it is validated on the real XCP-ng VM as well
|
||
- this significantly strengthens the path toward a more Guix-like Fruix system architecture on FreeBSD
|
||
- the main remaining native-runtime gap is now the baked-prefix / compatibility-shim problem, not whether Fruix can boot with Shepherd as PID 1
|
||
|
||
Next recommended step:
|
||
|
||
1. focus directly on eliminating the remaining Guile / Shepherd compatibility-prefix shims from the guest runtime
|
||
2. preserve `shepherd-pid1` as an experimental selectable boot mode while that cleanup proceeds
|
||
3. once the runtime-prefix issue is reduced, reassess whether `shepherd-pid1` should replace the older `freebsd-init+rc.d-shepherd` path as the preferred Fruix boot architecture
|
||
|
||
## 2026-04-02 — Post-Phase-10: removed runtime dependence on `/tmp` Guile / Shepherd compatibility-prefix shims
|
||
|
||
Completed work:
|
||
|
||
- removed the generated guest's runtime dependence on the old `/tmp` compatibility-prefix symlinks for Guile, guile-extra, and Shepherd
|
||
- wrote the subphase report:
|
||
- `docs/reports/postphase10-runtime-prefix-shims-freebsd.md`
|
||
- updated the prefix materializer in:
|
||
- `modules/fruix/system/freebsd.scm`
|
||
- bumped the prefix-materializer revision
|
||
- added deterministic post-copy sanitation for staged runtime prefixes
|
||
- removed activation-time recreation of these guest-side shims from the generated activation path:
|
||
- `/tmp/guile-freebsd-validate-install`
|
||
- `/tmp/guile-gnutls-freebsd-validate-install`
|
||
- `/tmp/shepherd-freebsd-validate-install`
|
||
- sanitized the staged guile-extra runtime so it no longer depends on those old prefixes for key module loading:
|
||
- patched `fibers/config.scm` to use `GUILE_EXTENSIONS_PATH`
|
||
- patched `gnutls.scm` to fall back to `GUILE_EXTENSIONS_PATH`
|
||
- removed stale compiled cache files that would otherwise retain the old prefix behavior:
|
||
- `fibers/config.go`
|
||
- `gnutls.go`
|
||
- sanitized the staged Shepherd runtime so it no longer depends on the old temporary prefix for `shepherd config`:
|
||
- patched `share/guile/site/3.0/shepherd/config.scm`
|
||
- removed stale compiled cache file:
|
||
- `shepherd/config.go`
|
||
- extended the real XCP-ng validation harnesses so they now explicitly check for:
|
||
- absence of the `/tmp` compatibility-prefix trees
|
||
- successful Guile module loading from the store-backed runtime
|
||
- updated:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh`
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase9-xcpng-boot.sh` passes on the real VM with:
|
||
- workdir: `/tmp/noshim-phase9-smoke-1775143001`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
- `ready_marker=ready`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh` passes on the real VM with:
|
||
- workdir: `/tmp/noshim-phase11-smoke-1775142712`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
- `ready_marker=ready`
|
||
- `shepherd_pid=1`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- a direct manual guest probe also confirmed that all three `/tmp` compatibility-prefix paths are absent while Guile can still load:
|
||
- `(fibers config)`
|
||
- `(gnutls)`
|
||
- `(shepherd config)`
|
||
|
||
Important findings:
|
||
|
||
- the remaining native-runtime problem was narrower than the earlier boot-manager issue:
|
||
- boot was already solved
|
||
- PID 1 was already solved
|
||
- the next real dependency to remove was the guest's reliance on temporary compatibility aliases
|
||
- deleting the stale compiled cache files for the affected modules was important; otherwise Guile could continue using prefix-baked compiled forms even after the source modules were patched
|
||
- this subphase removes runtime dependence on the old `/tmp` compatibility shims, but it does not yet guarantee that every embedded historical prefix string has disappeared from every binary or metadata artifact
|
||
|
||
Current assessment:
|
||
|
||
- Fruix now boots and runs from a store-backed Guile / Shepherd runtime arrangement on FreeBSD without needing guest-side `/tmp` compatibility-prefix symlinks
|
||
- this now holds for both validated real-VM boot modes:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- `shepherd-pid1`
|
||
- the main remaining cleanup is deeper and lower-level:
|
||
- move the local Guile / guile-extra / Shepherd build/install flow itself closer to a truly store-native prefix so the remaining baked strings disappear from the artifacts rather than merely becoming runtime-irrelevant
|
||
|
||
Next recommended step:
|
||
|
||
1. keep `shepherd-pid1` available as the stronger experimental boot architecture
|
||
2. start pushing the local Guile / guile-extra / Shepherd build/install process itself toward a truly store-native prefix layout
|
||
3. clean up the remaining historical prefix strings still present in binaries, libtool metadata, and pkg-config metadata where they still matter for developer/operator workflows
|
||
|
||
## 2026-04-02 — Phase 12.1: deployment provenance and diagnostic metadata improved
|
||
|
||
Completed work:
|
||
|
||
- wrote the next-stage plan document:
|
||
- `docs/PLAN_3.md`
|
||
- added a concise progress snapshot:
|
||
- `docs/PROG_SUMMARY.md`
|
||
- wrote the Phase 12.1 report:
|
||
- `docs/reports/phase12-provenance-diagnostics-freebsd.md`
|
||
- updated `modules/fruix/system/freebsd.scm` so generated system closures now carry explicit provenance files:
|
||
- `metadata/host-base-provenance.scm`
|
||
- `metadata/store-layout.scm`
|
||
- those closure metadata files now record at least:
|
||
- host `freebsd-version -kru`
|
||
- host `uname -a`
|
||
- `/usr/src` path
|
||
- `/usr/src` git revision/branch when available
|
||
- `newvers.sh` SHA256 as a fallback source-tree identifier
|
||
- exact host-staged FreeBSD base store paths
|
||
- exact Fruix runtime store paths
|
||
- selected init mode
|
||
- extended `scripts/fruix.scm` so `fruix system build` and `fruix system image` now emit explicit provenance/layout metadata including:
|
||
- `host_base_store_count`
|
||
- `host_base_stores`
|
||
- `fruix_runtime_store_count`
|
||
- `fruix_runtime_stores`
|
||
- `host_base_provenance_file`
|
||
- `store_layout_file`
|
||
- `host_freebsd_version`
|
||
- `host_uname`
|
||
- `usr_src_git_revision`
|
||
- `usr_src_git_branch`
|
||
- `usr_src_newvers_sha256`
|
||
- tightened the local closure/image validation harnesses so they now assert that this provenance metadata exists:
|
||
- `tests/system/run-phase7-system-closure.sh`
|
||
- `tests/system/run-phase8-system-image.sh`
|
||
- expanded the VM-oriented harnesses to collect more guest-side diagnostic tails where available:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
|
||
- now include additional capture for:
|
||
- `shepherd-bootstrap.out`
|
||
- `shepherd.log`
|
||
- recent `dmesg`
|
||
- stabilized local reproducibility checks by forcing:
|
||
- `GUILE_AUTO_COMPILE=0`
|
||
in the host-side closure/image harnesses when invoking `fruix` under `sudo env`
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase7-system-closure.sh` passes with the new provenance checks:
|
||
- workdir: `/tmp/phase12-1b-closure-1775157039`
|
||
- confirmed:
|
||
- `host_base_store_count=8`
|
||
- `fruix_runtime_store_count=3`
|
||
- `host_base_provenance_file=/frx/store/.../metadata/host-base-provenance.scm`
|
||
- `store_layout_file=/frx/store/.../metadata/store-layout.scm`
|
||
- `host_freebsd_version=15.0-STABLE`
|
||
- `tests/system/run-phase8-system-image.sh` passes with the new provenance checks:
|
||
- workdir: `/tmp/phase12-1b-image-1775157039`
|
||
- confirmed:
|
||
- `host_base_store_count=8`
|
||
- `fruix_runtime_store_count=3`
|
||
- `host_base_provenance_file=/frx/store/.../metadata/host-base-provenance.scm`
|
||
- `store_layout_file=/frx/store/.../metadata/store-layout.scm`
|
||
- `host_uname=FreeBSD fruixdev 15.0-STABLE ...`
|
||
- syntax-checked successfully:
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
|
||
|
||
Important findings:
|
||
|
||
- the current host-staged FreeBSD base pipeline is still transitional, but it is now much more inspectable and self-describing
|
||
- one-shot reproducibility failures immediately after source edits were partly a host-side auto-compilation artifact; forcing `GUILE_AUTO_COMPILE=0` in the validation harnesses makes the closure/image checks more stable
|
||
- the project can now identify much more directly:
|
||
- which closure/image inputs came from the host-staged FreeBSD base
|
||
- which came from Fruix-built Guile/Shepherd runtime artifacts
|
||
- what `/usr/src` identity was available at build time
|
||
|
||
Current assessment:
|
||
|
||
- Fruix now has a better-documented and easier-to-debug working pipeline for the current host-staged FreeBSD base model
|
||
- this is the right amount of hardening before beginning native FreeBSD base-build work; it improves traceability without pretending the current host-copy model is final
|
||
|
||
Next recommended step:
|
||
|
||
1. continue with Phase 12.2 and tighten the guest-side runtime/operator diagnostics
|
||
2. remove or reduce the most distracting remaining boot/runtime rough edges where the fixes are small and local
|
||
3. keep the deployment path stable so Phase 13 can start from a sharper baseline
|
||
|
||
## 2026-04-02 — Phase 12.2: guest runtime diagnostics tightened and `/etc` handling improved
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 12.2 report:
|
||
- `docs/reports/phase12-runtime-diagnostics-freebsd.md`
|
||
- updated `modules/fruix/system/freebsd.scm` so selected database-backed `/etc` files are now materialized as regular files in the guest rootfs instead of symlinks:
|
||
- `/etc/passwd`
|
||
- `/etc/master.passwd`
|
||
- `/etc/group`
|
||
- `/etc/login.conf`
|
||
- the generated activation script now refreshes those files from `/run/current-system/etc` before rebuilding FreeBSD databases
|
||
- activation now writes a guest-visible log:
|
||
- `/var/log/fruix-activate.log`
|
||
- with markers including:
|
||
- `fruix-activate:start`
|
||
- `fruix-activate:cap_mkdb=ok`
|
||
- `fruix-activate:pwd_mkdb=ok`
|
||
- `fruix-activate:done`
|
||
- exit status marker via shell trap
|
||
- tightened closure permissions slightly by making:
|
||
- `etc/master.passwd`
|
||
mode `0600`
|
||
- upgraded validation harnesses so they now assert the improved runtime behavior directly:
|
||
- `tests/system/run-phase8-system-image.sh`
|
||
- now checks that image `/etc/login.conf` is a regular file
|
||
- now checks that image `/etc/master.passwd` is a regular file
|
||
- `tests/system/run-phase9-xcpng-boot.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh`
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
|
||
- now check for:
|
||
- `login_conf_kind=regular`
|
||
- `login_conf_db=present`
|
||
- `pwd_dbs=present`
|
||
- activation log completion marker
|
||
- fixed a small follow-up bug in the activation log path:
|
||
- initial implementation used `touch`, which is not staged in the minimal guest
|
||
- switched to shell redirection instead:
|
||
- `: >> "$logfile"`
|
||
|
||
Validation:
|
||
|
||
- `tests/system/run-phase8-system-image.sh` passes locally with the new image-layout checks:
|
||
- workdir: `/tmp/phase12-2-image-1775159011`
|
||
- confirmed:
|
||
- `login_conf_kind=regular`
|
||
- `master_passwd_kind=regular`
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` passes locally again with the new activation/runtime checks:
|
||
- workdir: `/tmp/phase12-2b-qemu-1775161367`
|
||
- confirmed:
|
||
- `activate_log=fruix-activate:start ... fruix-activate:done ...`
|
||
- `login_conf_kind=regular`
|
||
- `login_conf_db=present`
|
||
- `pwd_dbs=present`
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
- `tests/system/run-phase9-xcpng-boot.sh` passes on the real VM with the new checks:
|
||
- workdir: `/tmp/phase12-2b-phase9-1775161731`
|
||
- confirmed:
|
||
- `activate_log=fruix-activate:start ... fruix-activate:done ...`
|
||
- `login_conf_kind=regular`
|
||
- `login_conf_db=present`
|
||
- `pwd_dbs=present`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
- `shepherd_status=running`
|
||
- `sshd_status=running`
|
||
- `tests/system/run-phase11-shepherd-pid1-xcpng.sh` passes on the real VM with the new checks:
|
||
- workdir: `/tmp/phase12-2b-phase11-1775162210`
|
||
- confirmed:
|
||
- `activate_log=fruix-activate:start ... fruix-activate:done ...`
|
||
- `login_conf_kind=regular`
|
||
- `login_conf_db=present`
|
||
- `pwd_dbs=present`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
|
||
Important findings:
|
||
|
||
- the old symlink-based handling for login/password database inputs was a real mismatch with FreeBSD expectations; making those files regular in the guest was a better fit than leaving them store-backed symlinks
|
||
- adding a direct activation log materially improves post-boot diagnosis and avoids guessing whether activation actually completed
|
||
- the first attempt exposed a missing-userland dependency (`touch`) quickly; because the new diagnostics were explicit, the follow-up fix was immediate and local
|
||
- both validated boot paths still hold after this change:
|
||
- `freebsd-init+rc.d-shepherd`
|
||
- `shepherd-pid1`
|
||
|
||
Current assessment:
|
||
|
||
- the current Fruix guest remains intentionally minimal, but its runtime behavior is now less prototype-noisy and easier to inspect as a basic FreeBSD-like system
|
||
- this is exactly the kind of targeted hardening that makes the existing system a better launch point for native FreeBSD base-build work
|
||
|
||
Next recommended step:
|
||
|
||
1. complete Phase 12.3 by making the host-staged FreeBSD base boundary explicit in the package/model layer and docs
|
||
2. document the first intended replacement order for native world/kernel work
|
||
3. then begin Phase 13 with a clearer transitional boundary
|
||
|
||
## 2026-04-02 — Phase 12.3: made the host-staged FreeBSD base boundary explicit
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 12.3 report:
|
||
- `docs/reports/phase12-host-staged-base-boundary-freebsd.md`
|
||
- refined `modules/fruix/packages/freebsd.scm` so the transitional host-copy base boundary is now explicit in the package/model layer
|
||
- added and exported named transitional package sets:
|
||
- `%freebsd-host-staged-all-packages`
|
||
- `%freebsd-host-staged-core-packages`
|
||
- `%freebsd-host-staged-development-profile-packages`
|
||
- `%freebsd-host-staged-system-packages`
|
||
- added and exported:
|
||
- `freebsd-host-staged-package?`
|
||
- `%freebsd-host-staged-replacement-order`
|
||
- preserved compatibility aliases so existing callers still work:
|
||
- `%freebsd-core-packages`
|
||
- `%freebsd-development-profile-packages`
|
||
- `%freebsd-system-packages`
|
||
- encoded the intended first replacement order for native base-build work directly in the package layer:
|
||
1. `freebsd-kernel`, `freebsd-bootloader`
|
||
2. `freebsd-runtime`, `freebsd-libc`, `freebsd-userland`, `freebsd-rc-scripts`
|
||
3. `freebsd-networking`, `freebsd-openssh`
|
||
4. `freebsd-kernel-headers`, `freebsd-clang-toolchain`
|
||
5. `freebsd-gmake`, `freebsd-autotools`, `freebsd-openssl`, `freebsd-zlib`, `freebsd-sh`, `freebsd-bash`
|
||
- updated `modules/fruix/system/freebsd.scm` so the generated closure metadata now carries this boundary information too:
|
||
- `metadata/store-layout.scm` now includes:
|
||
- `host-base-stores`
|
||
- `fruix-runtime-stores`
|
||
- `host-base-replacement-order`
|
||
- `init-mode`
|
||
|
||
Validation:
|
||
|
||
- confirmed package-layer behavior directly with Guile:
|
||
- `(freebsd-host-staged-package? freebsd-runtime)` => `#t`
|
||
- `%freebsd-host-staged-replacement-order` prints the expected staged replacement order
|
||
- `tests/system/run-phase7-system-closure.sh` still passes after the package-layer clarification:
|
||
- workdir: `/tmp/phase12-3-closure-1775162784`
|
||
- inspected generated closure metadata file:
|
||
- `/frx/store/25ae9bb85da60b8c77971325e0e11d5390a064132a35e1bab0866cabb802a606-fruix-system-fruix-freebsd/metadata/store-layout.scm`
|
||
- confirmed it now includes:
|
||
- `host-base-stores`
|
||
- `fruix-runtime-stores`
|
||
- `host-base-replacement-order`
|
||
|
||
Important findings:
|
||
|
||
- the current host-staged FreeBSD base model is no longer just an implicit fact of the implementation; it is now named and documented as a transitional boundary
|
||
- preserving compatibility aliases means the current working system model does not need a broad rename/refactor just to make that boundary explicit
|
||
- encoding the replacement order directly in the package/model layer gives Phase 13 a clearer starting point for native `world`/`kernel` work
|
||
|
||
Current assessment:
|
||
|
||
- Phase 12 is now complete
|
||
- the current Fruix pipeline is better documented, easier to diagnose, less noisy at runtime, and clearer about what remains transitional in the FreeBSD base layer
|
||
- this is a good stopping point before beginning native FreeBSD base-build artifacts in `/frx/store`
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 13.1 by modeling FreeBSD `world` and `kernel` as Fruix-managed build artifacts rather than host-copy packages
|
||
2. use `/usr/src` as the initial source of truth on the builder side
|
||
3. target the first bootable replacement for the current host-staged kernel and core runtime path
|
||
|
||
## 2026-04-02 — Phase 13.1: modeled native FreeBSD world/kernel artifacts
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 13.1 report:
|
||
- `docs/reports/phase13-native-base-model-freebsd.md`
|
||
- added native FreeBSD base package objects in `modules/fruix/packages/freebsd.scm`:
|
||
- `freebsd-native-kernel`
|
||
- `freebsd-native-world`
|
||
- added and exported:
|
||
- `freebsd-native-build-package?`
|
||
- encoded the first native build parameters directly in those package definitions, including:
|
||
- `source-root=/usr/src`
|
||
- `target=amd64`
|
||
- `target-arch=amd64`
|
||
- `kernconf=GENERIC`
|
||
- make flags:
|
||
- `__MAKE_CONF=/dev/null`
|
||
- `SRCCONF=/dev/null`
|
||
- `SRC_ENV_CONF=/dev/null`
|
||
- `MK_DEBUG_FILES=no`
|
||
- `MK_TESTS=no`
|
||
- the first native world artifact now also carries an explicit runtime-oriented prune list:
|
||
- `usr/share/doc`
|
||
- `usr/share/examples`
|
||
- `usr/share/info`
|
||
- `usr/share/man`
|
||
- `usr/tests`
|
||
- extended `modules/fruix/system/freebsd.scm` so `materialize-freebsd-package` now understands:
|
||
- `copy-build-system`
|
||
- `freebsd-world-build-system`
|
||
- `freebsd-kernel-build-system`
|
||
- added native-build identity/materialization helpers for:
|
||
- `/usr/src` source-tree identity
|
||
- `KERNCONF` path hashing
|
||
- build-root identity
|
||
- buildworld/buildkernel stamp handling
|
||
- staged installworld/installkernel materialization
|
||
- native build metadata files in store outputs
|
||
- chose an `mtree`-based `/usr/src` identity for the first native output model using:
|
||
- `type`
|
||
- `link`
|
||
- `size`
|
||
- `mode`
|
||
- `sha256digest`
|
||
- updated closure/image metadata modeling so the system can now distinguish:
|
||
- `host_base_stores`
|
||
- `native_base_stores`
|
||
- `fruix_runtime_stores`
|
||
- updated profile/tree merging to skip private dotfile metadata from store outputs so native-build metadata does not leak into the merged runtime tree
|
||
|
||
Validation:
|
||
|
||
- confirmed the updated package/system modules still load after the native build-model additions
|
||
- confirmed the new native package objects are present and classified as expected:
|
||
- `freebsd-native-kernel` reports build-system `freebsd-kernel-build-system`
|
||
- `freebsd-native-build-package? freebsd-native-world` returns `#t`
|
||
- re-ran the existing host-copy regression check successfully:
|
||
- `tests/system/run-phase7-system-closure.sh`
|
||
- workdir: `/tmp/phase13-1-closure-1775164392`
|
||
- result: `PASS phase7-system-closure`
|
||
|
||
Important findings:
|
||
|
||
- Fruix now has a real model for FreeBSD base artifacts built from `/usr/src`; the project is no longer limited to describing the FreeBSD base only as host-copy packages
|
||
- the first native identity story is explicit:
|
||
- `/usr/src` contributes through an `mtree`-based tree digest
|
||
- `KERNCONF` contributes through its resolved path hash
|
||
- selected make/build parameters are part of the manifest too
|
||
- the repo can now describe a mixed system more honestly by separating:
|
||
- transitional host-staged base stores
|
||
- native base stores
|
||
- Fruix runtime stores
|
||
|
||
Current assessment:
|
||
|
||
- Phase 13.1 is complete
|
||
- the next step is no longer architectural guesswork; it is concrete execution of the newly added native package/materialization path
|
||
|
||
Next recommended step:
|
||
|
||
1. build the first concrete `freebsd-native-kernel` and `freebsd-native-world` outputs from `/usr/src`
|
||
2. inspect/document their staged contents in `/frx/store`
|
||
3. then wire a bootable system closure/image around those native outputs
|
||
|
||
## 2026-04-03 — Phase 13.2: first native FreeBSD world/kernel outputs built from `/usr/src`
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 13.2 report:
|
||
- `docs/reports/phase13-native-world-kernel-build-freebsd.md`
|
||
- exercised the new native build path for real and produced the first concrete store outputs from `/usr/src`:
|
||
- native kernel output under `/frx/store`
|
||
- native world output under `/frx/store`
|
||
- added a dedicated Phase 13.2 template/harness:
|
||
- `tests/system/phase13-native-base-pid1-operating-system.scm.in`
|
||
- `tests/system/run-phase13-native-base-build.sh`
|
||
- fixed the first real native-build failure:
|
||
- `MAKEOBJDIRPREFIX` cannot be passed as a make command-line variable for this FreeBSD build path
|
||
- changed the native builder to invoke make as:
|
||
- `env MAKEOBJDIRPREFIX=... make ...`
|
||
- fixed a subtle output-identity bug in the first `/usr/src` hash implementation:
|
||
- the initial `mtree`-based source hash accidentally included unstable header comments such as date/user/machine lines
|
||
- now strips `# ...` header lines before hashing
|
||
- this stabilized the source-tree identity and stopped the native output/build-root identity from drifting on each run
|
||
- verified that native world and kernel now share the same:
|
||
- `source-tree-sha256`
|
||
- `build-root`
|
||
- the first native world split remains intentionally runtime-oriented and prunes at least:
|
||
- `usr/share/doc`
|
||
- `usr/share/examples`
|
||
- `usr/share/info`
|
||
- `usr/share/man`
|
||
- `usr/tests`
|
||
|
||
Concrete validated outputs:
|
||
|
||
- native kernel store path:
|
||
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
|
||
- native world store path:
|
||
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
|
||
- shared native build root:
|
||
- `/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58`
|
||
|
||
Validated native-world contents include at least:
|
||
|
||
- `/bin/sh`
|
||
- `/sbin/init`
|
||
- `/etc/rc`
|
||
- `/usr/sbin/sshd`
|
||
- `/sbin/dhclient`
|
||
- `/usr/bin/cap_mkdb`
|
||
- `/usr/sbin/pwd_mkdb`
|
||
- `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||
|
||
Validated pruned paths are absent from the world output:
|
||
|
||
- `/usr/share/man`
|
||
- `/usr/tests`
|
||
|
||
Validation:
|
||
|
||
- real native-base `fruix system build` succeeded with an operating-system using:
|
||
- `freebsd-native-kernel`
|
||
- `freebsd-native-world`
|
||
- host-staged `freebsd-bootloader`
|
||
- `shepherd-pid1`
|
||
- `tests/system/run-phase13-native-base-build.sh` passes:
|
||
- workdir: `/tmp/phase13-2-build-1775173551`
|
||
- result: `PASS phase13-native-base-build`
|
||
- the harness confirmed:
|
||
- closure rebuild path reproducibility
|
||
- native kernel/world store paths exist
|
||
- native build info files exist
|
||
- world/kernel source-tree hashes match
|
||
- world/kernel build roots match
|
||
- native build logs exist
|
||
- `native-base-stores` is present in closure metadata
|
||
- host/native store boundary now looks as expected for this mixed system:
|
||
- `host_base_store_count=1`
|
||
- `native_base_store_count=2`
|
||
|
||
Important findings:
|
||
|
||
- the native build path is now real, not just modeled
|
||
- the first mixed Phase-13 system boundary is explicit and sensible:
|
||
- host-staged bootloader only
|
||
- native kernel + native world
|
||
- Fruix runtime stores unchanged
|
||
- the `mtree` preamble bug would have made native output identity drift across runs; fixing it was essential before treating these as reproducible store artifacts
|
||
- the shared build-root result is important: the kernel/world pair now reuses the same `/usr/src` build state instead of acting like two unrelated builds
|
||
|
||
Current assessment:
|
||
|
||
- Phase 13.2 is complete
|
||
- Fruix can now build and stage native FreeBSD base artifacts from `/usr/src` in `/frx/store`
|
||
- the next step is to boot a system using those native outputs rather than stopping at build-time inspection
|
||
|
||
Next recommended step:
|
||
|
||
1. wire the image/boot path to use the native kernel/world outputs end-to-end
|
||
2. validate locally with QEMU/UEFI
|
||
3. validate on the approved XCP-ng VM and VDI path
|
||
|
||
## 2026-04-03 — Phase 13.3: booted Fruix from native FreeBSD kernel/world outputs
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 13.3 report:
|
||
- `docs/reports/phase13-native-base-boot-freebsd.md`
|
||
- completed the first end-to-end boot path using native `/usr/src`-built FreeBSD base artifacts in `/frx/store`
|
||
- fixed the first native-image sizing problem:
|
||
- the old fixed `root-size=256m` was too small once the image carried a native world
|
||
- added explicit root filesystem sizing support to the CLI/image path:
|
||
- `scripts/fruix.scm` now accepts `--root-size SIZE`
|
||
- image metadata now records `root_size`
|
||
- `tests/system/run-phase8-system-image.sh` now accepts:
|
||
- `ROOT_SIZE`
|
||
and records:
|
||
- `root_size`
|
||
- `native_base_store_count`
|
||
- `native_base_stores`
|
||
- fixed a follow-up image metadata bug:
|
||
- `materialize-bhyve-image` now returns:
|
||
- `native-base-stores`
|
||
- this removed the `length #f` failure in the native image path
|
||
- generalized the local PID1 QEMU harness a bit further:
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now accepts `OS_TEMPLATE`
|
||
- added dedicated Phase 13.3 native-base boot wrappers:
|
||
- `tests/system/run-phase13-native-base-qemu.sh`
|
||
- `tests/system/run-phase13-native-base-xcpng.sh`
|
||
- these wrappers reuse the validated PID1 boot path but additionally require the image metadata to prove the booted system is really using the intended Phase-13 base split:
|
||
- native kernel present
|
||
- native world present
|
||
- host base reduced to bootloader only
|
||
|
||
Working native-base boot configuration:
|
||
|
||
- 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
|
||
|
||
Validation:
|
||
|
||
- local QEMU/UEFI/TCG boot passes through the new wrapper:
|
||
- `tests/system/run-phase13-native-base-qemu.sh`
|
||
- workdir: `/tmp/phase13-3-qemu3-1775174863`
|
||
- result: `PASS phase13-native-base-qemu`
|
||
- confirmed:
|
||
- `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`
|
||
- real XCP-ng boot passes through the new wrapper:
|
||
- `tests/system/run-phase13-native-base-xcpng.sh`
|
||
- workdir: `/tmp/phase13-3-xcpng-1775175086`
|
||
- result: `PASS phase13-native-base-xcpng`
|
||
- confirmed:
|
||
- `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`
|
||
- validated native-base closure/image composition now boots with:
|
||
- 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`
|
||
|
||
Important findings:
|
||
|
||
- the native world is large enough that the older 256 MiB rootfs assumption is no longer realistic; explicit image sizing is now part of the practical Phase-13 path
|
||
- after the native-base transition, the remaining transitional boundary is now much narrower and explicit:
|
||
- host-staged bootloader/boot assets
|
||
- native kernel
|
||
- native core world runtime
|
||
- the real XCP-ng upload path still works with the larger native-world image, but the dynamic VHD is naturally much bigger now (~4.42 GiB)
|
||
|
||
Current assessment:
|
||
|
||
- Phase 13 is complete
|
||
- Fruix now builds FreeBSD kernel/world artifacts from `/usr/src` into `/frx/store` and successfully boots a declarative system from those native outputs
|
||
- this is the main architectural pivot Plan 3 called for before Phase 14
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 14 by replacing the remaining host-copy boot assets first
|
||
2. keep shrinking the host-staged base boundary around the now-working native world/kernel path
|
||
3. revisit cleaner runtime vs. development splits after the boot asset transition
|
||
|
||
## 2026-04-03 — Phase 14.1: removed host-copied boot assets from the validated native boot path
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 14.1 report:
|
||
- `docs/reports/phase14-native-boot-assets-freebsd.md`
|
||
- added a dedicated Phase 14.1 native-boot PID1 template:
|
||
- `tests/system/phase14-native-boot-pid1-operating-system.scm.in`
|
||
- added dedicated Phase 14.1 validation wrappers:
|
||
- `tests/system/run-phase14-native-boot-qemu.sh`
|
||
- `tests/system/run-phase14-native-boot-xcpng.sh`
|
||
- validated a cleaner native boot path by sourcing boot assets from the existing native world output instead of the host-staged `freebsd-bootloader` package:
|
||
- `#:kernel freebsd-native-kernel`
|
||
- `#:bootloader freebsd-native-world`
|
||
- `#:base-packages (list freebsd-native-world)`
|
||
- hardened the reusable local PID1 QEMU harness so it no longer boots the raw store image directly read/write from `/frx/store`:
|
||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now copies the generated raw image to:
|
||
- `boot-disk.img`
|
||
in the workdir before launching QEMU
|
||
- this prevents repeated local boots from mutating the supposed store artifact and causing dirty-filesystem follow-up failures
|
||
|
||
Validation:
|
||
|
||
- local QEMU/UEFI/TCG native-boot wrapper passes:
|
||
- `tests/system/run-phase14-native-boot-qemu.sh`
|
||
- workdir: `/tmp/phase14-1-qemu2-1775188371`
|
||
- result: `PASS phase14-native-boot-qemu`
|
||
- confirmed:
|
||
- `native_base_store_count=2`
|
||
- `host_base_store_count=0`
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
- `native_boot_assets=freebsd-native-world`
|
||
- `native_base_boot=ok`
|
||
- real XCP-ng native-boot wrapper passes:
|
||
- `tests/system/run-phase14-native-boot-xcpng.sh`
|
||
- workdir: `/tmp/phase14-1-xcpng-1775188701`
|
||
- result: `PASS phase14-native-boot-xcpng`
|
||
- confirmed:
|
||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- `guest_ip=192.168.213.62`
|
||
- `native_base_store_count=2`
|
||
- `host_base_store_count=0`
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
- `native_boot_assets=freebsd-native-world`
|
||
- `native_base_boot=ok`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 14.1 is complete
|
||
- the validated native boot path no longer depends on host-copied `/boot/...` material
|
||
- the current Phase-14.1 native boundary is now fully host-base-free for the validated path:
|
||
- native kernel
|
||
- native world supplying boot assets
|
||
- native world supplying runtime
|
||
|
||
Next recommended step:
|
||
|
||
1. introduce a clearer native runtime slice so runtime is no longer modeled by reusing the broader native world output for both boot and runtime
|
||
2. validate that explicit native runtime slice on QEMU and XCP-ng
|
||
3. then revisit headers/toolchain/development package boundaries
|
||
|
||
## 2026-04-03 — Phase 14.2: validated an explicit native FreeBSD runtime slice
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 14.2 report:
|
||
- `docs/reports/phase14-native-runtime-freebsd.md`
|
||
- added a new native package in `modules/fruix/packages/freebsd.scm`:
|
||
- `freebsd-native-runtime`
|
||
- this runtime slice is built from `/usr/src` through the native world path and now prunes at least:
|
||
- `boot`
|
||
- `usr/include`
|
||
- `usr/share/doc`
|
||
- `usr/share/examples`
|
||
- `usr/share/info`
|
||
- `usr/share/man`
|
||
- `usr/share/mk`
|
||
- `usr/tests`
|
||
- added a dedicated Phase 14.2 operating-system template:
|
||
- `tests/system/phase14-native-runtime-pid1-operating-system.scm.in`
|
||
- added dedicated validation wrappers:
|
||
- `tests/system/run-phase14-native-runtime-qemu.sh`
|
||
- `tests/system/run-phase14-native-runtime-xcpng.sh`
|
||
- the validated Phase 14.2 model now uses:
|
||
- `#:kernel freebsd-native-kernel`
|
||
- `#:bootloader freebsd-native-world`
|
||
- `#:base-packages (list freebsd-native-runtime)`
|
||
- this makes the system composition more explicit:
|
||
- native world provides boot assets
|
||
- native runtime provides the guest runtime slice
|
||
- host base stores remain absent from the validated path
|
||
|
||
Important finding:
|
||
|
||
- this Phase 14.2 layout still duplicates some content because boot assets still come from the broader native world output while runtime comes from the separate native runtime slice
|
||
- that made the earlier Phase 13 image sizes too small
|
||
- the working values are now:
|
||
- local QEMU:
|
||
- `DISK_CAPACITY=12g`
|
||
- `ROOT_SIZE=10g`
|
||
- real XCP-ng:
|
||
- `ROOT_SIZE=10g`
|
||
- disk capacity still matched to the fixed 30 GiB VDI
|
||
- the new Phase 14.2 wrappers now use those larger defaults
|
||
|
||
Validation:
|
||
|
||
- local QEMU/UEFI/TCG runtime wrapper passes:
|
||
- `tests/system/run-phase14-native-runtime-qemu.sh`
|
||
- workdir: `/tmp/phase14-2-qemu2-1775189802`
|
||
- result: `PASS phase14-native-runtime-qemu`
|
||
- confirmed:
|
||
- `disk_capacity=12g`
|
||
- `root_size=10g`
|
||
- `runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-freebsd-native-runtime-15.0-STABLE`
|
||
- `native_base_store_count=3`
|
||
- `host_base_store_count=0`
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
- `native_runtime_ready=ok`
|
||
- real XCP-ng runtime wrapper passes:
|
||
- `tests/system/run-phase14-native-runtime-xcpng.sh`
|
||
- workdir: `/tmp/phase14-2-xcpng-1775190184`
|
||
- result: `PASS phase14-native-runtime-xcpng`
|
||
- confirmed:
|
||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- `guest_ip=192.168.213.62`
|
||
- `root_size=10g`
|
||
- `runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-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_runtime_ready=ok`
|
||
- the wrappers also assert the runtime-split boundary directly:
|
||
- runtime store contains required boot-to-ready files such as:
|
||
- `/bin/sh`
|
||
- `/sbin/init`
|
||
- `/etc/rc`
|
||
- `/usr/sbin/sshd`
|
||
- `/sbin/dhclient`
|
||
- `/usr/bin/ssh-keygen`
|
||
- `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||
- runtime store no longer contains:
|
||
- `/boot`
|
||
- `/usr/include`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 14.2 is complete
|
||
- the validated Fruix guest now reaches ready state using an explicit native runtime artifact rather than reusing the broad native world output for both boot and runtime roles
|
||
- the validated path remains host-base-free:
|
||
- native kernel
|
||
- native world as the temporary boot-source artifact
|
||
- native runtime as the guest runtime artifact
|
||
|
||
Next recommended step:
|
||
|
||
1. define cleaner runtime vs. development boundaries in code/package sets
|
||
2. introduce a narrower native boot asset package so the broader native world output is no longer needed as the temporary boot-source store
|
||
3. revalidate the full host-base-free path after that split
|
||
|
||
## 2026-04-03 — Phase 14.3: split native FreeBSD boot, runtime, and development artifacts
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 14.3 report:
|
||
- `docs/reports/phase14-native-splits-freebsd.md`
|
||
- added new native packages in `modules/fruix/packages/freebsd.scm`:
|
||
- `freebsd-native-bootloader`
|
||
- `freebsd-native-headers`
|
||
- refined `freebsd-native-runtime` into a narrower runtime slice by pruning 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`
|
||
- extended the native world-derived build path in `modules/fruix/system/freebsd.scm` with support for:
|
||
- `keep-paths`
|
||
- native build manifests/output metadata now record both:
|
||
- `keep-paths`
|
||
- `prune-paths`
|
||
- added explicit native package-set boundaries:
|
||
- `%freebsd-native-system-packages`
|
||
- `%freebsd-native-development-profile-packages`
|
||
- the final validated Phase 14 system template now uses:
|
||
- `#:kernel freebsd-native-kernel`
|
||
- `#:bootloader freebsd-native-bootloader`
|
||
- `#:base-packages %freebsd-native-system-packages`
|
||
- this removes the need for the broad `freebsd-native-world` artifact from the final validated system closure
|
||
|
||
New validation files:
|
||
|
||
- `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/runtime split harness passes:
|
||
- `tests/system/run-phase14-native-development-split.sh`
|
||
- workdir: `/tmp/phase14-3-dev5-1775191195`
|
||
- result: `PASS phase14-native-development-split`
|
||
- confirmed:
|
||
- `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:
|
||
- bootloader slice contains the expected boot assets only
|
||
- headers slice contains headers/mk files
|
||
- headers slice does not contain `/boot` or runtime binaries
|
||
- final split-system local QEMU validation passes:
|
||
- `tests/system/run-phase14-native-split-qemu.sh`
|
||
- workdir: `/tmp/phase14-3-qemu-1775191337`
|
||
- result: `PASS phase14-native-split-qemu`
|
||
- confirmed:
|
||
- `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`
|
||
- final split-system real XCP-ng validation passes:
|
||
- `tests/system/run-phase14-native-split-xcpng.sh`
|
||
- workdir: `/tmp/phase14-3-xcpng-1775191743`
|
||
- result: `PASS phase14-native-split-xcpng`
|
||
- confirmed:
|
||
- `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`
|
||
|
||
Important findings:
|
||
|
||
- after replacing the temporary broad-world boot source with the narrower native bootloader slice and tightening the runtime slice, the validated image became much smaller again
|
||
- the real XCP-ng dynamic VHD upload for the final split path was:
|
||
- `1560725504` bytes (~1.45 GiB)
|
||
- that is far better than the temporary broad-world + runtime duplication in Phase 14.2
|
||
- the final validated Phase 14 closure no longer needs the broad `freebsd-native-world` artifact in its native base store set
|
||
|
||
Current assessment:
|
||
|
||
- Phase 14 is complete
|
||
- Fruix now has a validated, host-base-free FreeBSD system path composed from native artifacts in `/frx/store`:
|
||
- `freebsd-native-kernel`
|
||
- `freebsd-native-bootloader`
|
||
- `freebsd-native-runtime`
|
||
- the runtime vs. development boundary is also clearer now through:
|
||
- `freebsd-native-headers`
|
||
- `%freebsd-native-development-profile-packages`
|
||
- this completes the Plan-3 Phase-14 goal of incrementally replacing the host-copy FreeBSD base layer for the validated boot/runtime path
|
||
|
||
Next recommended step:
|
||
|
||
1. begin Phase 15 by making the FreeBSD base version a declarative Fruix input
|
||
2. demonstrate side-by-side native base versions in `/frx/store`
|
||
3. validate rebuild/redeploy/rollback across those base versions
|
||
|
||
## 2026-04-03 — Phase 15.1: made the FreeBSD base a declarative Fruix input
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 15.1 report:
|
||
- `docs/reports/phase15-declarative-base-freebsd.md`
|
||
- added a new declarative base record in `modules/fruix/packages/freebsd.scm`:
|
||
- `freebsd-base`
|
||
- `freebsd-base?`
|
||
- `%default-freebsd-base`
|
||
- the declarative base now records at least:
|
||
- `name`
|
||
- `version-label`
|
||
- `release`
|
||
- `branch`
|
||
- `source-root`
|
||
- `target`
|
||
- `target-arch`
|
||
- `kernconf`
|
||
- `make-flags`
|
||
- native FreeBSD package constructors are now parameterized by a declared base:
|
||
- `freebsd-native-kernel-for`
|
||
- `freebsd-native-world-for`
|
||
- `freebsd-native-runtime-for`
|
||
- `freebsd-native-bootloader-for`
|
||
- `freebsd-native-headers-for`
|
||
- `freebsd-native-system-packages-for`
|
||
- `freebsd-native-development-profile-packages-for`
|
||
- existing exported native package variables remain available as the `%default-freebsd-base` instances:
|
||
- `freebsd-native-kernel`
|
||
- `freebsd-native-world`
|
||
- `freebsd-native-runtime`
|
||
- `freebsd-native-bootloader`
|
||
- `freebsd-native-headers`
|
||
- added a new operating-system field in `modules/fruix/system/freebsd.scm`:
|
||
- `#:freebsd-base`
|
||
- exported accessor: `operating-system-freebsd-base`
|
||
- the declared base is now recorded in system/image metadata through:
|
||
- `operating-system-closure-spec`
|
||
- `operating-system-image-spec`
|
||
- `metadata/freebsd-base.scm`
|
||
- `metadata/store-layout.scm`
|
||
- native build manifests and `.freebsd-native-build-info.scm` now record:
|
||
- `declared-base`
|
||
- `scripts/fruix.scm` now emits declared base metadata for `build` and `image`:
|
||
- `freebsd_base_name`
|
||
- `freebsd_base_version_label`
|
||
- `freebsd_base_release`
|
||
- `freebsd_base_branch`
|
||
- `freebsd_base_source_root`
|
||
- `freebsd_base_target`
|
||
- `freebsd_base_target_arch`
|
||
- `freebsd_base_kernconf`
|
||
- `freebsd_base_file`
|
||
|
||
New validation files:
|
||
|
||
- `tests/system/phase15-declarative-base-pid1-operating-system.scm.in`
|
||
- `tests/system/run-phase15-declarative-base-build.sh`
|
||
|
||
Validation:
|
||
|
||
- declarative-base build harness passes:
|
||
- `tests/system/run-phase15-declarative-base-build.sh`
|
||
- workdir: `/tmp/phase15-1-build-1775202535`
|
||
- result: `PASS phase15-declarative-base-build`
|
||
- confirmed:
|
||
- `kernel_store=/frx/store/8fcef04c7e507e86ea5e92f251fe3c6ac1aa3bcf4809fa77ddd8b92854bfcde0-freebsd-native-kernel-15.0-STABLE-declarative`
|
||
- `bootloader_store=/frx/store/7a0ba431e487dc35a8f6318108da16a37c8426c43e77e7a7f91404ba1d980eef-freebsd-native-bootloader-15.0-STABLE-declarative`
|
||
- `runtime_store=/frx/store/17c24ad20ddcb136c39352b68e758deae0b480258ba0128a5546f696a7eba0a6-freebsd-native-runtime-15.0-STABLE-declarative`
|
||
- `native_base_store_count=3`
|
||
- `host_base_store_count=0`
|
||
- `freebsd_base_name=stable-default`
|
||
- `freebsd_base_version_label=15.0-STABLE-declarative`
|
||
- `freebsd_base_release=15.0-STABLE`
|
||
- `freebsd_base_branch=stable/15`
|
||
- `freebsd_base_source_root=/usr/src`
|
||
- `freebsd_base_kernconf=GENERIC`
|
||
- `declarative_base_input=ok`
|
||
- the harness also confirmed:
|
||
- `metadata/freebsd-base.scm` exists
|
||
- `parameters.scm` records the declared base
|
||
- `metadata/store-layout.scm` records the declared base
|
||
- native build info files record the declared base version/branch
|
||
|
||
Current assessment:
|
||
|
||
- Phase 15.1 is complete
|
||
- Fruix now models the FreeBSD base as an explicit declarative system input instead of leaving it implicit in the builder host alone
|
||
- the next step is to use that new declaration to prove side-by-side base versions and rollback-friendly rebuild/redeploy behavior
|
||
|
||
## 2026-04-03 — Phase 15.2: validated side-by-side base versions and rollback-friendly redeploy
|
||
|
||
Completed work:
|
||
|
||
- wrote the Phase 15.2 report:
|
||
- `docs/reports/phase15-base-upgrades-freebsd.md`
|
||
- added validation harnesses:
|
||
- `tests/system/run-phase15-base-coexistence.sh`
|
||
- `tests/system/run-phase15-base-rollback-qemu.sh`
|
||
- `tests/system/run-phase15-base-rollback-xcpng.sh`
|
||
- used two explicit declarative base identities against the current validated native Phase 14 package split:
|
||
- current base:
|
||
- `name=stable-default`
|
||
- `version-label=15.0-STABLE`
|
||
- `release=15.0-STABLE`
|
||
- `branch=stable/15`
|
||
- candidate base:
|
||
- `name=stable-canary`
|
||
- `version-label=15.0-STABLE-p1`
|
||
- `release=15.0-STABLE`
|
||
- `branch=stable/15`
|
||
- both declarations still use the same local `/usr/src`, but now produce distinct declared base/store/deployment identities
|
||
|
||
Validation:
|
||
|
||
- side-by-side base-coexistence harness passes:
|
||
- `tests/system/run-phase15-base-coexistence.sh`
|
||
- workdir: `/tmp/phase15-2-coexist-1775202833`
|
||
- result: `PASS phase15-base-coexistence`
|
||
- confirmed:
|
||
- `current_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||
- `current_base_version_label=15.0-STABLE`
|
||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||
- `side_by_side_base_versions=ok`
|
||
- `rollback_rebuild_path=ok`
|
||
- this also confirmed that:
|
||
- both closures exist side by side in `/frx/store`
|
||
- rebuilding the current declaration returns the exact original current closure path
|
||
- current native base stores remain separate from candidate native base stores
|
||
- local QEMU rollback harness passes:
|
||
- `tests/system/run-phase15-base-rollback-qemu.sh`
|
||
- workdir: `/tmp/phase15-2-qemu2-1775204321`
|
||
- result: `PASS phase15-base-rollback-qemu`
|
||
- validation sequence:
|
||
1. boot current base
|
||
2. boot candidate base
|
||
3. boot current base again
|
||
- confirmed:
|
||
- `current_first_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||
- `rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||
- `current_base_version_label=15.0-STABLE`
|
||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||
- `rollback_base_version_label=15.0-STABLE`
|
||
- `base_rollforward_and_rollback=ok`
|
||
- real XCP-ng rollback harness passes:
|
||
- `tests/system/run-phase15-base-rollback-xcpng.sh`
|
||
- workdir: `/tmp/phase15-2-xcpng-1775204839`
|
||
- result: `PASS phase15-base-rollback-xcpng`
|
||
- validation sequence:
|
||
1. boot candidate base on the approved VM/VDI
|
||
2. boot current base again on the same approved VM/VDI
|
||
- confirmed:
|
||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||
- `rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||
- `rollback_base_version_label=15.0-STABLE`
|
||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||
- `base_rollforward_and_rollback=ok`
|
||
- guest invariants stayed intact for both boots:
|
||
- `shepherd_pid=1`
|
||
- `sshd_status=running`
|
||
- `compat_prefix_shims=absent`
|
||
- `guile_module_smoke=ok`
|
||
|
||
Current assessment:
|
||
|
||
- Phase 15.2 is complete
|
||
- Fruix now supports a real upgrade-style FreeBSD base workflow at the store/deployment level:
|
||
- explicit current vs. candidate base declarations
|
||
- side-by-side native base outputs in `/frx/store`
|
||
- rollback to the earlier closure without mutating it in place
|
||
- the remaining Phase 15 work is to document the evidence-based decision on whether self-hosted base builds should be the next step, or whether host-built native base artifacts should remain the near-term path while reproducibility/source acquisition improve
|