ADR 0208: the graphical session is one module per piece, on the mesh's seats

Eleven node seats; a display as a provision with the machine's reach; other
modules' lines through the tool's own drop-in directory or ADR 0204's slots,
now also for xinitrc and xresources; the display server's module writes the
session's start.
This commit is contained in:
jochen
2026-10-04 12:29:13 +02:00
parent 0ba68c154e
commit 502cf4839b
3 changed files with 141 additions and 2 deletions
@@ -0,0 +1,138 @@
---
topic: what runs on it
status: accepted
date: 2026-10-04
deciders: jochen
reconstructed: false
extends: 02-DECISIONS/0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md
---
# 208. The graphical session is one module per piece, on the mesh's seats
## Context
The two workstations run one predecessor desktop
([research 026](../01-RESEARCH/026-the-graphical-session-as-modules/00-overview.md)). It was a module of
983 lines with four flavors and 92 theme variables. One of its machines carried another machine model's
hardware files, and its session's environment was a hand-kept copy of the account's. The operator asked
for the desktop as modules at the shell's level, consistent across machines, with sway as a sibling of i3.
To-be 38 named this WP7, and to-be 37 left one question for the resolver: how a module says it needs a
display server held on its node.
## Considered Options
- **One desktop module, as before** (research 026 §1, G1). Rejected: flavors again, and the evidence is
a flavor on the wrong machine.
- **One module per piece of software.** Chosen.
- **For "i3 needs an X server" (research 026 §3):**
- a new field (R2), rejected as a second way to say what provisions already say;
- assigning carefully (R3), rejected because that is the misassignment the evidence shows;
- **a provision with the machine's reach** (R1), chosen.
- **For other modules' lines in a holder's file (research 026 §5):**
- only drop-ins (C1), rejected because two files the session needs have no drop-in convention;
- only slots (C2), rejected as needless where the tool already reads a directory;
- **both, the boundary drawn by the tool** (C3), chosen.
## Decision
**1. One module per piece of software:** `lemurs`, `xorg`, `i3`, `xterm`, `picom`, `rofi`, `dmenu`,
`dunst`, the lock screen, `xclip`, the clipboard manager, `feh`, `i3status-rust`, a theme module,
`fonts`, `gnome-keyring`, and later `sway`, `foot`, `waybar` and `mako`. No flavors. What follows a
machine's hardware is that model's hardware module (research 027/03).
**2. The roles are node seats in the mesh's own set,** each with the verbs research 026/05 starts it with:
| seat | holders | verbs to start with |
|---|---|---|
| `node-login-manager` | lemurs | `sessions` |
| `node-display-server` | xorg, sway | `displays`, `layout` |
| `node-display-session` | i3, sway | `reload`, `workspaces`, `windows` |
| `node-terminal-emulator` | xterm, foot | `open` |
| `node-launcher` | rofi, dmenu | `menu`, the dmenu-compatible command |
| `node-notifier` | dunst, mako | `send`, `history` |
| `node-lock-screen` | the lock module, swaylock | `lock` |
| `node-clipboard` | the clipboard manager | `history`, `copy` |
| `node-bar`, `node-compositor` | i3status-rust, waybar; picom | none yet |
| `node-secret-service` | gnome-keyring | none yet |
A compositor that is its own server holds two seats, as sway does.
**3. A display is a provision with the machine's reach.**
- A display server provides `x11-display` or `wayland-display`, reachable only on its own machine.
- A module that draws on a display requires the one it speaks: i3, picom, xterm and the X lock require
`x11-display`; sway's companions require `wayland-display`.
- A requirement with the machine's reach is resolved on the requiring module's own node, or not at
all, and is refused naming the seat's holders.
- `xwayland`, as its own module, provides `x11-display` inside a Wayland session.
This answers to-be 37 §4 by reusing provisions and reach rather than a new field. A capability the host
reports, `graphical-session`, still gates the display server itself.
**4. Other modules contribute to a holder's file in the tool's own grain.**
- Where the tool reads a directory, the contributor places its own file there:
- i3's `include` directory;
- dunst's `dunstrc.d`;
- XDG autostart;
- `environment.d`;
- fontconfig's `conf.d`;
- ssh's `config.d`;
- the login manager's session directory.
- Where it does not, **ADR 0204's slots serve beyond shells.** A `shell` contribution's `for` may also
name:
- `xinitrc`: POSIX code the session's start runs;
- `xresources`: X resources merged at session start.
The holder of `node-display-server` places them with `${shell:xinitrc:<slot>}` and
`${shell:xresources:<slot>}`.
**5. The display server's module writes the session's start.** It writes a block at the start of
`~/.xinitrc`, in this order:
1. it sources the account's environment (ADR 0203);
2. it imports the session's own variables into the user manager and D-Bus activation, by an explicit
list;
3. it merges the X resources;
4. it runs the `xinitrc` slots;
5. it ends by starting the session holder's command, which the session module contributes in the
`last` slot.
The desktop's identity and the theme variables are environment contributions of the session and
theme modules. The hand-kept environment in today's file goes, and so does the predecessor's file of
secrets (research 027 question 2).
**6. Per-machine values:**
- Monitor layouts are profiles keyed by the monitors' identities (research 026/04). They are the
operator's data, and the display server's `layout` verb manages them.
- DPI and theme values are module defaults now, and settings after issue 168.
## Consequences
- A workstation's desktop is a list of assignments, the same on both. The one machine model's
hardware is one more assignment.
- The X stack is built first, and sway is designed in from the start.
- The controller learns:
- the eleven seats;
- provisions with the machine's reach;
- two more names for a contribution's `for`.
- **What got harder:** a module that draws must say which display it speaks, and one that wants both
ships twice.
## How it is checked
| Rule | Checked by |
|---|---|
| The seats are in the mesh's own set, refused to any module that declares them | the seat table's tests |
| A machine-reach requirement resolves on its own node only, refused naming the holders | the controller's resolve tests |
| `xinitrc` and `xresources` slots are placed only by the display server's holder | the catalogue check |
| The session block sources the environment, merges resources, runs the slots and ends with the session | the `xorg` module's manifest test, and on the proving workstation |
## References
- [Research 026](../01-RESEARCH/026-the-graphical-session-as-modules/00-overview.md), its 02, 04 and 05
- [ADR 0203](0203-the-accounts-environment-is-one-modules-and-every-module-contributes-to-it.md),
[ADR 0204](0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md),
[ADR 0207](0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md)
- [To-be 42](../03-DESIGN/01-to-be/42-the-machines-modules-in-order.md)
+1
View File
@@ -306,6 +306,7 @@ python3 00-META/checks/index.py fail if stale
- **0204** — [A module contributes shell code to the login shell in named slots, and the login shell is the mesh's seat](0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md)
- **0205** — [Software the distribution does not package ships as a pinned archive of the module's own](0205-software-the-distribution-does-not-package-ships-as-a-pinned-archive-of-the-module.md)
- **0206** — [A node reports the Anthropic grant it holds; the licence manager adopts a licence by refreshing it, and what each node should hold is the manager's state](0206-a-node-reports-the-anthropic-grant-it-holds-and-the-licence-manager-adopts-a-licence-by-refreshing-it.md)
- **0208** — [The graphical session is one module per piece, on the mesh's seats](0208-the-graphical-session-is-one-module-per-piece-on-the-meshs-seats.md)
### How it is built
@@ -14,6 +14,7 @@ decisions:
- 02-DECISIONS/0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md
- 02-DECISIONS/0205-software-the-distribution-does-not-package-ships-as-a-pinned-archive-of-the-module.md
- 02-DECISIONS/0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md
- 02-DECISIONS/0208-the-graphical-session-is-one-module-per-piece-on-the-meshs-seats.md
---
# 42. The machines' modules, in order
@@ -90,8 +91,7 @@ In order:
8. `gnome-keyring`;
9. `docker-compose`, `snapd`, `flatpak`, `cups`, `bluetooth`.
The seats, gating and session-start questions of research 026 §2–§5 are recorded when `xorg` and `i3`
need them.
The seats, gating, contributions and session start are [ADR 0208](../../02-DECISIONS/0208-the-graphical-session-is-one-module-per-piece-on-the-meshs-seats.md).
## Phase 3 — one machine model