diff options
Diffstat (limited to 'remote-dev')
| -rw-r--r-- | remote-dev/README.md | 109 | ||||
| -rw-r--r-- | remote-dev/home.nix | 35 |
2 files changed, 126 insertions, 18 deletions
diff --git a/remote-dev/README.md b/remote-dev/README.md index 0377b09..cc3eecc 100644 --- a/remote-dev/README.md +++ b/remote-dev/README.md @@ -21,36 +21,115 @@ GitHub on first launch. 2. Clones this repo to `~/.local/share/dotfiles`. 3. Runs `home-manager switch --flake .../remote-dev#vm`, which: - Installs the CLI tool subset (see `home.nix`). - - Symlinks `~/.config/{nvim,zellij,zsh,direnv,ghostty}` at the cloned - working tree via `mkOutOfStoreSymlink`, so `git pull` is enough to - pick up config edits — no rebuild needed for config-only changes. + - 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 +## Updating after a dotfiles change + +Two flavours of update: ```sh -cd ~/.local/share/dotfiles -git pull -nix run home-manager/master -- switch --flake ./remote-dev#vm +# (a) Config-only change (nvim/zellij/zsh/git/ssh): no rebuild needed. +git -C ~/.local/share/dotfiles pull + +# (b) Package set in home.nix changed: rebuild HM. +cd ~/.local/share/dotfiles/remote-dev +home-manager switch --impure --flake .#vm -b backup ``` ## Adding a tool Edit `home.nix`, add to `home.packages`, then `home-manager switch`. +## Single-shell policy (leaf tools only) + +Nix on this VM carries **leaf CLI tools** plus **editor/AI-agent +runtimes**, and nothing else. Specifically forbidden in `home.packages` +because they would shadow Ubuntu's 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` (`/usr/bin/python3`) stays the default +interpreter for project builds. + +Explicit carve-outs (used only by Mason/editor/AI agents, never by the +project build): + +- `nodejs` — `node`/`npm`/`npx` for npm-based LSPs. +- `uv` — `uv`/`uvx` for Python LSPs 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 `home.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 <<EOF +[gpg] + format = ssh +[gpg "ssh"] + allowedSignersFile = ~/.config/git/allowed_signers +[user] + signingkey = $(ssh-add -L | head -n1 | awk '{print $1" "$2}') +EOF +``` + +The tracked `dot_config/git/config` ends with `[include] path = +~/.config/git/config.local`, so the override is picked up +automatically (and silently ignored on machines that don't have it). + +Required on the **host's** `~/.ssh/config` for the VM `Host` block: + +``` +ForwardAgent yes +``` + +Verify on the VM after SSH-ing in: + +```sh +ssh-add -L # should list your auth pubkey(s) +git commit --allow-empty -m test +git log --show-signature -1 +``` + ## Caveats -- **GPG / pass**: HM installs `gnupg` and `pass` but does _not_ import any - private key. Bring your key separately if you need signed commits or - `pass`-backed env vars on the VM. +- **GPG / pass**: HM installs `gnupg` and `pass` but does _not_ import + any private key. Don't try; use SSH-format signing via the forwarded + agent instead (see above). - **Disk usage**: Nix store + nvim plugins consumes ~3-5 GB. Check the VM's root partition size first. -- **Network for first nvim launch**: `vim.pack.add` fetches plugins from - GitHub on first start. -- **Ubuntu apt collisions**: Nix-installed binaries appear first in PATH. - If you need a specific apt-version of something, install it manually - and prefix with the full path. +- **Network for first nvim launch**: `vim.pack.add` fetches plugins + from GitHub on first start. Mason will also fetch LSP servers using + `nodejs`/`uv` from this profile. +- **Ubuntu apt collisions**: Nix-installed binaries appear first in + PATH. The leaf-tools policy above exists precisely to keep this + shadowing contained to harmless tools. ## How it's wired diff --git a/remote-dev/home.nix b/remote-dev/home.nix index a2b9392..184de6b 100644 --- a/remote-dev/home.nix +++ b/remote-dev/home.nix @@ -15,9 +15,19 @@ in home.stateVersion = "25.05"; # ── Packages ──────────────────────────────────────────────────────────────── - # Mirrors the dev-tool subset of `meta/base.txt` on the Arch host. Tools that - # only make sense on a workstation (procs/gdu/duf for sysadmin, lazygit - # unused, node/yarn only needed for markdown-preview on GUI) are excluded. + # Policy: this profile carries leaf CLI tools plus editor/AI-agent + # runtimes (node, uv). It must NEVER carry anything the project build + # might invoke. Forbidden on PATH (would shadow Ubuntu's and break + # builds against the system sysroot/libc): cc, c++, gcc, g++, clang, + # clang++, ld, ld.lld, ar, nm, objcopy, make, cmake, ninja, meson, + # pkg-config, autoconf, automake, libtool, python, python3, pip, + # cargo, rustc, go. If a project needs a newer toolchain, put it in + # a project-local flake.nix + direnv `.envrc`, NOT here. + # + # Allowed runtimes (used only by Mason/editor/AI agents): node, npm, + # npx (via `nodejs`), uv, uvx (via `uv` — does NOT install a python3, + # manages its own interpreters under XDG). clang-tools is allowed + # because it ships only formatters/linters/clangd, no compiler driver. home.packages = with pkgs; [ # Editor + multiplexer neovim @@ -30,6 +40,7 @@ in fzf sd choose + zoxide # Viewers bat @@ -66,6 +77,17 @@ in gnupg pass + # C/C++ source tooling (no compiler driver in PATH) + clang-tools + + # Editor/AI agent runtimes — NOT for project builds (see policy above) + nodejs # Mason npm LSPs; system python3 stays at /usr/bin/python3 + uv # Mason python LSPs in isolated venvs; brings `uv`/`uvx` only + + # AI coding agents + claude-code + github-copilot-cli # NB: pkgs.copilot-cli is AWS Copilot, NOT this + # Zsh and plugins (sourced from $HOME/.nix-profile/share/... by the shared zshrc) zsh zsh-syntax-highlighting @@ -90,8 +112,15 @@ in "zsh/.zprofile".source = link "dot_config/zsh/dot_zprofile"; "ghostty".source = link "dot_config/ghostty"; # for terminfo refs only "direnv/direnvrc".source = link "dot_config/direnv/direnvrc"; + "git/config".source = link "dot_config/git/config"; + "git/attributes".source = link "dot_config/git/attributes"; + "git/ignore".source = link "dot_config/git/ignore"; }; + # ~/.ssh/config from the dotfiles tree (read-only); keys + known_hosts + # stay machine-local on the VM. + home.file.".ssh/config".source = link "private_dot_ssh/config"; + # ZDOTDIR redirect so login shells find ~/.config/zsh/.zprofile etc. home.file.".zshenv".text = '' export ZDOTDIR="$HOME/.config/zsh" |
