From d387465277a6645fce97c37849fbf3a906365b86 Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Thu, 19 Mar 2026 11:24:21 -0600 Subject: [PATCH 1/2] remove bidirectional --- docs/astro.config.mjs | 2 +- docs/src/content/docs/guides/batteries.mdx | 17 +- .../src/content/docs/guides/bidirectional.mdx | 280 ------------------ docs/src/content/docs/guides/mutual.mdx | 144 +++++++++ docs/src/content/docs/reference/batteries.mdx | 5 +- docs/src/content/docs/tutorials/ci.md | 4 +- modules/aspects/provides/bidirectional.nix | 16 - modules/aspects/provides/mutual-provider.nix | 7 +- modules/context/user.nix | 46 --- .../ci/modules/features/auto-parametric.nix | 17 +- .../features/batteries/define-user.nix | 4 +- .../modules/features/conditional-config.nix | 9 +- .../features/context/host-propagation.nix | 38 +-- .../external-namespace-deep-aspect.nix | 6 +- .../issue-201-forward-multiple-users.nix | 4 +- ...ue-292-hm-used-when-no-mutual-enabled.nix} | 2 +- ...uding-host-owned-and-included-statics.nix} | 26 +- .../ci/modules/features/host-options.nix | 4 +- .../ci/modules/features/perUser-perHost.nix | 25 +- ...config.nix => user-host-mutual-config.nix} | 22 +- 20 files changed, 234 insertions(+), 444 deletions(-) delete mode 100644 docs/src/content/docs/guides/bidirectional.mdx create mode 100644 docs/src/content/docs/guides/mutual.mdx delete mode 100644 modules/aspects/provides/bidirectional.nix rename templates/ci/modules/features/deadbugs/{issue-292-hm-used-when-no-bidir-enabled.nix => issue-292-hm-used-when-no-mutual-enabled.nix} (89%) rename templates/ci/modules/features/deadbugs/{issue-297-bidirectional-not-including-host-owned-and-included-statics.nix => issue-297-mutual-not-including-host-owned-and-included-statics.nix} (69%) rename templates/ci/modules/features/{user-host-bidirectional-config.nix => user-host-mutual-config.nix} (87%) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index edb249a2..b54059e5 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -70,7 +70,7 @@ export default defineConfig({ { label: 'From Flake to Den', slug: 'guides/from-flake-to-den' }, { label: 'Declare Hosts & Users', slug: 'guides/declare-hosts' }, { label: 'Configure Aspects', slug: 'guides/configure-aspects' }, - { label: 'Host<->User Mutual Config', slug: 'guides/bidirectional' }, + { label: 'Host<->User Mutual Config', slug: 'guides/mutual' }, { label: 'Custom Nix Classes', slug: 'guides/custom-classes' }, { label: 'Homes Integration', slug: 'guides/home-manager' }, { label: 'Use Batteries', slug: 'guides/batteries' }, diff --git a/docs/src/content/docs/guides/batteries.mdx b/docs/src/content/docs/guides/batteries.mdx index be9e5cd9..c62aa6be 100644 --- a/docs/src/content/docs/guides/batteries.mdx +++ b/docs/src/content/docs/guides/batteries.mdx @@ -38,27 +38,22 @@ den.default.includes = [ den.provides.hostname ]; ### `den.provides.mutual-provider` -Allows hosts and users to contribute configuration **to each other** through `provides`: +Allows hosts and users to contribute configuration **to each other** through `.provides.`: ```nix den.hosts.x86_64-linux.igloo.users.tux = { }; -den.default.includes = [ den._.mutual-provider ]; +den.ctx.user.includes = [ den._.mutual-provider ]; ``` -This is not the same as the built-in bidirectionality: - ```nix # contributes to ALL users of this host -den.aspects.my-host.homeManager = { ... } +den.aspects.my-host.provides.to-users.homeManager = { ... } # contributes to ALL hosts of where my-user exist -den.aspects.my-user.nixos = { ... } +den.aspects.my-user.provides.to-hosts.nixos = { ... } ``` -The difference is that this allows you to wire bidirectionality between -explictly-named hosts/users pairs. - -A user providing config TO the host: +A `tux` user providing config to **specific host** `igloo`: ```nix den.aspects.tux = { @@ -68,7 +63,7 @@ den.aspects.tux = { }; ``` -A host providing config TO the user: +A host providing config to **specific user** `tux`: ```nix den.aspects.igloo = { diff --git a/docs/src/content/docs/guides/bidirectional.mdx b/docs/src/content/docs/guides/bidirectional.mdx deleted file mode 100644 index b787a14d..00000000 --- a/docs/src/content/docs/guides/bidirectional.mdx +++ /dev/null @@ -1,280 +0,0 @@ ---- -title: Host<->User Bidirectionality -description: How to configure bidirectional behavior in Den. ---- - -import { Aside } from '@astrojs/starlight/components'; - - - -## What Bidirectionality Means - -__Bidirectionality__ means that not only a User contributes -configuration to a Host, but **also** that a Host contributes -configurations to a User. - - - - -There are at least two (built-in) ways to achieve this in Den. -The `den._.bidirectional` and `den._.mutual-provider` batteries. The -first one was extracted from den-core and the second started -life as an **aspect routing** example, but made it to become -proper battery itself and even safer than the first. - - -## Default, *unidirectional* OS configuration - -Den framework is built around **context pipeline** transformations. -In order to create a full OS configuration, everything starts with a host definition: - -```nix "igloo" "tux" -den.hostx.x86_64-linux.igloo.users.tux = {} -``` - -We need to build the `nixos` Nix module that will later be used by `lib.nixosSystem`. -To do so, Den invokes the `den.ctx.host` pipeline like this: - -> `Tip: Zoom diagrams using your mouse wheel or drag to move.` - -```mermaid -sequenceDiagram - participant Den - participant host as den.ctx.host - participant user as den.ctx.user - participant igloo as den.aspects.igloo - participant tux as den.aspects.tux - - Den ->> host : {host = igloo} - - host ->> igloo : request nixos class - igloo -->> igloo : each .includes takes { host } - igloo -->> host : { nixos = ... } owned and parametric results - - host ->> user : fan-outs for each user: { host, user } - - user ->> tux : request nixos class - tux -->> tux : home classes forwarded as nixos class - tux -->> tux : each .includes takes { host, user } - tux -->> user : { nixos = ... } owned and parametric results - - user -->> host : { nixos = ... } all user contributions - - host -->> Den : complete nixos module for lib.nixosSystem - -``` - -This is the normal NixOS pipeline an __Not Bidirectional__. All OS contributions come from -the host itself and from each of its user. - - - -## `den.provides.bidirectional` - -Bidirectionality is enabled __per-user__ or for _all_ of them. - -```nix -# only tux takes configurations from its hosts -den.aspects.tux.includes = [ den._.bidirectional ]; - -# for ALL users -den.ctx.user.includes = [ den._.bidirectional ]; -``` - -When Bidirectionality is enabled, the interaction looks like this: - -> `Tip: Zoom diagrams using your mouse wheel or drag to move.` - -```mermaid -sequenceDiagram - participant Den - participant host as den.ctx.host - participant user as den.ctx.user - participant igloo as den.aspects.igloo - participant tux as den.aspects.tux - - Den ->> host : {host = igloo} - - host ->> igloo : request nixos class - igloo -->> igloo : each .includes takes { host } - igloo -->> host : { nixos = ... } owned and parametric results - - host ->> user : fan-outs for each user: { host, user } - - user ->> tux : request nixos class - - tux ->> igloo : request home class - igloo -->> igloo : each .includes takes { host, user } - igloo -->> tux : { hjem = ... } owned and parametric results - - tux -->> tux : home classes forwarded as nixos class - - tux -->> tux : each .includes takes { host, user } - tux -->> user : { nixos = ... } owned and parametric results - - user -->> host : { nixos = ... } all user contributions - - host -->> Den : complete nixos module for lib.nixosSystem - -``` - - - - - -## `den.provides.mutual-provider` - -An alternative to bidirectionality is [`den.provides.mutual-provider`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix). - -This battery is safer, instead of using the host aspect directly, it requires you to define other named aspects under `.provides.` to create an explicit relationship between users and hosts. - -```nix -# mutual-provider is activated at a `{host,user}` context -den.ctx.user.includes = [ den._.mutual-provider ]; - -# user aspect provides to specific host or to all where it lives -den.aspects.tux = { - provides.igloo.nixos.programs.emacs.enable = true; - provides.to-hosts = { host, ... }: { - nixos.programs.nh.enable = host.name == "igloo"; - }; -}; - -# host aspect provides to specific user or to all its users -den.aspects.igloo = { - provides.alice.homeManager.programs.vim.enable = true; - provides.to-users = { user, ... }: { - homeManager.programs.helix.enable = user.name == "alice"; - }; -}; -``` - -> `Tip: Zoom diagrams using your mouse wheel or drag to move.` - -```mermaid -sequenceDiagram - participant Den - participant host as den.ctx.host - participant user as den.ctx.user - participant igloo as den.aspects.igloo - participant igloo-users as den.aspects.igloo.provides.to-users - participant igloo-tux as den.aspects.igloo.provides.tux - participant tux as den.aspects.tux - participant tux-hosts as den.aspects.tux.provides.to-hosts - participant tux-igloo as den.aspects.tux.provides.igloo - - Den ->> host : {host = igloo} - - host ->> igloo : request nixos class - igloo -->> igloo : each .includes takes { host } - igloo -->> host : { nixos = ... } owned and parametric results - - host ->> user : fan-outs for each user: { host, user } - - user ->> tux : request nixos class - tux -->> tux : home classes forwarded as nixos class - tux -->> tux : each .includes takes { host, user } - tux -->> user : { nixos = ... } owned and parametric results - - user ->> igloo-users : host configs its users: { host, user } - igloo-users -->> igloo-users : home classes forwarded as nixos class - igloo-users -->> igloo-users : each .includes takes { host, user } - igloo-users -->> user : { nixos = ... } - - user ->> igloo-tux : host configs tux: { host, user } - igloo-tux -->> igloo-tux : home classes forwarded as nixos class - igloo-tux -->> igloo-tux : each .includes takes { host, user } - igloo-tux -->> user : { nixos = ... } - - user ->> tux-hosts : user configs its hosts: { host, user } - tux-hosts -->> tux-hosts : home classes forwarded as nixos class - tux-hosts -->> tux-hosts : each .includes takes { host, user } - tux-hosts -->> user : { nixos = ... } - - user ->> tux-igloo : user configs igloo: { host, user } - tux-igloo -->> tux-igloo : home classes forwarded as nixos class - tux-igloo -->> tux-igloo : each .includes takes { host, user } - tux-igloo -->> user : { nixos = ... } - - - user -->> host : { nixos = ... } all user contributions - - host -->> Den : complete nixos module for lib.nixosSystem - -``` - diff --git a/docs/src/content/docs/guides/mutual.mdx b/docs/src/content/docs/guides/mutual.mdx new file mode 100644 index 00000000..a4380ccd --- /dev/null +++ b/docs/src/content/docs/guides/mutual.mdx @@ -0,0 +1,144 @@ +--- +title: Host<->User Mutual Providers +description: How to configure mutual configs in Den. +--- + +import { Aside } from '@astrojs/starlight/components'; + + + +## What Mutual-Config Mean + +__Mutual Configs__ means that not only a User contributes +configuration to a Host, but **also** that a Host contributes +configurations to a User. + + +## Default, *unidirectional* OS configuration + +Den framework is built around **context pipeline** transformations. +In order to create a full OS configuration, everything starts with a host definition: + +```nix "igloo" "tux" +den.hostx.x86_64-linux.igloo.users.tux = {} +``` + +We need to build the `nixos` Nix module that will later be used by `lib.nixosSystem`. +To do so, Den invokes the `den.ctx.host` pipeline like this: + +> `Tip: Zoom diagrams using your mouse wheel or drag to move.` + +```mermaid +sequenceDiagram + participant Den + participant host as den.ctx.host + participant user as den.ctx.user + participant igloo as den.aspects.igloo + participant tux as den.aspects.tux + + Den ->> host : {host = igloo} + + host ->> igloo : request nixos class + igloo -->> igloo : each .includes takes { host } + igloo -->> host : { nixos = ... } owned and parametric results + + host ->> user : fan-outs for each user: { host, user } + + user ->> tux : request nixos class + tux -->> tux : home classes forwarded as nixos class + tux -->> tux : each .includes takes { host, user } + tux -->> user : { nixos = ... } owned and parametric results + + user -->> host : { nixos = ... } all user contributions + + host -->> Den : complete nixos module for lib.nixosSystem + +``` + +This is the normal `den.ctx.host` pipeline. All OS contributions come from the host itself and from each of its user. + + +## `den.provides.mutual-provider` + +The [`den.provides.mutual-provider`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix) battery allows you to define mutual congigurations by letting you to define named aspects under `.provides.` to create explicit relationship between users and hosts. + +```nix +# mutual-provider is activated at a `{host,user}` context +# either per-user or for all of them. +den.ctx.user.includes = [ den._.mutual-provider ]; + +# user aspect provides to specific host or to all where it lives +den.aspects.tux = { + provides.igloo.nixos.programs.emacs.enable = true; + provides.to-hosts = { host, ... }: { + nixos.programs.nh.enable = host.name == "igloo"; + }; +}; + +# host aspect provides to specific user or to all its users +den.aspects.igloo = { + provides.alice.homeManager.programs.vim.enable = true; + provides.to-users = { user, ... }: { + homeManager.programs.helix.enable = user.name == "alice"; + }; +}; +``` + +> `Tip: Zoom diagrams using your mouse wheel or drag to move.` + +```mermaid +sequenceDiagram + participant Den + participant host as den.ctx.host + participant user as den.ctx.user + participant igloo as den.aspects.igloo + participant igloo-users as den.aspects.igloo.provides.to-users + participant igloo-tux as den.aspects.igloo.provides.tux + participant tux as den.aspects.tux + participant tux-hosts as den.aspects.tux.provides.to-hosts + participant tux-igloo as den.aspects.tux.provides.igloo + + Den ->> host : {host = igloo} + + host ->> igloo : request nixos class + igloo -->> igloo : each .includes takes { host } + igloo -->> host : { nixos = ... } owned and parametric results + + host ->> user : fan-outs for each user: { host, user } + + user ->> tux : request nixos class + tux -->> tux : home classes forwarded as nixos class + tux -->> tux : each .includes takes { host, user } + tux -->> user : { nixos = ... } owned and parametric results + + user ->> igloo-users : host configs its users: { host, user } + igloo-users -->> igloo-users : home classes forwarded as nixos class + igloo-users -->> igloo-users : each .includes takes { host, user } + igloo-users -->> user : { nixos = ... } + + user ->> igloo-tux : host configs tux: { host, user } + igloo-tux -->> igloo-tux : home classes forwarded as nixos class + igloo-tux -->> igloo-tux : each .includes takes { host, user } + igloo-tux -->> user : { nixos = ... } + + user ->> tux-hosts : user configs its hosts: { host, user } + tux-hosts -->> tux-hosts : home classes forwarded as nixos class + tux-hosts -->> tux-hosts : each .includes takes { host, user } + tux-hosts -->> user : { nixos = ... } + + user ->> tux-igloo : user configs igloo: { host, user } + tux-igloo -->> tux-igloo : home classes forwarded as nixos class + tux-igloo -->> tux-igloo : each .includes takes { host, user } + tux-igloo -->> user : { nixos = ... } + + + user -->> host : { nixos = ... } all user contributions + + host -->> Den : complete nixos module for lib.nixosSystem + +``` + diff --git a/docs/src/content/docs/reference/batteries.mdx b/docs/src/content/docs/reference/batteries.mdx index 684213f6..c86599a2 100644 --- a/docs/src/content/docs/reference/batteries.mdx +++ b/docs/src/content/docs/reference/batteries.mdx @@ -40,10 +40,7 @@ Sets the user's login shell. ### `den._.mutual-provider` -Allows the user and host to contribute configuration to each other via -`provides`. This is not the same as the built-in bidirectionality. The -difference is that this allows you to wire bidirectionality between -explictly-named hosts/users pairs. +Allows the user and host to contribute configuration to each other via `.provides.`. ### `den._.tty-autologin` diff --git a/docs/src/content/docs/tutorials/ci.md b/docs/src/content/docs/tutorials/ci.md index 05ac5727..f9195999 100644 --- a/docs/src/content/docs/tutorials/ci.md +++ b/docs/src/content/docs/tutorials/ci.md @@ -27,7 +27,7 @@ modules/ schema-base-modules.nix # den.schema modules special-args-custom-instantiate.nix # custom instantiation top-level-parametric.nix # top-level context aspects - user-host-bidirectional-config.nix # bidirectional providers + user-host-mutual-config.nix # mutual providers batteries/ define-user.nix # define-user battery flake-parts.nix # inputs' and self' @@ -70,7 +70,7 @@ modules/ | Test File | What It Tests | |-----------|---------------| -| [user-host-bidirectional-config.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/user-host-bidirectional-config.nix) | Host→user and user→host config flow | +| [user-host-mutual-config.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/user-host-mutual-config.nix) | Host→user and user→host config flow | | [context/cross-provider.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/context/cross-provider.nix) | Source providing config to target context | | [context/named-provider.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/context/named-provider.nix) | Self-named provider mechanism | diff --git a/modules/aspects/provides/bidirectional.nix b/modules/aspects/provides/bidirectional.nix deleted file mode 100644 index 2a2c9fa9..00000000 --- a/modules/aspects/provides/bidirectional.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ den, ... }: -let - description = '' - Enable Den bidirectionality: User takes configuration from Host. - - **REALLY** IMPORTANT: Read the documentation for den.ctx.user - - Consider as alternative den.provides.mutual-provider. - ''; -in -{ - den.provides.bidirectional = { - inherit description; - includes = [ den.ctx.user.provides.bidirectional ]; - }; -} diff --git a/modules/aspects/provides/mutual-provider.nix b/modules/aspects/provides/mutual-provider.nix index 5d303724..4b101969 100644 --- a/modules/aspects/provides/mutual-provider.nix +++ b/modules/aspects/provides/mutual-provider.nix @@ -9,13 +9,8 @@ let This battery implements an aspect "routing" pattern. - This is not the same as `den._.bidirectional` battery, but provides a - **safer** alternative to `den._.bidirectional`. - The reason is that this battery does not re-invoke the `host-aspect.includes`, - instead it relies on you defining provides. - Be sure to read diagrams for the Host context pipeline: - https://den.oeiuwq.com/guides/bidirectional + https://den.oeiuwq.com/guides/mutual ## Usage diff --git a/modules/context/user.nix b/modules/context/user.nix index 804f8a8e..b3f8337b 100644 --- a/modules/context/user.nix +++ b/modules/context/user.nix @@ -23,59 +23,13 @@ let - static includes like { nixos.foo = ... } or ({ class, aspect-chain }: { nixos.foo = ...; }) - atLeast{host,user} parametric includes like ({ host,user }: { nixos.foo = ...; }) - ## Bidirectionality - - Battery `den.provides.bidirectional` can be included on each user that needs to take configuration from the Host. - - Enable per user: - den.aspects.tux.includes = [ den._.bidirectional ]; - - Enable for all users: - den.ctx.user.includes = [ den._.bidirectional ]; - - IMPORTANT: Enabling bidirectionality means that the following pipeline is enabled: - - host-aspect{host} => user-aspect{host,user} => host-aspect{host,user} - - Notice that the host-aspect is being activated more than once! - - This means that host configurations are obtained - - once when the host is obtaining its own configuration with context {host} - - once PER user that has bidirectionality enabled with context {host,user} - - Due to Nix `lib.functionArgs` not distinguishing between `{host}` and `{host, ...}`, - Den provides these utilities built upon `den.lib.take.exactly`: - - # Do this to prevent being invoked with `{host,user}` - den.lib.perHost ({host}: ...) - - # Do this to prevent being invoked with `{host}` - den.lib.perUser ({host,user}: ...) - - Static aspects (plain-attrsets) or host-owned classes at a Host-aspect - have **no way** to distinguish when the calling context is - `{host}` or `{host,user}`, only functions are context-aware. - - Because of this, a host-aspect might produce duplicate values on list, - package types, or unique values like options: - - # lists, packages and options need to be unique. - # this line would produce duplicate errors IF bidirectional enabled - den.aspects.igloo.nixos.options.foo = lib.mkOption {}; - - # Instead, wrap in perHost things that must be unique - den.aspects.igloo.includes = [ - (den.lib.perHost { nixos.options.foo = lib.mkOption {}; }) - ] ''; ctx.user.into.default = lib.singleton; ctx.user.provides.user = take.exactly from-user; - ctx.user.provides.bidirectional = take.exactly from-host; from-user = { host, user }: fixedTo { inherit host user; } den.aspects.${user.aspect}; - from-host = { host, user }: fixedTo { inherit host user; } den.aspects.${host.aspect}; in { diff --git a/templates/ci/modules/features/auto-parametric.nix b/templates/ci/modules/features/auto-parametric.nix index 591f61a3..e5434bf8 100644 --- a/templates/ci/modules/features/auto-parametric.nix +++ b/templates/ci/modules/features/auto-parametric.nix @@ -69,7 +69,8 @@ test-explicit-exactly-not-overridden-by-default = denTest ( { den, igloo, ... }: { - den.ctx.user.includes = [ den._.bidirectional ]; + den.hosts.x86_64-linux.igloo.users.tux = { }; + den.aspects.strict-helper = den.lib.parametric.exactly { includes = [ ( @@ -80,8 +81,10 @@ ) ]; }; - den.aspects.igloo.includes = [ den.aspects.strict-helper ]; - den.hosts.x86_64-linux.igloo.users.tux = { }; + + den.ctx.user.includes = [ den._.mutual-provider ]; + den.aspects.igloo._.to-users.includes = [ den.aspects.strict-helper ]; + # strict-helper requires exactly { host, user } — since ctx.host only provides # { host }, strict-helper is skipped at host level (by exactly semantics). @@ -110,7 +113,7 @@ test-second-level-helper-owned-config-preserved = denTest ( { den, igloo, ... }: { - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; den.hosts.x86_64-linux.igloo.users.tux = { }; den.aspects.second-with-owned = { @@ -125,7 +128,7 @@ ]; }; den.aspects.helper.includes = [ den.aspects.second-with-owned ]; - den.aspects.igloo.includes = [ den.aspects.helper ]; + den.aspects.igloo._.to-users.includes = [ den.aspects.helper ]; expr = [ igloo.networking.hostName @@ -141,7 +144,7 @@ test-second-provides-helper-owned-config-preserved = denTest ( { den, igloo, ... }: { - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; den.hosts.x86_64-linux.igloo.users.tux = { }; den.aspects.second.provides.with-owned = { @@ -156,7 +159,7 @@ ]; }; den.aspects.helper.includes = [ den.aspects.second.provides.with-owned ]; - den.aspects.igloo.includes = [ den.aspects.helper ]; + den.aspects.igloo._.to-users.includes = [ den.aspects.helper ]; expr = [ igloo.networking.hostName diff --git a/templates/ci/modules/features/batteries/define-user.nix b/templates/ci/modules/features/batteries/define-user.nix index c6872aa2..73623c98 100644 --- a/templates/ci/modules/features/batteries/define-user.nix +++ b/templates/ci/modules/features/batteries/define-user.nix @@ -25,8 +25,8 @@ }: { den.hosts.x86_64-linux.igloo.users.tux = { }; - den.aspects.igloo.includes = [ den._.define-user ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; + den.aspects.igloo._.to-users.includes = [ den._.define-user ]; expr = igloo.users.users.tux.isNormalUser; expected = true; } diff --git a/templates/ci/modules/features/conditional-config.nix b/templates/ci/modules/features/conditional-config.nix index 6b042ffb..261ec885 100644 --- a/templates/ci/modules/features/conditional-config.nix +++ b/templates/ci/modules/features/conditional-config.nix @@ -41,9 +41,9 @@ users.tux.hasBar = true; }; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - den.aspects.igloo.includes = [ conditionalAspect ]; + den.aspects.igloo._.to-users.includes = [ conditionalAspect ]; expr = igloo.something; expected = "was-true"; @@ -68,9 +68,10 @@ tux = { }; pingu = { }; }; + den.default.homeManager.home.stateVersion = "25.11"; - den.ctx.user.includes = [ den._.bidirectional ]; - den.aspects.igloo.includes = [ git-for-linux-only ]; + den.ctx.user.includes = [ den._.mutual-provider ]; + den.aspects.igloo._.to-users.includes = [ git-for-linux-only ]; expr = [ tuxHm.programs.git.enable diff --git a/templates/ci/modules/features/context/host-propagation.nix b/templates/ci/modules/features/context/host-propagation.nix index a658a867..a74ad276 100644 --- a/templates/ci/modules/features/context/host-propagation.nix +++ b/templates/ci/modules/features/context/host-propagation.nix @@ -20,10 +20,24 @@ { den.hosts.x86_64-linux.igloo.users.tux = { }; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; den.aspects.igloo.funny.names = [ "host-owned" ]; den.aspects.igloo.includes = [ + (take.exactly ( + { host }: + { + funny.names = [ "host-exact" ]; + } + )) + (take.exactly ( + { host, user }: + { + funny.names = throw "unreachable"; + } + )) + ]; + den.aspects.igloo._.to-users.includes = [ { funny.names = [ "host-static" ]; } ( @@ -32,16 +46,10 @@ funny.names = [ "host-lax ${keys ctx}" ]; } ) - (take.exactly ( - { host }: - { - funny.names = [ "host-exact" ]; - } - )) (take.atLeast ( { host, never }: { - funny.names = [ "host-never" ]; + funny.names = throw "unreachable"; } )) @@ -64,7 +72,7 @@ never, }: { - funny.names = [ "host+user-never" ]; + funny.names = throw "unreachable"; } )) ]; @@ -92,7 +100,7 @@ never, }: { - funny.names = [ "user-never" ]; + funny.names = throw "unreachable"; } )) ]; @@ -139,9 +147,6 @@ funny.names = [ "default-host+user-lax ${keys ctx}" ]; } ) - - # the following error means an aspect is not parametric but static. (document this) - # > error: function 'anonymous lambda' called without required argument 'user' ]; expr = funnyNames ( @@ -174,12 +179,9 @@ "host-exact" "host-lax {host,user}" - "host-lax {host}" - "host-owned" # host - "host-owned" # user bidirectional - "host-static" # host - "host-static" # user bidirectional + "host-owned" + "host-static" "user-exact" "user-lax {host,user}" diff --git a/templates/ci/modules/features/deadbugs/external-namespace-deep-aspect.nix b/templates/ci/modules/features/deadbugs/external-namespace-deep-aspect.nix index 0ad049f5..c48a7d52 100644 --- a/templates/ci/modules/features/deadbugs/external-namespace-deep-aspect.nix +++ b/templates/ci/modules/features/deadbugs/external-namespace-deep-aspect.nix @@ -1,7 +1,7 @@ { denTest, inputs, ... }: { - flake.tests.deadbugs.namespace-deep-aspect = { + flake.tests.deadbugs-namespace-deep-aspect = { test-tools-has-underscore = denTest ( { provider, ... }: @@ -86,8 +86,8 @@ ]) ]; den.hosts.x86_64-linux.igloo.users.tux = { }; - den.aspects.igloo.includes = [ provider.tools._.dev._.user-stamp ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.aspects.igloo._.to-users.includes = [ provider.tools._.dev._.user-stamp ]; + den.ctx.user.includes = [ den._.mutual-provider ]; expr = igloo.users.users.tux.description; expected = "user-of-igloo"; } diff --git a/templates/ci/modules/features/deadbugs/issue-201-forward-multiple-users.nix b/templates/ci/modules/features/deadbugs/issue-201-forward-multiple-users.nix index 37dd253b..a849f232 100644 --- a/templates/ci/modules/features/deadbugs/issue-201-forward-multiple-users.nix +++ b/templates/ci/modules/features/deadbugs/issue-201-forward-multiple-users.nix @@ -13,14 +13,14 @@ }: { den.default.homeManager.home.stateVersion = "25.11"; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; den.hosts.x86_64-linux.igloo.users = { tux = { }; pingu = { }; }; - den.aspects.igloo.includes = [ + den.aspects.igloo._.to-users.includes = [ den._.define-user den.aspects.set-user-desc ]; diff --git a/templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-bidir-enabled.nix b/templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-mutual-enabled.nix similarity index 89% rename from templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-bidir-enabled.nix rename to templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-mutual-enabled.nix index 6f627cea..7799ffa1 100644 --- a/templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-bidir-enabled.nix +++ b/templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-mutual-enabled.nix @@ -2,7 +2,7 @@ { flake.tests.deadbugs-issue-292 = { - test-should-not-read-from-host-without-bidirectionality = denTest ( + test-should-not-read-from-host-without-mutuality = denTest ( { den, lib, diff --git a/templates/ci/modules/features/deadbugs/issue-297-bidirectional-not-including-host-owned-and-included-statics.nix b/templates/ci/modules/features/deadbugs/issue-297-mutual-not-including-host-owned-and-included-statics.nix similarity index 69% rename from templates/ci/modules/features/deadbugs/issue-297-bidirectional-not-including-host-owned-and-included-statics.nix rename to templates/ci/modules/features/deadbugs/issue-297-mutual-not-including-host-owned-and-included-statics.nix index 50836850..9b00d7ba 100644 --- a/templates/ci/modules/features/deadbugs/issue-297-bidirectional-not-including-host-owned-and-included-statics.nix +++ b/templates/ci/modules/features/deadbugs/issue-297-mutual-not-including-host-owned-and-included-statics.nix @@ -2,7 +2,7 @@ { flake.tests.deadbugs-issue-297 = { - test-bidirectional-host-owned = denTest ( + test-mutual-host-owned = denTest ( { den, lib, @@ -12,16 +12,16 @@ }: { den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - den.aspects.igloo.homeManager.home.keyboard.model = "denkbd"; + den.aspects.igloo._.to-users.homeManager.home.keyboard.model = "denkbd"; expr = tuxHm.home.keyboard.model; expected = "denkbd"; } ); - test-bidirectional-host-included-statics = denTest ( + test-mutual-host-included-statics = denTest ( { den, lib, @@ -31,17 +31,17 @@ }: { den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; den.aspects.base.homeManager.home.keyboard.model = "denkbd"; - den.aspects.igloo.includes = [ den.aspects.base ]; + den.aspects.igloo._.to-users.includes = [ den.aspects.base ]; expr = tuxHm.home.keyboard.model; expected = "denkbd"; } ); - test-bidirectional-host-owned-home-option = denTest ( + test-mutual-host-owned-home-option = denTest ( { den, lib, @@ -51,16 +51,16 @@ }: { den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - den.aspects.igloo.homeManager.options.foo = lib.mkOption { default = "foo"; }; + den.aspects.igloo._.to-users.homeManager.options.foo = lib.mkOption { default = "foo"; }; expr = tuxHm.foo; expected = "foo"; } ); - test-bidirectional-host-owned-host-option = denTest ( + test-mutual-host-owned-host-option = denTest ( { den, lib, @@ -70,12 +70,12 @@ }: { den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; # NOTE: this causes an error: Option already defined! - # This is because bidirectionality includes host configs again. + # This is because mutuality includes host configs again. # den.aspects.igloo.nixos.options.foo = lib.mkOption { default = "foo"; }; - # NOTE: Under bidirectionality, use perHost + # NOTE: Under mutuality, use perHost den.aspects.igloo.includes = [ (den.lib.perHost { nixos.options.foo = lib.mkOption { default = "foo"; }; diff --git a/templates/ci/modules/features/host-options.nix b/templates/ci/modules/features/host-options.nix index 47ca8e4a..62d7782d 100644 --- a/templates/ci/modules/features/host-options.nix +++ b/templates/ci/modules/features/host-options.nix @@ -56,8 +56,8 @@ { den, igloo, ... }: { den.hosts.x86_64-linux.igloo.users.tux.userName = "penguin"; - den.aspects.igloo.includes = [ den._.define-user ]; - den.ctx.user.includes = [ den._.bidirectional ]; + den.aspects.igloo._.to-users.includes = [ den._.define-user ]; + den.ctx.user.includes = [ den._.mutual-provider ]; expr = igloo.users.users.penguin.isNormalUser; expected = true; diff --git a/templates/ci/modules/features/perUser-perHost.nix b/templates/ci/modules/features/perUser-perHost.nix index 768952f9..ca12c093 100644 --- a/templates/ci/modules/features/perUser-perHost.nix +++ b/templates/ci/modules/features/perUser-perHost.nix @@ -28,21 +28,21 @@ nixos.funny = [ "atHost perHost ${host.name} fun" ]; } )) - (den.lib.perUser { nixos.funny = [ "atHost IGNORED perUser static" ]; }) + (den.lib.perUser { nixos.funny = [ (throw "atHost IGNORED perUser static") ]; }) (den.lib.perUser ( { user, host }: { - nixos.funny = [ "atHost IGNORED perUser ${user.name}@${host.name} fun" ]; + nixos.funny = [ (throw "atHost IGNORED perUser ${user.name}@${host.name} fun") ]; } )) ]; den.aspects.tux.includes = [ - (den.lib.perHost { nixos.funny = [ "atUser IGNORED perHost static" ]; }) + (den.lib.perHost { nixos.funny = [ (throw "atUser IGNORED perHost static") ]; }) (den.lib.perHost ( { host }: { - nixos.funny = [ "atUser IGNORED perHost ${host.name} fun" ]; + nixos.funny = [ (throw "atUser IGNORED perHost ${host.name} fun") ]; } )) (den.lib.perUser { nixos.funny = [ "atUser perUser static" ]; }) @@ -64,7 +64,7 @@ } ); - test-included-in-bidirectional-pipeline = denTest ( + test-included-in-mutual-pipeline = denTest ( { den, igloo, @@ -77,22 +77,19 @@ pingu = { }; }; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - # NOTE: Since options must be unique, include via perHost - den.aspects.funMod.nixos.options.funny = lib.mkOption { + den.aspects.igloo.nixos.options.funny = lib.mkOption { default = [ ]; type = lib.types.listOf lib.types.str; }; - den.aspects.igloo.includes = [ - (den.lib.perHost den.aspects.funMod) - - (den.lib.perHost { nixos.funny = [ "atHost perHost static" ]; }) + den.aspects.igloo._.to-users.includes = [ + (den.lib.perHost { nixos.funny = [ (throw "atHost perHost static") ]; }) (den.lib.perHost ( { host }: { - nixos.funny = [ "atHost perHost ${host.name} fun" ]; + nixos.funny = [ (throw "atHost perHost ${host.name} fun") ]; } )) (den.lib.perUser { nixos.funny = [ "atHost perUser static" ]; }) @@ -129,8 +126,6 @@ "atHost perUser static" # tux "atUser perUser tux@igloo fun" "atUser perUser static" - "atHost perHost igloo fun" - "atHost perHost static" ]; } ); diff --git a/templates/ci/modules/features/user-host-bidirectional-config.nix b/templates/ci/modules/features/user-host-mutual-config.nix similarity index 87% rename from templates/ci/modules/features/user-host-bidirectional-config.nix rename to templates/ci/modules/features/user-host-mutual-config.nix index dada3183..35936174 100644 --- a/templates/ci/modules/features/user-host-bidirectional-config.nix +++ b/templates/ci/modules/features/user-host-mutual-config.nix @@ -1,6 +1,6 @@ { denTest, ... }: { - flake.tests.user-host-bidirectional-config = { + flake.tests.user-host-mutual-config = { test-host-owned-unidirectional = denTest ( { @@ -15,7 +15,7 @@ pingu = { }; }; - # no bidirectionality enabled, this is ignored + # no mutuality enabled, this is ignored den.aspects.igloo.homeManager.programs.direnv.enable = true; expr = [ @@ -29,7 +29,7 @@ } ); - test-host-owned-bidirectional = denTest ( + test-host-owned-mutual = denTest ( { den, tuxHm, @@ -42,8 +42,8 @@ pingu = { }; }; - den.ctx.user.includes = [ den._.bidirectional ]; - den.aspects.igloo.homeManager.programs.direnv.enable = true; + den.ctx.user.includes = [ den._.mutual-provider ]; + den.aspects.igloo._.to-users.homeManager.programs.direnv.enable = true; expr = [ tuxHm.programs.direnv.enable @@ -56,7 +56,7 @@ } ); - test-host-bidirectional-static-includes-configures-all-users = denTest ( + test-host-mutual-static-includes-configures-all-users = denTest ( { den, tuxHm, @@ -69,9 +69,9 @@ pingu = { }; }; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - den.aspects.igloo.includes = [ + den.aspects.igloo._.to-users.includes = [ { homeManager.programs.direnv.enable = true; } @@ -122,7 +122,7 @@ } ); - test-host-parametric-bidirectional = denTest ( + test-host-parametric-mutual = denTest ( { den, tuxHm, @@ -136,9 +136,9 @@ pingu = { }; }; - den.ctx.user.includes = [ den._.bidirectional ]; + den.ctx.user.includes = [ den._.mutual-provider ]; - den.aspects.igloo.includes = [ + den.aspects.igloo._.to-users.includes = [ ( { host, user }: { From 3f94863a29e53e7d5957c0383c664a3f5b78dcaf Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Thu, 19 Mar 2026 12:20:09 -0600 Subject: [PATCH 2/2] fmt --- modules/context/user.nix | 1 - templates/ci/modules/features/auto-parametric.nix | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/context/user.nix b/modules/context/user.nix index b3f8337b..4dddb936 100644 --- a/modules/context/user.nix +++ b/modules/context/user.nix @@ -30,7 +30,6 @@ let from-user = { host, user }: fixedTo { inherit host user; } den.aspects.${user.aspect}; - in { den.ctx = ctx; diff --git a/templates/ci/modules/features/auto-parametric.nix b/templates/ci/modules/features/auto-parametric.nix index e5434bf8..aa981ab5 100644 --- a/templates/ci/modules/features/auto-parametric.nix +++ b/templates/ci/modules/features/auto-parametric.nix @@ -85,7 +85,6 @@ den.ctx.user.includes = [ den._.mutual-provider ]; den.aspects.igloo._.to-users.includes = [ den.aspects.strict-helper ]; - # strict-helper requires exactly { host, user } — since ctx.host only provides # { host }, strict-helper is skipped at host level (by exactly semantics). # At user level, { host, user } matches → description is set.