Files
nixfiles/home
Emma Thorpe 4029866ed4 chore(claude): require ticket-scoped conventional commits on every commit
The git conventions memory said to match the repository's existing log
style. Several repositories (multicluster, core-services-cloud) have
histories dominated by bare "WSP-1234: summary" subjects, so matching
them produced commits that were not in conventional form. A related
failure was scope decay within a session: the first commit was correct
and later ones degraded to bare "test:" or "refactor:" subjects. Both
required commit history to be rebased by hand.

- Make "<type>(<TICKET-ID>): <summary>" mandatory on every commit and
  explicitly override repository log style. Style matching now applies
  to branch names only.
- Describe how to establish the real ticket ID (named in the request,
  extracted from the branch, or taken from existing commits on the
  branch) and require asking rather than guessing when none is
  available. Replace the literal WSP-1234 examples with <TICKET-ID> so
  the placeholder cannot be committed verbatim.
- Record scope decay across a session as a named failure mode.
- Cover merge commits, preferring rebase and requiring an explicit
  message when a merge commit is unavoidable.
- Add a pre-push verification grep that must return no output.
- Note that a clean git log does not prove a subject was correct when
  written, because rebasing replaces it; compare author and committer
  dates instead.

Update the MEMORY.md index entry to match.
2026-08-06 15:20:16 +01:00
..

Interactive shell environment

Everything the shell, terminal multiplexer, git and ssh do beyond their defaults, and where each is defined. All of it is managed declaratively through home-manager — edit the listed file and rebuild, never the generated dotfiles.

Keyboard shortcuts have their own reference: KEYBINDINGS.md.

Area Defined in
zsh, CLI tools, tmux, ssh, auto-tmux shell.nix
git (+ delta, commitizen) git.nix
Neovim (nixvim) + LSP editor.nix
Claude Code (CLAUDE.md, style, memory) claude.nix
GUI apps, GTK/Firefox theming, cursor desktop.nix (graphical hosts only)

