diff --git a/AGENTS.md b/AGENTS.md index 19781df..4cd3e68 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,26 +1,212 @@ # AGENTS.md - AI Assistant Context -This file provides minimal context for assistants working with this Nix config repo. +This file provides context for AI assistants working with thegeneralist's Nix configuration. + +## Quick Commands + +### Build & Deploy Commands +```bash +# Build specific host +nixos-rebuild switch --flake .# # Linux +darwin-rebuild switch --flake .# # macOS + +# Update flake dependencies +nix flake update + +# Check configuration validity +nix flake check + +# Format Nix files +nixpkgs-fmt **/*.nix + +# Clean up old generations +nh clean all --keep 3 --keep-since 4d +``` + +### Development Commands +```bash +# Enter dev shell with tools +nix develop + +# Edit secrets +agenix -e .age + +# Re-encrypt all secrets +agenix -r +``` ## Architecture Overview ### File Structure Conventions -- `flake.nix` - Main entry point, defines inputs/outputs -- `hosts/` - Host-specific configurations +- **`flake.nix`** - Main entry point, defines inputs/outputs +- **`hosts/`** - Host-specific configurations - Each host has `default.nix` that calls `lib.mkSystem` - `configuration.nix` contains host-specific settings -- `modules/` - Reusable system modules +- **`modules/`** - Reusable system modules - `common/` - Cross-platform modules (always loaded) - - `darwin/` - macOS-specific modules + - `darwin/` - macOS-specific modules - `linux/` - Linux-specific modules -- `lib/` - Custom library functions +- **`lib/`** - Custom library functions - `mkSystem` - Main system builder function ### Host Naming & Categorization -- Hosts ending in `mbp` or containing `central-mbp` -> Darwin -- All others -> NixOS +- Hosts ending in `mbp` or containing `central-mbp` → Darwin +- All others → NixOS - Current hosts: - `thegeneralist` (NixOS) - - `thegeneralist-central` (NixOS) + - `thegeneralist-central` (NixOS) - `thegeneralist-mbp` (Darwin) - `thegeneralist-central-mbp` (Darwin) + +## Code Conventions + +### Nix Style Guidelines +- Use `nixpkgs-fmt` for formatting +- Prefer explicit attribute sets over `with` statements +- Use meaningful variable names +- Add comments for complex logic + +### Module Organization +```nix +# Standard module structure +{ config, lib, pkgs, ... }: +{ + # Module configuration here +} +``` + +### Host Configuration Pattern +```nix +# hosts//default.nix +lib: inputs: self: lib.mkSystem "" ./configuration.nix + +# hosts//configuration.nix +{ config, pkgs, ... }: { + # Host-specific settings +} +``` + +## Common Modification Patterns + +### Adding a New Package +1. **System-wide**: Add to appropriate `modules/*/packages.nix` +2. **User-specific**: Add to home-manager config in host's `configuration.nix` + +### Adding a New Module +1. Create `.nix` file in appropriate `modules/` subdirectory +2. Module is auto-discovered and loaded + +### Theme Defaults +- `modules/common/theme.nix` defines shared theme options used by multiple modules (e.g., `bat`, `ghostty`) +- Adjust `config.theme.*` there or override per-host in `hosts//configuration.nix` + +### Adding a New Host +1. Create `hosts//` directory +2. Add `default.nix` with system type +3. Add `configuration.nix` with host settings +4. Optionally add `hardware-configuration.nix` + +### Managing Secrets +1. Define in `secrets.nix` with proper recipients +2. Reference as `config.age.secrets..path` +3. Edit with `agenix -e .age` + +## Key Features to Remember + +### Distributed Builds +- `thegeneralist-central` is the main build machine +- Other hosts offload builds via SSH +- SSH keys and build users configured automatically + +### Binary Caches +- Personal: `cache.thegeneralist01.com` +- Community: `cache.garnix.io` +- Official: `cache.nixos.org` + +### Home Manager Integration +- Configured via `modules/common/home-manager.nix` +- Per-host customization in host's `configuration.nix` +- Includes `nh` tool for optimized rebuilds + +### Development Tools +- Development shell includes: `nil`, `nixpkgs-fmt`, `agenix` +- Custom options available via `lib.mkOption` +- Flake inputs follow nixpkgs for consistency + +### Rebuild Helper +- `rebuild.nu` at repo root wraps `nh` for local/remote rebuilds +- Shell alias `rebuild` points to the script (defined in `modules/common/shell/aliases.nix`) + +## Debugging Tips + +### Build Issues +1. Check syntax: `nix flake check` +2. Update dependencies: `nix flake update` +3. Clear cache: `nix-collect-garbage -d` +4. Verify module imports and paths + +### Secret Issues +1. Check `keys.nix` has correct public keys +2. Verify secret recipient list in `secrets.nix` +3. Re-encrypt if needed: `agenix -r` + +### Module Not Loading +1. Verify file is in correct `modules/` subdirectory +2. Check file extension is `.nix` +3. Ensure valid Nix syntax + +### Forgejo Actions Runner (NixOS) +1. `DynamicUser` conflicts require `lib.mkForce` if overriding module defaults. +2. Runner state dir should be `/var/lib/gitea-runner/`; set `StateDirectory = "gitea-runner"` and let the instance name append. +3. If the register script fails with `permission denied`, ensure `/var/lib/gitea-runner` exists and is owned by `gitea-runner`. +4. If workflows need to read a home symlink target, `/home/` must be `0750` (group traverse) and the runner user must be in that group. +5. A Forgejo deploy token for HTTPS pulls should be stored in agenix and owned by `gitea-runner`; use env-file format (`TOKEN=...`) and read it at runtime. + +### Nushell Warnings +1. Deprecated `get -i` warning from direnv integration is a short-term workaround in `modules/common/shell/direnv.nix` (custom Nushell hook with `get -o` and HM integration disabled) until upstream home-manager updates. + +## Performance Optimizations + +### Recommended Practices +- Use distributed builds when available +- Leverage binary caches +- Regular garbage collection via `nh clean` +- Keep flake inputs updated but stable + +### Avoiding Rebuilds +- Prefer adding packages to existing modules over creating new ones +- Use overlays for package modifications +- Consider impact on all hosts when modifying common modules + +## Testing Strategy + +### Before Major Changes +1. Test on single host first +2. Verify flake builds: `nix flake check` +3. Check that all hosts can still build +4. Consider impact on secrets/distributed builds + +### Rollback Strategy +```bash +# System level rollback +nixos-rebuild switch --rollback +darwin-rebuild switch --rollback + +# Or boot into previous generation from bootloader +``` + +## User Preferences + +### Code Style +- Clean, readable Nix code +- Proper indentation and formatting +- Meaningful comments for complex logic +- Consistent naming conventions + +### Organization Preferences +- Modular approach over monolithic configs +- Platform-specific separation (darwin/linux/common) +- Host-specific customization in host directories +- Secrets properly encrypted and organized + +This configuration emphasizes maintainability, security, and cross-platform consistency. diff --git a/hosts/thegeneralist-central/forgejo/default.nix b/hosts/thegeneralist-central/forgejo/default.nix index fd196d0..1f54c11 100644 --- a/hosts/thegeneralist-central/forgejo/default.nix +++ b/hosts/thegeneralist-central/forgejo/default.nix @@ -142,8 +142,6 @@ in DynamicUser = lib.mkForce false; StateDirectory = lib.mkForce "gitea-runner"; StateDirectoryMode = "0755"; - # Ensure newly created files are group-writable for the shared repo. - UMask = "0002"; }; users.groups.gitea-runner = { }; @@ -158,15 +156,7 @@ in systemd.tmpfiles.rules = [ "d /var/lib/gitea-runner 0755 gitea-runner gitea-runner -" "d /var/lib/gitea-runner/central 0755 gitea-runner gitea-runner -" - # Allow gitea-runner (in group users) to write to the blog repo's .git dir. - "d /home/thegeneralist/blog 2770 thegeneralist users -" - "Z /home/thegeneralist/blog/.git - thegeneralist users -" ]; - system.activationScripts.blogGitPerms.text = '' - ${pkgs.coreutils}/bin/chmod -R g+rwX /home/thegeneralist/blog/.git/objects - ${pkgs.acl}/bin/setfacl -R -m g:users:rwx -m d:g:users:rwx /home/thegeneralist/blog/.git/objects - ''; - networking.firewall.allowedTCPPorts = [ 2222 ]; }