From 460fc927ec70185511031313378062e293f26cfa Mon Sep 17 00:00:00 2001
From: m3tm3re
Date: Sun, 28 Dec 2025 11:28:19 +0100
Subject: [PATCH] +AGENTS.md for AI coding agents
---
AGENTS.md | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 247 insertions(+)
create mode 100644 AGENTS.md
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..c31d4f0
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,247 @@
+# AGENTS.md - NixOS Configuration Repository
+
+This document provides guidelines for AI agents working on this NixOS flake configuration.
+
+## Repository Overview
+
+Multi-host NixOS flake managing servers and workstations with home-manager integration.
+- **Hosts**: m3-aether, m3-ares, m3-atlas, m3-helios, m3-kratos
+- **User**: m3tam3re
+- **Key inputs**: nixpkgs (unstable), home-manager, agenix, disko, nix-colors
+
+## Build/Rebuild Commands
+
+```bash
+# NixOS system rebuild
+sudo nixos-rebuild switch --flake .#
+sudo nixos-rebuild switch --flake .#m3-atlas
+
+# Home-manager rebuild
+home-manager --flake . switch
+home-manager --flake .#m3tam3re@m3-daedalus switch
+
+# Flake operations
+nix flake check # Validate flake
+nix flake update # Update all inputs
+nix flake lock --update-input # Update single input
+
+# Development shell
+nix develop .#infraShell # OpenTofu + nixos-anywhere
+
+# Format Nix files
+alejandra . # Format all .nix files
+alejandra # Format single file
+```
+
+## Testing
+
+No formal test suite. Verification is done via:
+```bash
+nix flake check # Syntax and evaluation check
+nix build .#nixosConfigurations..config.system.build.toplevel --dry-run
+```
+
+## Directory Structure
+
+```
+.
+├── flake.nix # Flake definition with all hosts
+├── secrets.nix # Agenix public key mappings
+├── home/
+│ ├── common/ # Shared home-manager config (overlays, nix settings)
+│ ├── features/ # Modular features
+│ │ ├── cli/ # Shell tools (fish, nushell, starship, zellij)
+│ │ ├── coding/ # Development tools
+│ │ └── desktop/ # GUI apps, Hyprland, theming
+│ └── m3tam3re/ # Per-host user configs
+├── hosts/
+│ ├── common/ # Shared NixOS config
+│ │ ├── extraServices/ # Toggle-able services (ollama, podman, flatpak)
+│ │ ├── users/ # User definitions
+│ │ └── ports.nix # Port allocations
+│ └── m3-*/ # Host-specific configs
+│ ├── default.nix # Entry point (imports common + host modules)
+│ ├── configuration.nix # Core system config
+│ ├── hardware-configuration.nix
+│ ├── programs.nix # Host-specific programs
+│ ├── secrets.nix # Agenix secret declarations
+│ └── services/ # Service configurations
+│ └── containers/ # OCI container definitions
+├── modules/ # Custom NixOS/home-manager modules
+├── overlays/ # Nixpkgs overlays (stable, locked, pinned, master)
+├── pkgs/ # Custom package definitions
+└── secrets/ # Encrypted .age files
+```
+
+## Code Style Guidelines
+
+### Module Pattern
+
+Standard Nix module structure:
+```nix
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: {
+ imports = [
+ ./submodule.nix
+ ];
+
+ # Configuration here
+}
+```
+
+### Formatting
+
+- **Formatter**: Use `alejandra` (included in CLI packages)
+- **Indentation**: 2 spaces
+- **Line length**: No strict limit, but keep readable
+- **Trailing commas**: Required in lists and attrsets
+- **Semicolons**: Required after each attribute
+
+### Naming Conventions
+
+| Type | Convention | Example |
+|------|------------|---------|
+| Files | lowercase, hyphenated | `hardware-configuration.nix` |
+| Hosts | `m3-` | `m3-atlas`, `m3-kratos` |
+| Options | camelCase path | `extraServices.ollama.enable` |
+| Feature flags | `features...enable` | `features.cli.nushell.enable` |
+| Secrets | `-env.age` or descriptive | `n8n-env.age`, `wg-DE.age` |
+
+### Option Definitions
+
+Use lib functions for custom options:
+```nix
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.features.cli.myFeature;
+in {
+ options.features.cli.myFeature.enable = mkEnableOption "enable myFeature";
+
+ config = mkIf cfg.enable {
+ # Configuration when enabled
+ };
+}
+```
+
+### Imports
+
+- Import order: inputs/modules first, then local files
+- Use relative paths: `./subdir` or `../common`
+- Group related imports together
+
+### Package Lists
+
+```nix
+home.packages = with pkgs; [
+ package1
+ package2
+ # Commented packages for reference
+ # disabled-package
+];
+```
+
+## Secrets Management
+
+Uses **agenix** for encrypted secrets.
+
+### Adding a New Secret
+
+1. Create the secret file:
+ ```bash
+ agenix -e secrets/my-secret.age
+ ```
+
+2. Register in `secrets.nix`:
+ ```nix
+ "secrets/my-secret.age".publicKeys = systems ++ users;
+ ```
+
+3. Declare in host's `secrets.nix`:
+ ```nix
+ age.secrets.my-secret = {
+ file = ../../secrets/my-secret.age;
+ owner = "service-user"; # Optional
+ mode = "644"; # Optional
+ };
+ ```
+
+4. Reference in config:
+ ```nix
+ environmentFiles = [config.age.secrets.my-secret.path];
+ ```
+
+## Container Services Pattern
+
+OCI containers via podman:
+```nix
+{config, ...}: {
+ virtualisation.oci-containers.containers."service-name" = {
+ image = "registry/image:tag";
+ environmentFiles = [config.age.secrets.service-env.path];
+ ports = ["127.0.0.1:8080:8080"];
+ volumes = ["service_data:/data"];
+ extraOptions = ["--network=web"];
+ };
+
+ # Traefik routing
+ services.traefik.dynamicConfigOptions.http = {
+ services.service-name.loadBalancer.servers = [
+ { url = "http://localhost:8080/"; }
+ ];
+ routers.service-name = {
+ rule = "Host(`service.domain.com`)";
+ tls.certResolver = "godaddy";
+ service = "service-name";
+ entrypoints = "websecure";
+ };
+ };
+}
+```
+
+## Theming
+
+Uses **nix-colors** with Dracula scheme:
+```nix
+colorScheme = inputs.nix-colors.colorSchemes.dracula;
+
+# Reference colors
+"#${config.colorScheme.palette.base00}" # Background
+"#${config.colorScheme.palette.base05}" # Foreground
+```
+
+## Overlays
+
+Custom overlays in `overlays/default.nix`:
+- `stable-packages`: nixpkgs-stable as `pkgs.stable.*`
+- `locked-packages`: Pinned nixpkgs as `pkgs.locked.*`
+- `master-packages`: nixpkgs-master as `pkgs.master.*`
+
+Use when you need a specific package version:
+```nix
+home.packages = [ pkgs.stable.somePackage ];
+```
+
+## Common Pitfalls
+
+1. **Missing imports**: Ensure new files are imported in parent `default.nix`
+2. **Secret paths**: Use `config.age.secrets..path`, not hardcoded paths
+3. **Rebuild required**: Changes need `nixos-rebuild` or `home-manager switch`
+4. **Overlay scope**: Overlays must be added to both `home/common` and `hosts/common`
+5. **Port conflicts**: Check `hosts/common/ports.nix` before allocating new ports
+
+## Commit Style
+
+Short, descriptive messages:
+- `flake update` - Dependency updates
+- `+package` - Adding new package
+- `service-name: description` - Service changes
+- `host: description` - Host-specific changes