`.chezmoiignore.tmpl` skips the Linux desktop layer unless the machine runs Linux **and** its role is `desktop` or `laptop`. The gated targets are `~/.config/niri`, `~/.config/hypr`, `~/.config/umbriel`, `~/.config/uwsm`, `~/.config/noctalia`, `~/.config/vicinae`, `~/.config/niri-dynamic-workspaces`, `~/.config/fontconfig`, `~/.config/mimeapps.list`, `~/.config/xdg-terminals.list`, `~/.config/systemd`, `~/.local/bin/kitty-day-save`, `~/.local/bin/niri-launch`, `~/.local/bin/umbriel-launch`, `~/.local/bin/umbriel-smart-move`, `~/.local/bin/umbriel-float-square`, `~/.local/bin/cp-appid`, `~/.local/bin/projects-sync`, and `~/.config/fish/auto-Niri.fish`. On `mac` and `server` roles these are not applied.
`~/.config/waybar`, the `omarchy-*` scripts, the `niri-launch-ai` / `-browser` / `-terminal` / `-webapp` wrappers, and `~/.local/bin/tmux-niri-title` are **not** listed there, so chezmoi applies them on every role and OS. Only the exact path `.local/bin/niri-launch` is ignored, not the wrappers that call it.
Three Wayland compositors are configured side by side. niri is the original setup, paired with the Noctalia shell. Umbriel, Noctalia's own scrolling compositor, ports the niri config and adds Hyprland's per-app scratchpads, with Noctalia as the only session process. Hyprland runs on top of [Omarchy](https://omarchy.org), and its bindings are ported from the niri config: the same keys launch the same apps where both compositors support it. Waybar is the Hyprland bar. Noctalia replaces it under niri and Umbriel.
| [niri](/desktop/niri) | `~/.config/niri` (base config, Noctalia colors, the `config.d/` fragments, per-display profiles), niri helper scripts, the `niri-launch*` launchers, `cp-appid`, the `nirinit` user service |
| [Hyprland](/desktop/hyprland) | `~/.config/hypr` Lua config on Omarchy: bindings, input, look and feel, monitors, hyprsunset, the portal; every `omarchy-*` script in `~/.local/bin`. `~/.config/omarchy` (shell, hooks, menus, themes) is the [prdlk/omarchy](https://github.com/prdlk/omarchy) external, see [externals](/chezmoi/externals-and-ignore#app-externals) |
| [Waybar](/desktop/waybar) | `~/.config/waybar`: module layout, stylesheet, the `window_pill.py` title module |
| [Fonts and default apps](/desktop/fonts-and-apps) | `~/.config/fontconfig/fonts.conf`, `~/.config/mimeapps.list`, the Victor Mono Nerd Font packages |
`.chezmoidata/packages.yaml` declares the desktop packages under `packages.arch.desktop`. `.chezmoiscripts/run_onchange_before_10-packages.sh.tmpl` installs them only when the role is `desktop` or `laptop`:
| AUR via `yay`/`paru` (a sync repo wins when it has the name) | `vicinae-bin`, `tldraw-offline-bin`, `bibata-cursor-translucent`, `umbriel-git` (with `xdg-desktop-portal-umbriel-git`), and the desktop apps `beeper-bin`, `fastmail`, `1password`, `brave-origin-bin`, `claude-desktop`, `spotify` |
AUR names that an installed package already provides are skipped; with no `yay` or `paru` the script bootstraps `yay` first. strata, the default file manager, comes from its own installer in [15-tools](/chezmoi/scripts#15-tools). Hyprland, Waybar, and the `omarchy-*` commands that the scripts call (`omarchy-menu`, `omarchy-launch-or-focus`, and others) come from an Omarchy install. This repo does not install them. See [chezmoi scripts](/chezmoi/scripts) for the full install flow and [packages.yaml](/chezmoi/data#packagesyaml) for the complete lists.
The RTX 5060 Ti in a USB4 enclosure (Minisforum `TBGAA`, bolt policy `iommu`) is for CUDA only: AI models, never displays or rendering. Every display hangs off the Radeon 8060S iGPU (PCI `c4:00.0`). Packages: `linux-cachyos-nvidia-open`, `nvidia-utils`, `cuda`, `opencl-nvidia`. Nothing in this section is managed by chezmoi except the session environment.
| `/etc/default/limine` | no `pci=nommconf`, no `pcie_aspm=off`; `pcie_aspm.policy=performance` instead | The first two make Linux skip the PCIe `_OSC` control request (`not requesting OS control; OS requires [ExtendedConfig ASPM …]`). Then `pciehp` never binds the USB4 bridges `00:01.1`/`00:01.2`, and the enclosure authorizes while the GPU never shows up in `lspci`. `pcie_aspm.policy=performance` disables ASPM without that side effect. Run `limine-update` after editing. |
| `/etc/modprobe.d/nvidia-egpu.conf` | `install nvidia_drm /bin/true`, `install nvidia_modeset /bin/true`, `NVreg_DynamicPowerManagement=0x00`, `NVreg_PreserveVideoMemoryAllocations=0` | Without `nvidia_drm` there is no `/dev/dri` node for the eGPU, so no compositor, GBM, or VA-API driver can open it. CUDA needs only `nvidia` and `nvidia_uvm`. `nvidia-suspend.service` is not enabled, and with `PreserveVideoMemoryAllocations=1` suspend fails while the eGPU is bound. |
| `/etc/modprobe.d/thunderbolt-egpu.conf` | `options thunderbolt host_reset=0 clx=0` | `host_reset=0` keeps the firmware-built PCIe tunnel at boot; with the default reset the tunnel drops while `nvidia` initialises the card (Xid 79, GPU stuck until reboot). `clx=0` keeps the USB4 lanes out of CL1/CL2 low-power states. |
| `/etc/systemd/system/nvidia-egpu-powercap.service`, `/etc/udev/rules.d/62-nvidia-egpu-powercap.rules` | `nvidia-smi -pm 1 -pl 150 -lgc 210,1800` when the `nvidia` module loads | Caps the card at 150 W / 1800 MHz before anything can load it. |
| `/etc/udev/rules.d/61-nvidia-compute.rules` | `nvidia-modprobe -c0 -u` when the `nvidia` module loads | `nvidia-utils`' own rule creates `/dev/nvidia*` when `nvidia_drm` loads, and that module never loads here. |
| no `/etc/modules-load.d` entry | none | udev loads `nvidia` by modalias when the GPU reaches the bus, at boot or on hotplug. |
`nouveau` is blacklisted by `nvidia-utils` (`/usr/lib/modprobe.d/nvidia-utils.conf`). Without that blacklist, nouveau binds the card, the NVIDIA driver reports `GPU … is already bound to nouveau`, and a link drop deadlocks `pciehp` in nouveau's GSP teardown.
Session side: `conf.d/10-env.fish` sets `__EGL_VENDOR_LIBRARY_FILENAMES` (Mesa) and `VK_DRIVER_FILES` (RADV), see [fish](/shell/fish#10-envfish). niri and Umbriel both start through a fish login shell, so the compositor, Noctalia, and every app inherit them. Without them, glvnd and the Vulkan loader load the NVIDIA vendor libraries into every process, and those processes hold `/dev/nvidiactl`. Hyprland gets the same pins from `~/.config/uwsm/env-hyprland`, see [Hyprland](/desktop/hyprland#monitors).
Never expose `nvidia_icd.json` to LM Studio. When its engine survey reaches the eGPU through NVIDIA's Vulkan driver, the card falls off the bus (`Xid 79`) and the machine hard-resets. The survey runs when the app starts and when the `llmster` daemon starts, and any `lms` command starts that daemon.
Check: `nvidia-smi` lists the card, and `fuser -v /dev/nvidia*` shows only CUDA processes. A short CUDA kernel (vector add) runs correctly.
### Status: unusable under load on the Flow Z13 (GZ302EA, BIOS 311)
The moment a model starts inference on the eGPU, the platform hard-resets with `x86/amd: Previous system reset reason [0x08000800]: an uncorrected error caused a data fabric sync flood event`, no Xid, no log tail. Firmware grants no AER/DPC to the OS, so a tunnel fault under load becomes a full reset. Everything above was tested one variable at a time on 2026-10-17 and none of it changed the outcome: CUDA or Vulkan engine, model size (27B and 12B), both USB4 ports, dock wiring per the DEG2 manual on a 650 W PSU, ASPM off, `clx=0`, 150 W power cap, KMS loaded or not, and the previous OS install with stock NVIDIA config. The same models run fine on the iGPU with the dock unplugged, so the fault is the Z13's USB4 PCIe path under GPU load, not the SoC alone. Other GZ302EA owners report the same reset code under sustained load ([Level1Techs](https://forum.level1techs.com/t/strix-halo-hard-power-off-under-sustained-inference-load-rog-flow-z13-gz302ea-instrumented-root-cause-hunt-ec-cooling-gated-power-cut-a-data-fabric-sync-flood-can-framework-desktop-other-strix-halo-owners-try-to-repro/252607)) and eGPU trouble on this platform ([ROG forum](https://rog-forum.asus.com/t5/rog-flow-series/gz302ea-bios-311-tb4-egpu-permanently-fails-on-linux-after/td-p/1146714)). Untested: a shorter certified 40 Gbps cable, the same dock and card on another host, Windows. LLM work runs on the 8060S (Vulkan/ROCm, unified memory) until one of those changes the picture.