2026-06-08 Nix Home-Manager Review and Cross-Platform Fixes
What I set out to do
A complete best-practices / nixisms review of the nix/ + Home Manager setup in .config, then work through every finding. Follows on from the 2026-05-14 Dotfiles Nix Audit Cleanup pass.
What I actually did
Reviewed ~50 nix files (flake-parts flakes, auto-discovered HM modules, custom home.mutableFile and mkUvProject abstractions, hand-built pkgs/ derivations) via four parallel review agents plus tree-wide statix/deadnix. Verdict: well above average, only one true DRY violation and a couple of real bugs. Then remediated the whole review across ~11 hm switch-verified commits, in batches:
HIGH/MEDIUM core
- signoz-mcp-server — gated on
aarch64-darwin(the prebuilt is arm64-only), tightened the derivation (dontBuild/dontConfigure,install -Dm755, Apache-2.0 license), and made the MCP entry tolerate the package’s absence. - Cooldown dedupe — collapsed the 3-day supply-chain cooldown duplicated across npm/yarn/bun, uv, and prek into one
local.releaseCooldownDaysoption, re-encoded per tool. - Linux portability — guarded Darwin-only blocks (
targets.darwin, jankyborders launchd),pkgs.ghostty(source) on Linux, chromium for the mermaid wrapper, and alib.meta.availableOnfilter so arch-unsupported packages drop out instead of breaking eval. - macmon launchd agent narrowed to aarch64 (package is Apple-Silicon-only).
Security / correctness / tooling
- sillytavern whitelist CIDR typo (
172.0.0.0/8→172.16.0.0/12); kept the port LAN-reachable by intent. installClaudeactivation: download installer to a file and guard each step with$DRY_RUN_CMD(acurl | bashpipe can’t be guarded).golint→golangci-lint; gitleaksprotect --staged→git --staged.
Low nits + typing
commonLib.toClientServersto dedupe the MCP projection; single-sourceenabledPlugins;pkgs.formats.jsonin claude-desktop; dropped the shadowinghome-manageralias;mkShellbuildInputs→packages.- Typed all 7 service ports as
lib.types.port+toStringat every interpolation site.
Structural refactors
modules/docker/lib.nix: shareddesktopPath+mkComposeDeployfor the open-webui/sillytavern/sqlite-seed compose-activation pattern.- Extracted the ~150-line signoz OTel Python transform to a ruff-linted
files/scripts/patch-otel-config.py, and 8 interpolation-free tmux scripts tofiles/scripts/tmux/.
What was striking
The “remaining failure” on x86_64-darwin was two stacked issues: a macmon gating bug, then an upstream wall: arrow-cpp is marked broken on x86_64-darwin in nixpkgs (genuine Hydra failure), pulled transitively by litellm -> datasets -> pyarrow -> arrow-cpp. Not fixable in-config, so I dropped x86_64-darwin from systems rather than gut the LiteLLM stack on Intel. That made the isIntelDarwin workarounds dead code, whose removal also killed the bare fetchTarball nixpkgs pin the review had flagged.
Lessons banked:
- Dropping a platform can beat fighting an upstream-broken dependency, and often unlocks dead-code cleanup downstream.
- Verify before “fixing”: the review claimed jupyter’s
fetchNews = "false"wanted a bool, but the JupyterLab schema is a string enum (true/false/none). Checked the schema instead of trusting the finding. - DRY divergent code with a flag, not by forcing unification:
mkComposeDeploy’sensureRunninglets open-webui stay ensure-running and sillytavern stay manual-start, so the abstraction is behavior-preserving rather than a flag-soup compromise. - Footgun caught: a broad unanchored
tmux/.gitignorerule silently swallowed the new tracked source dir; anchoring to/tmux/(matching the existing/claude-ops/precedent) fixed it.