169 lines
8.6 KiB
Markdown
169 lines
8.6 KiB
Markdown
# TASK 76 — Provisioning belongs to a package, per device, per arch
|
||
|
||
**Status:** in progress 2026-08-24. The ViewTop session edge, wrapper targets,
|
||
and x86 SDDM entry are package-owned. Package-owned QuickShell content,
|
||
commission-time activation, removal of local shadows, fresh-install proof and
|
||
the first x86 ViewTop login remain.
|
||
**Size:** one session for the audit fixes, a second for the provision packages.
|
||
|
||
Every souveraine binary ships as a package. Activation is only partly owned:
|
||
ViewTop now carries its x86 session entry, while five system files on the two
|
||
live devices remain unowned and one shadows a packaged unit on both machines
|
||
at once.
|
||
|
||
## Measured 2026-08-15
|
||
|
||
`pacman -Qo` across the laptop (souveraine r506) and the phone (r503):
|
||
|
||
```
|
||
phone /etc/pam.d/souveraine-sessiond Jul 16 21:17 UNOWNED
|
||
phone /etc/systemd/system/souveraine-machined.service Jul 16 12:36 UNOWNED
|
||
phone /etc/systemd/system/souveraine-splash.service Jul 17 08:23 UNOWNED
|
||
phone /etc/systemd/user/souveraine-shell.service Jul 17 07:49 UNOWNED
|
||
laptop /etc/systemd/system/souveraine-machined.service UNOWNED
|
||
```
|
||
|
||
All five were hand-placed inside one 20-hour window on 2026-07-16/17 — the
|
||
Phase C session in `session-authority-boot-order.md` — and none has been
|
||
touched since.
|
||
|
||
**The shadow is live on both devices.** `systemctl show souveraine-machined -p
|
||
FragmentPath` returns `/etc/systemd/system/souveraine-machined.service` on the
|
||
laptop *and* the phone. `/etc/systemd/system` outranks `/usr/lib/systemd/system`,
|
||
so the packaged copy — which both machines carry and `pacman -Qo` attributes to
|
||
`souveraine` — is inert. machined is the Ed25519 identity signer; every
|
||
capability token in the system descends from the unit systemd is not reading.
|
||
|
||
Nothing misbehaves today: the laptop's two copies are byte-identical. That is
|
||
what makes it dangerous. The first packaged change to that unit — the tmpfiles
|
||
socket ACL `provisioning-gaps.md` §6 still owes, ordering, hardening — lands in
|
||
a file nothing loads, and `-Syu` reports success.
|
||
|
||
**Activation is unpackaged too.** The sessiond unit ships correctly from
|
||
`PKGBUILD.prebuilt:51` to `/usr/lib/systemd/user/` on both arches, and on both
|
||
devices it is `disabled` and `active` — started by a hand-written line in a
|
||
file that lives in no repo:
|
||
|
||
```
|
||
laptop ~/.config/hypr/hyprland/execs.lua:19 systemctl --user start souveraine-sessiond.service
|
||
phone ~/.config/hypr/hyprland.lua:420 systemctl --user reset-failed …; systemctl --user restart souveraine-sessiond.service
|
||
```
|
||
|
||
Two devices, two different invocations, versioned nowhere. Reinstall either
|
||
machine and its proprioception does not come up.
|
||
|
||
## The root cause: nobody was lighting the target
|
||
|
||
Measured 2026-08-15: `graphical-session.target` is inactive on both devices.
|
||
Every `[Install] WantedBy=` in the tree is written against a target that never
|
||
runs, so activation has been hand-rolled in lua instead. Five symptoms, one
|
||
cause — sensord dead every boot until 07-27, the grip costing a day on 07-29,
|
||
sessiond's `[Install]` inert, edge-sense forced to hang off a *service* rather
|
||
than a target, and both lua lines existing at all.
|
||
|
||
Four docs and one PKGBUILD had recorded *"nothing starts
|
||
graphical-session.target"* as settled fact and drawn the wrong conclusion from
|
||
it: **don't use the target**, where the available conclusion was **light the
|
||
target**. Corrected in place 2026-08-15 (`TASK-40`, `DUMP-keyboards-2026-07-29`
|
||
×2, `saf/device/edge-sense.md`, `pkgs/blueline-edge-sense/PKGBUILD`).
|
||
|
||
**The phone's session leader already did the hard half.**
|
||
`/usr/bin/souveraine-session-viewtop`, package-owned by `souveraine-viewtop`,
|
||
waits for the Wayland socket and runs both `dbus-update-activation-environment
|
||
--systemd` and `systemctl --user import-environment`. It then hand-kicked three
|
||
units with `reset-failed`, `restart` and a `sleep 3` — a hand-rolled `PartOf=`
|
||
and a hand-rolled `After=`, respectively. It now starts the targets instead:
|
||
|
||
```
|
||
graphical-session-pre.target sessiond takes ext-session-lock
|
||
graphical-session.target shell, keyboard, every surface
|
||
```
|
||
|
||
Sessiond cannot start earlier than this: `ext-session-lock` is a Wayland
|
||
protocol and needs the compositor's socket. `-pre` is exactly the window
|
||
systemd reserves for it.
|
||
|
||
The `sleep 3` is replaced by a bounded wait on
|
||
`$XDG_RUNTIME_DIR/souveraine/sessiond.sock`, because `Type=simple` means
|
||
systemd calls sessiond started the instant it forks — before it holds the lock.
|
||
That block deletes itself when sessiond gains `Type=notify`.
|
||
|
||
### Still unowned after this lands
|
||
|
||
```
|
||
phone ~/.config/hypr/hyprland.lua 558 lines, md5 2808e7fe…
|
||
repo Pixel3Arch/overlays/hypr/hyprland.lua 545 lines, md5 16f0170a…
|
||
```
|
||
|
||
Thirteen lines of the phone's hyprland config exist in no repo, and the
|
||
laptop's `~/.config/hypr/hyprland/execs.lua` has no repo home at all. Hyprland
|
||
is being retired in favour of viewtop, so this matters only until the laptop
|
||
reaches parity — but until then a laptop reinstall loses sessiond activation
|
||
on the fallback Hyprland path.
|
||
|
||
## X86 session edge — packaged and selected 2026-08-24
|
||
|
||
`souveraine-viewtop` r127 (`0.1.0.r127.g58b09e6d914c-1`) owns
|
||
`/usr/share/wayland-sessions/viewtop-x86.desktop`. Its visible name is
|
||
**ViewTop on x86** and its `Exec`/`TryExec` both point at the package-owned
|
||
`/usr/bin/souveraine-session-viewtop` launcher. The signed package installed
|
||
cleanly; `pacman -Qkk` reported 16 files with none altered.
|
||
|
||
`/var/lib/sddm/state.conf` now selects that entry. The previous selector was
|
||
copied to `state.conf.before-viewtop-20260824`. No logout or display-manager
|
||
restart was performed: the live Hyprland session began on 2026-08-15, while
|
||
ViewTop r127 arrived on 2026-08-24. Configuration and package ownership are
|
||
proved; an x86 ViewTop login is not.
|
||
|
||
## What is missing
|
||
|
||
1. **The four unowned files get a package.** PAM has a rail already —
|
||
`PKGBUILD.prebuilt:15` carries `backup=('etc/pam.d/souveraine-stepup')` and
|
||
installs it at `:103`; `souveraine-sessiond`'s PAM file simply never got
|
||
added. `souveraine-machined.service` is already packaged to
|
||
`/usr/lib/systemd/system/`; the `/etc/` copies are what must go, and
|
||
removing a file no package owns needs Casey's hand, not a hook.
|
||
2. **A `souveraine-provision-<device>` package per device.** Owns the `.wants`
|
||
symlinks that replace both lua lines, plus device-scoped config. `blueline`
|
||
and the laptop are the two that exist; the arch split falls out of the
|
||
package's own `arch=()`.
|
||
3. **Delete the vestigial `[Install]` section**, or make it correct. Two
|
||
activation paths where one black-screens the device is not a choice a
|
||
reader should be offered.
|
||
4. **`rootfs-overlay/etc/systemd/user/souveraine-sessiond.service` in
|
||
Pixel3Arch is a loaded gun.** Verified *not* on the phone — there is no
|
||
`/etc/systemd/user/souveraine-sessiond.service` and `FragmentPath` is the
|
||
packaged one. If a flash ever lands it, it shadows every future package
|
||
update of that unit permanently. Same question for
|
||
`rootfs-overlay/etc/pam.d/souveraine-sessiond`.
|
||
5. **`session-authority-boot-order.md`'s deploy checklist is stale and
|
||
harmful.** Its §1 still says build on-device and install to
|
||
`/usr/local/bin`, which `souveraine/CLAUDE.md` banned on 2026-07-24. Fix in
|
||
place; do not delete the doc.
|
||
|
||
## Acceptance
|
||
|
||
- `pacman -Qo` returns an owner for every `souveraine-*` file under
|
||
`/etc/pam.d`, `/etc/systemd`, and `/usr/lib/systemd` on both devices.
|
||
- `systemctl show souveraine-machined -p FragmentPath` returns the
|
||
`/usr/lib/systemd/system/` path on both devices.
|
||
- Neither `hyprland.lua` nor `execs.lua` mentions sessiond; both devices still
|
||
come up with sessiond active after a cold boot, and the lock surface is the
|
||
shell's, not the fallback PIN.
|
||
- A fresh install of either device brings up sessiond with no hand-editing.
|
||
|
||
## Connects to
|
||
|
||
`docs/provisioning-gaps.md` §4 named this requirement on 2026-07-16 —
|
||
*"installed by packaging, enabled at commission"* — for `souveraine-server`.
|
||
The packaging half landed everywhere; the commission half is the node ceremony
|
||
`FEDERATION.md` still parks, and this task is its first concrete piece.
|
||
|
||
TASK-25 (one repo, all packages) and TASK-27 (overlay is not a package) own the
|
||
*delivery* rails; TASK-28 owns authority moving mid-upgrade. This is neither —
|
||
it is who owns activation at commission time, which has had no task file. If a
|
||
future session decides it belongs inside 27, fold it there rather than leaving
|
||
two.
|
||
|
||
`SESSION-AUTHORITY-DOCTRINE` §11 (one authority) is the reason the machined
|
||
shadow matters: two copies of the signer's unit is two answers to who signs.
|