Files
hq/01-RESEARCH/026-the-graphical-session-as-modules/01-what-the-workstations-run.md
T
jochen de032e704c Research 026 (the graphical session) and 027 (the system layer)
Evidence from both workstations and all four machines, read-only, and the
questions each must answer: seats and gating for the display stack, who starts
the session with which environment, contributions beyond shells, sway as a
sibling session; the container runtime with docker-compose on workstations
only, software outside the official repositories, secrets in the account's
environment, and three security findings.
2026-10-04 11:17:34 +02:00

142 lines
8.1 KiB
Markdown

# 01 — What the workstations run
Measured 2026-10-04 on the two workstations of one installation, read-only: a laptop with a hybrid
GPU and an internal panel, and a desktop with one GPU and two external monitors. Both run the same
predecessor-generated desktop. File equality was checked by checksum across the two machines.
## How a session starts
The chain is the same on both:
1. The login manager (`lemurs`, built from the distribution's user repository, its package now in
the official one) runs its X setup script on a virtual terminal.
2. That script sources the login shell's profile files, then `~/.xprofile`, then the system's
`xinitrc.d` drop-ins, then merges `~/.Xresources`.
3. `~/.xprofile` reuses the systemd user manager's bus, then sources `~/.xinitrc`.
4. `~/.xinitrc` sets up the session and ends with `exec i3`.
The login manager's own window-manager entry (`exec startx`) is never reached. Its configuration
file uses a format two releases old, and an unmerged newer one sits beside it.
**What `~/.xinitrc` does**, in order:
1. Sources the system drop-ins, which import `DISPLAY` and `XAUTHORITY` into the user manager.
2. Starts the keyring and exports its ssh socket.
3. Exports the session's environment:
- `PATH`, with nine entries, one of them a directory that no longer exists;
- toolchain variables;
- `XDG_CONFIG_HOME` and `XDG_DATA_DIRS` (with flatpak);
- five GTK/Qt theme variables;
- the desktop's identity (`XDG_CURRENT_DESKTOP`, `XDG_SESSION_DESKTOP`);
- three of the operator's own variables.
4. Imports an explicit allowlist of ten of those into the user manager and D-Bus activation. It is
never `--all`, because:
5. a predecessor file of **secrets as environment variables** (package-registry and API tokens) is
sourced next.
6. Sets the screensaver and display power timeouts, restores the wallpaper, and starts the lock
watcher in a respawn loop. It is deliberately not a unit, because it needs the login session.
7. `exec i3`.
**The account's environment, as of today, has three sources that disagree:**
- this file, for the session;
- the mesh's `environment.sh`, for shells
([ADR 0203](../../02-DECISIONS/0203-the-accounts-environment-is-one-modules-and-every-module-contributes-to-it.md));
- `~/.config/environment.d/`, for the user manager. It holds the mesh's `50-mesh.conf`, and a
predecessor file that **sets `PATH` outright** and sorts after it.
## The roles, and what fills them
| role | software | where configured |
|---|---|---|
| login manager | lemurs | `/etc/lemurs/*` (identical on both, and to the predecessor's source) |
| session start and environment | the login manager's X setup, `~/.xprofile`, `~/.xinitrc`, `xinitrc.d`, the D-Bus import, `environment.d` | `~/.xprofile`, `~/.xinitrc`, `~/.config/environment.d/*` |
| display server | Xorg (`xorg-server`, `xinit`, the X apps; vendor drivers per GPU) | **no** `xorg.conf.d`; monitors by `xrandr` scripts |
| monitor layout | `xrandr` scripts (arandr), a hotplug rule on the laptop | `~/.screenlayout/`, a scripts folder, a window-manager fragment |
| window manager | i3 4.25 | `~/.config/i3/config` and `config.d/*`, a reload watcher (user unit) |
| bar | i3bar with i3status-rust | `~/.config/i3status-rust/*`, 14 themes, a bar watchdog (user unit) |
| terminal | xterm (the only terminal installed) | `~/.Xresources.d/xterm`, the window manager's binding, the compositor's opacity rule |
| compositor | picom | `~/.config/picom/picom.conf` |
| launcher and menus | rofi | `~/.config/rofi/*`, launcher, power-menu and theme-picker scripts |
| notifier | dunst (D-Bus activated) | `~/.config/dunst/dunstrc`, `dunstrc.d/*` |
| lock, idle, display power | xss-lock and i3lock-color, `xset` | `~/.xinitrc`, a lock script |
| clipboard | greenclip, xclip | `greenclip.toml` |
| wallpaper | feh | `~/.fehbg` (points into the predecessor's tree) |
| theming | Adwaita dark, qt5ct/qt6ct, the desktop portal (GTK backend pinned) | GTK `settings.ini`, `qt*ct.conf`, `portals.conf`, an appearance script, `.Xresources` cursor |
| fonts | Hack and Meslo Nerd fonts in `~/.local/share/fonts` (not packaged), noto | `~/.Xresources.d/xft` (DPI fixed at 96) |
| keyboard | nothing set; the default layout; vendor keys via triggerhappy on the laptop | window-manager bindings, `/etc/triggerhappy` |
**Packages:** every piece except two is in the distribution's official repositories, and the login
manager now is too. The two exceptions are the lock screen's colour build (`i3lock-color`) and the
clipboard manager (`rofi-greenclip`). The Nerd fonts exist as official packages, but both machines
carry hand-copied files instead.
## Identical, different, and why
**Byte-identical on both machines:**
- the session files: `.xinitrc`, `.xprofile`, `.Xresources` and its drop-ins;
- the i3 main configuration and two of its fragments;
- the bar's top configuration and themes;
- picom, rofi, the GTK and Qt settings, the portal configuration, the login manager.
**Different, by cause:**
| cause | what |
|---|---|
| hardware | the monitor layout script; the bar's battery block; the laptop's power and vendor-key units and udev rules |
| misassignment | the desktop carries the **laptop's** hardware fragments: the vendor-key daemon and its triggers, the backlight rule, the brightness drop-in, a touchpad reset, and the laptop's monitor layouts, in an older version |
| drift | the notifier's position and corner radius; a "temporary" window-manager fragment from a test; the bar watchdog disabled; a second Qt configuration tool; different font builds |
| a stale session | the desktop's session began before two fixes, so it runs two notification daemons and two portals, and its user manager lacks the desktop's identity |
**Dead references:** the window manager starts a polkit agent that is installed on neither machine,
so there is no polkit agent at all. `PATH` names a directory that does not exist.
**Per-machine values inside shared files:**
- the DPI;
- absolute home paths, in the clipboard configuration and the flatpak data directories;
- the laptop's panel name, inside a fragment both machines carry.
## User units the desktop needs
| unit | does | laptop | desktop |
|---|---|---|---|
| reload watcher | reloads the window manager and bar when their files change | on | on |
| bar watchdog | restarts a dead bar | on | off |
| clipboard daemon | from its package | via the window manager | unit **and** window manager |
| vendor power profile, memory guard | laptop power | on | — |
None is managed. Applying them as the account needs the host's user scope
([ADR 0177](../../02-DECISIONS/0177-a-unit-may-be-user-scoped-and-the-service-manager-is-a-node-seat.md)),
which is still an open change.
## The predecessor's module
One manifest of 983 lines covers the window manager, bar, launcher, notifier, compositor, lock
screen, session bootstrap, theming and scripts. It:
- has four *flavors*: i3, laptop (i3 plus the monitor wizard and hotplug), desktop (i3 plus
nothing) and a laptop model (laptop plus vendor keys);
- has about **105 theme variables** substituted into templates: border, gaps, fonts, workspace
names, every colour of bar, launcher, notifier and lock screen, compositor opacity, cursor, idle
times, Qt and GTK theme names;
- enables the two user units from an install hook.
Separate modules held the login manager and the display server (one flavor, `xorg`, with a comment
calling `wayland` "the intended sibling"). The shell module held no graphical part.
## Wayland and sway
**Nothing exists.** There is no compositor, no sway configuration, no Wayland session entry, and the
login manager's Wayland directory is empty. What is installed is libraries:
- Wayland itself and the Qt Wayland plugins, which other packages pull in;
- `xwayland`, explicitly installed and required by nothing;
- on the desktop, an orphaned compositor library from another desktop environment, and that
environment's portal backend, pulled in by a game launcher. The portal configuration pins
against it.
Every piece a sway session needs is in the official repositories: the compositor, its lock screen,
a terminal (`foot`), a bar (`waybar`), a notifier (`mako`) and `xwayland`.