docs: correct statements that no longer match the configuration

Assisted-by: DeepSeek Harness 0.2.1-rc.2 (claude-opus-5-5)
This commit is contained in:
Ryan Yin authored and ryan4yin | 二花 committed 2026-10-21 20:59:07 +08:00
1 parent a3c75250c4
commit 1324131c6d
23 files changed
+161 -101

No files matched your search

+7 -2
View File
@@ -97,8 +97,10 @@ introduces one, and re-evaluate entries when their `Revisit` trigger comes up.
commit the lock file. Use `nix flake update <input>` when the update should remain uncommitted. commit the lock file. Use `nix flake update <input>` when the update should remain uncommitted.
- `just niri` and `just local` activate the machine you are on through `sudo` and block on a - `just niri` and `just local` activate the machine you are on through `sudo` and block on a
password prompt; `just darwin-rollback` switches the macOS generation on the machine you are on, password prompt; `just darwin-rollback` switches the macOS generation on the machine you are on,
and a bare `sudo systemctl restart <unit>` activates a running service the same way. The user runs and a bare `sudo systemctl restart <unit>` activates a running service the same way.
these, not an agent. `just mihomo-geo` (mihomo's state directory) and `just shoukei-home-wifi` (a persistent
NetworkManager profile) change the local machine through `sudo` too. The user runs these, not an
agent.
- `just shoryu`, `just shushou`, `just youko`, `just aquamarine`, `just ruby`, `just kana`, - `just shoryu`, `just shushou`, `just youko`, `just aquamarine`, `just ruby`, `just kana`,
`just lab`, `just k3s-test`, and `just col <tag>` activate systems through Colmena. Use the `just lab`, `just k3s-test`, and `just col <tag>` activate systems through Colmena. Use the
narrower recipe that matches the intended host scope. narrower recipe that matches the intended host scope.
@@ -115,6 +117,9 @@ introduces one, and re-evaluate entries when their `Revisit` trigger comes up.
only for the intended cleanup or history operation. only for the intended cleanup or history operation.
- `just penvof` reads a process environment and can expose secrets. Use normal process inspection - `just penvof` reads a process environment and can expose secrets. Use normal process inspection
commands when environment values are not required. commands when environment values are not required.
- `just del-failed` deletes failed pods in every namespace of the current kube context.
- `just pkg-review <pr>` and `just pkg-test <pr> <pname>` dispatch a workflow in
`ryan4yin/nixpkgs-review-gha` that posts its result on the nixpkgs PR, a public GitHub write.
## Task Skills ## Task Skills
+1 -1
View File
@@ -60,7 +60,7 @@ upp input:
history: history:
nix profile history --profile /nix/var/nix/profiles/system nix profile history --profile /nix/var/nix/profiles/system
# Open a nix shell with the flake # Open a nix repl with nixpkgs from the flake registry
[group('nix')] [group('nix')]
repl: repl:
nix repl -f flake:nixpkgs nix repl -f flake:nixpkgs
+15 -8
View File
@@ -43,7 +43,7 @@ small, reversible controls and narrow exceptions; benchmark before adopting expe
| MicroVM storage | Host store shared read-only through virtiofs; guest `/etc`, `/var` and `/home` persisted in separate images | Read-only store does not isolate the host-side virtiofs implementation or protect writable guest state | | MicroVM storage | Host store shared read-only through virtiofs; guest `/etc`, `/var` and `/home` persisted in separate images | Read-only store does not isolate the host-side virtiofs implementation or protect writable guest state |
| Desktop apps | Selected apps use nixpak/bubblewrap; Podman is rootless | Rules and shared directories vary per app; user namespaces are needed for these sandboxes | | Desktop apps | Selected apps use nixpak/bubblewrap; Podman is rootless | Rules and shared directories vary per app; user namespaces are needed for these sandboxes |
| Secrets | agenix declarations here, encrypted data in the private nix-secrets repository | Recipients and plaintext file permissions must be reviewed; root on a recipient can read its decrypted secrets | | Secrets | agenix declarations here, encrypted data in the private nix-secrets repository | Recipients and plaintext file permissions must be reviewed; root on a recipient can read its decrypted secrets |
| Supply chain | Locked flake inputs; explicit binary-cache trust keys; normal user is not a Nix trusted-user | A trusted cache or imported Nix module can supply code executed as root; a lock file is not a security audit | | Supply chain | Locked flake inputs; explicit binary-cache trust keys on NixOS; normal user is not a Nix trusted-user | A trusted cache or imported Nix module can supply code executed as root; a lock file is not a security audit |
| Recovery | NixOS generations, btrbk/restic, hourly read-only snapshots of the REST store, and documented backup procedures | A rollback does not undo compromised data or secrets; backup configuration alone does not prove restore works; the offsite immutable copy is still planned | | Recovery | NixOS generations, btrbk/restic, hourly read-only snapshots of the REST store, and documented backup procedures | A rollback does not undo compromised data or secrets; backup configuration alone does not prove restore works; the offsite immutable copy is still planned |
Sources: [host layout](hosts/README.md), [k3s deployment](hosts/k8s/README.md), Sources: [host layout](hosts/README.md), [k3s deployment](hosts/k8s/README.md),
@@ -51,6 +51,11 @@ Sources: [host layout](hosts/README.md), [k3s deployment](hosts/k8s/README.md),
[Nix trust](modules/base/nix.nix), [secrets](secrets/README.md), and [backup](BACKUP.md). Cluster [Nix trust](modules/base/nix.nix), [secrets](secrets/README.md), and [backup](BACKUP.md). Cluster
resources are maintained in the separate k8s-gitops repository. resources are maintained in the separate k8s-gitops repository.
The Macs set `nix.enable = false` ([nix-core.nix](modules/darwin/nix-core.nix)), so nix-darwin
writes no `/etc/nix/nix.conf`: the substituters, trusted keys and access-token include declared here
do not reach them. Their Nix settings come from the Determinate installation, which this repository
does not manage; those settings were not verified on the Macs.
## Kernel and process baseline ## Kernel and process baseline
The following explicit, overridable baseline is implemented in The following explicit, overridable baseline is implemented in
@@ -96,9 +101,9 @@ an advisory and affected kernel versions before adding CVE claims; search snippe
enrollment and actual Secure Boot state with `sbctl status`; do not assume all hosts have it. enrollment and actual Secure Boot state with `sbctl status`; do not assume all hosts have it.
- Secure Boot, signed boot images, kernel lockdown and module signature enforcement are distinct - Secure Boot, signed boot images, kernel lockdown and module signature enforcement are distinct
controls. Test custom kernels and NVIDIA/out-of-tree modules before extending enforcement. controls. Test custom kernels and NVIDIA/out-of-tree modules before extending enforcement.
- AppArmor is enabled, but the explicit sudo policy is in complain mode and the default-deny/nix - AppArmor is enabled, but the only explicit policy, sudo's, is in complain mode. Complain mode logs
scaffolds are disabled. Complain mode logs rather than blocks. Existing FHS-oriented abstractions rather than blocks. Existing FHS-oriented abstractions need Nix store path review; this is not
need Nix store path review; this is not broad enforced application confinement. broad enforced application confinement.
- Systemd service sandboxing is per-service, not a global policy. Review capabilities, writable - Systemd service sandboxing is per-service, not a global policy. Review capabilities, writable
paths, network access and syscall requirements before tightening an individual service. paths, network access and syscall requirements before tightening an individual service.
@@ -242,10 +247,12 @@ export, credential, DNS record or firmware configuration was changed during the
- Darwin's activation now re-applies each secret's declared ownership explicitly instead of a - Darwin's activation now re-applies each secret's declared ownership explicitly instead of a
blanket `chown` over `/etc/agenix/*`, so the root-only `rclone.conf` stays root-owned. Runtime blanket `chown` over `/etc/agenix/*`, so the root-only `rclone.conf` stays root-owned. Runtime
ownership (`ls -l /etc/agenix`) on each Darwin host still needs a check after the next activation. ownership (`ls -l /etc/agenix`) on each Darwin host still needs a check after the next activation.
- PostgreSQL's loopback TCP listener still trusts application roles by password (Immich and the - PostgreSQL's loopback TCP listener still trusts every role except `postgres` without a password,
exporter use it), but `postgres` and replication now require `scram-sha-256`, closing the so any local process can log in as `immich` or `playground`. No service configured here uses that
local-superuser path. Provisioning per-role passwords for full loopback `scram-sha-256` is the path: Immich and the exporter connect over the Unix socket with peer authentication. `postgres`
follow-up (the Grafana datasource file already tracks this as its item 1.5). and replication now require `scram-sha-256`, closing the local-superuser path. Provisioning
per-role passwords for full loopback `scram-sha-256` is the follow-up; the disabled Grafana
`postgres-playground` datasource also waits on a `playground` password.
### Sandbox and agent boundaries ### Sandbox and agent boundaries
+2 -2
View File
@@ -25,7 +25,7 @@ A version or revision pinned for a reason that can go away.
| WA-005 | `tuios` input — `flake.nix`; `home/base/tui/tuios/` | nixpkgs lags behind upstream | Use nixpkgs' `tuios` once it is recent enough | 2026-10-03 | on nixpkgs bump | active | | WA-005 | `tuios` input — `flake.nix`; `home/base/tui/tuios/` | nixpkgs lags behind upstream | Use nixpkgs' `tuios` once it is recent enough | 2026-10-03 | on nixpkgs bump | active |
| WA-006 | `nixpkgs-blender` — `flake.nix` | Blender 5.2 LTS + CUDA/OptiX pin; keeps `just up` from triggering a full source rebuild | Bump deliberately when needed; drop the pin if the current nixpkgs build is acceptable | 2026-07-24 | deliberate | active | | WA-006 | `nixpkgs-blender` — `flake.nix` | Blender 5.2 LTS + CUDA/OptiX pin; keeps `just up` from triggering a full source rebuild | Bump deliberately when needed; drop the pin if the current nixpkgs build is acceptable | 2026-07-24 | deliberate | active |
| WA-007 | WeChat from `nixpkgs-master` — `hardening/bwraps/default.nix` | newest builds; the pinned channel lags | Fall back to the stable channel once it has a good build | 2026-10-03 | on nixpkgs bump | active | | WA-007 | WeChat from `nixpkgs-master` — `hardening/bwraps/default.nix` | newest builds; the pinned channel lags | Fall back to the stable channel once it has a good build | 2026-10-03 | on nixpkgs bump | active |
| WA-020 | `fcitx5-vinput` pinned to release tag `v2.4.0` — `flake.nix`; consumer `home/linux/gui/base/vinput/default.nix` | Tracks a release tag instead of a branch, so `just up` stays on that release | Bump to a newer release tag when its changes are wanted | 2026-10-04 | on vinput release | active | | WA-020 | `fcitx5-vinput` pinned to release tag `v2.4.2` — `flake.nix`; consumer `home/linux/gui/base/vinput/default.nix` | Tracks a release tag instead of a branch, so `just up` stays on that release | Bump to a newer release tag when its changes are wanted | 2026-10-04 | on vinput release | active |
| WA-021 | `nix-x86-on-aarch64` input — our fork of rowanG077's patched FEX + muvm runtime — `flake.nix`; `hosts/12kingdoms-shoukei/game/` | FEX does not support 16K pages, so x86/x86_64 apps and games on shoukei need this pinned flake's 4K-page microVM runtime; our fork lets upstream changes be reviewed before use | Drop once FEX supports 16K pages directly, or nixpkgs/nixos-apple-silicon ships an equivalent runtime | 2026-10-07 | on FEX/nixpkgs/muvm update | active | | WA-021 | `nix-x86-on-aarch64` input — our fork of rowanG077's patched FEX + muvm runtime — `flake.nix`; `hosts/12kingdoms-shoukei/game/` | FEX does not support 16K pages, so x86/x86_64 apps and games on shoukei need this pinned flake's 4K-page microVM runtime; our fork lets upstream changes be reviewed before use | Drop once FEX supports 16K pages directly, or nixpkgs/nixos-apple-silicon ships an equivalent runtime | 2026-10-07 | on FEX/nixpkgs/muvm update | active |
| WA-023 | `nix.package = pkgs.nixVersions.latest` — `modules/nixos/base/nix.nix` | NixOS is opted into Nix 2.35 (2.35.2), which nixpkgs ships as `nixVersions.latest`, while `nixVersions.stable` is still 2.34 | Drop the override and fall back to the default `pkgs.nix` once `nixVersions.stable` is 2.35 or newer | 2026-10-07 | next nixpkgs bump | active | | WA-023 | `nix.package = pkgs.nixVersions.latest` — `modules/nixos/base/nix.nix` | NixOS is opted into Nix 2.35 (2.35.2), which nixpkgs ships as `nixVersions.latest`, while `nixVersions.stable` is still 2.34 | Drop the override and fall back to the default `pkgs.nix` once `nixVersions.stable` is 2.35 or newer | 2026-10-07 | next nixpkgs bump | active |
| WA-037 | `nixpkgs-npu` input pinned to `2ddccb854d89` — the `openvino-npu-compiler` branch of `ryan4yin/nixpkgs`, carrying [NixOS/nixpkgs#570230](https://github.com/NixOS/nixpkgs/pull/570230) — `flake.nix`; consumer `pkgs-npu` in `outputs/default.nix`, `hosts/idols-aquamarine/asr.nix` | The Intel NPU compiler, and the driver change that loads it, are unmerged, so the NPU driver the Whisper service needs comes from that branch | Drop the input and load `intel-npu-driver` from `nixos-unstable` once #570230 merges | 2026-10-17 | when #570230 merges | active | | WA-037 | `nixpkgs-npu` input pinned to `2ddccb854d89` — the `openvino-npu-compiler` branch of `ryan4yin/nixpkgs`, carrying [NixOS/nixpkgs#570230](https://github.com/NixOS/nixpkgs/pull/570230) — `flake.nix`; consumer `pkgs-npu` in `outputs/default.nix`, `hosts/idols-aquamarine/asr.nix` | The Intel NPU compiler, and the driver change that loads it, are unmerged, so the NPU driver the Whisper service needs comes from that branch | Drop the input and load `intel-npu-driver` from `nixos-unstable` once #570230 merges | 2026-10-17 | when #570230 merges | active |
@@ -52,7 +52,7 @@ A setting that works around a bug or a hardware quirk.
| WA-032 | `amdgpu.runpm=0` kernel parameter — `hosts/idols-aquamarine/hardware-amd-gpu.nix` | this board's DSDT advertises ATPX power control (`\_SB.PC00.GFX0.ATPX`) but never defines the `PEG0.PEGP._OFF`/`_ON` symbols its body calls, so the first idle resume of the headless R9700 leaves it in `runtime_status = error` (`resume of IP block <smu> failed -62`) until reboot, and amdgpu discards the ACPI error. Root cause, kernel-source trail and the measured field comparison: `hosts/idols-aquamarine/ROCM.md`. | Drop once a BIOS update defines those ACPI methods (upstream releases 1023/1066 exist for this board; a flash changes PCR7, so re-enroll TPM2), or a kernel release stops trusting ATPX when its power methods are missing | 2026-10-14 | on a BIOS update or kernel bump | active | | WA-032 | `amdgpu.runpm=0` kernel parameter — `hosts/idols-aquamarine/hardware-amd-gpu.nix` | this board's DSDT advertises ATPX power control (`\_SB.PC00.GFX0.ATPX`) but never defines the `PEG0.PEGP._OFF`/`_ON` symbols its body calls, so the first idle resume of the headless R9700 leaves it in `runtime_status = error` (`resume of IP block <smu> failed -62`) until reboot, and amdgpu discards the ACPI error. Root cause, kernel-source trail and the measured field comparison: `hosts/idols-aquamarine/ROCM.md`. | Drop once a BIOS update defines those ACPI methods (upstream releases 1023/1066 exist for this board; a flash changes PCR7, so re-enroll TPM2), or a kernel release stops trusting ATPX when its power methods are missing | 2026-10-14 | on a BIOS update or kernel bump | active |
| WA-036 | catppuccin eval-time ports kept in the home closure (`home.extraDependencies`) — `home/base/core/theme.nix` | catppuccin/nix reads some ports at eval time (`lib.importTOML "${sources.starship}/<flavor>.toml"`) and inlines the result, so the built port, catppuccin's build/install hooks and the fetched port source stay unreachable: every gc deletes them, and the deploy after it rebuilds them (build logs: 2026-10-16). `home.extraDependencies` records the port in the generation, which is a gc root. Also read at eval time upstream: `bottom`, `element` (option `element-desktop`), `firefox`, `rio`, `palette` (options `skim`, `tty`), `spotify-player`. | Drop once catppuccin/nix stops reading port files at eval time, or those ports come from a binary cache | 2026-10-16 | on a catppuccin bump | active | | WA-036 | catppuccin eval-time ports kept in the home closure (`home.extraDependencies`) — `home/base/core/theme.nix` | catppuccin/nix reads some ports at eval time (`lib.importTOML "${sources.starship}/<flavor>.toml"`) and inlines the result, so the built port, catppuccin's build/install hooks and the fetched port source stay unreachable: every gc deletes them, and the deploy after it rebuilds them (build logs: 2026-10-16). `home.extraDependencies` records the port in the generation, which is a gc root. Also read at eval time upstream: `bottom`, `element` (option `element-desktop`), `firefox`, `rio`, `palette` (options `skim`, `tty`), `spotify-player`. | Drop once catppuccin/nix stops reading port files at eval time, or those ports come from a binary cache | 2026-10-16 | on a catppuccin bump | active |
| WA-039 | niri's NVIDIA free-buffer pool bounded (`GLVidHeapReuseRatio` 0) — `hosts/idols-ai/hardware-nvidia.nix` | the driver does not return freed vidmem buffers to its free pool, so niri's VRAM grows to ~1.1 GiB instead of the ~100 MiB its NVIDIA notes expect (measured 1137 MiB after 24 h uptime; [NVIDIA/egl-wayland#126](https://github.com/NVIDIA/egl-wayland/issues/126)) | Drop once a driver stops growing niri's VRAM without the profile, or niri ships its own default | 2026-10-19 | on an nvidia driver bump | active | | WA-039 | niri's NVIDIA free-buffer pool bounded (`GLVidHeapReuseRatio` 0) — `hosts/idols-ai/hardware-nvidia.nix` | the driver does not return freed vidmem buffers to its free pool, so niri's VRAM grows to ~1.1 GiB instead of the ~100 MiB its NVIDIA notes expect (measured 1137 MiB after 24 h uptime; [NVIDIA/egl-wayland#126](https://github.com/NVIDIA/egl-wayland/issues/126)) | Drop once a driver stops growing niri's VRAM without the profile, or niri ships its own default | 2026-10-19 | on an nvidia driver bump | active |
| WA-040 | NixOS root CA blacklist — `modules/base/security.nix` | eMudhra intermediate keys were compromised; [NixOS/nixpkgs#576390](https://github.com/NixOS/nixpkgs/pull/576390) and [#576401](https://github.com/NixOS/nixpkgs/pull/576401) merged before reaching release channels | Drop once every consumed NixOS nixpkgs revision includes the upstream root blacklist | 2026-10-20 | on nixpkgs bump | active | | WA-040 | Root CA blacklist on NixOS and Darwin (Nix CA bundle only, not the macOS Keychain) — `modules/base/security.nix` | eMudhra intermediate keys were compromised; [NixOS/nixpkgs#576390](https://github.com/NixOS/nixpkgs/pull/576390) and [#576401](https://github.com/NixOS/nixpkgs/pull/576401) merged before reaching release channels | Drop once every consumed nixpkgs revision (`nixpkgs` and `nixpkgs-darwin`) includes the upstream root blacklist | 2026-10-20 | on nixpkgs bump | active |
| WA-041 | Monitor OSD "no-signal auto power-off" disabled — no code in this repo (the P32A2V OSD setting) | during a DPMS-off idle the panel drops and re-adds HPD every ~13 s, and after wake niri keeps scanning out while the panel stays dark until the monitor is power cycled; the panel's own auto power-off drives that state, so it is now disabled. Pinning the mode to 120 Hz did not change the symptom | Drop once a driver retrains the DP link after a DPMS wake, the monitor firmware stops cycling HPD, or this monitor is replaced | 2026-10-21 | confirm on the next full idle cycle, then on an nvidia or monitor firmware update | active | | WA-041 | Monitor OSD "no-signal auto power-off" disabled — no code in this repo (the P32A2V OSD setting) | during a DPMS-off idle the panel drops and re-adds HPD every ~13 s, and after wake niri keeps scanning out while the panel stays dark until the monitor is power cycled; the panel's own auto power-off drives that state, so it is now disabled. Pinning the mode to 120 Hz did not change the symptom | Drop once a driver retrains the DP link after a DPMS wake, the monitor firmware stops cycling HPD, or this monitor is replaced | 2026-10-21 | confirm on the next full idle cycle, then on an nvidia or monitor firmware update | active |
If WA-008 freezes recur, the fallback is to restore the parameters commented out in If WA-008 freezes recur, the fallback is to restore the parameters commented out in
+77 -44
View File
@@ -2,10 +2,14 @@
> **Purpose:** let the maintainer decide, per candidate, whether it is worth adopting — by comparing > **Purpose:** let the maintainer decide, per candidate, whether it is worth adopting — by comparing
> it against what this repository does **today**. A plan derived from this file is only approved > it against what this repository does **today**. A plan derived from this file is only approved
> work once its card here says **adopt**. > work once its card here says **adopt**. The plans are not on `main`: they exist only on the local,
> unpushed git tag `modernization-plans-wip`, under `docs/plans/`:
> `2026-10-07-boot-chain-limine-uki-repart.md`, `2026-10-07-host-level-modernization.md` and
> `2026-10-07-lab-experimental-etc-init.md` (`git show modernization-plans-wip:docs/plans/<file>`).
> >
> Researched against nixpkgs `nixos-unstable` on 2026-10-07. Option names and upstream wording are > Researched against nixpkgs `nixos-unstable` on 2026-10-07. Option names and upstream wording are
> quoted from the module sources cited in each card. > quoted from the module sources cited in each card. The **Current:** sections were re-checked
> against this repository on 2026-10-21; the upstream research was not redone.
## How to use this file ## How to use this file
@@ -56,16 +60,20 @@ LAN-only client can run Tailscale.
## A2. systemd-resolved ## A2. systemd-resolved
**Current:** `services.resolved.enable` is set **nowhere**; hosts get DNS from systemd-networkd or **Current:** `services.resolved.enable` evaluates `true` on 14 of the 15 NixOS hosts (all but
NetworkManager (or static config) and use the default `/etc/resolv.conf`. Note `akane`): nixpkgs enables it by default with systemd-networkd
`modules/nixos/base/networking/mdns.nix` already sets (`nixos/modules/system/boot/networkd.nix`), and `shoukei`, which runs NetworkManager, enables it
`services.resolved.settings.Resolve.MulticastDNS = false` — currently inert, and it will activate through `modules.networking.mihomo.resolvedIntegration` (asserted by the eval test
the moment resolved is enabled. mDNS itself is provided by avahi. `outputs/aarch64-linux/tests/mihomo-dns`). On `ai`, a mihomo lifecycle hook points the link's
resolved DNS at mihomo (`hosts/idols-ai/default.nix`). `DNSOverTLS` and `DNSSEC` evaluate `false`.
The `services.resolved.settings.Resolve.MulticastDNS = false` in
`modules/nixos/base/networking/mdns.nix` is therefore live; mDNS itself is provided by avahi.
**Proposed:** `services.resolved.enable = true`, optionally with `DNSOverTLS`/DNSSEC and caching. **Proposed:** `DNSOverTLS`/DNSSEC and caching settings on the resolved instance the hosts already
run (`services.resolved.enable = true` would still be new on `akane`).
**Pros:** caching resolver, DoT/DNSSEC available, consistent stub across hosts, and the mDNS caveat **Pros:** DoT/DNSSEC available; the caching resolver and a consistent stub across hosts already come
is already handled by the existing setting. with the resolved instance in use, and the mDNS caveat is already handled by the existing setting.
**Cons:** the LAN gateway `suzi` is a mihomo transparent proxy that **hijacks DNS to fake IPs that **Cons:** the LAN gateway `suzi` is a mihomo transparent proxy that **hijacks DNS to fake IPs that
are only routable through the proxy** — DoT/DoH on a host would bypass that hijack and break proxied are only routable through the proxy** — DoT/DoH on a host would bypass that hijack and break proxied
@@ -84,12 +92,16 @@ changes.
## A3. systemd-networkd instead of dhcpcd ## A3. systemd-networkd instead of dhcpcd
**Current:** dhcpcd is not used anywhere in this repo. `ai`, `kana` and `ruby` already set **Current:** dhcpcd is not used anywhere in this repo. `networking.useNetworkd = true` is set on 13
`networking.useNetworkd = true`; `shoukei` and `akane` run NetworkManager; VM hosts and MicroVM of the 15 hosts: every VM host (`lib/genVmHostModule.nix`) and MicroVM guest
guests use static config with `useDHCP = false`. The `br0` bridge on VM hosts is declared through (`lib/genMicrovmGuestModule.nix`), plus `ai`, `aquamarine`, `kana` and `ruby`; only `shoukei` and
`systemd.network.netdevs/networks` already. `akane` run NetworkManager. VM hosts and MicroVM guests use static config with `useDHCP = false`.
The `br0` bridge on VM hosts is declared through `systemd.network.netdevs/networks` already.
**Proposed:** `networking.networkd.enable = true` with `networking.networks`/`networkdOptions`. **Proposed:** systemd-networkd on the remaining NetworkManager hosts, through the options the other
hosts already use: `networking.useNetworkd` and `systemd.network.{networks,netdevs}`. The
`networking.networkd.enable` / `networking.networks` / `networkdOptions` names first recorded here
do not exist in the locked nixpkgs.
**Pros:** declarative per-interface config, one implementation for stage 1 and stage 2, no dhcpcd **Pros:** declarative per-interface config, one implementation for stage 1 and stage 2, no dhcpcd
anywhere in the path (nothing in this repo uses it), and VM hosts already speak `systemd.network` anywhere in the path (nothing in this repo uses it), and VM hosts already speak `systemd.network`
@@ -103,7 +115,10 @@ lease/renew and DNS handling.
**Trigger to adopt:** guest-only first, then a non-VM host with console access. **Trigger to adopt:** guest-only first, then a non-VM host with console access.
**Recommendation:** **watch**, guest-only experiment (plan 3, task 5). **Recommendation:** **watch**, guest-only experiment (`lab-experimental-etc-init.md`, Task 5). The
corrected facts make that experiment moot — every MicroVM guest already runs networkd, and the plan
task uses the non-existent option names above — so the open call is whether `shoukei` and `akane`
move off NetworkManager.
**Decision:** _pending_ **Decision:** _pending_
@@ -134,12 +149,16 @@ missing-log incident shows up.
## A5. zram-generator instead of zramSwap ## A5. zram-generator instead of zramSwap
**Current:** a local module `modules/nixos/base/zram.nix` wraps `zramSwap` and adds sysctl tunings **Current:** a local module `modules/nixos/base/zram.nix` wraps `zramSwap` and adds sysctl tunings
(swappiness, readahead), disabled on idols-ai (disk swapfile) and memoryPercent-tuned on shoukei. (swappiness, readahead), disabled on idols-ai (disk swapfile) and aquamarine, memoryPercent-tuned on
shoukei, and not imported on akane. In the locked nixpkgs `zramSwap` is itself implemented on
zram-generator (`nixos/modules/config/zram.nix` sets `services.zram-generator.enable`, which youko
evaluates `true`).
**Proposed:** `services.zram-generator.enable` with a `zram0` definition. **Proposed:** `services.zram-generator.enable` with a `zram0` definition.
**Pros:** systemd-native unit generator, config expressed as data, upstream-maintained, no **Pros:** systemd-native unit generator, config expressed as data, upstream-maintained, no
NixOS-specific script. NixOS-specific script — all but writing the `zram0` settings directly already come with `zramSwap`
(see Current).
**Cons:** your module couples zram presence to sysctl tunings — the migration must keep that logic **Cons:** your module couples zram presence to sysctl tunings — the migration must keep that logic
working when zram is off; two zram implementations are easy to have half-enabled during the change; working when zram is off; two zram implementations are easy to have half-enabled during the change;
@@ -155,8 +174,8 @@ the gain over a working `zramSwap` is mostly cosmetic.
## A6. nixos-facter instead of hand-written hardware-configuration.nix ## A6. nixos-facter instead of hand-written hardware-configuration.nix
**Current:** 3 hosts carry hand-written `hardware-configuration.nix` (`shoryu`, `shoukei`, `ai`; **Current:** 4 hosts carry hand-written `hardware-configuration.nix` (`shoryu`, `shoukei`, `ai`,
`shushou` and `youko` import `shoryu`'s, and the qemu guests use the shared `aquamarine`; `shushou` and `youko` import `shoryu`'s, and the qemu guests use the shared
`modules/nixos/server/qemu-guest-hardware-configuration.nix`), plus deliberate per-host quirks such `modules/nixos/server/qemu-guest-hardware-configuration.nix`), plus deliberate per-host quirks such
as the NVMe APST workaround WA-008 and USB-SATA mitigations WA-009. as the NVMe APST workaround WA-008 and USB-SATA mitigations WA-009.
@@ -174,7 +193,7 @@ defaults become less transparent than a file you can read in the diff; your deli
**Trigger to adopt:** on a new host build, or when a hardware change forces a regeneration anyway. **Trigger to adopt:** on a new host build, or when a hardware change forces a regeneration anyway.
**Recommendation:** **watch** — adopt on the next new host rather than retrofitting eight. **Recommendation:** **watch** — adopt on the next new host rather than retrofitting four.
**Decision:** _pending_ **Decision:** _pending_
@@ -204,10 +223,12 @@ cannot go to a public cache.
**Current:** static `nix.buildMachines` (`modules/nixos/base/remote-builders.nix`); the plain user **Current:** static `nix.buildMachines` (`modules/nixos/base/remote-builders.nix`); the plain user
is deliberately not a trusted user on the clients, though the builder host trusts its builder login; is deliberately not a trusted user on the clients, though the builder host trusts its builder login;
Nix 2.35 via `nixVersions.latest` (WA-023). Nix 2.35 via `nixVersions.latest` (WA-023). `auto-allocate-uids` (with `cgroups`) is already enabled
in `modules/nixos/base/nix.nix` for nixpkgs' nspawn-based tests, and the locked nixpkgs has no
`nix-servd` module or package.
**Proposed:** `nix-servd` for scheduling, plus `auto-allocate-uids` and `local-overlay-store` **Proposed:** `nix-servd` for scheduling, plus the `local-overlay-store` experimental feature
experimental features. (`auto-allocate-uids` is already on, see Current).
**Pros:** dynamic builder selection and health checks instead of a hand-maintained list; the **Pros:** dynamic builder selection and health checks instead of a hand-maintained list; the
experimental features move toward running the daemon without root, consistent with the experimental features move toward running the daemon without root, consistent with the
@@ -253,9 +274,10 @@ are hard to attribute; no measured problem to solve yet.
## B1. limine instead of systemd-boot + lanzaboote ## B1. limine instead of systemd-boot + lanzaboote
**Current:** systemd-boot everywhere, except qemu guests (GRUB on `/dev/vda`) and idols-ai, where **Current:** systemd-boot on akane, shoukei and the VM hosts (shoryu, shushou, youko); GRUB on
lanzaboote provides Secure Boot with a `/etc/secureboot` (lzpt) bundle; the lanzaboote flake input `/dev/vda` on the libvirt guests kana and ruby; no bootloader on the MicroVM guests; on idols-ai and
must track a rust-overlay follow (WA-003). aquamarine, lanzaboote provides Secure Boot with a `/etc/secureboot` (lzpt) bundle. The lanzaboote
flake input must track a rust-overlay follow (WA-003).
**Proposed:** `boot.loader.limine` — in nixpkgs, with `secureBoot`, `validateChecksums`, **Proposed:** `boot.loader.limine` — in nixpkgs, with `secureBoot`, `validateChecksums`,
`panicOnChecksumMismatch`, `biosSupport`, `maxGenerations`, graphical menu. `panicOnChecksumMismatch`, `biosSupport`, `maxGenerations`, graphical menu.
@@ -282,8 +304,8 @@ but it is the highest-risk item on this list.
## B2. boot.uki / system.build.uki ## B2. boot.uki / system.build.uki
**Current:** lanzaboote already produces and signs a UKI on idols-ai; other hosts boot **Current:** lanzaboote already produces and signs a UKI on idols-ai and aquamarine; other hosts
kernel+initrd. boot kernel+initrd.
**Proposed:** `boot.uki`. **Proposed:** `boot.uki`.
@@ -355,8 +377,13 @@ and its own state; unclear what problem it solves here.
## B6. Measured boot phases / FIDO2 credentials ## B6. Measured boot phases / FIDO2 credentials
**Current:** Secure Boot via lanzaboote; TPM2/FIDO2 initrd options are off, so boot is signed but **Current:** Secure Boot via lanzaboote on ai and aquamarine, whose LUKS volumes are enrolled for
not measured into a policy. TPM2 unlock bound to PCRs 0+7, with the passphrase slot as fallback (`hosts/idols-ai/README.md`,
`hosts/idols-aquamarine/README.md`). `boot.initrd.systemd.tpm2.enable` evaluates `true` on every
host except the MicroVM guests, and on ai and aquamarine `systemd.tpm2.enable` and
`boot.initrd.systemd.fido2.enable` are `true` as well (nixpkgs defaults from the systemd package).
Not adopted: `systemd.tpm2.pcrphases.enable` is `false`, and the READMEs document no FIDO2
credential, only TPM2 and passphrase slots.
**Proposed:** `systemd.tpm2.enable`, `systemd.tpm2.pcrphases.enable`, **Proposed:** `systemd.tpm2.enable`, `systemd.tpm2.pcrphases.enable`,
`boot.initrd.systemd.tpm2.enable`, `boot.initrd.systemd.fido2.enable`. `boot.initrd.systemd.tpm2.enable`, `boot.initrd.systemd.fido2.enable`.
@@ -413,16 +440,22 @@ are deleted early. **Recommendation:** **adopt additively**. **Decision:** _pend
## C3. nix-fast-build ## C3. nix-fast-build
**Current:** serial evaluation in CI. **Proposed:** `nix-fast-build` over the eval tests and the **Current:** CI (`.github/workflows/flake_evaltests.yml`) runs one `nix eval .#evalTests` and one VM
three host systems, reusing remote builders. **Pros:** parallel eval/build, no new CI infra. test (`checks.x86_64-linux.security-exporters`) on GitHub-hosted `ubuntu-latest` runners.
**Cons:** one more tool in the Justfile; CI already gates merges. **Recommendation:** **adopt**. **Proposed:** `nix-fast-build` over the eval tests and the three host systems; the remote builder
**Decision:** _pending_ (aquamarine, over SSH from repo machines) serves only a local Justfile run, not the hosted CI
runners. **Pros:** parallel eval/build, no new CI infra. **Cons:** one more tool in the Justfile; CI
already gates merges. **Recommendation:** **adopt**. **Decision:** _pending_
## C4. Cleanups (no decision needed) ## C4. Cleanups (no decision needed)
WA-001 (smartctl pin) should be dropped once nixpkgs carries the upstream fix; the "nixfmt with WA-001 (smartctl pin) should be dropped once nixpkgs carries the upstream fix; the "nixfmt with
width 100" sentence in `AGENTS.md` should be checked against the formatter `just fmt` actually width 100" sentence in `AGENTS.md` should be checked against the formatter `just fmt` actually
resolves to. **Recommendation:** **adopt**. **Decision:** _pending_ resolves to. Checked 2026-10-21: the locked nixpkgs still ships smartctl_exporter 0.14.0, which
lacks the #329 fix (`overlays/smartctl-exporter/`), so WA-001 stays; `just fmt` runs the dev shell's
nixfmt 1.5.0, whose default width is 100, and `pre-commit-check` sets width 100
(`outputs/default.nix`), so the `AGENTS.md` sentence is correct. **Recommendation:** **adopt**.
**Decision:** _pending_
## C5. jj ## C5. jj
@@ -434,18 +467,18 @@ _pending_
# D. Lab-only experimental group # D. Lab-only experimental group
The whole group shares one characteristic: upstream labels it experimental, and a mistake can The whole group shares one characteristic: upstream labels it experimental, and a mistake can
prevent boot or login. **Recommendation for the group: evaluate in a disposable guest (plan 3), prevent boot or login. **Recommendation for the group: evaluate in a disposable guest
adopt individually only afterwards.** (`lab-experimental-etc-init.md` on the plans tag), adopt individually only afterwards.**
| # | Candidate | Current | Main pro | Main con | Recommendation | | # | Candidate | Current | Main pro | Main con | Recommendation |
| --- | ------------------------------------------------------ | -------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | | --- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| D1 | `system.etc.overlay.enable` | /etc generated by the perl activation script | /etc becomes an EROFS + overlay mount; foundation for an immutable /etc | upstream: _"This is currently experimental. Only enable this option if you are confident that you can recover your system if it breaks."_; every /etc writer must be audited | lab only | | D1 | `system.etc.overlay.enable` | /etc generated by the perl activation script | /etc becomes an EROFS + overlay mount; foundation for an immutable /etc | upstream: _"This is currently experimental. Only enable this option if you are confident that you can recover your system if it breaks."_; every /etc writer must be audited | lab only |
| D2 | `systemd.sysusers.enable` / `services.userborn.enable` | `update-users-groups.pl` | removes the perl script; prerequisite for an immutable /etc | experimental; uid/gid migration risk | lab only | | D2 | `systemd.sysusers.enable` / `services.userborn.enable` | `update-users-groups.pl` | removes the perl script; prerequisite for an immutable /etc | experimental; uid/gid migration risk | lab only |
| D3 | `system.etc.overlay.mutable = false` | writable /etc | truly immutable /etc | **blocked**: agenix writes `/etc/agenix` (see the `environment.etc` copies in `secrets/nixos.nix`), so secrets must move to /run or to sops-nix first | lab only, after secrets move | | D3 | `system.etc.overlay.mutable = false` | writable /etc | truly immutable /etc | **blocked**: agenix writes `/etc/agenix` (see the `environment.etc` copies in `secrets/nixos.nix`), so secrets must move to /run or to sops-nix first | lab only, after secrets move |
| D4 | `system.nixos-init.enable` | `activationScripts` | bashless init | makes `activationScripts` a silent no-op — btrbk/restic hooks would stop running without an error | lab only | | D4 | `system.nixos-init.enable` | `activationScripts` | bashless init | makes `activationScripts` a silent no-op — youko's `data-ro-backing`, `installCaddyWallpapers` and `installHomepageDashboardConfig` would stop running without an error | lab only |
| D5 | `security.pam.settings` | per-service booleans | freeform PAM config | upstream marks it subject to breaking changes; a mistake locks you out | lab only | | D5 | `security.pam.services.<name>.rules` | per-service booleans | freeform PAM config | upstream marks it subject to breaking changes; a mistake locks you out | lab only |
| D6 | `security.shadow.enable = false` + greetd | shadow suite provides login/su | fewer setuid programs | assertion couples the two; changes VT login semantics | lab only | | D6 | `security.shadow.enable = false` + greetd | shadow suite provides login/su | fewer setuid programs | assertion couples the two; changes VT login semantics | lab only |
| D7 | `security.apparmor.policies` | deprecated `profiles` option | policy set is now data | writing profiles is real work and breakage-prone; `SECURITY.md` explicitly warns against untested profiles | lab only | | D7 | `security.apparmor.policies` | `policies.sudo` already in use (`hardening/apparmor/default.nix`); the old `profiles` option is removed upstream | policy set is now data | writing profiles is real work and breakage-prone; `SECURITY.md` explicitly warns against untested profiles | lab only |
--- ---
@@ -465,8 +498,8 @@ adopt individually only afterwards.**
# F. Decision summary # F. Decision summary
Fill this in as cards are decided; the plan documents should then be trimmed to **adopt** items Fill this in as cards are decided; the plan documents (on the `modernization-plans-wip` tag, see the
only. header) should then be trimmed to **adopt** items only.
| Card | Candidate | Decision | Date | Note | | Card | Candidate | Decision | Date | Note |
| ----- | --------------------------- | -------- | ---- | ---- | | ----- | --------------------------- | -------- | ---- | ---- |
+1 -1
View File
@@ -21,7 +21,7 @@
# https://hydra.nixos.org/jobset/nixpkgs/unstable # https://hydra.nixos.org/jobset/nixpkgs/unstable
# update via nix flake update nixpkgs --override-input nixpkgs github:NixOS/nixpkgs/<commit-hash> # update via nix flake update nixpkgs --override-input nixpkgs github:NixOS/nixpkgs/<commit-hash>
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# Pinned to release tag v2.4.0 (not a branch); bump deliberately when needed. # Pinned to release tag v2.4.2 (not a branch); bump deliberately when needed.
fcitx5-vinput = { fcitx5-vinput = {
url = "github:xifan2333/fcitx5-vinput/v2.4.2"; url = "github:xifan2333/fcitx5-vinput/v2.4.2";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
+3 -2
View File
@@ -31,12 +31,13 @@ systems.
- **terminal/**: Terminal emulator configurations - **terminal/**: Terminal emulator configurations
- **ghostty.nix**: Ghostty terminal (default) - **ghostty.nix**: Ghostty terminal (default)
- **kitty.nix**: Kitty terminal - **kitty.nix**: Kitty terminal
- **work-gitconfig.nix**: Work git identity for repositories under `~/work`, linked from agenix
### Terminal Interface ### Terminal Interface
- **tui/**: Terminal-based interface configurations - **tui/**: Terminal-based interface configurations
- **agents/**: AI coding agents — global rules deployment, CLIs, and telemetry/auto-update - **agents/**: AI coding agents — global rules and skills deployment, CLIs, and
opt-outs telemetry/auto-update opt-outs
- **cloud/**: Cloud development tools (Terraform, etc.) - **cloud/**: Cloud development tools (Terraform, etc.)
- **container.nix**: Container tools (Docker, Podman) - **container.nix**: Container tools (Docker, Podman)
- **dev-tools.nix**: Terminal-based development tools - **dev-tools.nix**: Terminal-based development tools
+8 -8
View File
@@ -13,13 +13,13 @@ Markdown with no Nix dependency; this module only wires it into place.
- `skills.nix`: links the global skills into `~/.agents/skills/<name>`, from pinned flake inputs and - `skills.nix`: links the global skills into `~/.agents/skills/<name>`, from pinned flake inputs and
from `agents/skills/`; the inventory is from `agents/skills/`; the inventory is
[agents/skills/README.md](../../../../agents/skills/README.md). [agents/skills/README.md](../../../../agents/skills/README.md).
- `packages.nix`: agent CLIs (`codex`, `opencode2`, `pi`) from the `llm-agents` flake input, plus - `packages.nix`: agent CLIs (`codex`, `opencode2`, `pi`) from the `llm-agents` flake input, dsh
`pkgs.mcp-grafana` for the Grafana MCP server. from `nur-ryan4yin`, `pkgs.ctx7` for the `find-docs` skill, and `pkgs.mcp-grafana` for the Grafana
- `env.nix`: telemetry and auto-update opt-outs for the agents. dsh is installed by this module and MCP server. dsh's Nushell-only shell is selected when the package is built, via `dsh.withPlugins`
configured at runtime: profile patches live in `~/.dsh/profiles/<name>/cordis.patch.yml`. The with the plugin from the `dsh-nu` flake input, so it is a derivation choice rather than runtime
Nushell-only shell is selected when the package is built, via `dsh.withPlugins` from state; profile patches live in `~/.dsh/profiles/<name>/cordis.patch.yml`. See [dsh.md](./dsh.md)
`nur-ryan4yin`, so it is a derivation choice rather than runtime state. See [dsh.md](./dsh.md) for for the layer order and the settings that bite.
the layer order and the settings that bite. - `env.nix`: telemetry and auto-update opt-outs for the agents.
## Deployed rule targets ## Deployed rule targets
@@ -65,7 +65,7 @@ compatibility links are needed:
includes `~/.agents/skills` and follows symlink directories. includes `~/.agents/skills` and follows symlink directories.
- **dsh**: - **dsh**:
[Filesystem skill package](https://www.npmjs.com/package/@deepseek-ai/dsh-skill-filesystem) [Filesystem skill package](https://www.npmjs.com/package/@deepseek-ai/dsh-skill-filesystem)
documents `~/.agents/skills` and directory symlinks; confirmed in the shipped 0.2.0-rc.2 loader. documents `~/.agents/skills` and directory symlinks; confirmed in the shipped 0.2.1-rc.2 loader.
Adding or removing links requires a user-run Home Manager switch. Changes to an already-linked skill Adding or removing links requires a user-run Home Manager switch. Changes to an already-linked skill
are available without a rebuild; start a new session or use the harness's reload mechanism to read are available without a rebuild; start a new session or use the harness's reload mechanism to read
+5 -3
View File
@@ -81,8 +81,10 @@ not been boot-tested.
Verify after a switch: Verify after a switch:
```sh ```sh
dsh --profile web --dump-config | grep -n "nu-executor\|nu-teaching" dsh --profile web --dump-config | grep -nE 'nu-executor|nu-teaching'
# expect the first-party shell rows disabled, nu-executor and nu-teaching inserted # expect the first-party shell rows disabled, nu-executor and nu-teaching inserted
dsh --profile web o+e>| grep "disabling profile plugin"
# a dsh bump can disable a row whose manifest no longer matches; nothing prints when healthy
``` ```
A dsh bump can disable a row whose manifest no longer matches. That compatibility check runs only
when a profile boots, not under the boot-free `--dump-config`, so read the stderr of the next boot
(for example `just dsh-web`) for `disabling profile plugin`; nothing prints when healthy.
+5 -4
View File
@@ -19,7 +19,8 @@ This directory contains macOS-specific Home Manager configurations for Darwin sy
## Features ## Features
- macOS-specific package installations and configurations - macOS-specific package installations and configurations
- Native macOS applications and utilities - macOS-specific shell configurations (Homebrew's `bin` directories on `PATH` for bash and zsh)
- Touch ID and system integration
- Homebrew integration for additional packages System-level macOS settings live in the nix-darwin modules: Touch ID for `sudo` in
- macOS-specific shell configurations and aliases [`modules/darwin/system.nix`](../../modules/darwin/system.nix), and native applications and Homebrew
packages in [`modules/darwin/apps.nix`](../../modules/darwin/apps.nix).
+2 -2
View File
@@ -11,7 +11,7 @@ This directory contains host-specific Home Manager entry modules.
1. Each host output should reference only one file under `home/hosts/...`. 1. Each host output should reference only one file under `home/hosts/...`.
2. Shared home module imports should be handled in the host file itself. 2. Shared home module imports should be handled in the host file itself.
- Linux hosts usually import `../linux/core.nix` or `../linux/gui.nix`. - Linux hosts usually import `../../linux/core.nix` or `../../linux/gui.nix`.
- Darwin hosts import `../darwin`. - Darwin hosts import `../../darwin`.
3. Host-specific overrides (SSH keys, desktop toggles, host-local config links) live in the same 3. Host-specific overrides (SSH keys, desktop toggles, host-local config links) live in the same
host file. host file.
+1 -2
View File
@@ -22,9 +22,8 @@ Manager.
- Fcitx5 input method framework - Fcitx5 input method framework
- Games and gaming utilities - Games and gaming utilities
- GTK theme configurations - GTK theme configurations
- Immutable file handling
- Note-taking applications - Note-taking applications
- Wayland applications - Wayland session tools and environment variables
- XDG desktop configurations - XDG desktop configurations
## Why install Desktop Environments in Home Manager instead of NixOS Module? ## Why install Desktop Environments in Home Manager instead of NixOS Module?
+3 -2
View File
@@ -84,14 +84,15 @@ Noctalia consolidates functionality that previously required multiple tools:
screen recording, auto-mount, virt-manager/virt-viewer, `wlogout` emergency fallback) screen recording, auto-mount, virt-manager/virt-viewer, `wlogout` emergency fallback)
- **[`browsers.nix`](./browsers.nix)**: Web browsers - **[`browsers.nix`](./browsers.nix)**: Web browsers
- **[`vscode.nix`](./vscode.nix)**: VS Code - **[`vscode.nix`](./vscode.nix)**: VS Code
- **[`media.nix`](./media.nix)**: Media players - **[`media.nix`](./media.nix)**: Audio control, mpv, go-musicfox, an image viewer, GPU video
diagnostics, Zoom (x86_64 only), and EasyEffects loudness normalization
- **[`gaming.nix`](./gaming.nix)**: Gaming applications - **[`gaming.nix`](./gaming.nix)**: Gaming applications
- **[`creative.nix`](./creative.nix)**: Creative software - **[`creative.nix`](./creative.nix)**: Creative software
- **[`note-taking.nix`](./note-taking.nix)**: Note-taking apps - **[`note-taking.nix`](./note-taking.nix)**: Note-taking apps
### Development ### Development
- **[`dev-tools.nix`](./dev-tools.nix)**: Development tools and IDEs - **[`dev-tools.nix`](./dev-tools.nix)**: Android platform tools (`android-tools`)
### System Utilities ### System Utilities
@@ -90,8 +90,8 @@
} }
# Disabled: the `playground` role has no password and remote logins # Disabled: the `playground` role has no password and remote logins
# require scram-sha-256, so this datasource could never authenticate. # require scram-sha-256, so this datasource could never authenticate.
# Re-enable once a `playground` DB password is provisioned # Re-enable once a `playground` DB password is provisioned (the PostgreSQL
# (docs/system-audit-2026-09-19.md, item 1.5). # per-role password follow-up in SECURITY.md).
/* /*
{ {
# https://grafana.com/docs/grafana/latest/datasources/postgres/configure/ # https://grafana.com/docs/grafana/latest/datasources/postgres/configure/
@@ -96,10 +96,11 @@ in
# "local" is for Unix domain socket connections only # "local" is for Unix domain socket connections only
local all all peer map=superuser_map local all all peer map=superuser_map
# TCP loopback: application roles may still connect without a password # TCP loopback: application roles may still connect without a password,
# (Immich, the exporter), but the superuser and replication may not. That # but the superuser and replication may not. That is the path a
# is the path a compromised local service would take. No password is set # compromised local service would take. No password is set for postgres,
# for postgres, so these lines deny it over TCP. # so these lines deny it over TCP. Immich and the exporter use the Unix
# socket above, so no configured client needs the loopback trust lines.
host all postgres 127.0.0.1/32 scram-sha-256 host all postgres 127.0.0.1/32 scram-sha-256
host all postgres ::1/128 scram-sha-256 host all postgres ::1/128 scram-sha-256
host all all 127.0.0.1/32 trust host all all 127.0.0.1/32 trust
+1 -1
View File
@@ -17,7 +17,7 @@ in
options.modules.desktop = { options.modules.desktop = {
gaming = { gaming = {
enable = mkEnableOption "Enable desktop gaming support"; enable = mkEnableOption "desktop gaming support";
}; };
}; };
+1 -1
View File
@@ -2,7 +2,7 @@
default: default:
@just --list @just --list
# Enter a shell session which has all the necessary tools for this flake # Build the ai host's system closure to check this flake
[linux] [linux]
test: test:
nix build ".#nixosConfigurations.ai.config.system.build.toplevel" --show-trace --verbose nix build ".#nixosConfigurations.ai.config.system.build.toplevel" --show-trace --verbose
+4 -1
View File
@@ -84,6 +84,10 @@ nixos-enter
# mv /etc/ssh /persistent/etc/ # mv /etc/ssh /persistent/etc/
# Then exit and: # Then exit and:
exit exit
# keep this checkout (still in nix-config/nixos-installer); / is tmpfs, so put it where
# preservation mounts ~/nix-config from
mkdir -p /mnt/persistent/home/ryan
cp -r .. /mnt/persistent/home/ryan/nix-config
umount -R /mnt umount -R /mnt
reboot reboot
``` ```
@@ -115,7 +119,6 @@ After the first boot:
3. Deploy the main config: 3. Deploy the main config:
```bash ```bash
sudo mv /etc/nixos ~/nix-config
sudo chown -R ryan:ryan ~/nix-config sudo chown -R ryan:ryan ~/nix-config
cd ~/nix-config cd ~/nix-config
just niri just niri
+6 -5
View File
@@ -236,7 +236,7 @@ Then, generate the NixOS configuration:
nixos-generate-config --root /mnt nixos-generate-config --root /mnt
# we need to update our filesystem configs in old hardware-configuration.nix according to the generated one. # we need to update our filesystem configs in old hardware-configuration.nix according to the generated one.
cp /etc/nixos/hardware-configuration.nix ./nix-config/hosts/12kingdoms-shoukei/hardware-configuration-new.nix cp /mnt/etc/nixos/hardware-configuration.nix ./nix-config/hosts/12kingdoms-shoukei/hardware-configuration-new.nix
vim ./nix-config vim ./nix-config
``` ```
@@ -278,7 +278,7 @@ mv /etc/ssh /persistent/etc/
exit exit
# delete the generated configuration after editing # delete the generated configuration after editing
rm -f /mnt/etc/nixos rm -rf /mnt/etc/nixos
rm ~/nix-config/hosts/12kingdoms-shoukei/hardware-configuration-new.nix rm ~/nix-config/hosts/12kingdoms-shoukei/hardware-configuration-new.nix
# NOTE: `cat README.shoukei.md | grep git-1 > git-1.sh` to generate this script # NOTE: `cat README.shoukei.md | grep git-1 > git-1.sh` to generate this script
@@ -287,8 +287,10 @@ git config --global user.email "ryan4yin@linux.com" # git-1
git config --global user.name "Ryan Yin" # git-1 git config --global user.name "Ryan Yin" # git-1
git commit -am "feat: update hardware-configuration" git commit -am "feat: update hardware-configuration"
# copy our configuration to the installed file system # copy our configuration to the installed file system; / is tmpfs there, so put it where
cp -r ~/nix-config /mnt/etc/nixos # preservation mounts ~/nix-config from
mkdir -p /mnt/persistent/home/ryan
cp -r ~/nix-config /mnt/persistent/home/ryan/nix-config
# sync the disk, unmount the partitions, and close the encrypted device # sync the disk, unmount the partitions, and close the encrypted device
sync sync
@@ -319,7 +321,6 @@ decrypt them automatically on the new host when I deploy my NixOS configuration.
After all these steps, we can finally deploy the main flake's NixOS configuration by: After all these steps, we can finally deploy the main flake's NixOS configuration by:
```bash ```bash
sudo mv /etc/nixos ~/nix-config
sudo chown -R ryan:ryan ~/nix-config sudo chown -R ryan:ryan ~/nix-config
cd ~/nix-config cd ~/nix-config
+3 -2
View File
@@ -48,9 +48,9 @@ them. Others name specific hosts — or a name prefix, like `k3s-api-endpoint`,
`k3s-test-1-*` configuration — and only cover a new host if you add it. `k3s-test-1-*` configuration — and only cover a new host if you add it.
| Kind | Tests | | Kind | Tests |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Every configuration | `hostname`, `kernel`, `nix-system-features`, `security-apparmor`, `security-container-groups`, `security-exporters`, `security-firewall`, `security-k3s-kubeconfig`, `security-k3s-pod-firewall`, `security-kernel`, `security-ssh-x11` | | Every configuration | `hostname`, `kernel`, `nix-system-features`, `security-apparmor`, `security-container-groups`, `security-exporters`, `security-firewall`, `security-k3s-kubeconfig`, `security-k3s-pod-firewall`, `security-kernel`, `security-ssh-x11` |
| Named hosts only | `btrbk`, `cpu-power`, `home-manager`, `home-manager-xdg`, `computer-use-headless`, `k3s-api-endpoint`, `k3s-node-home-manager`, `idols-ai-gpu`, `idols-ai-net`, `idols-ai-voice-input`, `idols-aquamarine`, `security-postgres-auth`, `youko-metrics`, `ups-metrics`, `shoukei-logind` | | Named hosts only | `btrbk`, `cpu-power`, `home-manager`, `home-manager-xdg`, `computer-use-headless`, `k3s-api-endpoint`, `k3s-node-home-manager`, `idols-ai-gpu`, `idols-ai-net`, `idols-ai-voice-input`, `idols-aquamarine`, `security-postgres-auth`, `youko-metrics`, `ups-metrics`, `shoukei-logind`, `mihomo-dns`, `vm-host-power`, `colmena-parity` |
`hostname` expects each configuration's `networking.hostName` to equal its name. Niri desktop `hostname` expects each configuration's `networking.hostName` to equal its name. Niri desktop
configurations are the exception (`ai-niri` → `ai`, `shoukei-niri` → `shoukei`) and are listed in configurations are the exception (`ai-niri` → `ai`, `shoukei-niri` → `shoukei`) and are listed in
@@ -107,6 +107,7 @@ All the outputs of this flake are defined here.
│ ├── 12kingdoms-shushou.nix │ ├── 12kingdoms-shushou.nix
│ ├── 12kingdoms-youko.nix │ ├── 12kingdoms-youko.nix
│ ├── idols-ai.nix │ ├── idols-ai.nix
│ ├── idols-aquamarine.nix
│ ├── idols-kana.nix │ ├── idols-kana.nix
│ ├── idols-ruby.nix │ ├── idols-ruby.nix
│ ├── k3s-test-1-master-1.nix │ ├── k3s-test-1-master-1.nix
+1 -1
View File
@@ -6,7 +6,7 @@
# HOME_SSID: the script refuses to run unless the current Wi-Fi network is that # HOME_SSID: the script refuses to run unless the current Wi-Fi network is that
# exact SSID, so it can never pin the wrong network by accident. Every other # exact SSID, so it can never pin the wrong network by accident. Every other
# network keeps using DHCP. The change is stored in the profile under # network keeps using DHCP. The change is stored in the profile under
# /etc/NetworkManager/system-connections (preserved by impermanence), so it # /etc/NetworkManager/system-connections (preserved by preservation), so it
# survives reboots and rebuilds -- no need to run it again. # survives reboots and rebuilds -- no need to run it again.
# #
# just shoukei-home-wifi # just shoukei-home-wifi
+2 -2
View File
@@ -268,8 +268,8 @@ in
mode = "0400"; mode = "0400";
owner = "root"; owner = "root";
}; };
# restic repository password (used by modules.restic-backup). Gated # restic repository password (used by modules.restic-backup): declared in
# separately below so desktops get it without enabling a server group. # the blocks above, so desktops get their own without a server group.
}; };
# place secrets in /etc/ # place secrets in /etc/
+6 -1
View File
@@ -21,15 +21,20 @@ Contains user information, SSH keys, and password configuration:
- Initial hashed password for new installations - Initial hashed password for new installations
- SSH authorized keys (main and backup sets) - SSH authorized keys (main and backup sets)
- Public key references for system access - Public key references for system access
- Remote-builder client host keys (`remoteBuilderClientKeys`) that may build through aquamarine
### 2. `networking.nix` ### 2. `networking.nix`
Defines: Defines:
- **Gateway settings**: Main router and proxy gateway configurations - **Gateway settings**: Main router and proxy gateway configurations
- **Home LAN** (`lanCidr`): the trusted LAN prefix the shared host firewall trusts by source
- **Cluster addressing**: `clusterULA6`, the IPv6 ULA prefix for MicroVM guest addresses, and
`k8sVip`, each k3s cluster's kube-vip API and LoadBalancer VIP block
- **DNS servers**: IPv4 and IPv6 name servers - **DNS servers**: IPv4 and IPv6 name servers
- **Host inventory**: static LAN hosts and their interfaces; DHCP/mobile hosts (such as the macOS - **Host inventory**: static LAN hosts and their interfaces; DHCP/mobile hosts (such as the macOS
hosts) are omitted by design hosts) are omitted by design. `homeOnly = true` marks an address that exists only at home; SSH
aliases and monitoring skip it
- **SSH configuration**: Host aliases and known hosts configuration - **SSH configuration**: Host aliases and known hosts configuration
- **Network topology**: Physical machines, VMs, Kubernetes clusters, and SBCs - **Network topology**: Physical machines, VMs, Kubernetes clusters, and SBCs