1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# enzo — laptop. Gets the shared common/ base plus laptop-only settings.
{ inputs, pkgs, ... }:
{
imports = [
# Shared desktop base + enzo-only extras. Add ../../profiles/dev.nix or
# apps.nix here, or one-off packages below, as needed.
../../profiles/desktop.nix
../../profiles/dev.nix
../../profiles/sandbox.nix
./desktop.nix
inputs.disko.nixosModules.disko
./disko.nix
./hardware-configuration.nix
];
networking.hostName = "enzo";
lanDiscovery.interface = "wlp1s0";
# Set this to the NixOS release the laptop is first installed from, then
# leave it. (See the comment in machines/kusanagi/default.nix.)
system.stateVersion = "26.05";
# --- User account (hwebs) ---
# (Desktop groups audio/input come from ./desktop.nix.)
users.users.hwebs = {
isNormalUser = true;
description = "Henry J. Webster";
# (ikai — the sandbox group — is added by profiles/sandbox.nix.)
extraGroups = [
"networkmanager"
"wheel"
];
packages = with pkgs; [
git
tmux
neovim
# TODO figure out
#ripgrep
wl-clipboard
bc
psmisc
usbutils
stow
];
};
# --- Sandbox account (yokai) ---
# The yokai user, ikai group, /srv/git drop dir, and the sudo de-escalation
# rule all live in profiles/sandbox.nix (imported above); that file also
# documents the local-clones workflow. Only the owner name is per-machine:
sandbox.owner = "hwebs";
nix.settings.trusted-users = [
"root"
"hwebs"
];
# Wifi is managed from the CLI (nmcli/nmtui); trim the rest.
networking.modemmanager.enable = false; # no cellular modem
# NOTE: iwd backend was tried but caused interface rename (wlp8s0 -> wlan0),
# stale-profile and secret-passing breakage. Back on the default wpa_supplicant.
# networking.networkmanager.wifi.backend = "iwd"; # auto-enables iwd, drops wpa_supplicant
# --- Disk encryption / hibernation / swap ---
# systemd in initrd is required for TPM2 unlock and clean hibernate resume.
boot.initrd.systemd.enable = true;
# TPM2 auto-unlock. Enroll the key WITH A PIN post-install:
# sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 \
# --tpm2-with-pin=yes /dev/nvme0n1p2
# The original LUKS passphrase stays as a fallback keyslot. disko already
# declares boot.initrd.luks.devices."crypted".device.
boot.initrd.luks.devices."crypted".crypttabExtraOpts = [ "tpm2-device=auto" ];
# zram for everyday paging; the encrypted LVM swap from disko.nix is the
# hibernation target (boot.resumeDevice comes from disko's resumeDevice=true).
zramSwap.enable = true;
# Suspend-to-RAM on lid close, auto-hibernate after a delay so a dying battery
# doesn't lose the session. Everyday resume needs only the login password; the
# LUKS PIN appears only on cold boot / hibernate resume.
services.logind.settings.Login.HandleLidSwitch = "suspend-then-hibernate";
systemd.sleep.settings.Sleep.HibernateDelaySec = "60min";
# Idle trigger. Bare niri has no power daemon watching for inactivity, so with
# the lid open the box never sleeps on its own. swayidle (a Wayland idle
# client) fires the same suspend-then-hibernate after 15 min of no input. niri
# binds it to graphical-session.target and exports WAYLAND_DISPLAY to the user
# manager, so this Just Works in the session. `-w` waits for the resume to
# finish before re-arming the timer.
systemd.user.services.swayidle = {
description = "Suspend-then-hibernate after idle";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.swayidle}/bin/swayidle -w timeout 900 'systemctl suspend-then-hibernate'";
Restart = "on-failure";
};
};
# btrfs + SSD upkeep.
services.btrfs.autoScrub.enable = true;
services.fstrim.enable = true;
# --- Laptop power management ---
# power-profiles-daemon integrates with GNOME's power settings. If you prefer
# finer-grained control, disable this and enable services.tlp instead.
services.power-profiles-daemon.enable = true;
powerManagement.enable = true;
# Backlight control from the CLI / keybinds (programs.light was removed from
# nixpkgs; acpilight provides the udev rules and brightnessctl the CLI).
hardware.acpilight.enable = true;
environment.systemPackages = [ pkgs.brightnessctl ];
# --- GPU (AMD integrated) ---
# Load amdgpu in the initrd (early KMS) so the native mode is set before the
# console font is applied. Otherwise amdgpu loads late, resets the fbcon to
# the kernel's 8x16 font, and the greeter shows the wrong (tiny) font while
# the Terminus font only survives in the pre-driver LUKS prompt.
# (Merges with the dm-snapshot entry in hardware-configuration.nix. If the
# driver check shows `radeon` instead of `amdgpu`, swap the name.)
boot.initrd.kernelModules = [ "amdgpu" ];
}
|