Files
chiasson-nix/docs/conventions.md
T

5.4 KiB

Conventions

How the flake is wired

flake.nix runs import-tree on ./modules with a few extra filters: skip /package/, /packages/, and dms/home-manager/ (callPackage noise + DMS HM colocation). Don't add a global /home-manager/ filter — modules/ssh/home-manager/ needs to load.

Every scanned .nix should be a flake fragment:

{ self, inputs, ... }: {
  flake.nixosModules.systemFoo = { config, lib, pkgs, ... }: { /* … */ };
}

Don't define the same flake.nixosModules.foo in two files — merge order isn't something to bet on.

Outputs I actually use: nixosConfigurations.*, nixosModules.*, homeManagerModules.*, lib.*, packages.*, navi / naviHive. modules/parts.nix declares supported systems and the flake.lib / flake.homeManagerModules option slots.

Option namespaces

Project options live under chiasson.* only:

Prefix For
chiasson.system.* Machine policy — docker, flatpak, audio, gaming, deploy builder, …
chiasson.desktop.* GUI — compositors, DMS, wallpapers, display manager
chiasson.home.* Home Manager toggles (module exports are still wisdom*)
chiasson.users.* Catalog, enabled, hostOverrides, extraModules
chiasson.ssh.* SSH inventory

Leave upstream services.*, networking.*, home.*, etc. alone.

Module shape

NixOS leaf — camelCase export, usually prefixed (systemDocker, desktopNiri):

{ ... }: {
  flake.nixosModules.systemSomething = { config, lib, pkgs, ... }:
  let cfg = config.chiasson.system.something;
  in {
    options.chiasson.system.something.enable = lib.mkEnableOption "…";
    config = lib.mkIf cfg.enable { /* … */ };
  };
}

Aggregates: nixosModules.system and nixosModules.desktop import their leaves. Host configs import those stacks and set options — they shouldn't reimplement whole subsystems.

Home — files under modules/wisdom/. Baseline is homeManagerModules.wisdom (chiasson.home.enable). Everything else is separate exports (wisdomBrowsersZen, …); enable on a host via chiasson.users.extraModules.<user> and the matching chiasson.home.*.enable.

User apps / dotfiles → wisdom. Daemons, firewall, kernel → NixOS. Sometimes both (LocalSend: HM installs, systemLocalsend opens the firewall).

Odd exports

  • "client-services" — shared setup for laptops/tablets/desktops (not the VMs). Turns on Bluetooth, lets Navi log in as builder to update the machine, enables printing and mounting USB drives, and sets SSH to password. Used on t2mbp, 14900k, ideapad, uConsole. Skipped on nix-server and r5500.
  • systemUconsoleKernelBuilder — cross-build the uConsole kernel on x86_64, not for running on the Pi.
  • systemFlatpak — allowlist sync; skips heavy flatpak update when lists unchanged (runHeavyMaintenanceEverySwitch).

Desktop notes

  • chiasson.desktop.displayManager.variant: sddm vs dankgreeter (DMS + Hyprland/Niri tends toward DankGreeter).
  • desktopWallpapers copies inputs.wallpapers into the store; override chiasson.desktop.wallpapers.source if needed.

Users

User definitions live in usersCatalogDefaults (modules/system/users/catalog-default.nix) — olivier, server, builder, etc. Pick who exists on a host with chiasson.users.enabled.

Passwords aren't in the repo. They're in secrets/secrets.yaml (encrypted with sops). Each host that has olivier must declare that secret and set neededForUsers = true; sops-nix decrypts it at boot, and the catalog points hashedPasswordFile at that file. That's why the catalog is a proper module instead of a static list — it needs config.sops.secrets.… at eval time.

On a host:

chiasson.users.enabled = [ "olivier" ];
chiasson.users.hostOverrides.<name> = { /* optional */ };
chiasson.users.extraModules.olivier = [
  self.homeManagerModules.wisdomTerminalsKitty
  # …
];

usersHomeIntegration turns that into users.users + HM. Don't hand-roll catalog users unless you're changing the users module itself.

SSH: sshInbound on NixOS, outbound/rbw under modules/ssh/home-manager/.

Adding things

New NixOS leaf: export flake.nixosModules.whatever, wire from system/default.nix or desktop/default.nix if it's global, or only from a host configuration.nix if it's not. nix flake check. Git-add new paths if eval uses the git tree.

New HM slice: export flake.homeManagerModules.wisdomFoo, add the file to imports in modules/wisdom/default.nix, then wire extraModules + options on hosts that need it.

Derivations: let inside a fragment, or flake.packages / flake.lib — not a bare mkDerivation file import-tree will try to load.

New host: hosts/<name>/default.nix with nixosSystem, configuration.nix exporting *Configuration, hardware + _private/ as needed, register in modules/deploy/navi.nix if it should be in the fleet.

When editing

  • nix flake check after touching modules/.
  • Stage/commit new files if the flake is read from git.
  • Small diffs; mkEnableOption + mkIf for toggles.
  • Cross-module deps: assertions or mkDefault, mention it in the option description.
  • New flake inputs in flake.nix with follows where versions should track nixpkgs.
  • client-services SSH defaults are for my LAN — don't copy to anything internet-facing without tightening.
  • If I'll forget the behavior in six months, update these docs in the same change.