No gitea-axi, tea or gh exists on the NixOS build, and there is no tea login or GITEA_* environment to authenticate with. The flake names gitea-axi only in the claude-code module's permissions and never packages it, so pull requests cannot be opened from this machine. The previous wording described the laptop while it still ran CachyOS with these tools installed by hand.
7.6 KiB
7.6 KiB
dotfiles-nixos
One flake that builds every machine the user owns.
The domain model (Host, Module, Skeleton, Auto-loader, Enable convention, overlays) lives in .claude/CONTEXT.md; the current deliverable's spec is .claude/spec/laptop-mvi.md.
Conventions
- Write comments only where they earn their place, and keep them concise.
Assume the reader can read code: comment the "why", not the "what", and explain "what" only when it is genuinely non-obvious.
A comment must be self-contained to its file — accurate to a reader looking at that file alone.
Do not write about history ("used to be X", "now moved here") or future state, about how a value is consumed elsewhere, or to justify the choice against alternatives; state the positive reason a thing exists, keeping any real stakes as a present-tense consequence.
The only permitted cross-file mention is a bare pointer explaining why something is absent here (e.g. "disko derives
fileSystems; none declared here"), never narrating what the other file or tool does. Do not use the domain model's capitalized terms (Host, Module, Skeleton, Auto-loader, Enable convention) as glossary references; describe things in plain language, using "host"/"module" only as ordinary lowercase nouns. Never reference agent-facing state (anything under.claude/orCLAUDE.md). A file-top header is one concise purpose line, added only where the filename or path does not already say it — never a feature inventory of the code below. For a placeholder, say so plainly plus any actionable present-tense directive ("Placeholder: regenerate with nixos-generate-config on the target machine"), never "placeholder for ". Optiondescription/mkEnableOptionstrings are user-facing documentation rather than comments, so they may describe behaviour more fully — but the self-contained rule and the bans on glossary terms and agent-state references still apply. - Comments posted to Gitea (pull requests, issues, reviews) go out under the operator's account, so sign every one to make clear the author is the agent, not the operator.
End the comment with a
— Claudesign-off. (A dedicated bot account may replace this later; until then, the sign-off is the only marker.) - Commit messages follow Conventional Commits, specified in
docs/conventional-commits.md. Scope is the module or host the change belongs to (fish,nvim,neogaia), omitted for repo-wide changes. Keep messages free of Gitea-specific references: this repository is mirrored to GitHub, where issue and pull-request numbers resolve to unrelated things.
Gotchas
- This repo is developed on
neogaia, which now runs the NixOS it builds. Flakes and the chaotic substituter come from this flake's ownnix.settings, so noNIX_CONFIGexport or per-command--extra-experimental-featuresis needed, and building a toplevel withboot.kernelPackages = linuxPackages_cachyosfetches the kernel fromnyx-cacherather than compiling it. Both were true only while the machine still ran CachyOS against a distro Nix daemon. - The substituters a
nix buildfetches from are the daemon's (/etc/nix/nix.conf), not thenix.settingsof the config being built — those only govern the built system. The two coincide here because the dev host runs this flake; they diverge on any machine that does not. - Git identity is not configured anywhere yet — no
programs.gitin the flake and no~/.gitconfig, sogit commitfails with "Author identity unknown". History usesalexion <contact@alexion.dev>; pass it per-commit withgit -c user.name=… -c user.email=…rather than writing config outside the flake. - The primary build/verify seam for any Host is
nix flake check, which buildschecks.x86_64-linux.<host>(the system toplevel); cheap targeted checks usenix eval .#nixosConfigurations.<host>.config.... - chaotic-nyx must not follow our
nixpkgs, and its packages are built against chaotic's own pinned nixpkgs (its overlay defaults toonTopOf = "flake-nixpkgs", the cache-friendly path). That is what lets thenyx-cache.chaotic.cxbinary cache hit instead of compiling the CachyOS kernel from source; the tradeoff is that chaotic packages do not see ourunstable/stableoverlays. - The remote is self-hosted Gitea (
git.alexion.dev), and the intended CLI isgitea-axirather thantea.gitea-axiresolves the repository from theoriginremote and takes credentials from theaxitea login, so both are implicit inside a checkout. None of it is installed on the NixOS build. Nogitea-axi, notea, nogh, no tea login under~/.config/tea, and noGITEA_*environment — the flake namesgitea-axionly in the claude-code module's permissions and never packages it. Pull requests therefore cannot be opened from this machine until a module provides the tool and its credentials; branches can only be pushed. The earlier claim thattearemains installed described the machine while it still ran CachyOS with these tools installed by hand. ~/.claude/skillsis generated by home-manager withrecursive = 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 ismodules/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. Copying out of that tree needscp -rLpluschmod -R u+w: a plaincp -rcopies the symlinks, putting store paths into the destination, and dereferenced files keep the store's read-only mode.- nixpkgs
vimPlugins.nord-nvimisshaunsingh/nord.nvim(norequire("nord").setup()); the config wantsgbprod/nord.nvim, which is packaged asvimPlugins.gbprod-nord. - nixpkgs
vimPlugins.nvim-treesittertracks the rewrittenmainbranch: there is norequire("nvim-treesitter.configs").setup{ensure_installed,highlight,indent}. Under nixvim, useplugins.treesitterwithhighlight.enable/indent.enableandgrammarPackages = with config.programs.nixvim.plugins.treesitter.package.builtGrammars; [ ... ]— the module's ownpackage.builtGrammars, notpkgs.vimPlugins.nvim-treesitter.*(whose query files can mismatch). The module targets the main branch and enables features via neovim-native APIs (vim.treesitter.start(),require'nvim-treesitter'.indentexpr()). - Neovim is configured via nixvim (flake input
nixvim, consumed asinputs.nixvim.homeModules.nixvimadded tohome-manager.sharedModules, config underhome-manager.users.<user>.programs.nixvim).nixvim.inputs.nixpkgs.follows = "nixpkgs"is set; nixvim then emits a benign eval warning that its pinned nixpkgs differs from the followed one — builds and runs fine, do not "fix" it by dropping the follows. - To reference the nixvim-built package's own attrs (e.g. treesitter
builtGrammars) inside our NixOS module, givehome-manager.users.<user>the module-function form (hm: { programs.nixvim = { ... hm.config.programs.nixvim... }; }), since the outerconfigis the NixOS config, not the home-manager one. - Verifying a nixvim change headless:
programs.nixvim.build.package's wrapper has no-u, so running$OUT/bin/nvimloads the caller's~/.config/nvim(the dev host's real config), not the built config — silently. To exercise the built config, launch with-u "$(nix build --no-link --print-out-paths .#…programs.nixvim.build.initFile)"and a scratchHOME/XDG_CONFIG_HOME.conceallevelis window-local: set it withopt_local/vim.wo, nevervim.bo[buf](which errors).