Objective

Evaluate adopting Gabriel Volpe’s “Private Nix flake” pattern to add a host axis (personal vs. enterprise) on top of the current architecture-only split in Nix - Home Manager, without refactoring this repo or cluttering it with inline override hooks.

Context

Current dotfiles at ~/.config only vary by system (aarch64-darwin, x86_64-darwin, aarch64-linux, x86_64-linux) via forAllSystems in nix/flake.nix. Host-level customization (personal vs. work machine on the same arch) is not supported. Two ad-hoc override hooks exist today:

  • nix/home-manager/modules/packages.nix:6-12 — inline overrideAdd / overrideRemove arrays relying on git rerere to absorb rebase conflicts.
  • nix/home-manager/modules/coding-agents/claude/claude.nix:46-60 — sidecar claude-overrides.nix loaded via builtins.pathExists.

Research conducted 2026-04-24 found:

  • Home-manager has no first-class host abstraction (HM FAQ just says “one top-level file per user-machine combo”).
  • No native “override file” convention under flakes; legacy ~/.config/nixpkgs/overlays/ is inert under pure eval.
  • Community canon splits into four patterns: hosts/<hostname>/ directories (Misterio77, EmergentMind), option-based feature flags (options.my.*), flake-parts per-host modules (srid, Lite-system), and composable profile stacks.

Approach

Prefer downstream-as-input over a host-axis refactor of this repo:

  • Public repo (this one) stays minimal and unchanged.
  • A separate private flake takes this as a flake input, layers its own hosts/work.nix + overlay exposing mkHomeConfigurations per Volpe’s writeup.
  • “Rebase on upstream” collapses to nix flake update <input> on the private flake.
  • Secrets stay out of the public repo entirely; use sops-nix or agenix in the private flake.

Alternative (rejected for current scope): refactor this repo to Misterio77/EmergentMind-style host axis with hosts/, specialArgs, options.my.*. Touches every module; high churn; only worthwhile if multiple hosts need to co-exist in one repo.

Next Actions

  • Decide whether the enterprise use case is concrete enough to warrant creating a private flake yet, or whether the existing overrideAdd / claude-overrides.nix hooks are sufficient for now.
  • If proceeding: scaffold a private flake with this repo as input, one host module, and a test overlay that swaps one small surface (e.g. isTrusted, git identity, or a coding-agent API base URL).
  • Validate that the override-priority mechanics (lib.mkForce, disabledModules) actually compose cleanly against this repo’s modules without per-module changes.
  • Consider whether the existing claude-overrides.nix sidecar pattern should be generalized or retired once the private-flake approach is in place.
  • Smaller stepping-stone option: refactor one module (e.g. git.nix or claude.nix) to declare options.dotfiles.<feature>.* with mkEnableOption / mkPackageOption, gated via lib.mkIf. Validates whether a Misterio77-style feature-flag layer composes cleanly with the rest of the tree before committing to the full private-flake refactor. Lower-risk than scaffolding a downstream consumer; reversible if it doesn’t pay off.

Resources

Notes

Status is paused because the enterprise host isn’t yet a concrete requirement. Unblocked when: (1) a specific work machine materializes, or (2) the current overrideAdd / claude-overrides.nix hooks start causing rebase pain.

Non-obvious finding from research: disabledModules matches by path, so any upstream tree restructure would silently break a downstream consumer relying on it. That argues for keeping module paths stable in this repo once downstream consumers exist, or for preferring lib.mkForce over disabledModules in the private flake.

Academic-frame addition (2026-04-27): the multi-host variability problem is a textbook fit for Tarr et al.’s Multi-Dimensional Separation of Concerns (ICSE 1999), realized over Dolstra & Hemel’s purely-functional configuration paradigm (HotOS 2007). The Software Product Lines / Feature-Oriented Programming literature (Ferreira et al. 2014; Gaia et al. 2014) maps more cleanly to what the Nix module system enables than the “aspect-oriented” framing the dendritic community uses. This doesn’t change the architectural recommendation — Misterio77-style feature flags remain the lowest-friction path — but provides defensible grounding if the choice ever needs to be written up. See Academic Foundations of Nix Configuration Patterns.

Module-system primitives worth remembering for whichever path is taken: mkEnableOption "<feature>" (boolean toggle shorthand), mkPackageOption pkgs "<name>" {} (typed package selection), mkDefault (priority 1000) / mkForce (priority 50) for layered overrides, extraSpecialArgs (vs _module.args) when imports need to depend on host or profile.