Desktop Host Composition

The workstation host demonstrates the full branch model: global profile branches, optional host branches, NixOS modules, Home Manager modules, hardware modules, impermanence, and secrets.

Up: hosts

Down: base branch | desktop branch | security branch | persist

What this host does

The host begins with profile branches and adds host-specific branches.

selectedBranchNames = lib.unique (
  cfg.profile.branches ++ hostCfg.branches
);

For a workstation, this means the default profile can provide base, desktop, security, legacy, and addons without repeating that list inside the host file.

Validation

The host validates branch names before building the system.

unknownBranches = builtins.filter (
  name: !(builtins.elem name knownBranchNames)
) selectedBranchNames;

This turns a typo into an evaluation error instead of silently dropping a module set.

NixOS and Home Manager convergence

The host passes branch NixOS modules to lib.nixosSystem and branch Home Manager modules to the configured user.

home-manager.users.${user}.imports =
  branchHmModules
  ++ hostCfg.hmModules
  ++ [
    inputs.sops-nix.homeManagerModules.sops
    inputs.hyprland.homeManagerModules.default
  ];

This is why leaves distinguish nixosModules from hmModules. The host composes both worlds at the correct layer.

Hardware and impermanence

The hardware file uses a tmpfs root and a persistent /persist filesystem. The tutorial lesson is not the specific disk IDs, but the split between disposable root state and explicitly persisted state.

Public docs should avoid copying disk UUIDs, local usernames, or machine-specific paths from generated hardware files.