From de5146c7976e1fb38e8d1f82c30544462d881100 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Wed, 20 May 2026 13:56:09 +0100 Subject: refactor(nix): promote remote-dev/ to nix/ with common/vm/host split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructures the Home-Manager profile to support both the Arch host and the Ubuntu remote-dev VM from the same flake. - remote-dev/ → nix/ (hard rename; .chezmoiignore updated) - home.nix split into common.nix (shared), vm.nix (Mason runtime carve-outs + podman stack), host.nix (gpg scdaemon delegation to system pcscd) - flake.nix exposes homeConfigurations.{vm,host} via a mkProfile helper - rj alias in dot_zshrc updated to ~/.local/share/dotfiles/nix - bootstrap.sh / justfile updated to use #vm against the new path The split is behaviour-preserving for the VM: vm.nix + common.nix together carry the same package set as the previous home.nix. host.nix is provisioned but not yet wired into bootstrap (phase p8). Phase 1 of the nix-on-host migration plan. --- nix/README.md | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 nix/README.md (limited to 'nix/README.md') diff --git a/nix/README.md b/nix/README.md new file mode 100644 index 0000000..2bf3383 --- /dev/null +++ b/nix/README.md @@ -0,0 +1,201 @@ +# nix + +Home-Manager profiles for the Arch host (`host.nix`) and the Ubuntu +remote-dev VM (`vm.nix`), both layered on top of `common.nix`. Shares +the same nvim, zellij, and zsh configs from the same repo — no +duplication across machines. + +## Bootstrap + +**Host (Arch)**: managed by the top-level `bootstrap.sh` in the repo +root (installs nix + runs `home-manager switch --flake .../nix#host` +as part of `just init`). + +**VM (Ubuntu)**: as the dev user (must have sudo): + +```sh +curl -fsSL https://raw.githubusercontent.com/sommerfelddev/dotfiles/master/nix/bootstrap.sh | sh +``` + +Then log out and back in. Run `nvim` once to let it fetch plugins from +GitHub on first launch. + +## What the VM bootstrap does + +1. Installs Nix (Determinate Systems multi-user installer). +2. Clones this repo to `~/.local/share/dotfiles`. +3. Runs `home-manager switch --flake .../nix#vm`, which: + - Installs the CLI tool subset (see `common.nix` + `vm.nix`). + - Symlinks `~/.config/{nvim,zellij,zsh,direnv,ghostty,git}` and + `~/.ssh/config` at the cloned working tree via + `mkOutOfStoreSymlink`, so `git pull` is enough to pick up config + edits — no rebuild needed for config-only changes. + - Sets `ZDOTDIR=$HOME/.config/zsh` so the shared zshrc/zprofile load. +4. Appends the nix-store zsh to `/etc/shells` and `chsh`'s to it. + +## Updating after a dotfiles change + +Run from `~/.local/share/dotfiles/nix` (host or VM): + +```sh +just update # pull + home-manager switch (handles everything) +``` + +Or piece-by-piece if you know which one you need: + +```sh +just pull # config-only changes (nvim/zellij/zsh/git/ssh): no rebuild needed +just switch # rebuild home-manager from the current checkout +``` + +> `just update` runs `pull` then `switch`. The home-manager invocation +> uses `--impure --flake '.#vm' -b backup`; the single-quotes around the +> flake ref matter because our zsh enables `extendedglob`, which would +> otherwise interpret `.#vm` as a glob pattern. On the host, swap +> `#vm` → `#host`. + +## Adding a tool + +Edit `common.nix` (shared) or the profile-specific file (`host.nix` / +`vm.nix`), add to `home.packages`, then `just switch` (or `just +update`). + +## Single-shell policy (leaf tools only) + +The nix profile carries **leaf CLI tools** plus **editor/AI-agent +runtimes**, and nothing else. Specifically forbidden in `home.packages` +because they would shadow the system toolchain via `PATH` and silently +break builds against the system sysroot/libc/CI: `cc`, `c++`, `gcc`, +`g++`, `clang`, `clang++`, `ld`, `make`, `cmake`, `ninja`, `meson`, +`pkg-config`, `autoconf`, `automake`, `python`, `python3`, `pip`, +`cargo`, `rustc`, `go`. The system `python3` stays the default +interpreter for project builds. + +Explicit carve-outs (used only by editor/AI agents, never by the +project build): + +- `nodejs` — `node`/`npm`/`npx` for npm-based LSPs and + copilot-language-server. +- `uv` — `uv`/`uvx` for ad-hoc Python tooling in isolated venvs. `uv` + does NOT install a `python3` in PATH; it manages its own + interpreters under `~/.local/share/uv/`. System `python3` is + untouched. +- `clang-tools` — `clang-format`, `clang-tidy`, `clangd` only (no + compiler driver). + +If a project needs a newer build toolchain, drop a `flake.nix` + +`.envrc` in that project tree (direnv + nix-direnv is already wired +up). Don't add it to `common.nix`/`host.nix`/`vm.nix`. + +## Commit signing on the VM (SSH-format, no GPG secrets) + +GPG private keys never leave the host. Commits on the VM are signed +with the **forwarded SSH agent** in SSH-signature format, using the +authentication subkey gpg-agent already exposes via `ssh-add -L`. + +One-time setup on the VM: + +```sh +mkdir -p ~/.config/git + +# allowed_signers: maps your committer email to the SSH pubkey of the +# auth subkey. Adjust the grep if you have multiple keys. +printf '%s %s\n' \ + "$(git config user.email)" \ + "$(ssh-add -L | head -n1)" \ + > ~/.config/git/allowed_signers + +# Machine-local git override (NOT tracked in dotfiles). +cat > ~/.config/git/config.local <