Clean up CLAUDE.md and make the claude skill correctly this time
Some checks failed
Check Flake / check-flake (push) Failing after 6s

This commit is contained in:
2026-02-10 21:08:13 -08:00
parent 869b6af7f7
commit 60e89dfc90
3 changed files with 213 additions and 285 deletions

103
CLAUDE.md
View File

@@ -1,78 +1,81 @@
# NixOS Configuration
# CLAUDE.md
This is a NixOS flake configuration managing multiple machines.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Adding Packages
## What This Is
**User packages** go in `home/googlebot.nix`:
- Development tools, editors, language-specific tools
- Use `home.packages` for CLI tools
- Use `programs.<name>` for configurable programs (preferred when available)
- Gate dev tools with `thisMachineIsPersonal` so they only install on workstations
A NixOS flake managing multiple machines. All machines import `/common` for shared config, and each machine has its own directory under `/machines/<hostname>/` with a `default.nix` (machine-specific config), `hardware-configuration.nix`, and `properties.nix` (metadata: hostnames, arch, roles, SSH keys).
**System packages** go in `common/default.nix`:
- Basic utilities needed on every machine (servers and workstations)
- Examples: git, htop, tmux, wget, dnsutils
- Keep this minimal - most packages belong in home/googlebot.nix
## Common Commands
**Personal machine system packages** go in `common/pc/default.nix`:
- Packages that must be system-level (not per-user) due to technical limitations
- But only needed on personal/development machines, not servers
- Examples: packages requiring udev rules, system services, or setuid
```bash
# Build a machine config (check for errors without deploying)
nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel --no-link
## Machine Roles
# Deploy to local machine (user must run this themselves - requires privileges)
doas nixos-rebuild switch --flake .
Machines have roles defined in their configuration:
# Deploy to a remote machine (boot-only, no activate)
deploy --remote-build --boot --debug-logs --skip-checks .#<hostname>
- **personal**: Development workstations (desktops, laptops). Install dev tools, GUI apps, editors here.
- **Non-personal**: Servers and production machines. Keep minimal.
# Deploy to a remote machine (activate immediately)
deploy --remote-build --debug-logs --skip-checks .#<hostname>
Use `thisMachineIsPersonal` (or `osConfig.thisMachine.hasRole."personal"`) to conditionally include packages:
# Update flake lockfile
make update-lockfile
```nix
home.packages = lib.mkIf thisMachineIsPersonal [
pkgs.some-dev-tool
];
# Update a single flake input
make update-input <input-name>
# Edit an agenix secret
make edit-secret <secret-filename>
# Rekey all secrets (after adding/removing machine host keys)
make rekey-secrets
```
## Sandboxed Workspaces
## Architecture
Isolated development environments using VMs or containers. See `skills/create-workspace/SKILL.md`.
### Machine Discovery (Auto-Registration)
- VMs: Full kernel isolation via microvm.nix
- Containers: Lighter weight via systemd-nspawn
Machines are **not** listed in `flake.nix`. Instead, `common/machine-info/default.nix` recursively scans `/machines/` for any `properties.nix` file and auto-registers that directory as a machine. To add a machine, create `machines/<name>/properties.nix` and `machines/<name>/default.nix`.
Configuration: `common/sandboxed-workspace/`
`properties.nix` returns a plain attrset (no NixOS module args) with: `hostNames`, `arch`, `systemRoles`, `hostKey`, and optionally `userKeys`, `deployKeys`, `remoteUnlock`.
## Key Directories
### Role System
- `common/` - Shared NixOS modules for all machines
- `home/` - Home Manager configurations
- `lib/` - Custom lib functions (extends nixpkgs lib, accessible as `lib.*` in modules)
- `machines/` - Per-machine configurations
- `skills/` - Claude Code skills for common tasks
Each machine declares `systemRoles` in its `properties.nix` (e.g., `["personal" "dns-challenge"]`). Roles drive conditional config:
- `config.thisMachine.hasRole.<role>` - boolean, used to conditionally enable features (e.g., `de.enable` for `personal` role)
- `config.machines.withRole.<role>` - list of hostnames with that role
- Roles also determine which machines can decrypt which agenix secrets (see `secrets/secrets.nix`)
## Shared Library
### Secrets (agenix)
Custom utility functions go in `lib/default.nix`. The flake extends `nixpkgs.lib` with these functions, so they're accessible as `lib.functionName` in all modules. Add reusable functions here when used in multiple places.
Secrets in `/secrets/` are encrypted `.age` files. `secrets.nix` maps each secret to the SSH host keys (by role) that can decrypt it. After changing which machines have access, run `make rekey-secrets`.
## Code Comments
### Sandboxed Workspaces
Only add comments that provide value beyond what the code already shows:
- Explain *why* something is done, not *what* is being done
- Document non-obvious constraints or gotchas
- Never add filler comments that repeat the code (e.g. `# Start the service` before a start command)
`common/sandboxed-workspace/` provides isolated dev environments. Three backends: `vm` (microvm/cloud-hypervisor), `container` (systemd-nspawn), `incus`. Workspaces are defined in machine `default.nix` files and their per-workspace config goes in `machines/<hostname>/workspaces/<name>.nix`. The base config (`base.nix`) handles networking, SSH, user setup, and Claude Code pre-configuration.
## Bash Commands
IP allocation convention: VMs `.10-.49`, containers `.50-.89`, incus `.90-.129` in `192.168.83.0/24`.
Do not redirect stderr to stdout (no `2>&1`). This can hide important output and errors.
### Backups
Do not use `doas` or `sudo` - they will fail. Ask the user to run privileged commands themselves.
`common/backups.nix` defines a `backup.group` option. Machines declare backup groups with paths; restic handles daily backups to Backblaze B2 with automatic ZFS/btrfs snapshot support. Each group gets a `restic_<group>` CLI wrapper for manual operations.
## Nix Commands
### Nixpkgs Patching
Use `--no-link` with `nix build` to avoid creating `result` symlinks in the working directory.
`flake.nix` applies patches from `/patches/` to nixpkgs before building (workaround for nix#3920).
## Git Commits
### Key Conventions
Do not add "Co-Authored-By" lines to commit messages.
- Uses `doas` instead of `sudo` everywhere
- Fish shell is the default user shell
- Home Manager is used for user-level config (`home/googlebot.nix`)
- `lib/default.nix` extends nixpkgs lib with custom utility functions (extends via `nixpkgs.lib.extend`)
- Overlays are in `/overlays/` and applied globally via `flake.nix`
- The Nix formatter for this project is `nixpkgs-fmt`
- Do not add "Co-Authored-By" lines to commit messages
- Always use `--no-link` when running `nix build`
- Don't use `nix build --dry-run` unless you only need evaluation — it skips the actual build
- Avoid `2>&1` on nix commands — it can cause error output to be missed