# Spec: Refactor Flake Targets into Platform × Build-Type Matrix ## Context The flake at `~/nixos` currently defines these output targets (flat, ad-hoc naming): - `docker` - `linode-minimal` - `nix-cache` - `nix-minimal` - `nixos` - `server` - `pxe-boot` Some already follow a `platform-buildtype` convention (`linode-minimal`), most don't. `~/nix-auto-installer` is a related repo and should be checked for any coupling to these target names (scripts, docs, CI, or install automation that reference them by name) before renaming anything. ## Goal Restructure the flake so targets are generated from two orthogonal concepts: **Build types** (what the system is for): - `minimal` - `nix-cache` - `server` - `docker` - `pxe-boot` - `gui` **Platforms** (what it's deployed on): - `linode` (Linode VM) - `proxmox` (Proxmox VM) - `lxc` (Proxmox LXC container) Final targets should be named consistently as `-`, e.g.: ``` linode-minimal proxmox-minimal lxc-minimal linode-nix-cache proxmox-nix-cache lxc-nix-cache linode-server proxmox-server lxc-server linode-docker proxmox-docker lxc-docker linode-pxe-boot proxmox-pxe-boot lxc-pxe-boot linode-gui proxmox-gui lxc-gui ``` That's the full matrix (18 targets) if every build type applies to every platform. See **Open Questions** below — some combinations may not make sense and should be confirmed with me before being built out, not silently included or dropped. ## Migration mapping (old → new) | Old target | New target | Notes | |--------------------|------------------------------------------------------|-------| | `linode-minimal` | `linode-minimal` | Already correct, keep as-is | | `nix-minimal` | likely `proxmox-minimal` or a platform-less base module | Ambiguous — see Open Questions | | `nix-cache` | base module consumed by `linode-nix-cache`, `proxmox-nix-cache`, `lxc-nix-cache` | Currently platform-less; needs to become a build-type module, not a standalone target | | `server` | base module consumed by `linode-server`, `proxmox-server`, `lxc-server` | Same as above | | `docker` | base module consumed by `linode-docker`, `proxmox-docker`, `lxc-docker` | Confirm docker actually makes sense as an LXC/VM guest build vs. a standalone container image — see Open Questions | | `pxe-boot` | TBD — may stay a single target rather than a per-platform one | See Open Questions | | `nixos` | TBD — unclear what this maps to in the new scheme | See Open Questions | ## Open Questions (Claude Code: raise these with me before implementing, don't guess) 1. **`nixos` target** — what is this currently used for (bare metal install, dev shell, template)? It doesn't obviously map to any of the six build types. 2. **`nix-minimal` vs `linode-minimal`** — are these two different things, or is `nix-minimal` a leftover/duplicate? 3. **`pxe-boot` and `gui` across all three platforms** — does PXE boot make sense for an LXC container or a cloud VM (Linode), or is it inherently bare-metal/ network-boot only and should remain a single non-platform target? Does `gui` make sense inside an LXC container? 4. **`docker` as a build type** — is this "a NixOS host configured to run Docker" (which would sensibly have linode/proxmox/lxc variants), or "a Docker container image built by the flake" (which wouldn't take a platform prefix at all, since it doesn't run on Linode/Proxmox/LXC as a guest OS)? These are structurally different and change how it should be wired in. 5. Confirm whether all 18 combinations should actually exist, or whether this is meant to produce only the combinations that are genuinely useful (e.g. maybe no one needs `lxc-pxe-boot`). ## Implementation approach 1. **Inventory first.** Read the current `flake.nix` and any `nixosConfigurations`/ `modules` structure. Map every existing target to what module(s) it actually pulls in. Don't assume — confirm against the real file contents. 2. **Separate build-type and platform into their own module directories**, e.g.: ``` modules/build-types/minimal.nix modules/build-types/nix-cache.nix modules/build-types/server.nix modules/build-types/docker.nix modules/build-types/pxe-boot.nix modules/build-types/gui.nix modules/platforms/linode.nix modules/platforms/proxmox.nix modules/platforms/lxc.nix ``` Build-type modules should contain only what makes a system "minimal" vs "server" vs "gui", etc. Platform modules should contain only what's specific to running as a Linode VM vs Proxmox VM vs LXC container (virtualisation guest tools, boot method, filesystem/image format, LXC-specific constraints like no kernel modules, etc). 3. **Generate the target matrix programmatically** in `flake.nix` rather than hand-writing 18 near-identical `nixosConfigurations` entries — e.g. a small function that takes a platform name and build-type name, composes the two modules plus any shared base module, and produces the named output. This keeps future build types/platforms a one-line addition rather than a copy-paste job. 4. **Only build combinations we've confirmed make sense** (see Open Questions) — don't emit all 18 by default if some are structurally invalid. 5. **Preserve existing working configs during the transition.** Don't delete the old target names until their replacements build successfully — rename/alias at the end, not the start, so there's no window where the flake is broken. ## Verification For every new target produced: ```bash nix flake check nix build .#nixosConfigurations..config.system.build.toplevel ``` Confirm each builds without evaluation errors before considering it done. If a target fails to build, report which one and why rather than silently skipping it. ## Deliverables - Refactored `flake.nix` using the composed module + generated-matrix approach. - New `modules/build-types/*.nix` and `modules/platforms/*.nix` files. - Old flat target names removed only after their replacements are verified. - A short `README.md` (or section in existing docs) listing the final target names and what each one is for. - A summary at the end of what changed, what was removed, and any of the Open Questions above that got resolved differently than expected. ## Out of scope - Don't touch `~/nix-auto-installer` contents beyond checking it for references to the old target names — if changes there are needed, flag them, don't make them without confirming. - Don't add new build types or platforms beyond the ones listed here.