Fold dotfiles-nixos into this repository #1

Merged
alexion merged 32 commits from nixos-migration into main 2026-07-19 09:30:46 -04:00
5 changed files with 73 additions and 3 deletions
Showing only changes of commit 053c4de529 - Show all commits

View File

@@ -0,0 +1,27 @@
---
spec: laptop-mvi
blocked-by: 0001-skeleton-and-building-host
---
## What to build
Give `neogaia` the kernel and hardware enablement it needs to run well on the Dell XPS 13 9380: the CachyOS kernel pulled as a binary from chaotic-nyx (not compiled from source), Intel microcode, and the redistributable firmware for the QCA6174 wifi. Add a zram toggle `Module` and enable it here.
The kernel is selected through a small per-`Host` kernel mechanism so other `Host`s can choose different kernels. The chaotic substituter and its trusted public key are added to the Nix settings so the kernel is fetched from the binary cache from the first build.
## Acceptance criteria
- [x] `neogaia` runs the CachyOS kernel selected via a per-`Host` kernel mechanism, sourced from chaotic-nyx.
- [x] The chaotic substituter and trusted public key are in the Nix settings, so the kernel is fetched from cache rather than compiled.
- [x] Intel microcode is enabled.
- [x] Redistributable firmware is enabled so the QCA6174 wifi hardware is available.
- [x] A zram toggle `Module` exists (following the `Enable convention`) and is enabled on `neogaia`.
- [x] The `neogaia` toplevel still builds with all of the above.
## Implementation Notes
- **Per-`Host` kernel mechanism = native `boot.kernelPackages`.** neogaia sets `boot.kernelPackages = pkgs.linuxPackages_cachyos` directly in its Host directory (`hosts/neogaia/default.nix`). No custom wrapper option was added: `boot.kernelPackages` is already a per-`Host` setting, so other `Host`s pick their own kernel the same way. A string→package wrapper would have been premature abstraction with one `Host` and one kernel, so it was deliberately left out; the "mechanism" is the per-`Host` placement of the native option.
- **Substituter/key live in the shared base, via the `extra-` options.** They were added to `system/default.nix` (shared by every `Host`), not just neogaia, because the chaotic module is wired for all `Host`s and the cache is general plumbing. `nix.settings.extra-substituters` / `extra-trusted-public-keys` are used rather than the replacing `substituters` / `trusted-public-keys`, so `cache.nixos.org` (and any other substituter) is only appended to, never dropped. chaotic's own module also provides these entries; the explicit declaration is belt-and-suspenders and keeps the built system's cache config visible and independent of that module.
- **Dev-host build needed a daemon-level cache.** Building the toplevel here first compiled the CachyOS kernel (and rustc bootstrap) from source, because the build daemon's `/etc/nix/nix.conf` had no `nyx-cache` substituter — the built system's `nix.settings` do not govern the daemon doing the build, and the dev user is a non-trusted client that cannot add substituters from the CLI. Adding `extra-substituters`/`extra-trusted-public-keys` for `nyx-cache` to `/etc/nix/nix.conf` (sudo) and restarting `nix-daemon` fixed it; the build then fetched the kernel (7.1.3) from the cache. Recorded as a gotcha in `CLAUDE.md`.
- **zram `Module` kept minimal.** `modules/zram.nix` is a pure toggle (`zramSwap.enable = true` under `mkIf`), following the `modules/example.nix` reference shape. This preserves task 0002's exact behaviour while moving the switch behind the `Enable convention`; the direct `zramSwap.enable = true` previously inline in the `Host` was removed in favour of `modules.zram.enable = true`.
- **Why zram graduated to a `Module` but kernel/microcode/firmware stayed inline.** zram is a reusable, cross-`Host` feature toggle (the spec calls for it as a `Module`), whereas the kernel choice, Intel microcode, and firmware are neogaia-specific hardware facts that belong to the `Host` itself.

View File

