···116116> Den is a playground for some very advanced concepts. I’m convinced that some of its ideas will play a role in future Nix areas. In my opinion there are some raw diamonds in Den.\
117117> — `@Doc-Steve` - Author of [Dendritic Design Guide](https://github.com/Doc-Steve/dendritic-design-with-flake-parts)
118118119119-## Code example (OS configuration domain)
119119+## Code examples (OS configuration framework)
120120121121### Defining hosts, users and homes.
122122+123123+Simplest example, one-liner definitions.
122124123125```nix
124126den.hosts.x86_64-linux.lap.users.vic = {};
125127den.hosts.aarch64-darwin.mac.users.vic = {};
126126-den.homes.aarch64-darwin.vic = {};
128128+den.homes.aarch64-darwin."vic@mac" = {};
127129```
130130+131131+The `den.aspects.vic` aspect is shared between
132132+these two hosts and standalone home-manager.
133133+134134+The `vic@mac` homeConfiguration has `osConfig = mac.config`.
135135+136136+Activate with:
128137129138```console
130130-$ nixos-rebuild switch --flake .#lap
139139+$ nixos-rebuild switch --flake .#lap
131140$ darwin-rebuild switch --flake .#mac
132141$ home-manager switch --flake .#vic
133142```
134143135144### Extensible Schemas for hosts, users and homes.
136145146146+These allow meta-configuration on entities, akin to
147147+what Dendritic flake-parts users do with top-level
148148+options, but here scoped to each entity type.
149149+150150+People use this for declaring host or user capabilities
151151+that will later be used by aspects to implement configurations.
152152+137153```nix
138154# extensible base modules for common, typed schemas
139155den.schema.user = { user, lib, ... }: {
···147163148164### Dendritic Multi-Platform Hosts
149165166166+A single aspect like `den.aspects.workstation` can be
167167+shared between (included-at) NixOS/nix-Darwin/WSL hosts.
168168+169169+Each aspect uses several Nix classes to define behaviour.
170170+150171```nix
151151-# modules/my-laptop.nix
172172+# modules/workstation.nix
152173{ den, inputs, ... }: {
153153- den.aspects.my-laptop = {
174174+ den.aspects.workstation = {
154175 # re-usable configuration aspects. Den batteries and yours.
155176 includes = [ den.provides.hostname den.aspects.work-vpn ];
156177···158179 nixos = { pkgs, ... }: { imports = [ inputs.disko.nixosModules.disko ]; };
159180 darwin = { pkgs, ... }: { imports = [ inputs.nix-homebrew.darwinModules.nix-homebrew ]; };
160181161161- # Custom Nix classes. `os` applies to both nixos and darwin. contributed by @Risa-G.
182182+ # Custom Nix classes. `os` applies to both nixos and darwin.
183183+ # Contributed by @Risa-G.
162184 # See https://den.oeiuwq.com/guides/custom-classes/#user-contributed-examples
163185 os = { pkgs, ... }: {
164186 environment.systemPackages = [ pkgs.direnv ];
165187 };
166188167167- # host can contribute default home environments to all its users.
168168- homeManager.programs.vim.enable = true;
189189+ # host can contribute default home environments
190190+ # to all its users.
191191+ provides.to-users = {
192192+ homeManager = { pkgs, ... }: {
193193+ programs.vim.enable = true;
194194+ home.packages = [ pkgs.neovide ];
195195+ };
196196+ };
169197 };
170198}
171199```
172200173201### Multiple User Home Environments
174202203203+Each user can define configurations for different
204204+home environments, aiding with migration from
205205+homeManager to hjem or others.
206206+175207```nix
176208# modules/vic.nix
177209{ den, ... }: {
210210+178211 den.aspects.vic = {
179179- # supports multiple home environments, eg: for migrating from homeManager.
212212+ # supports multiple home environments
180213 homeManager = { pkgs, ... }: { };
181214 hjem.files.".envrc".text = "use flake ~/hk/home";
182215 maid.kconfig.settings.kwinrc.Desktops.Number = 3;
183216184184- # user can contribute OS-configurations to any host it lives on
217217+ # user can contribute OS-configurations
218218+ # to all hosts it lives on
185219 darwin.services.karabiner-elements.enable = true;
186220187187- # user class forwards into {nixos/darwin}.users.users.<userName>
221221+ # user can specify config for specific host
222222+ provides.rog-tower = {
223223+ nixos = ...; # enable CUDA and gaming profile
224224+ };
225225+226226+ # user class forwards into
227227+ # {nixos/darwin}.users.users.<userName>
188228 user = { pkgs, ... }: {
189229 packages = [ pkgs.helix ];
190230 description = "oeiuwq";
···202242203243### Custom Dendritic Nix Classes
204244205205-[Custom classes](https://den.oeiuwq.com/guides/custom-classes) is how Den implements `homeManager`, `hjem`, `wsl`, `microvm` support. You can use the very same mechanism to create your own classes.
245245+[Custom classes](https://den.oeiuwq.com/guides/custom-classes) is how Den implements `user`, `homeManager`, `hjem`, `wsl`, `microvm` support. You can use the very same mechanism to create your own Nix classes.
246246+247247+The `den.provides.forward` battery is the core of it.
206248207249```nix
208250# Example: A class for role-based configuration between users and hosts
···244286245287### Guarded Forwarding Classes
246288247247-Forward guards allow feature-detection without mkIf/mkMerge cluttering.
289289+Any module/file can contribute to any aspects directly
290290+into their feature-concern Nix classes, without
291291+having to deal with feature-detection or having
292292+`mkIf`/`mkMerge` clutterring on all the codebase.
248293249249-Aspects can simply assign configurations into a class (here `persys`)
250250-from any file, without any `mkIf`/`mkMerge` cluttering. The logic for
251251-determining if the class takes effect is defined at a single place.
294294+The logic (guard) for conditional inclusion of a
295295+forwarded-class configuration is defined at a
296296+single place.
252297253298#### Example: Platform Aware `homeManager` classes
254299···257302on specific platforms.
258303259304```nix
260260-hmPlatforms =
305305+# aspect `tux` is used on both platforms
306306+den.hosts.x86_64-linux.igloo.users.tux = { };
307307+den.hosts.aarch64-darwin.apple.users.tux = { };
308308+309309+den.aspects.hmPlatforms =
261310 { class, aspect-chain }:
262311 den._.forward {
263312 each = [ "Linux" "Darwin" ];
···268317 guard = { pkgs, ... }: platform: lib.mkIf pkgs.stdenv."is${platform}";
269318 adaptArgs = { config, ... }: { osConfig = config; };
270319 };
271271-272272-den.hosts.x86_64-linux.igloo.users.tux = { };
273273-den.hosts.aarch64-darwin.apple.users.tux = { };
274320275321den.aspects.tux = {
276276- includes = [ hmPlatforms ];
322322+ includes = [ den.aspects.hmPlatforms ];
323323+277324 hmDarwin = { pkgs, ... }: { home.packages = [ pkgs.iterm2 ]; };
325325+278326 hmLinux = { pkgs, ... }: { home.packages = [ pkgs.wl-clipboard-rs ]; };
279327};
280328```
281329282330#### Example: Class for Impermanence Capability
283331332332+Modules define configurations at aspects using the
333333+`persys` class directly, without any conditional.
334334+335335+The guard guarantees they are applied **only**
336336+when impermanence module is enabled at host.
337337+284338> Inspired by @Doc-Steve
285339286340```nix
287287-# Aspects use the `persys` class without any conditional. And guard guarantees
288288-# settings are applied **only** when impermanence module has been imported.
289341persys = { host }: den._.forward {
290342 each = lib.singleton true;
291343 fromClass = _: "persys";