Phase 401 — materialize live /etc
| Item | Value |
|---|---|
| Command | make phase 401 |
| Underlying make target/script | vm/phase4/materialize-etc.sh |
| Mutates disk/image? | Yes, it mounts artifacts/onix-image/onix.raw and updates the root filesystem |
| Boots QEMU? | No |
| Main proof | Live /etc is created from package-owned defaults without overwriting local overrides. |
The basic Linux idea
Most Linux programs look in /etc for machine configuration.
Examples:
/etc/fstab
/etc/hostname
/etc/os-release
/etc/profile.d/*.sh
/etc/machine-id
But ONIX does not want random packages to own live mutable machine state directly.
So ONIX separates two ideas:
/usr/share/defaults packaged defaults
/etc live machine configuration
That means a package can say:
Here is the default fstab template.
without claiming:
I own your live /etc/fstab forever.
That distinction becomes important later when a user changes networking, hostname, SSH keys, Nix config, or anything else machine-local.
What Phase 2 already did
Phase 2 already copied some defaults into the root tree so the first boot could work.
For example, the boot image needs:
/etc/fstab
before systemd can mount:
/boot
/efi
/persist
/home
/nix
That Phase 2 behavior was necessary, but it was still image-assembly glue.
Phase 401 turns it into an explicit policy.
What Phase 401 materializes
Phase 401 reads packaged defaults from:
/usr/share/defaults/etc/
and ensures these live files exist:
/etc/issue
/etc/motd
/etc/fstab
/etc/profile.d/onix-path.sh
It also enforces:
/etc/os-release -> ../usr/lib/os-release
That symlink is the normal compatibility path. The actual identity file remains package-generated under:
/usr/lib/os-release
Preserve local overrides
The script does not blindly overwrite live /etc files.
The rule is:
if missing:
create from /usr/share/defaults
if present and same as default:
OK
if present and different:
preserve as local override
That is the seed of the future ONIX drift model.
Later, onix status should be able to say:
/etc/fstab differs from packaged default
without calling that a failure.
Why /etc/machine-id is different
/etc/machine-id is not a package default.
It identifies one installed machine. systemd may create or persist it during boot.
So Phase 401 only ensures the file exists. It does not replace it.
That is why the script reports:
preserve : /etc/machine-id exists as machine-local state
What the script writes as proof
Phase 401 writes:
/usr/share/onix/bootstrap/etc-materialization.txt
That file records the temporary bootstrap policy:
- defaults live in
/usr/share/defaults - live config lives in
/etc - missing files may be created from defaults
- differing files are preserved as overrides
- machine identity is not overwritten
This proof file is not the final architecture. Later ONIX should probably have a small first-boot materializer or systemd unit owned by an ONIX stone.
Run it
From the repo root:
make phase 401
Expected output includes lines like:
symlink : /etc/os-release -> ../usr/lib/os-release
default : /etc/fstab already matches packaged default
preserve : /etc/machine-id exists as machine-local state
proof : /usr/share/onix/bootstrap/etc-materialization.txt
Then the phase verifies:
/usr/lib/os-releasesaysNAME="ONIX"andID="onix"/etc/os-releasepoints to../usr/lib/os-release- packaged defaults exist under
/usr/share/defaults/etc - live files exist under
/etc /etc/fstabstill contains the ONIX volume labels/etc/profile.d/onix-path.shexports a PATH
What this phase does not do
Phase 401 does not create users yet.
That belongs in the next users/groups/shell-policy phase.
It also does not replace the borrowed Alpine kernel payload. That remains reserved for Phase 3.