diff --git a/configs/nixos/AGENTS.md b/configs/nixos/AGENTS.md deleted file mode 100644 index 3e8450d..0000000 --- a/configs/nixos/AGENTS.md +++ /dev/null @@ -1,70 +0,0 @@ -# NixOS configuration instructions - -## Desktop - -- When adding a graphical application, register its workspace icon in `registry.window-icon`. - The workspace indicator uses this mapping to show an application icon instead of the generic default glyph. - Match the mapping on the window class. - Store the icon as the rendered string. - Run `hyprctl clients -j | jq -r '.[].class' | sort -u` to list classes in the running session. -- TODO: Verify this path after the NixOS configuration is migrated. - Set Hyprland session environment variables in `modules/desktop/session/hyprland/default.nix` with `env = KEY,VALUE`. - `home.sessionVariables` do **not** reach the Hyprland session because UWSM does not source `hm-session-vars.sh`. - Source cursor values from `config.stylix.cursor`. - Set `XCURSOR_*` and `HYPRCURSOR_*` to the same theme for Bibata. - -## Firefox - -- Manage Firefox search engines through `programs.firefox.search` with `force = true`. - Hide built-in engines with `.metaData.hidden = true` because omission does not remove them. - Use current engine ids, such as `default = "ddg"` instead of `"DuckDuckGo"`. - Decode the built `search.json.mozlz4` with `mozlz4a -d ` to check the result. -- Avoid Home Manager Firefox extension settings unless the whole profile can use the legacy extension-storage backend. - Any non-empty `profiles..extensions.settings..settings` sets `extensions.webextensions.ExtensionStorageIDB.enabled = false` for the whole profile. - -## Neovim - -- Nixvim's flake input follows the root nixpkgs source, but its Home Manager module does not reuse the host's `pkgs` instance. - Keep `programs.nixvim.nixpkgs.useGlobalPackages = true`. - That setting makes Nixvim use the shared package set without warning that its source default changed. - -## AI tooling - -- Use produced literals for Herdr key names that include shifted punctuation. - For example, use `prefix+<` instead of `prefix+shift+comma`. -- Put monorepo Pi extension sources in `.pi/extensions/`. - Pi discovers them from subdirectories through the local ancestor-resource patch. -- Treat Home Manager-managed Pi settings as generated output. - Do not edit them except for throwaway development or local experiments. - Promote finished settings into the NixOS configuration before treating them as deployed. - -## Gotchas - -- `configs/nixos/registry/stable-uid.nix` receives library functions through `lib`. - Qualify its library calls with `lib.`. -- Guest modules are host-agnostic wiring, while host files own deployment-specific service configuration such as served volumes and host paths. - For example, `guests/copyparty.nix` should expose options and translate them into guest mounts/service settings, while `hosts/pikachu/default.nix` chooses `/inbox`, `/media`, and their backing paths. - Guest addresses and routes are host-level configuration because a guest module can be used on multiple hosts. -- `sops.secrets..owner` must name a user known on the decrypting host. - Do not set the owner to a guest-only service user unless the host also declares that user. - Use a host-visible owner plus a shared group mode when the guest service can read the decrypted secret file through its group. -- A read-only guest bind mount cannot contain nested writable bind mounts unless their mount-point - directories already exist inside the read-only source. - For aggregate Copyparty volumes such as `/srv` with nested `/srv/inbox`, keep the guest bind mount - writable and enforce read-only behavior through Copyparty access plus service `ReadWritePaths`. -- `deploy-to` builds from the source checkout, records the imported closure as the target system profile, - and activates it. Do not rely on a target-local monorepo checkout for remote deployment. -- On Pikachu, `nix copy --to ssh://pikachu` accepted a small `nix store add-file` probe, - but rejected locally built system paths that lacked trusted signatures. - Use a sudo `nix-store --import` path for unsigned deploy closures. -- Public DNS entries are not managed through the NixOS configuration. - Do not describe NixOS route choices as public-DNS management. -- Do not hand-author `hardware-configuration.nix` for a host that has not been generated on that machine. - Generate it on the target system or live ISO, then stage it before evaluating the flake. -- Configure the Chaotic Nyx cache only on hosts that select `linuxPackages_cachyos` (currently Neogaia - and Zeus), not in the generic host module. -- Module-relative paths resolve from the module file. Update them when moving a module into a subdirectory. -- On Pikachu, `uptime` does not support `-s`. Use `who -b` to report the boot time. -- Evaluating a NixOS guest's inner `config.services.nginx` can force incomplete ACME values. - Evaluate the parent host's `config.system.build.toplevel` to validate an ACME-enabled guest. -- `pkgs.systemd` does not set `meta.mainProgram`. Use `lib.getExe' pkgs.systemd "systemctl"` instead of `lib.getExe pkgs.systemd`. diff --git a/configs/nixos/modules/desktop/apps/firefox.nix b/configs/nixos/modules/desktop/apps/firefox.nix index fafbf85..ebe660b 100644 --- a/configs/nixos/modules/desktop/apps/firefox.nix +++ b/configs/nixos/modules/desktop/apps/firefox.nix @@ -67,6 +67,8 @@ in # Stylix uses a near-white selection background. # Use the Nord selection color because its text stays readable. + # Home Manager writes extension settings through Firefox's legacy storage backend. + # Extension settings disable `ExtensionStorageIDB` for the whole profile. extensions.settings."FirefoxColor@mozilla.com".settings.theme.colors.popup_highlight = let c = hm.config.lib.stylix.colors; diff --git a/configs/nixos/modules/shell/nvim/default.nix b/configs/nixos/modules/shell/nvim/default.nix index 658a7d9..0208140 100644 --- a/configs/nixos/modules/shell/nvim/default.nix +++ b/configs/nixos/modules/shell/nvim/default.nix @@ -24,6 +24,9 @@ in home-manager.users.${user} = hm: { programs.nixvim = { enable = true; + + # Aligns Nixvim plugins with this flake's `Nixpkgs`. + # `nixpkgs.useGlobalPackages` prevents Home Manager from creating a separate package set. nixpkgs.useGlobalPackages = true; extraPackages = with pkgs; [ diff --git a/docs/00 INBOX/ai/nixos-agents-style-scope-design-tree.md b/docs/00 INBOX/ai/nixos-agents-style-scope-design-tree.md new file mode 100644 index 0000000..6c12919 --- /dev/null +++ b/docs/00 INBOX/ai/nixos-agents-style-scope-design-tree.md @@ -0,0 +1,130 @@ +# NixOS AGENTS and style-skill scope design tree + +This tree reviews `configs/nixos/AGENTS.md`. +It decides which instructions belong in Nix style rules. + +## Known facts + +- `configs/nixos/AGENTS.md` has 70 lines. +- Each frontier question quotes the complete instruction under review. +- This review decides instruction placement only. +- It supplies guidance for desktop, Firefox, Neovim, AI tooling, and NixOS gotchas. +- The `/review` prompt loads `nix-style` for Nix files. +- `nix-style` loads every rule under `src/skills/style/nix/rules/`. +- The current Nix rules cover Nix syntax and flake structure. +- `configs/nixos/AGENTS.md` includes a guest-module ownership rule. +- The RomM session missed that ownership rule during implementation. +- `registry.window-icon` exists in `configs/nixos/registry/window-icon.nix`. +- Desktop application modules declare window classes and rendered icons in that registry. +- Hyprland reads the registry to generate workspace icon mappings. +- The AGENTS instruction named the registry after its introduction on 2026-10-11. +- The `class` option describes its window-class match. +- The `icon` option describes a string icon value. +- The registry schema does not document the rendered-string requirement or the class-discovery command. +- Hyprland renders `config.registry.env` as its `env` configuration. +- The `env` registry replaced direct Hyprland environment declarations in commit `370cab8f8`. +- `configs/nixos/modules/desktop/apps/r2modman.nix` enables a graphical application without a `registry.window-icon` declaration. +- The current registry modules already validate value uniqueness and field combinations. +- They do not validate required producer declarations. +- The registry collector is specific to the NixOS dotfiles configuration. +- A non-discoverable environment fact records local behavior that configuration, source code, and normal tool help do not reveal. +- The current instruction groups are: + - Desktop: window icons, Hyprland environment variables, and cursor settings. + - Firefox: search-engine declarations and extension-storage compatibility. + - Neovim: Nixvim package-set selection. + - AI tooling: Herdr key names and Pi configuration locations. + - Gotchas: registry APIs, guest boundaries, SOPS ownership, guest mounts, deployment, DNS, hardware, module paths, and host commands. + +## Decision tree + +- Instruction review + - Settled: Review each complete instruction in source order. + - Registry conventions + - Settled: Create `src/skills/style/nix/rules/dotfiles.md`. + - Graphical application icon instruction + - Settled: Move the complete instruction to `src/skills/style/nix/rules/dotfiles.md`. + - Hyprland session environment instruction + - Settled: Remove it because `registry.env` superseded it. + - Firefox search-engine instruction + - Settled: Remove it because the Firefox module documents the configuration. + - Firefox extension-storage instruction + - Settled: Move it to a comment above `extensions.settings` in `modules/desktop/apps/firefox.nix`. + - Neovim package-set instruction + - Settled: Move it to a comment above `nixpkgs.useGlobalPackages` in `modules/shell/nvim/default.nix`. + - Herdr key-name instruction + - Settled: Remove it. + - Pi extension location instruction + - Settled: Remove it. It recorded a completed migration from NixOS-managed sources. + - Pi generated-settings instruction + - Settled: Remove it because the Pi module documents the managed boundary. + - Library-function qualification instruction + - Settled: Generalize it and move it to `src/skills/style/nix/rules/general.md`. + - Guest ownership instruction + - Settled: Move it to `src/skills/style/nix/rules/dotfiles.md`. + - SOPS guest-owner instruction + - Settled: Move it to `src/skills/style/nix/rules/dotfiles.md`. + - Nested guest-mount instruction + - Settled: Remove it because the example describes no active layout. + - `deploy-to` instruction + - Settled: Remove it. Agents cannot complete its remote sudo steps. + - Pikachu deploy-closure instruction + - Settled: Remove it because `deploy-to` encodes the required import path. + - Public-DNS instruction + - Settled: Remove it. + - Hardware-configuration instruction + - Settled: Remove it because the root auto-generated-file rule owns the policy. + - Chaotic-cache instruction + - Settled: Remove it because `modules.host.cachyos.enable` owns the cache configuration. + - Module-relative-path instruction + - Settled: Remove it because Nix evaluation reports invalid paths. + - Pikachu `uptime` instruction + - Settled: Remove it because the command exposes its supported options. + - Guest-ACME-evaluation instruction + - Settled: Remove it because current direct guest evaluation succeeds. + - systemd executable instruction + - Settled: Remove it because `general.md` already requires `lib.getExe'` for non-main executables. + +## Frontier + +The frontier is empty. + +## Shared understanding + +Remove these instructions from `configs/nixos/AGENTS.md`: + +- Hyprland session environment +- Firefox search engines +- Herdr shifted punctuation +- Pi extension source location +- Pi managed settings +- Nested guest mounts +- `deploy-to` behavior +- Pikachu deploy closures +- Public DNS boundary +- Hardware configuration +- Chaotic cache selection +- Module-relative paths +- Pikachu boot time +- Guest ACME evaluation +- systemd executable selection + +Move these instructions intact to `src/skills/style/nix/rules/dotfiles.md`: + +- Graphical application icons +- Guest ownership +- SOPS guest ownership + +Move the generalized library-function qualification convention to +`src/skills/style/nix/rules/general.md`. + +Move these instructions to code comments: + +- Firefox extension storage: above `extensions.settings` in + `configs/nixos/modules/desktop/apps/firefox.nix` +- Nixvim package set: above `nixpkgs.useGlobalPackages` in + `configs/nixos/modules/shell/nvim/default.nix` + +The review does not decide how to restore the auto-generated status of +`configs/nixos/hosts/pikachu/hardware-configuration.nix`. + +The operator confirmed this design and authorized the edits. diff --git a/src/skills/style/nix/rules/dotfiles.md b/src/skills/style/nix/rules/dotfiles.md new file mode 100644 index 0000000..59a33b7 --- /dev/null +++ b/src/skills/style/nix/rules/dotfiles.md @@ -0,0 +1,43 @@ +## Register window icons + +### Rule + +Each graphical application has a `registry.window-icon` entry with a window-class match and rendered icon. + +### Rationale + +Hyprland uses this registry to render workspace icons for open application windows. + +Run this command to list window classes from the running compositor: + +```bash +hyprctl clients -j | jq -r '.[].class' | sort -u +``` + +## Separate guest wrappers from service modules + +### Rule + +Each guest module wraps one service module. +The guest enables its service through `guests..interior`. +Service modules own service configuration. +Guest modules configure bind mounts, secret delivery, resource limits, and registry entries. +Host configuration supplies deployment-specific paths, volumes, addresses, and routes. + +### Rationale + +Service modules support a service without guest infrastructure. +Guest modules adapt a service module to a guest. +Host configuration provides deployment-specific values. + +## Decrypt guest secrets on the host + +### Rule + +A host user owns each guest secret before SOPS decrypts it. +Each guest service group accesses its secrets through a read-only bind mount. + +### Rationale + +Guest service accounts do not exist on the host, where SOPS creates secrets. +The shared service group preserves read access across the guest boundary. diff --git a/src/skills/style/nix/rules/general.md b/src/skills/style/nix/rules/general.md index ed367ef..73af43e 100644 --- a/src/skills/style/nix/rules/general.md +++ b/src/skills/style/nix/rules/general.md @@ -22,6 +22,17 @@ Do not call `lib.removeSuffix ".nix"` outside the utility definition. The utility centralizes Nix file-name normalization. +## Qualify library functions + +### Rule + +Keep library functions qualified as `lib.`. + +### Rationale + +Qualification makes library ownership explicit. +It prevents local namespace collisions. + ## Use executable helpers for package commands ### Rule