Shared by every host via default.nix; the work box also layers work.nix on top (its own ssh config, extra packages, and the C#/Helm language servers). The committer identity (name, email, signing key) comes from the user registry (../users/registry.nix), not this module.


zsh

Feature Notes
oh-my-zsh plugins git, man, sudo (Esc-Esc to prepend sudo), colored-man-pages, extract; theme robbyrussell
Autosuggestion fish-style history suggestions as you type (→ to accept)
Syntax highlighting commands coloured by validity as you type
Completion menu completion; the dump is rebuilt on every activation (see Maintenance)
History 100k in-memory/on-disk, deduped, space-prefixed commands ignored, timestamped, shared live across sessions; file stays at ~/.zsh_history
Dotfiles location dotDir is ~/.config/zsh (XDG) — .zshrc/.zshenv/.zcompdump live there; ~/.zshenv only bootstraps $ZDOTDIR
History substring search type a fragment, then ↑/↓ cycles matching past commands — works in foot, iTerm2 and the Linux TTY (both CSI and SS3 arrow encodings bound)
Prompt hostname is prefixed when over SSH

Aliases: ls/ll/la/lteza (icons + git), clsclear. git aliases live in git.nix (below).

CLI tools

Tool What it gives you
fzf Ctrl-R fuzzy history, Ctrl-T file picker, Alt-C fuzzy cd (Catppuccin-themed)
zoxide z <fragment> jumps to frecent directories
direnv + nix-direnv per-project environments auto-loaded on cd (cached Nix dev shells)
eza modern ls (drives the ls aliases)
bat syntax-highlighting pager (Catppuccin Mocha theme); behaves like cat when piped; also the MANPAGER
ripgrep / fd fast search (rg) and find (fd); also back fzf
jq JSON processor
gh / tea GitHub and Gitea (code.emmathe.dev) CLIs; gh uses SSH
nix-index command-not-found: an unknown command tells you which Nix package provides it (prebuilt DB, no manual indexing)
comma (,) run an uninstalled program once: , cowsay hi
nh nicer nixos-rebuild/home-manager with diffs; $NH_FLAKE set to the repo. No scheduled GC (it could reap paths a running generation still references) — collect garbage manually with nh clean all / nix-collect-garbage -d
btop resource monitor, themed Catppuccin Mocha (vendored theme)
lazygit git TUI for staging/rebasing, themed to match (git.nix)
hyperfine / sd command-line benchmarking; saner find-and-replace than sed

Theming: fzf, bat, btop, lazygit and git's delta pager are all Catppuccin Mocha, driven from the shared ../lib/catppuccin-mocha.nix palette / the catppuccin upstream themes.

Env & defaults: xdg.enable on; PAGER/MANPAGER (bat) set in default.nix (the editor owns $EDITOR/$VISUAL); xdg.mimeApps maps web→Firefox, directories→nemo (desktop.nix).

tmux

Auto-start: opening any interactive terminal — foot, iTerm2, the WSL shell, the Linux console — drops you straight into a tmux session named main (attach if it exists, else create). Panes run a plain non-login zsh. It deliberately does not fire for SSH sessions, VS Code's integrated terminal, already-inside-tmux, or non-interactive shells. Escape hatch: NO_TMUX=1 <terminal> opens a bare shell.

Setting Value
Mode keys vi
Mouse on
Scrollback 500000 lines
escape-time 10ms (the 500ms default lagged vim's ESC)
focus-events on (vim autoread)
base-index / pane-base-index 1
Splits prefix s vertical, prefix v horizontal (stock %/" unbound)
Pane nav Alt+arrows (no prefix)
Terminal default-terminal tmux-256color; truecolor advertised per outer terminal (foot*, xterm-256color/iTerm2) via terminal-features … RGB
Clipboard set-clipboard on; foot terminal-features advertise truecolor/sync/OSC52/title/cursor

Plugins: sensible, vim-tmux-navigator (Ctrl-h/j/k/l across vim ↔ tmux), yank, extrakto (prefix+Tab: fzf-grab paths/URLs/text from the pane into the prompt), catppuccin (Mocha statusline), resurrect + continuum (sessions auto-save and restore across reboots). The statusline draws Nerd-Font glyphs — see Fonts.

Fonts

JetBrainsMono Nerd Font, Noto Sans and Noto Color Emoji are installed on every host (in common-nixos.nix, because tmux/terminals run everywhere; the Mac installs the Nerd Font to /Library/Fonts via the Darwin config). fonts.fontconfig.defaultFonts maps the generic families so anything asking for monospace gets the Nerd Font (with emoji fallback) — this also gives the WSL box emoji/sans coverage it otherwise lacked. foot uses the Nerd Font as its main font automatically. iTerm2's font is a GUI setting — set it to JetBrainsMono Nerd Font (Settings → Profiles → Text → Font) so the tmux statusline glyphs render instead of ?.

Editor (Neovim)

nvim — aliased to vi/vim, and set as $EDITOR/$VISUAL — is configured declaratively with nixvim, so the same plugins and config are baked in on every host. Migrated from plain vim; the practical gain is a real LSP stack in place of the old (inert) ALE.

Feature Notes
Colorscheme Catppuccin Mocha (matches the terminal and the rest of the desktop)
File tree nvim-tree, toggled with ,, (comma twice; was nerdtree)
Fuzzy finder telescope (+fzf-native): <leader>ff files, <leader>fg grep, <leader>fb buffers
Format on save conform-nvim (nixfmt, stylua, ruff, shfmt, prettier, gofumpt; LSP fallback otherwise)
Git fugitive (:Git …) + gitsigns gutter signs/blame
Diagnostics inline + trouble list (<leader>xx)
Completion nvim-cmp (LSP/buffer/path) with luasnip snippet expansion
Indent guides indent-blankline, on by default (was vim-indent-guides)
Statusline lualine (Catppuccin theme)
Editing which-key hints, comment (gc/gcc), autopairs, treesitter textobjects
Pane nav vim-tmux-navigator — Ctrl+h/j/k/l moves across vim splits and tmux panes
Syntax tree-sitter (nix, lua, bash, markdown, groovy, c#, python, terraform, yaml)
LSP nvim-cmp completion + servers nil_ls (Nix), lua_ls, pyright (Python), terraformls
Indentation 2-wide hard tabs (noexpandtab, tabstop/shiftwidth = 2); line numbers on
Filetypes *Jenkinsfile → groovy

Leader is Space. LSP keymaps (gd, gr, K, <leader>rn, <leader>ca) and the file-tree toggle are listed in KEYBINDINGS.md. Add a universal language server by enabling it under programs.nixvim.plugins.lsp.servers in editor.nix; host-specific ones go in that host's module — the work box (work.nix) adds omnisharp (C#) and helm_ls (Helm), kept off the personal machines.

git

Pager is delta. commitizen is installed on every host; cz defaults to Conventional Commits. lazygit (themed) is the TUI. The commit-graph is kept current (gc/fetch.writeCommitGraph) so lg stays fast.

Aliases
st co sw br ci status / checkout / switch / branch / commit
last unstage last commit / unstage
amend fixup undo amend-no-edit / commit --fixup / soft-reset HEAD~1 (keep staged)
lg graph log, all branches
cz cc git cz <sub> (e.g. git cz c) and git cc → commitizen prompt
Behaviour
Pulls rebase, with autostash + autosquash
Fetch prune deleted remote branches
Conflicts zdiff3 (shows the common ancestor)
Diffs histogram algorithm, colour-moved
rerere remembers + replays conflict resolutions
Commit editor full diff shown (commit.verbose)
Misc branches sorted by date, column.ui = auto, help.autocorrect = prompt, push.autoSetupRemote
Global ignores result, result-*, .direnv, *.swp, .DS_Store
Signing SSH commit + tag signing (mkDefault, so a host without the key in its agent can disable it). Name, email and signing key all come from the per-user identity (the user registry, ../users/registry.nix).

ssh

Feature Notes
ssh-agent runs on Linux (launchd on macOS); keys added on first use so the passphrase is typed once per login session — this also feeds git commit signing
macOS UseKeychain caches the passphrase in the login keychain (guarded by IgnoreUnknown, so a non-Apple ssh skips it instead of erroring)
Gitea remote code.emmathe.devHostName 10.187.1.76 (DNS-override), Port 30009, user git, dedicated key, identitiesOnly
Defaults the module's deprecated default block is opted out; equivalents kept under settings."*"

The work box keeps its own ~/.ssh/config (home-manager's programs.ssh is forced off there) but still runs the agent.

Claude Code

Managed declaratively by claude.nix on every host (the CLI is pkgs.claude-code, tracked to unstable via the flake overlay).

Managed (static, from Nix) Left mutable (runtime state)
~/.claude/CLAUDE.md (persona + memory workflow) settings.json (permissions, model, theme, /config)
~/.claude/output-styles/soviet-engineer.md .credentials.json, history, caches
~/.claude/memory/ (read-only symlink to the repo)

settings.json is intentionally not managed: Claude rewrites it at runtime (interactive permission grants, /config), which a read-only store symlink would break.

Memory is sourced from this repo. The files in claude/memory/ are the source of truth; they are symlinked read-only into ~/.claude/memory, so recall works but the runtime "save a memory" path does not. To add/change/remove a memory, edit claude/memory/ (one file per memory + the MEMORY.md index) and rebuild — CLAUDE.md tells Claude to route new memories there.

Maintenance behaviours

  • zcompdump reset~/.config/zsh/.zcompdump* (plus legacy ~/.zcompdump* and the cache copy) is removed on every activation, so a stale dump (pointing at /nix/store paths a rebuild or a manual GC removed) can't break completion with _git: function definition file not found.
  • GC — no scheduled timer; collect garbage deliberately (nh clean all / nix-collect-garbage -d) when no important session is running.

Per-host differences

Personal Linux (sway) macOS Work WSL (EDaaS)
Auto-tmux yes (foot/TTY) yes (iTerm2) yes (WSL shell)
git email iam@emmathe.dev iam@emmathe.dev …@citrix.com (work)
ssh config managed yes yes no (keeps corporate config)
ssh-agent yes launchd yes (work module)
GUI / theming (desktop.nix) yes no no