5.7 KiB
Repository Guidelines
Project Structure & Module Organization
This repository is a simplified flake-parts NixOS flake. flake.nix imports ./modules through import-tree, so normal .nix files under modules/ are loaded automatically unless their file or directory name starts with _.
modules/flake-parts.nixdefines theflake-partssetup, formatter, and the exportednixosConfigurations.modules/hosts/<name>/default.nixdefines one top-levelflake.modules.nixos.<host>module and assembles that machine by importing reusable features, user modules, and host-local helpers.modules/hosts/<name>/_*.nixare private host-local helper modules such as hardware and disk layout files.modules/users/<name>.nixdefines one reusable NixOS user module and the baseline Home Manager imports for that account.modules/features/*.nixcontains reusable NixOS and Home Manager feature modules.modules/features/<feature>/default.nixis used when a feature needs private helper files, for exampleniri/_bindings.nix.modules/features/services/*.nixcontains reusable service-oriented NixOS modules.modules/secrets/sops.nixwiressops-nixfor both NixOS and Home Manager.modules/secrets/secrets.yamlstores encrypted secrets, with.sops.yamldefining SOPS creation rules.modules/_treefmt.nixconfigures repository formatting.
Keep host files thin. Shared behavior belongs in modules/features/ or modules/users/. Host files should mainly compose imports and hold host-only settings such as monitor layouts, hardware quirks, boot tweaks, and machine-local firewall or service choices.
Mental Model
This repo is direct module composition around flake.modules, not the old inventory-driven dendritic design.
- Reusable building blocks are exposed as
flake.modules.nixos.<name>andflake.modules.homeManager.<name>. - Host modules are the composition root. They import the reusable NixOS modules they need, enable Home Manager, and add any host-specific Home Manager imports inline.
- User modules define the Unix user plus that account’s baseline Home Manager setup.
- There is no
config.repo, inventory schema, profiles layer, or attachment builder anymore.
In practice:
- Prefer importing a feature module directly over inventing a repo-local option just to toggle it.
- Put cross-host reusable behavior in
modules/features/. - Put account-specific defaults in
modules/users/. - Keep private helper files
_-prefixed soimport-treedoes not expose them as top-level modules. - Match the existing split between NixOS composition in host modules and Home Manager composition in user or host modules.
Current Host Composition
There are three exported hosts:
orion: server-oriented host withkiri, SOPS, and service modules such as Caddy, Gitea, Vaultwarden, Radicale, Actual, and OpenSSH.polaris: graphical desktop host withkiriandergon, hardware imports, Niri, Steam, local desktop features, and host-specific monitor layout.zenith: graphical laptop host withkiriandergon, Niri, laptop hardware support, firmware updates, and host-specific monitor layout.
When adjusting user-facing software, check whether it belongs in:
- a user baseline in
modules/users/<name>.nix - a reusable Home Manager feature in
modules/features/*.nix - a host-local extension inside
modules/hosts/<name>/default.nix
Be careful not to move host-specific Home Manager imports into a user baseline unless that behavior should apply on every host that imports that user module.
Validation And Development Commands
Run commands from the repository root.
nix build --no-link --show-trace .#nixosConfigurations.<host>.config.system.build.toplevel: baseline validation for one host.nix build --no-link --show-trace .#nixosConfigurations.orion.config.system.build.toplevel .#nixosConfigurations.polaris.config.system.build.toplevel .#nixosConfigurations.zenith.config.system.build.toplevel: validate all defined hosts in one invocation.nixos-rebuild build --flake .#<host>: use when you specifically wantnixos-rebuildsemantics without activation.nix eval --json .#nixosConfigurations.<host>.config.<option>: inspect a single evaluated option while iterating.nix fmt: format the repository using the flake-provided formatter frommodules/_treefmt.nix.nix store diff-closures <old> <new>: compare built system closures when reviewing refactors for parity or regressions.
This repo does not define a first-party checks output. Validation is primarily host builds plus targeted nix eval checks.
Coding Style & Naming Conventions
Use two-space indentation and standard Nix attrset formatting. Prefer small let bindings, lowerCamelCase local names, and lowercase file names.
- Define reusable modules as
flake.modules.nixos.<name>orflake.modules.homeManager.<name>. - Keep one obvious feature per file or directory.
- Use
default.nixonly when the feature needs private helper files alongside it. - Match surrounding style instead of reformatting unrelated code.
- Prefer explicit host imports over hidden indirection.
Commit
Follow the existing history style: short imperative subjects, optionally with a conventional prefix, for example refactor: simplify host composition.
Security & Configuration Tips
Never commit plaintext secrets. Add or update secrets through modules/secrets/secrets.yaml and reference them via config.sops.secrets.<name>.path.
Be explicit and cautious with changes to:
- firewall and OpenSSH settings
- disk layout and boot configuration
- SOPS key handling and admin user access
- firmware, hardware, and authentication settings
- host-vs-user module boundaries, because it is easy to accidentally broaden behavior to the wrong machines