@@ -10,6 +10,10 @@ The domain model (Host, Module, Skeleton, Auto-loader, Enable convention, overla
The system `/etc/nix/nix.conf` does not enable flakes, so export `NIX_CONFIG="experimental-features = nix-command flakes"` (or pass `--extra-experimental-features 'nix-command flakes'`) for every command. The system `/etc/nix/nix.conf` does not enable flakes, so export `NIX_CONFIG="experimental-features = nix-command flakes"` (or pass `--extra-experimental-features 'nix-command flakes'`) for every command.
- The dev user is a non-trusted daemon client (`nix store info` reports `Trusted: 0`). - The dev user is a non-trusted daemon client (`nix store info` reports `Trusted: 0`).
You cannot add substituters from the CLI, so rely on what the flake/config declares (e.g. the chaotic cache is wired by the chaotic module, not a CLI flag). You cannot add substituters from the CLI, so rely on what the flake/config declares (e.g. the chaotic cache is wired by the chaotic module, not a CLI flag).
Caveat that bites when a Host actually selects the CachyOS kernel: the substituters a `nix build` fetches from are the **daemon's** (`/etc/nix/nix.conf`), *not* the `nix.settings` of the config being built — those only govern the built system.
This dev host's `/etc/nix/nix.conf` has no `substituters`/`trusted-substituters` lines, so building a toplevel whose `boot.kernelPackages` is `linuxPackages_cachyos` compiles the kernel (and rustc bootstrap, etc.) from source instead of hitting `nyx-cache`.
To build such a Host here, first add `extra-substituters = https://nyx-cache.chaotic.cx/` and `extra-trusted-public-keys = nyx-cache.chaotic.cx:dJxTrgMC3V3cFfyIiBQDQorG6k1LsqurH/srpMSq7qk=` to `/etc/nix/nix.conf` (sudo) and `sudo systemctl restart nix-daemon`.
`nix eval` of the kernel version does *not* trigger this — only a real build does.
- If `/nix/store` is missing or `nix-daemon` is inactive after a fresh Nix install, initialise it with `sudo systemd-tmpfiles --create nix-daemon.conf && sudo systemctl enable --now nix-daemon.socket`. - If `/nix/store` is missing or `nix-daemon` is inactive after a fresh Nix install, initialise it with `sudo systemd-tmpfiles --create nix-daemon.conf && sudo systemctl enable --now nix-daemon.socket`.
- The primary build/verify seam for any Host is `nix flake check`, which builds `checks.x86_64-linux.<host>` (the system toplevel); cheap targeted checks use `nix eval .#nixosConfigurations.<host>.config...`. - The primary build/verify seam for any Host is `nix flake check`, which builds `checks.x86_64-linux.<host>` (the system toplevel); cheap targeted checks use `nix eval .#nixosConfigurations.<host>.config...`.
- chaotic-nyx must **not** follow our `nixpkgs`, and its packages are built against chaotic's own pinned nixpkgs (its overlay defaults to `onTopOf = "flake-nixpkgs"`, the cache-friendly path). - chaotic-nyx must **not** follow our `nixpkgs`, and its packages are built against chaotic's own pinned nixpkgs (its overlay defaults to `onTopOf = "flake-nixpkgs"`, the cache-friendly path).

View File

@@ -1,4 +1,4 @@
{ ... }: { pkgs, ... }:
# neogaia — Dell XPS 13 9380 laptop. # neogaia — Dell XPS 13 9380 laptop.
# #
# The disk layout lives in ./disk.nix (disko); the resulting `fileSystems` are # The disk layout lives in ./disk.nix (disko); the resulting `fileSystems` are
@@ -17,6 +17,19 @@
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
# Swap is RAM-backed zram rather than an on-disk partition. # Kernel is a per-Host choice, expressed through boot.kernelPackages: neogaia
zramSwap.enable = true; # runs the CachyOS kernel from chaotic-nyx (fetched from the chaotic binary
# cache wired in system/, not compiled from source). Other Hosts pick their
# own kernel the same way, so the choice never leaves the Host.
boot.kernelPackages = pkgs.linuxPackages_cachyos;
# Intel CPU microcode updates for the XPS 13's Core i7-8565U.
hardware.cpu.intel.updateMicrocode = true;
# Redistributable firmware — carries the ath10k blobs the QCA6174 wifi needs.
hardware.enableRedistributableFirmware = true;
# Swap is RAM-backed zram (the zram Module) rather than an on-disk partition,
# matching the disko layout, which declares no swap partition.
modules.zram.enable = true;
} }

14
modules/zram.nix Normal file
View File

@@ -0,0 +1,14 @@
{ config, lib, ... }:
# A toggle for RAM-backed swap. A Host that has no on-disk swap partition (like
# neogaia, whose disko layout deliberately omits one) enables this to get a
# compressed zram device instead.
let
cfg = config.modules.zram;
in
{
options.modules.zram.enable = lib.mkEnableOption "zram-backed compressed swap";
config = lib.mkIf cfg.enable {
zramSwap.enable = true;
};
}

View File

@@ -51,6 +51,18 @@ in
"nix-command" "nix-command"
"flakes" "flakes"
]; ];
# The chaotic binary cache, declared explicitly on the built system so the
# CachyOS kernel is substituted rather than compiled. chaotic's own module
# also provides these, but stating them here keeps the built system's cache
# config visible and independent of that module. Added via the `extra-`
# options so they only append — cache.nixos.org and any other substituter
# are never dropped. (Fetching at install time depends on the installing
# daemon's substituters, not this — see the chaotic gotcha in CLAUDE.md.)
nix.settings.extra-substituters = [ "https://nyx-cache.chaotic.cx/" ];
nix.settings.extra-trusted-public-keys = [
"nyx-cache.chaotic.cx:dJxTrgMC3V3cFfyIiBQDQorG6k1LsqurH/srpMSq7qk="
];
environment.systemPackages = [ pkgs.git ]; environment.systemPackages = [ pkgs.git ];
# Primary user, in wheel. No password is set here. # Primary user, in wheel. No password is set here.