AGENTS.md: init

This commit is contained in:
2026-03-21 19:43:35 -04:00
parent b5c7b15af3
commit e53e6f16d0

166
AGENTS.md Normal file
View File

@@ -0,0 +1,166 @@
# AGENTS.md
## Project Overview
NixOS dotfiles for two hosts using Nix flakes + home-manager:
- **mreow** — Framework 13 AMD AI 300 laptop, niri WM, greetd, swaylock
- **yarn** — Desktop, Jovian-NixOS (Steam deck mode), impermanence, sddm, deploy-rs target
Secrets in `system/secrets/` and `home-manager/secrets/` are encrypted with git-crypt. **Never read or write files in those directories.**
## Build & Deploy Commands
```sh
# Build and apply (default: boot, or pass switch/test/build)
./deploy.sh # nixos-rebuild boot --flake . --use-remote-sudo
./deploy.sh switch # apply immediately
./deploy.sh test # apply without adding boot entry
./deploy.sh build # build only, no activation
# Build a specific host without deploying
nix build .#nixosConfigurations.mreow.config.system.build.toplevel -L
nix build .#nixosConfigurations.yarn.config.system.build.toplevel -L
# Remote deploy to yarn via deploy-rs
deploy .#yarn
# Format all Nix files (uses nixfmt-tree, declared in flake.nix)
nix fmt
# Evaluate without building (quick syntax/type check)
nix eval .#nixosConfigurations.mreow.config.system.build.toplevel --no-build 2>&1 | head -5
nix eval .#nixosConfigurations.yarn.config.system.build.toplevel --no-build 2>&1 | head -5
# Update flake inputs
nix flake update
nix flake update --input-name nixpkgs # update a single input
```
There are no tests. Validation is done by building the system configuration (`nix build -L`).
Always append `-L` to `nix build` for verbose build logs.
If nix complains a file isn't found, `git add` the file first — Nix flakes only see tracked files.
## Repository Structure
```
flake.nix # Root flake: inputs, outputs, host definitions
deploy.sh # Wrapper around nixos-rebuild
system/
common.nix # Shared system config (boot, audio, users, etc.)
system-mreow.nix # Laptop-specific system config
system-yarn.nix # Desktop-specific system config
networking.nix # NetworkManager, DNS
impermanence.nix # Ephemeral root for yarn
disk_mreow.nix / disk_yarn.nix # Disko disk layouts
vm.nix # Virtualization (libvirt, waydroid)
vr.nix / no-rgb.nix / steam.nix # Feature modules
secrets/ # git-crypt encrypted, DO NOT READ
home-manager/
home-mreow.nix # Laptop home-manager entry point
home-yarn.nix # Desktop home-manager entry point
gui.nix # GUI packages + theming (imports no-gui.nix)
no-gui.nix # CLI tools, dev toolchains, git config
desktop.nix # Desktop environment (niri, dunst, swaylock, noctalia)
wallpaper.png # Shared wallpaper
progs/ # One file per program
fish.nix, alacritty.nix, emacs.nix, helix.nix, niri.nix, ...
zen/ # Zen Browser (multi-file: default.nix, ublock.nix, dark-reader.nix)
opencode.nix # AI coding tools config
util/ # Helper derivations (blur.nix, inverse_color.nix)
secrets/ # git-crypt encrypted, DO NOT READ
```
## Import Hierarchy
```
flake.nix
├─ system/system-{host}.nix → common.nix → networking.nix, vm.nix, steam.nix
└─ home-manager/home-{host}.nix → gui.nix → no-gui.nix
→ desktop.nix → niri.nix, dunst.nix, swaylock.nix, noctalia.nix
```
Adding a new program: create `home-manager/progs/myprog.nix`, import it from the appropriate layer (`gui.nix` for GUI apps, `no-gui.nix` for CLI tools, or `home-{host}.nix` for host-specific).
## Nix Code Style
**Formatter**: `nixfmt-tree` — run `nix fmt` before committing. All style below conforms to what nixfmt-tree produces.
### Module Structure
```nix
# Function arguments: destructured attrset, alphabetical-ish, always end with `...`
{ pkgs, lib, inputs, config, ... }:
# Optional let bindings for local values
let
myThing = "value";
in
{
imports = [
./other-module.nix
];
# Configuration here
}
```
### Conventions
- **Indentation**: 2 spaces (enforced by nixfmt-tree)
- **Imports**: relative paths (`./progs/fish.nix`), one per line in a list
- **Package references**: use `lib.getExe pkgs.foo` for bin paths, not `${pkgs.foo}/bin/foo`
- **Package lists**: group thematically with comments, use `with pkgs;` or `lib.concatLists` for multiple groups
- **Unfree packages**: explicitly allowlisted per-file via `nixpkgs.config.allowUnfreePredicate`
- **Comments**: lowercase, informal, `#` style. Use `# BUG!` or `# TODO!` prefixes for known issues
- **No trailing commas**: Nix syntax does not support them
- **Attribute sets**: opening brace on same line, closing brace aligned with the key
- **Overlays**: imported inline within the module that needs them via `nixpkgs.overlays`
- **Special args**: passed through `specialArgs` (system) or `extraSpecialArgs` (home-manager) in flake.nix — includes `inputs`, `username`, `hostname`, `niri-package`, `homeDirectory`, `stateVersion`
### Patterns Used
```nix
# Package path references
lib.getExe pkgs.swaylock # preferred
"${pkgs.avizo}/bin/volumectl" # acceptable when lib.getExe doesn't work
# Conditional/host-specific overrides
lib.mkForce false # override inherited values
lib.mkDefault "value" # set overridable defaults
# Helper derivations (see home-manager/util/)
pkgs.callPackage ../util/blur.nix # for derivations that take { stdenv, ... }:
# Combining package lists
home.packages = with pkgs; lib.concatLists [
[ pkg1 pkg2 ] # group 1
[ pkg3 pkg4 ] # group 2
someList # from let binding
];
```
### Naming
- **Host configs**: `system-{hostname}.nix`, `home-{hostname}.nix`, `disk_{hostname}.nix`
- **Program modules**: `progs/{program-name}.nix` (one program per file)
- **Utility derivations**: `util/{descriptive-name}.nix`
- **Variables**: `snake_case` or `camelCase` (no strict rule, follow local context)
## Key Technical Details
- **nixpkgs channel**: unstable (`nixos-unstable`)
- **Secure boot**: lanzaboote with keys extracted from `system/secrets/secureboot.tar`
- **Disk management**: disko
- **Privilege escalation**: doas (sudo is disabled), shim at `doas-sudo-shim`
- **Shell**: fish (bash redirects to fish via `programs.bash.interactiveShellInit`)
- **Wayland**: niri compositor, xwayland-satellite for X11 compat
- **Desktop shell**: noctalia-shell (bar, launcher, notifications)
- **Git**: GPG signing enabled (`signByDefault = true`), default branch `main`
- **Impermanence** (yarn only): root is ephemeral, `/persistent` holds state, home is bind-mounted
## Agent-Specific Instructions
- If instructed to commit, **disable GPG signing** (`git commit --no-gpg-sign`).
- Use `nix-shell -p <package>` if a tool is not available in the environment.
- For `nix build`, always append `-L` for verbose logs.
- If nix reports a missing file, run `git add <file>` first — flakes only see git-tracked files.
- Do not read files under `system/secrets/` or `home-manager/secrets/`.
- Run `nix fmt` after editing any `.nix` file.
- Validate changes with `nix build .#nixosConfigurations.{host}.config.system.build.toplevel -L`.