Files
fruix/docs/PROGRESS.md

67 KiB

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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document FreeBSD syscall mapping
  • 7621798Prototype 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
  1. if possible, use outputs or dependency relationships realistic enough to model how a future FreeBSD Guix daemon would retain referenced store items
  2. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document FreeBSD syscall mapping
  • 7621798Prototype FreeBSD jail build isolation
  • d65b2afPrototype 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document FreeBSD syscall mapping
  • 7621798Prototype FreeBSD jail build isolation
  • d65b2afPrototype FreeBSD build user isolation
  • e404e2ePrototype 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document FreeBSD syscall mapping
  • 7621798Prototype FreeBSD jail build isolation
  • d65b2afPrototype FreeBSD build user isolation
  • e404e2ePrototype FreeBSD store management
  • eb0d77cAdapt 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
  1. 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:

  • e380e88Add FreeBSD Guile verification harness
  • cd721b1Update progress after Guile verification
  • 27916cbDiagnose Guile subprocess crash on FreeBSD
  • 02f7a7fValidate local Guile fix on FreeBSD
  • 4aebea4Add native GNU Hello FreeBSD build harness
  • c944cdbValidate Guix builder phases on FreeBSD
  • 0a2e48eValidate GNU which builder phases on FreeBSD
  • 245a47dDocument gaps to real Guix FreeBSD builds
  • d62e9b0Investigate Guix derivation generation on FreeBSD
  • c0a85edBuild local Guile-GnuTLS on FreeBSD
  • 15b9037Build local Guile-Git on FreeBSD
  • 47d31e8Build local Guile-JSON on FreeBSD
  • d82195bAdvance Guix checkout on FreeBSD
  • 9bf3d30Document FreeBSD syscall mapping
  • 7621798Prototype FreeBSD jail build isolation
  • d65b2afPrototype FreeBSD build user isolation
  • e404e2ePrototype FreeBSD store management
  • eb0d77cAdapt GNU build phases for FreeBSD
  • d47dc9bPrototype 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