docs: Opus review
This commit is contained in:
+599
@@ -0,0 +1,599 @@
|
||||
# Fruix System Review
|
||||
|
||||
An external review of the Fruix operating system: a hybrid combining
|
||||
the FreeBSD kernel and userland with GNU Guix-style declarative package
|
||||
management and GNU Shepherd as the init system.
|
||||
|
||||
Review date: 2026-04-07
|
||||
|
||||
---
|
||||
|
||||
## 1. Philosophical Fit
|
||||
|
||||
### Do FreeBSD and Guix Complement Each Other?
|
||||
|
||||
Yes — and more naturally than one might expect. The two projects share
|
||||
a deeper kinship than their surface differences suggest:
|
||||
|
||||
- **Clean boundaries.** FreeBSD's base/ports split is structurally
|
||||
analogous to Guix's separation of the system definition from the
|
||||
package graph. Both projects value knowing exactly what "the system"
|
||||
is versus what the user has layered on top. Fruix exploits this
|
||||
directly: FreeBSD's base becomes the declared `freebsd-base` record,
|
||||
and everything above it is Guix-managed store content.
|
||||
|
||||
- **Whole-system coherence.** FreeBSD builds its base as a single
|
||||
coordinated unit (`make world`). Guix builds its system as a single
|
||||
coordinated closure. Fruix's three-layer profile model
|
||||
(runtime/development/build) maps cleanly onto both traditions —
|
||||
FreeBSD developers will recognise the split as familiar, and Guix
|
||||
users will recognise the closure semantics.
|
||||
|
||||
- **Conservative engineering.** Both upstream projects favour
|
||||
correctness over novelty. FreeBSD's resistance to unnecessary
|
||||
abstraction pairs well with Guix's emphasis on reproducibility over
|
||||
convenience. The result is a system where "works the same way every
|
||||
time" is a shared first principle, not a bolted-on afterthought.
|
||||
|
||||
- **Auditability.** FreeBSD's single-source-tree base is already
|
||||
unusually auditable for a Unix. Adding content-addressed store paths
|
||||
and explicit provenance metadata makes it *more* auditable, not less.
|
||||
The Fruix design of embedding `metadata/freebsd-source.scm` and
|
||||
materialisation records into every closure is a genuine improvement
|
||||
over either upstream's status quo.
|
||||
|
||||
The combination is not merely compatible — it is arguably a better
|
||||
expression of both projects' values than either achieves alone. FreeBSD
|
||||
gains reproducibility and declarative configuration. Guix gains a
|
||||
mature, coherent kernel and userland with superior network stack, jail
|
||||
isolation, and ZFS. Neither project currently offers what the hybrid
|
||||
provides.
|
||||
|
||||
### Tension Points
|
||||
|
||||
The tensions are real but tractable. Each one has already been
|
||||
partially addressed in the current codebase:
|
||||
|
||||
**Mutable `/etc` vs. store-based immutability.** FreeBSD expects
|
||||
`/etc` to be a mutable directory owned by the administrator. Guix
|
||||
expects it to be a rendered artifact derived from the system
|
||||
declaration. Fruix currently renders `/etc` files at activation time
|
||||
from the closure's metadata — this is the correct approach, but it
|
||||
will need careful handling as the system grows. The risk is drift: if
|
||||
an operator hand-edits `/etc/rc.conf` and the next `reconfigure`
|
||||
silently overwrites it, trust erodes. The solution (used by NixOS) is
|
||||
to make the rendered files clearly machine-managed and to provide a
|
||||
sanctioned escape hatch for local overrides. Fruix should plan for
|
||||
this now, before the habit of hand-editing `/etc` becomes entrenched
|
||||
among early users.
|
||||
|
||||
**FreeBSD's boot/rc model vs. Shepherd.** The dual-boot-mode design
|
||||
(`freebsd-init+rc.d-shepherd` and `shepherd-pid1`) is a pragmatic
|
||||
and intelligent decision. It allows incremental migration: operators
|
||||
can start with FreeBSD init managing rc.d scripts (familiar) and
|
||||
transition to Shepherd as PID 1 (more Guix-native) when confidence
|
||||
grows. The tension here is that maintaining two boot paths doubles the
|
||||
surface area for boot bugs. Over time, one mode should become the
|
||||
default and the other should be explicitly marked as legacy.
|
||||
Recommendation: `shepherd-pid1` should be the default for new
|
||||
installations once it has been validated on a wider range of hardware.
|
||||
|
||||
**The role of the base system.** In stock Guix, the kernel and core
|
||||
userland are packages in the store like any other. In Fruix, the
|
||||
FreeBSD base is a privileged entity: it is built via `make world`
|
||||
rather than through the Guix build system, and it has its own
|
||||
source-materialisation and promotion pipeline. This asymmetry is
|
||||
necessary (FreeBSD's build system is not trivially expressible as a
|
||||
Guix derivation), but it creates a conceptual gap. Users coming from
|
||||
Guix will ask "why can't I just `guix package -i kernel`?" and users
|
||||
coming from FreeBSD will ask "why is my kernel in `/frx/store`?"
|
||||
Clear documentation explaining the boundary and the reasons for it
|
||||
is essential.
|
||||
|
||||
**rc.conf semantics.** The operating-system model includes
|
||||
`rc-conf-entries`, which is a direct concession to FreeBSD's
|
||||
configuration idiom. This is fine as a compatibility bridge, but it
|
||||
introduces a second configuration surface alongside Shepherd service
|
||||
declarations. Over time, the system should converge on one
|
||||
authoritative service-configuration mechanism. The current design
|
||||
wisely keeps rc.conf entries as a rendered output of the declaration
|
||||
rather than a primary input.
|
||||
|
||||
### What Does the Hybrid Offer?
|
||||
|
||||
The value proposition, stated plainly:
|
||||
|
||||
1. **For FreeBSD users:** Declarative, reproducible system
|
||||
configuration with transactional upgrades and rollback — things
|
||||
FreeBSD has never had. The ability to define an entire system in a
|
||||
single Scheme file and materialise it deterministically is
|
||||
transformative for FreeBSD operations.
|
||||
|
||||
2. **For Guix/NixOS users:** FreeBSD's kernel, network stack, jails,
|
||||
ZFS, DTrace, and Capsicum — mature subsystems that Linux either
|
||||
lacks or implements differently. Plus a genuinely unified base
|
||||
system rather than a collection of independently-packaged GNU
|
||||
components.
|
||||
|
||||
3. **For both:** A system where provenance is tracked from source
|
||||
commit through build through deployment, with explicit generation
|
||||
metadata and rollback. Neither upstream currently offers the full
|
||||
chain that Fruix is building.
|
||||
|
||||
The value proposition is clear. The question is not "is this worth
|
||||
doing?" but "can a small team sustain the maintenance burden of a
|
||||
hybrid?" That is an execution risk, not a design flaw.
|
||||
|
||||
### Is Shepherd a Good Fit?
|
||||
|
||||
Shepherd is a reasonable choice, with caveats:
|
||||
|
||||
**Strengths:** Scheme-native service definitions compose naturally
|
||||
with the Guix-style system declaration. Shepherd's service graph
|
||||
model is more expressive than rc.d's linear ordering. The existing
|
||||
FreeBSD-specific service helpers (`freebsd-rc-service`,
|
||||
`freebsd-tmpfs-service`, etc.) demonstrate that Shepherd can drive
|
||||
FreeBSD's native tools without friction.
|
||||
|
||||
**Concerns:** FreeBSD's kernel hands off to `/sbin/init` with
|
||||
specific expectations about early boot (single-user mode, fsck,
|
||||
console configuration). Shepherd-as-PID-1 must handle these
|
||||
correctly or the system will be fragile in recovery scenarios.
|
||||
FreeBSD jails expect their own init process and service tree — jail
|
||||
integration will need either per-jail Shepherd instances or a clean
|
||||
delegation model. The current implementation does not yet address
|
||||
jail service management, and this should be a design priority before
|
||||
jails are documented as a supported feature.
|
||||
|
||||
The rc.d bridge mode provides a safe fallback, which is wise. But
|
||||
the long-term health of the project depends on Shepherd-as-PID-1
|
||||
being robust enough that operators trust it for production FreeBSD
|
||||
workloads. This requires focused testing of edge cases: kernel panic
|
||||
recovery, single-user boot, fsck failures, and unclean shutdown
|
||||
handling.
|
||||
|
||||
---
|
||||
|
||||
## 2. Documentation Strategy
|
||||
|
||||
### Documentation Layers Needed
|
||||
|
||||
The system requires five distinct documentation layers, in priority
|
||||
order:
|
||||
|
||||
**Layer 1: Conceptual Guide ("What is Fruix?")**
|
||||
Priority: Critical. This is the first thing any visitor encounters.
|
||||
It must explain:
|
||||
- What the system is and why it exists
|
||||
- The FreeBSD base + Guix store + Shepherd init architecture
|
||||
- How it differs from stock FreeBSD and stock Guix
|
||||
- The mental model: declarations, closures, generations, store paths
|
||||
- Who this is for and what the tradeoffs are
|
||||
|
||||
This cannot be derived from either upstream's documentation. It must
|
||||
be written from scratch. Target length: 10-15 pages. This is the
|
||||
single highest-priority documentation deliverable.
|
||||
|
||||
**Layer 2: Quick-Start / Installation Guide**
|
||||
Priority: Critical. A new user must be able to:
|
||||
- Obtain or build an installer image
|
||||
- Install Fruix on a machine (real or virtual)
|
||||
- Write a minimal system declaration
|
||||
- Build and deploy it
|
||||
- Understand what happened and what to do next
|
||||
|
||||
This is partially derivable from the existing phase reports but needs
|
||||
to be written as a clean, linear narrative. The bootstrap procedure
|
||||
(`prepare-builder`) should be documented separately as a contributor
|
||||
guide, not as the primary installation path.
|
||||
|
||||
**Layer 3: System Declaration Reference**
|
||||
Priority: High. A complete reference for the `operating-system`
|
||||
record and all its constituent types:
|
||||
- `freebsd-base`, `freebsd-source`
|
||||
- Package lists and profiles
|
||||
- `storage-layout`, partitions, filesystems
|
||||
- Users, groups, services
|
||||
- Shepherd service declarations
|
||||
- Init modes, loader entries, rc.conf entries
|
||||
|
||||
This is the equivalent of the NixOS options reference or the Guix
|
||||
system configuration reference. It should be generated or
|
||||
semi-generated from the Scheme record definitions where possible.
|
||||
|
||||
**Layer 4: Command Reference**
|
||||
Priority: High. Every `fruix` subcommand documented:
|
||||
- `fruix system build|image|install|deploy|reconfigure|switch|rollback`
|
||||
- `fruix source materialize`
|
||||
- `fruix native-build promote`
|
||||
- Node-local commands (`fruix system status`, `fruix system build-base`)
|
||||
|
||||
Format: man pages (see tooling recommendation below).
|
||||
|
||||
**Layer 5: FreeBSD Integration Guide**
|
||||
Priority: Medium. For users with FreeBSD background:
|
||||
- What changed from stock FreeBSD and why
|
||||
- Where familiar tools still work (`ifconfig`, `gpart`, `service`)
|
||||
- Where they don't (hand-editing `/etc` files)
|
||||
- How jails, ZFS, DTrace, and other FreeBSD features interact with
|
||||
the Guix layer
|
||||
- Migration guide from stock FreeBSD
|
||||
|
||||
### Reconciling Upstream Documentation
|
||||
|
||||
**FreeBSD man pages:** The stock FreeBSD man pages for kernel
|
||||
interfaces, system calls, library functions, and file formats
|
||||
(sections 2, 3, 4, 5, 7, 9) can be shipped largely unchanged. Section
|
||||
1 (user commands) and section 8 (system administration) need auditing:
|
||||
commands that Fruix overrides or wraps should get Fruix-specific man
|
||||
pages. Section 5 pages for files that Fruix renders (e.g., `fstab(5)`,
|
||||
`rc.conf(5)`, `loader.conf(5)`) should include a note that these are
|
||||
managed by the system declaration and should not be hand-edited.
|
||||
|
||||
**Guix manual:** The Guix manual's conceptual sections on the store,
|
||||
derivations, profiles, and generations are excellent educational
|
||||
material but describe GNU/Linux-specific implementation details. The
|
||||
concepts can be adapted; the specifics must be rewritten. The Guix
|
||||
system configuration reference is a good structural model but every
|
||||
concrete example needs FreeBSD equivalents. The package management
|
||||
sections are largely inapplicable until Fruix has its own package
|
||||
management story beyond the base system.
|
||||
|
||||
**What requires full rewrites:**
|
||||
- Boot process documentation (entirely different from both upstreams)
|
||||
- Service management (Shepherd on FreeBSD is unique to Fruix)
|
||||
- System installation (Fruix's installer is its own thing)
|
||||
- Package definitions (FreeBSD native builds differ from Guix derivations)
|
||||
- Store layout (`/frx/store` vs. `/gnu/store`, different hash scheme)
|
||||
|
||||
**What can be adapted with light editing:**
|
||||
- FreeBSD kernel and hardware documentation
|
||||
- Networking fundamentals (FreeBSD's stack is unchanged)
|
||||
- Filesystem semantics (UFS/ZFS behaviour is unchanged)
|
||||
- Guix conceptual material on functional package management
|
||||
|
||||
### Highest-Priority Gaps
|
||||
|
||||
**For FreeBSD users arriving:**
|
||||
1. "Where is `rc.conf`?" — How system configuration works now
|
||||
2. "How do I install software?" — The package/profile model
|
||||
3. "Where is `/usr/local`?" — The store and profiles explained
|
||||
4. "How do I update the system?" — Generations and reconfigure
|
||||
|
||||
**For Guix/NixOS users arriving:**
|
||||
1. "Where is `guix system reconfigure`?" — The Fruix equivalents
|
||||
2. "Why is the kernel special?" — The FreeBSD base boundary
|
||||
3. "Where are the packages?" — The current ecosystem scope
|
||||
4. "How do services work?" — Shepherd on FreeBSD specifics
|
||||
|
||||
### Tooling Recommendation
|
||||
|
||||
**Man pages** for command references and file format references. Use
|
||||
`mdoc(7)` format (FreeBSD's native macro set). Reasons:
|
||||
- Offline availability without extra tooling
|
||||
- Consistent with the FreeBSD base tradition
|
||||
- Discoverable via `apropos(1)`
|
||||
- Well-understood by the target audience
|
||||
|
||||
**A static-site handbook** for conceptual guides, the quick-start,
|
||||
and the system declaration reference. Recommended format: **AsciiDoc**
|
||||
processed with Asciidoctor. Reasons:
|
||||
- Richer structure than Markdown (admonitions, cross-references,
|
||||
includes, conditional content)
|
||||
- Generates HTML for a project website and PDF for offline use
|
||||
- Lower barrier to contribution than Texinfo
|
||||
- Used successfully by FreeBSD's own handbook toolchain
|
||||
(though they use DocBook/AsciiDoc)
|
||||
|
||||
**Not Texinfo.** While Guix uses Texinfo and it has strengths (Info
|
||||
reader integration, structured cross-referencing), it is an
|
||||
unfamiliar format for FreeBSD contributors and adds friction for a
|
||||
project that needs to attract contributors from both communities. The
|
||||
Guix community knows Texinfo; the FreeBSD community does not. AsciiDoc
|
||||
is a pragmatic middle ground.
|
||||
|
||||
### Man Pages vs. Separate Handbook
|
||||
|
||||
Both. They serve different purposes:
|
||||
|
||||
- **Man pages** for "how do I use this command right now?" — terse,
|
||||
reference-oriented, available offline via `man(1)`.
|
||||
- **Handbook** for "how does this system work and how do I configure
|
||||
it?" — narrative, conceptual, cross-referenced.
|
||||
|
||||
Consider a new man section (e.g., section `fruix` or a subsection
|
||||
of section 8) for Fruix-specific system administration. This would
|
||||
include:
|
||||
- `fruix(8)` — overview and subcommand index
|
||||
- `fruix-system(8)` — system management commands
|
||||
- `fruix-deploy(8)` — deployment workflow
|
||||
- `shepherd-freebsd(8)` — Shepherd integration specifics
|
||||
- `operating-system.scm(5)` — system declaration file format
|
||||
|
||||
---
|
||||
|
||||
## 3. Completeness Assessment
|
||||
|
||||
### Installer / System Installation
|
||||
|
||||
**Current state:** A working non-interactive installer (`fruix system
|
||||
install`) and a prototype Newt TUI. Bootable installer images and
|
||||
UEFI ISOs can be produced. Storage layout supports GPT + EFI + UFS +
|
||||
optional swap.
|
||||
|
||||
**Gaps:**
|
||||
- ZFS root support (high demand from FreeBSD users, model prepared
|
||||
but not implemented)
|
||||
- Disk encryption (GELI/LUKS equivalent)
|
||||
- Network-based installation (PXE, remote image fetch)
|
||||
- Post-install first-boot wizard
|
||||
|
||||
**Blocking?** No — the current installer is functional for basic use.
|
||||
**Upstream reuse?** FreeBSD's `bsdinstall` is not easily adapted
|
||||
(tightly coupled to rc.conf-based configuration). The Guix installer
|
||||
is structurally similar but Linux-specific. The current from-scratch
|
||||
approach is correct.
|
||||
**Priority:** Medium. The installer works. ZFS support should be high
|
||||
priority given the FreeBSD audience.
|
||||
|
||||
### Bootstrap and Cross-Compilation
|
||||
|
||||
**Current state:** A `prepare-builder` script that builds a local
|
||||
Guile, Shepherd, and Guix checkout on a vanilla FreeBSD host.
|
||||
Produces a reusable builder at `~/.local/opt/fruix-builder`. No
|
||||
cross-compilation support.
|
||||
|
||||
**Gaps:**
|
||||
- No automated builder provisioning (e.g., a single `curl | sh`
|
||||
bootstrap like Nix or Guix)
|
||||
- No cross-compilation from non-FreeBSD hosts
|
||||
- Builder preparation is slow and requires manual steps
|
||||
- Guile subprocess stability workarounds suggest fragility
|
||||
|
||||
**Blocking?** Partially — the current bootstrap works but is brittle
|
||||
and underdocumented. A new contributor cannot easily get started.
|
||||
**Upstream reuse?** Guix's bootstrap story is heavily Linux-specific.
|
||||
FreeBSD's `pkg bootstrap` is irrelevant. This must be solved
|
||||
independently.
|
||||
**Priority:** High. The bootstrap experience is the first thing any
|
||||
contributor or tester encounters.
|
||||
|
||||
### Init and Service Management Completeness
|
||||
|
||||
**Current state:** Shepherd runs as PID 1 or as an rc.d-launched
|
||||
service. A handful of FreeBSD-specific service helpers exist
|
||||
(loopback, tmpfs, user/group, rc-service wrapper). Basic services
|
||||
(SSH, logging) are configured.
|
||||
|
||||
**Gaps:**
|
||||
- No Shepherd services for: cron, syslog (native), NTP, firewall
|
||||
(pf/ipfw), devd, automount, powerd, jail management
|
||||
- No service dependency graph for full FreeBSD boot sequence
|
||||
- No `herd` equivalent for interactive service management
|
||||
documentation
|
||||
- No watchdog or health-check integration
|
||||
- Jail service isolation not designed
|
||||
|
||||
**Blocking?** Yes, for production use. The current set is sufficient
|
||||
for a demo VM but not for a real workload.
|
||||
**Upstream reuse?** Guix's service definitions are a structural model
|
||||
but every concrete service must be rewritten for FreeBSD. FreeBSD's
|
||||
rc.d scripts can be wrapped via `freebsd-rc-service` as a bridge.
|
||||
**Priority:** High. Service completeness directly determines whether
|
||||
the system is usable for real tasks.
|
||||
|
||||
### System Configuration Interface
|
||||
|
||||
**Current state:** System declarations are Scheme files loaded by
|
||||
the `fruix` CLI. There is no interactive configuration tool, no
|
||||
`guix system reconfigure` equivalent that reads from a canonical
|
||||
system path, and no `guix system vm` for testing.
|
||||
|
||||
**Gaps:**
|
||||
- No canonical system declaration location (e.g.,
|
||||
`/etc/fruix/system.scm`)
|
||||
- No `fruix system reconfigure` that reads from a default location
|
||||
(the node-local version exists but requires the declaration to be
|
||||
embedded in the closure)
|
||||
- No `fruix system vm` for testing declarations without deploying
|
||||
- No configuration validation beyond storage layout checks
|
||||
- No configuration diffing ("what would change if I reconfigure?")
|
||||
|
||||
**Blocking?** Partially. The current workflow (explicit paths) works
|
||||
but is not ergonomic for daily use.
|
||||
**Upstream reuse?** Guix's `guix system` subcommands are the direct
|
||||
model. NixOS's `nixos-rebuild` is another.
|
||||
**Priority:** Medium-high. Ergonomic configuration management is a
|
||||
core value proposition.
|
||||
|
||||
### Security Model and Updates
|
||||
|
||||
**Current state:** Store paths are content-addressed. FreeBSD sources
|
||||
can be SHA256-pinned. No signing, no binary cache, no substitute
|
||||
mechanism, no trust model.
|
||||
|
||||
**Gaps:**
|
||||
- No cryptographic signing of store paths or closures
|
||||
- No binary substitute/cache infrastructure
|
||||
- No trust model for third-party packages
|
||||
- No security advisory integration
|
||||
- No automatic update mechanism
|
||||
- No verified boot chain
|
||||
|
||||
**Blocking?** Not for development use. Blocking for any multi-user
|
||||
or production deployment.
|
||||
**Upstream reuse?** Guix's substitute mechanism and signing
|
||||
infrastructure are well-designed and could be adapted. FreeBSD's
|
||||
`pkg` signing could inform the trust model.
|
||||
**Priority:** Medium for now, becomes critical before any production
|
||||
use.
|
||||
|
||||
### Jail and Virtualisation Integration
|
||||
|
||||
**Current state:** Jails are mentioned in the bootstrap reports
|
||||
(jail-based build isolation was explored) but no jail management is
|
||||
integrated into the system model or Shepherd services. bhyve is
|
||||
blocked by nested VT-x under Xen.
|
||||
|
||||
**Gaps:**
|
||||
- No `jail` record type in the operating-system model
|
||||
- No Shepherd service for jail lifecycle management
|
||||
- No jail-specific store sharing (read-only nullfs mounts of
|
||||
`/frx/store` into jails)
|
||||
- No jail networking integration (vnet, epair)
|
||||
- No `fruix jail` subcommands
|
||||
- No bhyve integration
|
||||
|
||||
**Blocking?** Not for basic use, but jails are a flagship FreeBSD
|
||||
feature and a major reason to choose FreeBSD. Users will expect
|
||||
them.
|
||||
**Upstream reuse?** FreeBSD's `jail(8)` and `jail.conf(5)` are the
|
||||
foundation. Guix has no jail equivalent. This must be designed from
|
||||
scratch, but the operating-system model provides a natural extension
|
||||
point.
|
||||
**Priority:** Medium-high. Jail integration is part of the value
|
||||
proposition. A basic `jail` record type with Shepherd lifecycle
|
||||
services should be an early post-MVP feature.
|
||||
|
||||
### Networking Configuration
|
||||
|
||||
**Current state:** `rc-conf-entries` in the operating-system model
|
||||
handle network interface configuration via the traditional rc.conf
|
||||
mechanism. No declarative networking model exists.
|
||||
|
||||
**Gaps:**
|
||||
- No first-class network interface declarations in the system model
|
||||
- No declarative firewall (pf/ipfw) configuration
|
||||
- No VLAN, bridge, or lagg configuration
|
||||
- No wireless configuration
|
||||
- No DNS resolver configuration beyond rc.conf
|
||||
- Network configuration split between rc.conf entries and potential
|
||||
Shepherd services
|
||||
|
||||
**Blocking?** Partially. Basic DHCP works via rc.conf. Static
|
||||
configuration works via rc.conf entries. But the lack of a
|
||||
declarative network model means networking is the least
|
||||
"Guix-like" part of the system.
|
||||
**Upstream reuse?** Guix's networking services (for Linux) are a
|
||||
structural model. FreeBSD's rc.conf networking is the current
|
||||
backend and works. The gap is the declarative layer on top.
|
||||
**Priority:** Medium. Networking works via rc.conf bridge. A
|
||||
declarative model is important for the vision but not blocking.
|
||||
|
||||
### User-Facing Tooling
|
||||
|
||||
**Current state:** The `fruix` CLI exists with subcommands for
|
||||
system building, deployment, source management, and native builds.
|
||||
Node-local commands exist for build, reconfigure, switch, rollback,
|
||||
and status. No `guix pull` equivalent.
|
||||
|
||||
**Gaps:**
|
||||
- No channel/repository update mechanism (`guix pull` equivalent)
|
||||
- No user-level package management (`guix install` equivalent)
|
||||
- No user profiles or per-user environments
|
||||
- No `fruix search` for finding packages
|
||||
- No garbage collection command (`fruix gc`)
|
||||
- No generation listing or management UI
|
||||
- No system diff/dry-run tooling
|
||||
|
||||
**Blocking?** Partially. The system can be managed but the
|
||||
experience is manual and requires understanding internals.
|
||||
**Upstream reuse?** Guix's CLI is the direct model for all of
|
||||
these. The commands exist in Guix; they need FreeBSD-specific
|
||||
implementations.
|
||||
**Priority:** High for `gc` and generation management. Medium for
|
||||
user profiles. Channel updates become critical when there is a
|
||||
package ecosystem to update.
|
||||
|
||||
### Release Engineering / Reproducible Build Infrastructure
|
||||
|
||||
**Current state:** The system can produce disk images and ISOs.
|
||||
No CI, no automated testing, no release process, no reproducibility
|
||||
verification.
|
||||
|
||||
**Gaps:**
|
||||
- No CI/CD pipeline
|
||||
- No automated build-and-boot testing
|
||||
- No reproducibility verification (build twice, compare)
|
||||
- No release versioning scheme
|
||||
- No changelog generation
|
||||
- No upgrade path between releases
|
||||
|
||||
**Blocking?** Not for development. Blocking for any claim of
|
||||
"reproducibility" — without verification, it is an aspiration, not
|
||||
a property.
|
||||
**Upstream reuse?** Guix's build farm (Cuirass) is the model but
|
||||
is Linux-specific. FreeBSD's release engineering toolchain could
|
||||
inform the process.
|
||||
**Priority:** Medium. Should be established before the project
|
||||
seeks external users.
|
||||
|
||||
### Testing and CI
|
||||
|
||||
**Current state:** A collection of shell-script tests in
|
||||
`fruix-bootstrap/tests/` covering build system phases, native
|
||||
builds, and system materialisation. Validation is done manually on
|
||||
XCP-ng VMs and locally via QEMU. No automated CI.
|
||||
|
||||
**Gaps:**
|
||||
- No automated test suite that runs on commit
|
||||
- No boot-level testing (VM boots, services come up, assertions pass)
|
||||
- No unit tests for Scheme modules
|
||||
- No integration tests for the CLI
|
||||
- No regression tests for store-path identity stability
|
||||
|
||||
**Blocking?** Not for a solo developer. Blocking for accepting
|
||||
contributions — without CI, contributions cannot be validated.
|
||||
**Upstream reuse?** Guix's test infrastructure is extensive but
|
||||
Linux-specific. FreeBSD's CI (Phabricator/GitHub Actions) could
|
||||
host the pipeline.
|
||||
**Priority:** High. Even a minimal "build an image and boot it in
|
||||
QEMU" CI pipeline would significantly improve development velocity
|
||||
and confidence.
|
||||
|
||||
---
|
||||
|
||||
## Overall Verdict
|
||||
|
||||
**This project is worth pursuing.** The philosophical fit between
|
||||
FreeBSD and Guix is stronger than it appears on the surface, and
|
||||
the implementation demonstrates that the core ideas translate
|
||||
cleanly. The codebase shows thoughtful engineering: the store-path
|
||||
design, the three-layer profile model, the executor abstraction,
|
||||
the source-provenance tracking, and the safety boundaries around
|
||||
storage operations are all evidence of considered design rather than
|
||||
expedient hacking.
|
||||
|
||||
The project has crossed the hardest threshold: proving that the
|
||||
hybrid *can work*. Shepherd runs as PID 1 on FreeBSD. The store
|
||||
semantics function. Systems can be declared, built, deployed, and
|
||||
rolled back. Installer media can be produced. The remaining work is
|
||||
substantial but straightforward — it is engineering, not research.
|
||||
|
||||
### The Single Most Important Next Step
|
||||
|
||||
**Write the conceptual guide.** The project's biggest risk right now
|
||||
is not technical — it is legibility. A capable developer encountering
|
||||
this project today would face 93 markdown files, 44 Scheme modules,
|
||||
and no clear entry point explaining what the system is, how it works,
|
||||
or how to use it. The phase reports are a development journal, not
|
||||
documentation.
|
||||
|
||||
A 10-15 page document explaining the architecture, the mental model,
|
||||
and the basic workflows would:
|
||||
1. Enable contributors to onboard without archaeology
|
||||
2. Force design decisions to be stated explicitly (which sometimes
|
||||
reveals inconsistencies worth fixing)
|
||||
3. Provide a foundation for all other documentation
|
||||
4. Make the project presentable to the FreeBSD and Guix communities
|
||||
|
||||
The second priority is the bootstrap experience. A contributor should
|
||||
be able to go from "I have a FreeBSD machine" to "I have built and
|
||||
booted a Fruix image" in under an hour, with clear instructions at
|
||||
every step. The current bootstrap pipeline works but is not documented
|
||||
as a user-facing workflow.
|
||||
|
||||
Everything else — more packages, more services, jails, ZFS, CI — is
|
||||
important but secondary. Without documentation and an accessible
|
||||
onboarding path, the project remains a brilliant proof of concept that
|
||||
only its author can operate.
|
||||
Reference in New Issue
Block a user