# 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:

```nix
{ 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`):

```nix
{ ... }: {
  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`, wired via `chiasson.desktop.homeManager.bundleWisdom`). Other `wisdom*` slices auto-wire once per user via `lib.wisdomCatalogExtraModules self` (`modules/lib/wisdom-catalog.nix`); hosts only set matching `chiasson.home.*.enable` toggles — no re-import in `home.nix`.

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:

```nix
# configuration.nix — machine policy
chiasson.users.enabled = [ "olivier" ];
chiasson.users.hostOverrides.<name> = { /* optional */ };
```

Desktop hosts also have `home.nix` exporting `flake.nixosModules.<host>Home`, wired from `default.nix` alongside `*Configuration`:

```nix
# default.nix
modules = [
  self.nixosModules."14900kConfiguration"
  self.nixosModules."14900kHome"
];

# home.nix — flake fragment, per-host `chiasson.home.*` toggles
{ self, inputs, ... }: {
  flake.nixosModules."14900kHome" = { self, pkgs, ... }: {
    imports = [ self.nixosModules.desktopHomeBase ];
    chiasson.users.extraModules.olivier = [
      {
        chiasson.home.browsers.edge.enable = true;
        # …
      }
    ];
  };
}
```

`flake.nixosModules.desktopHomeBase` expands `lib.wisdomCatalogExtraModules` plus shared desktop toggles. Host `*Home` modules append per-host `chiasson.home` overrides (and rare inline `home.packages` blocks). `chiasson.users.extraModules` concatenates lists from multiple modules (base + host), so both can set the same user key.

`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:** add `modules/wisdom/.../foo.nix` exporting `flake.homeManagerModules.wisdomFoo` (import-tree picks it up; `wisdomCatalogExtraModules` includes every `wisdom*` export except `wisdom` / `wisdomShellBash`). Gate packages on `chiasson.home.*.enable`, set `mkDefault true` in `desktop-home-base.nix` if shared, or `enable = true` in a host `home.nix`. Upstream HM deps stay imported unconditionally — use `mkIf` on `cfg.enable` for config (never `config`-dependent `imports`; that recurses).

**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` listing `*Configuration` (+ `*Home` for desktops), `configuration.nix` exporting `*Configuration`, hardware + `_private/` as needed. Desktop/laptop hosts also get `home.nix` exporting `*Home` (import `self.nixosModules.desktopHomeBase` unless it's a special case). 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.
