Skip to content

Restructure nebula into dendritic (flake-parts + import-tree) layout - #17

Merged
kriswill merged 5 commits into
nebula-snowglobefrom
dendritic-refactor
Jun 15, 2026
Merged

Restructure nebula into dendritic (flake-parts + import-tree) layout#17
kriswill merged 5 commits into
nebula-snowglobefrom
dendritic-refactor

Conversation

@kriswill

Copy link
Copy Markdown
Owner

What

Restructures the nebula NixOS flake to the dendritic pattern, mirroring the main/macOS branch. flake.nix's outputs is now just:

outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);

Every component lives as its own file under modules/ and is exposed through flake-parts outputs. snowglobe-lib's mkNixosHost is still the host builder — this is a reorganization of the local flake wiring, not a replacement of snowglobe.

Layout

File Role
modules/flake-parts.nix enables the flake.modules.nixos.* namespace + systems
modules/nixos.nix host realizer — configurations.nixos registry → flake.nixosConfigurations + flake.checks via slib.mkNixosHost
modules/nixos/*.nix the 8 shared modules, each wrapped { flake.modules.nixos.<name> = …; } (always-on, bodies unchanged)
modules/hosts/nebula.nix registers the host; imports all features + _nebula/, applies overlays + sops
modules/hosts/_nebula/ host-specific plain modules — excluded from the import-tree scan (path contains /_), pulled in by explicit imports
modules/overlays.nix / modules/packages.nix flake.overlays and per-system packages

Removes nixosConfigurations/, nixosModules/, overlays/default.nix (history preserved via git mv). Host secrets are now referenced via an explicit sops.defaultSopsFile (previously set by mkNixosHost's configDir, which is no longer passed).

Verification

  • nixosConfigurations.nebula's system.build.toplevel is functionally identical to the pre-refactor baseline — closure 2866→2866, delta +0. The only diff is the sops secrets store path (the whole config dir → the secrets.yaml file); same encrypted content.
  • nix flake check passes (one harmless unknown flake output 'modules' warning — the flake.modules.nixos.* namespace, same as on main).
  • nix build .#packages.x86_64-linux.{helium,wowup,dots-adopt} all build through the overlays.
  • CLAUDE.md and docs/ path references updated.

Notes

  • Not yet activated (nixos-rebuild switch) — the new generation is functionally identical, so this can be switched at leisure.
  • keyring.nix moved to modules/nixos/keyring.nix; harmless for the running system, noted in CLAUDE.md in case the snowglobe installer needs it on a fresh reinstall.

Mirror the macOS/main branch: flake.nix's outputs is now just
`flake-parts.lib.mkFlake { inherit inputs; } (import-tree ./modules)`,
and every component lives as its own file under modules/, exposed
through flake-parts outputs. snowglobe-lib's mkNixosHost is still the
host builder.

- modules/flake-parts.nix  enables the flake.modules.nixos.* namespace
- modules/nixos.nix         host realizer (configurations.nixos registry
                            -> flake.nixosConfigurations + flake.checks
                            via slib.mkNixosHost)
- modules/nixos/*.nix       the 8 shared modules, each wrapped as
                            flake.modules.nixos.<name> (always-on, bodies
                            unchanged)
- modules/hosts/nebula.nix  registers the host; imports all features +
                            _nebula/ host modules, applies overlays + sops
- modules/hosts/_nebula/    host-specific plain modules; excluded from the
                            import-tree scan (path contains /_) and pulled
                            in by explicit imports
- modules/overlays.nix      flake.overlays
- modules/packages.nix      per-system packages (perSystem)

Removes nixosConfigurations/, nixosModules/, overlays/default.nix.
Host secrets now referenced via an explicit sops.defaultSopsFile (was
set by mkNixosHost's configDir, which is no longer passed).

Verified: nixosConfigurations.nebula's system.build.toplevel is
functionally identical to the pre-refactor baseline (closure delta +0;
only the sops secrets store path differs). nix flake check passes; the
custom packages build through the overlays. Docs/CLAUDE.md paths updated.
@kriswill

Copy link
Copy Markdown
Owner Author

Code review

Found 1 issue:

  1. The secrets file was moved (nixosConfigurations/nebula/secrets.yamlmodules/hosts/_nebula/secrets.yaml), but .sops.yaml's creation_rules path_regex still points at the old path and wasn't updated in this PR. Editing secrets will fail with "no matching creation rules" — and the PR's own updated CLAUDE.md instructs sops modules/hosts/_nebula/secrets.yaml. (Build-time decryption is unaffected, since sops reads keys from the file's embedded metadata; only sops-editing/re-keying breaks.) Fix: update path_regex to modules/hosts/_nebula/secrets.yaml.

dotfiles/.sops.yaml

Lines 3 to 7 in 7b3e64d

creation_rules:
- path_regex: nixosConfigurations/nebula/secrets.yaml
key_groups:
- age:
- *nebula

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

kriswill added 4 commits June 14, 2026 16:11
The dendritic refactor moved nixosConfigurations/nebula/secrets.yaml to
modules/hosts/_nebula/secrets.yaml but left .sops.yaml's creation_rules
path_regex pointing at the old path, so editing/re-keying secrets failed
with 'no matching creation rules'. (Build-time decryption was unaffected.)
Verified the new path matches and encrypts with the nebula recipient.
…xclusion)

Previously the host's plain NixOS modules lived in modules/hosts/_nebula/,
underscore-prefixed so import-tree would skip them (they aren't flake-parts
modules). That exclusion hack is gone.

Each host file now lives under modules/hosts/nebula/ as a normal first-class
dendritic file of the form `{ configurations.nixos.nebula.module = <module>; }`.
Because that `module` option (declared in modules/nixos.nix) is a deferredModule,
every such file MERGES into the one host module — no path is excluded and there
is no hand-maintained imports list (this is the vimjoyer/dendritic pattern).

- modules/hosts/_nebula/ -> modules/hosts/nebula/ (git mv), each .nix wrapped
- hardware-configuration.nix wrapped too, with a note to re-wrap if regenerated
- secrets.yaml / *.pub keep living beside the host files (import-tree only
  scans .nix, so they're ignored)
- modules/hosts/nebula.nix: drop the explicit imports list; keep metadata +
  shared-feature imports + overlays + sops.defaultSopsFile
- .sops.yaml path_regex -> modules/hosts/nebula/secrets.yaml
- flake.nix / flake-parts.nix / CLAUDE.md / docs: describe the new layout

Verified functionally identical to the prior build: nvd shows no version or
selection changes, closure delta +0, disk +0B. The only store-hash churn is
system-path (environment.systemPackages reordered by the new module import
order — identical contents, different buildEnv hash). nix flake check passes.
@kriswill
kriswill merged commit 281194f into nebula-snowglobe Jun 15, 2026
@kriswill
kriswill deleted the dendritic-refactor branch June 15, 2026 05:12
kriswill added a commit that referenced this pull request Jun 20, 2026
Restructure nebula into dendritic (flake-parts + import-tree) layout
kriswill added a commit that referenced this pull request Jun 29, 2026
nix-darwin has no programs.* for most of these tools, so port them the way
the rest of the repo already does (cf. tmux/zsh/yazi): static config lives in
the stow tree (home/) and the /nix/store-derived bits are generated and linked
during activation. The shell integrations (fzf/zoxide/direnv/hstr) already live
in the stow zshrc, so only the FZF_* env vars needed re-adding there.

Moved out of modules/home-manager/core.nix (now deleted) into system-level
modules/darwin/<feature>.nix + home/<pkg> stow packages:

  git/gh      modules/darwin/git.nix         + home/git, home/gh (bare-name
                                                helpers, no stale store paths)
  ssh         modules/darwin/ssh.nix         + home/ssh
  zk          modules/darwin/zk.nix
  diffnav     modules/darwin/diffnav.nix     installs a delta wrapped with the
                                              kanagawa theme (matches HM's
                                              finalPackage; diffnav bundles its
                                              own delta and is unaffected)
  kitty       modules/darwin/kitty.nix       + home/kitty
  neovide     modules/darwin/neovide.nix     toggle only; pkg is per-host
  direnv      modules/darwin/direnv.nix      + home/direnv; nix-direnv stdlib
                                              linked into ~/.config/direnv/lib
  direnv-nom  modules/darwin/direnv-nom.nix  nom wrapper generated + linked
  htop        modules/darwin/htop.nix        immutable htoprc generated + linked
  qmd-sqlite  modules/darwin/qmd-sqlite.nix  extension-enabled sqlite (hiPrio so
                                              it wins the sqlite3 collision with
                                              neovim's plain sqlite) + qmd link
  bat jq nix-index lazygit rmpc fzf go nodejs_24 yamlfmt -> user-packages.nix
  FZF_* env vars -> home/zsh/.config/zsh/.zshrc

The home-manager master `kriswill.enable` toggle and core.nix were removed;
home-manager stays wired only for the GUI/per-host modules (brave, firefox,
vscode, podman-desktop, claude-account-selector). All three host configs build
(nix flake check) and the HM->stow config handoff is clean (the old HM configs
were store symlinks HM removes on switch, then stow/activation redeploys).

flake.lock: `nix flake update` bumps nixpkgs, home-manager and yazi-plugins.
This is a closure no-op for host k -- the new lock evaluates to the identical
darwin-system derivation (verified: same .drv d15di5x4..., same output
axiznxg2...). It is included so future builds and the other hosts track the
newer inputs.

nvd diff -- previous generation (system-184, pre-migration) -> this commit's
closure (== the running gen-185 system). The Selection-state / Added / Removed
sections are this port (note the hm_* generated configs removed and the
delta-wrapped/delta-config -> delta-kanagawa swap); the Version changes are the
already-committed af761b8 nixpkgs bump that the pre-port generation had not yet
realized.

<<< /nix/store/7kx6ii60i6fwp4gsn4l987r9klgwd909-darwin-system-26.11.a1fa429
>>> /nix/store/axiznxg2fgby564shlpxjkjp208wa6p8-darwin-system-26.11.a1fa429
Version changes:
[U*]  #1  buf                           1.70.0 -> 1.71.0
[U.]  #2  expat                         2.8.0 -> 2.8.1
[U*]  #3  fastfetch                     2.64.2, 2.64.2-man -> 2.65.1, 2.65.1-man
[U.]  #4  ffmpeg-headless               8.1-bin, 8.1-data, 8.1-lib -> 8.1.1-bin, 8.1.1-data, 8.1.1-lib
[U.]  #5  fftw-double                   3.3.10 -> 3.3.11
[U*]  #6  fish                          4.7.1, 4.7.1-doc -> 4.8.0, 4.8.0-doc
[U.]  #7  freetype                      2.14.2 -> 2.14.3
[U+]  #8  gh                            2.94.0 -> 2.95.0
[U*]  #9  ghostscript                   10.07.0, 10.07.0-fonts, 10.07.0-man -> 10.07.1, 10.07.1-fonts, 10.07.1-man
[U*]  #10  go                            1.26.3 -> 1.26.4
[U.]  #11  icu4c                         76.1, 76.1-dev -> 78.3, 78.3-dev
[U.]  #12  ijs                           10.07.0 -> 10.07.1
[U*]  #13  imagemagick                   7.1.2-23 -> 7.1.2-24
[U.]  #14  just                          1.51.0, 1.51.0-man -> 1.54.0, 1.54.0-man
[U.]  #15  krb5                          1.22.1-lib -> 1.22.2-lib
[U.]  #16  libde265                      1.0.18 -> 1.1.1
[U.]  #17  libgcrypt                     1.11.2-lib -> 1.12.2-lib
[U.]  #18  libheif                       1.21.2-lib -> 1.23.0-lib
[U.]  #19  libpng-apng                   1.6.56 -> 1.6.58
[U*]  #20  libxml2                       2.15.2, 2.15.2-bin -> 2.15.3, 2.15.3-bin
[U*]  #21  lua-language-server           3.18.1 -> 3.18.2
[D.]  #22  nix                           2.34.7+1 x2 -> 2.34.7 x2
[D.]  #23  nix-cmd                       2.34.7+1 -> 2.34.7
[D.]  #24  nix-expr                      2.34.7+1 -> 2.34.7
[D.]  #25  nix-fetchers                  2.34.7+1 -> 2.34.7
[D.]  #26  nix-flake                     2.34.7+1 -> 2.34.7
[D.]  #27  nix-main                      2.34.7+1 -> 2.34.7
[D.]  #28  nix-store                     2.34.7+1 -> 2.34.7
[D.]  #29  nix-util                      2.34.7+1 -> 2.34.7
[U*]  #30  nodejs                        24.15.0 -> 24.16.0
[C.]  #31  nodejs-slim                   22.22.3, 24.15.0, 24.15.0-corepack, 24.15.0-npm -> 22.23.1, 24.16.0, 24.16.0-corepack, 24.16.0-npm
[U.]  #32  openapv                       0.2.1.2 -> 0.2.1.3
[U.]  #33  openexr                       3.4.10 -> 3.4.11
[U.]  #34  podman                        5.8.2, 5.8.2-man -> 5.8.3, 5.8.3-man
[U.]  #35  publicsuffix-list             0-unstable-2026-03-26 -> 0-unstable-2026-05-13
[U.]  #36  rsync                         3.4.1 -> 3.4.4
[U*]  #37  rumdl                         0.2.16 -> 0.2.21
[U.]  #38  simdjson                      4.6.0 -> 4.6.4
[C*]  #39  sqlite                        3.51.2 x2, 3.51.2-bin x2, 3.51.2-dev, 3.51.2-man x2 -> 3.51.2 x2, 3.51.2-bin x2, 3.51.2-dev, 3.51.2-man
[U.]  #40  unbound                       1.25.0-lib -> 1.25.1-lib
[U.]  #41  uv                            0.11.19 -> 0.11.22
[D*]  #42  vscode-langservers-extracted  4.10.0 -> 1.121.03429
Selection state changes:
[C+]  #1  direnv   2.37.1
[C+]  #2  git-lfs  3.7.1
[C+]  #3  htop     3.5.1, 3.5.1-man
[C+]  #4  kitty    0.47.4, 0.47.4-terminfo
Added packages:
[A+]  #1  delta-kanagawa                                   <none>
[A.]  #2  delta-kanagawa.gitconfig                         <none>
[A.]  #3  fastfetch-unwrapped                              2.65.1, 2.65.1-man
[A.]  #4  home-manager-agent-domains                       <none>
[A.]  #5  org.nix-community.home.claude-config-dir.domain  <none>
[A.]  #6  zz-nom-wrapper.sh                                <none>
Removed packages:
[R.]  #1  delta-config                 <none>
[R.]  #2  delta-wrapped                <none>
[R.]  #3  direnv-config                <none>
[R.]  #4  empty-directory              <none>
[R.]  #5  gh-config.yml                <none>
[R.]  #6  hm_.sshconfig                <none>
[R.]  #7  hm_direnvlibzznomwrapper.sh  <none>
[R.]  #8  hm_gitallowed_signers        <none>
[R.]  #9  hm_gitconfig                 <none>
[R.]  #10  hm_gitignore                 <none>
[R.]  #11  hm_kanagawa.conf             <none>
[R.]  #12  hm_kittydiff.conf            <none>
[R.]  #13  hm_kittykitty.conf           <none>
[R.]  #14  yyjson                       0.12.0
Closure size: 624 -> 616 (611 paths added, 619 paths removed, delta -8, disk usage -53.1MiB).
kriswill added a commit that referenced this pull request Jun 29, 2026
Completes the migration. The home-manager bridge, flake input, and the last
runtime hook are gone; the repo is now pure nix-darwin + the GNU Stow tree under
home/.

- flake.nix: drop the home-manager input (flake.lock: removed the home-manager
  and home-manager/nixpkgs nodes).
- modules/home.nix deleted -- the darwin <- home-manager bridge.
- modules/darwin/core.nix: drop pkgs.home-manager from environment.systemPackages.
- home/zsh/.config/zsh/.zshrc: drop the hm-session-vars.sh source line.
- AGENTS.md / CLAUDE.md updated to describe a darwin-only repo (no home.nix, no
  modules/home-manager/, no mkOutOfStoreSymlink mechanism).

Terminfo is unaffected -- the one real risk. nix-darwin's own set-environment
already exports the full TERMINFO_DIRS (the Ghostty.app bundle, the per-user and
system nix profiles, and /usr/share/terminfo), so xterm-kitty (in the system
profile's share/terminfo) and xterm-ghostty (Ghostty's bundle) still resolve
without the home-manager session-vars line. Verified with infocmp.

nix flake check passes for k, mini, SOC.

nvd diff -- previous generation (system-186, home-manager present) -> this commit
(system-187, now active). Removes the entire home-manager apparatus plus the deps
nothing else in the closure used (man-db, groff, diffutils, inetutils,
libpipeline).

<<< /nix/store/gf8hnm6w88ng2kajiy4x5n29k55nq0wz-darwin-system-26.11.a1fa429
>>> /run/current-system
Removed packages:
[R.]  #1  activation-k                             <none>
[R.]  #2  check-link-targets.sh                    <none>
[R.]  #3  cleanup                                  <none>
[R.]  #4  diffutils                                3.12
[R.]  #5  groff                                    1.24.1
[R.]  #6  hm-modules-messages                      <none>
[R.]  #7  hm-session-vars.sh                       <none>
[R.]  #8  hm_LibraryFonts.homemanagerfontsversion  <none>
[R.]  #9  hm_Usersk.cache.keep                     <none>
[R.]  #10  hm_Usersk.localstate.keep                <none>
[R-]  #11  home-manager                             0-unstable-2026-04-24
[R.]  #12  home-manager-agent-domains               <none>
[R.]  #13  home-manager-agents                      <none>
[R.]  #14  home-manager-applications                <none>
[R.]  #15  home-manager-files                       <none>
[R.]  #16  home-manager-fonts                       <none>
[R.]  #17  home-manager-generation                  <none>
[R.]  #18  home-manager-path                        <none>
[R.]  #19  home-manager-source                      <none>
[R.]  #20  home-manager.sh                          <none>
[R.]  #21  inetutils                                2.7
[R.]  #22  libpipeline                              1.5.8
[R.]  #23  link                                     <none>
[R.]  #24  man-db                                   2.13.1
[R.]  #25  nixos-option                             <none>
[R.]  #26  nixos-option.nix                         <none>
Closure size: 613 -> 587 (6 paths added, 32 paths removed, delta -26, disk usage -20.7MiB).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant