refactor(ssh): extract the host key wiring into a module
The sops secret declarations, the empty `hostKeys`, and the `HostKey` lines were boilerplate sitting in the host, and every future host restoring its identity would have repeated them. `modules.ssh` takes the encrypted file and the key types, deriving the secret names and the `HostKey` lines from one list, so the daemon and the secrets cannot disagree about where a key lives. The resulting system derivation is unchanged. Also record two gotchas: reading PR review comments needs the Gitea API rather than tea, and host keys are not user authentication keys.
This commit is contained in:
@@ -50,6 +50,15 @@ The domain model (Host, Module, Skeleton, Auto-loader, Enable convention, overla
|
||||
**No forge CLI is installed on the NixOS build.** No `gitea-axi`, no `tea`, no `gh` on `PATH` — the flake names `gitea-axi` only as the claude-code module's `SessionStart` hook command and never packages it, so that hook invokes a binary that is not there.
|
||||
Credentials, however, do exist: `~/.config/tea/config.yml` holds a token-bearing login named `alexion` (not `axi`), so pull requests **can** be opened with `nix run nixpkgs#tea -- pr create --login alexion --repo alexion/dotfiles --base main --head <branch> ...`.
|
||||
The `--repo` flag is required on that path, since `tea` resolves `origin` only for a login whose SSH host matches.
|
||||
The same token reads PR discussion, which `tea` itself does poorly: `tea pr <n> --comments` prints only the body, and `-f comments` returns no comments field at all.
|
||||
Use the API instead, taking the token from `.logins[] | select(.name=="alexion") | .token`.
|
||||
Review comments are **not** at `/issues/<n>/comments` — that endpoint holds only top-level discussion and is usually empty.
|
||||
Inline comments need two calls: `/pulls/<n>/reviews` for the review ids, then `/pulls/<n>/reviews/<id>/comments` for the bodies, whose `path` and `diff_hunk` fields say what each one is attached to.
|
||||
A review row with an empty `body` is the normal shape when the operator left only inline comments.
|
||||
- SSH **host** keys (`ssh_host_<type>_key`, served by the daemon from `/etc/ssh` or a secret) are not user authentication keys (`~/.ssh/id_ed25519`, offered to a remote server).
|
||||
The `ssh_host_` prefix is OpenSSH's own name for the former, and the `root@<host>` trailing field in a `.pub` is a free-text comment stamped by `ssh-keygen` at generation time, not a claim about which account uses the key.
|
||||
On this machine the two are provably distinct: the daemon presents `SHA256:2ysuBX0+Z6GbdCTujz5JHX6rqnJzIyWhYNrxdhhGwEM`, while pushes to `git.alexion.dev` authenticate with `SHA256:nEhHwtHDnLlsuFxyfp+cETgHUZ8xDMxaPVmYM5vuCkA`.
|
||||
Renaming host keys after user keys, or vice versa, is therefore always wrong.
|
||||
- `~/.claude/skills` is generated by home-manager with `recursive = true`, so the directories are real and writable but every leaf file is a read-only symlink into the store.
|
||||
Editing a skill in place fails; its source is `modules/claude-code/skills/<name>/` here, applied by a rebuild.
|
||||
Creating a new file under `~/.claude/skills/` succeeds silently and is the trap — it stays outside the repo and reaches no other machine.
|
||||
|
||||
Reference in New Issue
Block a user