···11---
22-title: Host<->User Mutual Configurations
22+title: Host<->User Bidirectionality
33description: How to configure bidirectional behavior in Den.
44---
55···1212[`mutual-provider.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix)
1313</Aside>
14141515-## What Mutual Configurations Means
1515+## What Bidirectionality Means
16161717__Bidirectionality__ means that not only a User contributes
1818configuration to a Host, but **also** that a Host contributes
···4141We need to build the `nixos` Nix module that will later be used by `lib.nixosSystem`.
4242To do so, Den invokes the `den.ctx.host` pipeline like this:
43434444+> `Tip: Zoom diagrams using your mouse wheel or drag to move.`
44454546```mermaid
4647sequenceDiagram
···5354 Den ->> host : {host = igloo}
54555556 host ->> igloo : request nixos class
5656- igloo -->> igloo : each igloo.includes takes { host }
5757+ igloo -->> igloo : each .includes takes { host }
5758 igloo -->> host : { nixos = ... } owned and parametric results
58595960 host ->> user : fan-outs for each user: { host, user }
60616162 user ->> tux : request nixos class
6263 tux -->> tux : home classes forwarded as nixos class
6363- tux -->> tux : each tux.includes takes { host, user }
6464+ tux -->> tux : each .includes takes { host, user }
6465 tux -->> user : { nixos = ... } owned and parametric results
65666667 user -->> host : { nixos = ... } all user contributions
···88898990When Bidirectionality is enabled, the interaction looks like this:
90919292+> `Tip: Zoom diagrams using your mouse wheel or drag to move.`
9393+9194```mermaid
9295sequenceDiagram
9396 participant Den
···99102 Den ->> host : {host = igloo}
100103101104 host ->> igloo : request nixos class
102102- igloo -->> igloo : each igloo.includes takes { host }
105105+ igloo -->> igloo : each .includes takes { host }
103106 igloo -->> host : { nixos = ... } owned and parametric results
104107105108 host ->> user : fan-outs for each user: { host, user }
···107110 user ->> tux : request nixos class
108111109112 tux ->> igloo : request home class
110110- igloo -->> igloo : each igloo.includes takes { host, user }
113113+ igloo -->> igloo : each .includes takes { host, user }
111114 igloo -->> tux : { hjem = ... } owned and parametric results
112115113116 tux -->> tux : home classes forwarded as nixos class
114117115115- tux -->> tux : each tux.includes takes { host, user }
118118+ tux -->> tux : each .includes takes { host, user }
116119 tux -->> user : { nixos = ... } owned and parametric results
117120118121 user -->> host : { nixos = ... } all user contributions
···121124122125```
123126124124-Crucial points here are `igloo.includes takes { host }` and `igloo.includes takes { host, user }`.
127127+Crucial points here are when `den.aspects.igloo.includes` are called with `{ host }` and later with `{ host, user }` per-user.
125128126126-Because the list of aspects at `igloo.includes` get invoked twice, with different contexts,
129129+Because the list of aspects at `igloo.includes` get invoked more than once, with different contexts,
127130functions at `igloo.includes` must take care of the following:
128131129132```nix
···143146This 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.
144147145148```nix
146146-den.default.includes = [ den._.mutual-provider ];
149149+# mutual-provider is activated at a `{host,user}` context
150150+den.ctx.user.includes = [ den._.mutual-provider ];
147151148152# user aspect provides to specific host or to all where it lives
149153den.aspects.tux = {
···161165 };
162166};
163167```
168168+169169+> `Tip: Zoom diagrams using your mouse wheel or drag to move.`
170170+171171+```mermaid
172172+sequenceDiagram
173173+ participant Den
174174+ participant host as den.ctx.host
175175+ participant user as den.ctx.user
176176+ participant igloo as den.aspects.igloo
177177+ participant igloo-users as den.aspects.igloo.provides.to-users
178178+ participant igloo-tux as den.aspects.igloo.provides.tux
179179+ participant tux as den.aspects.tux
180180+ participant tux-hosts as den.aspects.tux.provides.to-hosts
181181+ participant tux-igloo as den.aspects.tux.provides.igloo
182182+183183+ Den ->> host : {host = igloo}
184184+185185+ host ->> igloo : request nixos class
186186+ igloo -->> igloo : each .includes takes { host }
187187+ igloo -->> host : { nixos = ... } owned and parametric results
188188+189189+ host ->> user : fan-outs for each user: { host, user }
190190+191191+ user ->> tux : request nixos class
192192+ tux -->> tux : home classes forwarded as nixos class
193193+ tux -->> tux : each .includes takes { host, user }
194194+ tux -->> user : { nixos = ... } owned and parametric results
195195+196196+ user ->> igloo-users : host configs its users: { host, user }
197197+ igloo-users -->> igloo-users : home classes forwarded as nixos class
198198+ igloo-users -->> igloo-users : each .includes takes { host, user }
199199+ igloo-users -->> user : { nixos = ... }
200200+201201+ user ->> igloo-tux : host configs tux: { host, user }
202202+ igloo-tux -->> igloo-tux : home classes forwarded as nixos class
203203+ igloo-tux -->> igloo-tux : each .includes takes { host, user }
204204+ igloo-tux -->> user : { nixos = ... }
205205+206206+ user ->> tux-hosts : user configs its hosts: { host, user }
207207+ tux-hosts -->> tux-hosts : home classes forwarded as nixos class
208208+ tux-hosts -->> tux-hosts : each .includes takes { host, user }
209209+ tux-hosts -->> user : { nixos = ... }
210210+211211+ user ->> tux-igloo : user configs igloo: { host, user }
212212+ tux-igloo -->> tux-igloo : home classes forwarded as nixos class
213213+ tux-igloo -->> tux-igloo : each .includes takes { host, user }
214214+ tux-igloo -->> user : { nixos = ... }
215215+216216+217217+ user -->> host : { nixos = ... } all user contributions
218218+219219+ host -->> Den : complete nixos module for lib.nixosSystem
220220+221221+```
222222+
+1-10
modules/aspects/provides/mutual-provider.nix
···1414 The reason is that this battery does not re-invoke the `host-aspect.includes`,
1515 instead it relies on you defining provides.
16161717- Unlike `den.default` which is `parametric.atLeast` we use
1818- `parametric.fixedTo` here, which help us propagate an already computed
1919- context to all includes.
2020-2121- This battery, when installed in a `parametric.atLeast` will just forward
2222- the same context. The `find-mutual` helper returns an static configuration
2323- which is ignored by parametric aspects, thus allowing non-existing
2424- aspects to be just ignored.
2525-2617 Be sure to read diagrams for the Host context pipeline:
2718 https://den.oeiuwq.com/guides/bidirectional
28192920 ## Usage
30213122 den.hosts.x86_64-linux.igloo.users.tux = { };
3232- den.default.includes = [ den._.mutual-provider ];
2323+ den.ctx.user.includes = [ den._.mutual-provider ];
33243425 # user aspect provides to specific host or to all where it lives
3526 den.aspects.tux = {