docs(backlog): file #157 redundant hyprlock on suspend-then-hibernate resume
All checks were successful
Check / eval (push) Successful in 4m12s
All checks were successful
Check / eval (push) Successful in 4m12s
On LUKS machines the s2h auto-hibernate path resumes to a hyprlock screen despite the LUKS passphrase already gating resume — a second password. Root cause: s2h's hibernate phase runs inside systemd-suspend-then-hibernate.service and never activates hibernate.target, so nomarchy-unlock-before-encrypted-hibernate (wantedBy hibernate.target) never fires; and phase-1 already started hyprlock, which a live Wayland session-lock cannot safely drop. Direct systemctl hibernate is unaffected. Shares the s2h switch with #155; safe failure mode (never leaves unlocked). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,46 @@ risk. Look into: what polls fprintd on that interval (hyprlock fingerprint backe
|
|||||||
from `nomarchy.idle.fingerprint`? a geoclue/other watcher?), and whether the reset is
|
from `nomarchy.idle.fingerprint`? a geoclue/other watcher?), and whether the reset is
|
||||||
avoidable (autosuspend quirk, or gating the poll). Cost: investigation only; low.
|
avoidable (autosuspend quirk, or gating the poll). Cost: investigation only; low.
|
||||||
|
|
||||||
|
### 157. Redundant hyprlock on suspend-then-hibernate resume (encrypted disks)
|
||||||
|
|
||||||
|
Filed 2026-07-24 (dev box, reported by Bernardo + journal-confirmed). On a LUKS
|
||||||
|
machine, resuming from the **suspend-then-hibernate** path lands on a **hyprlock** screen
|
||||||
|
even though the LUKS passphrase already gated the resume — a second password. The design
|
||||||
|
intent (idle.nix + `nomarchy-{lock,unlock}-before-*` in `modules/nixos/default.nix`) is
|
||||||
|
exactly "no hyprlock on encrypted hibernate — LUKS is the gate"; it holds for a **direct**
|
||||||
|
`systemctl hibernate` but **not** for s2h.
|
||||||
|
|
||||||
|
**Root cause (two layers).** (1) s2h's hibernate phase runs *inside*
|
||||||
|
`systemd-suspend-then-hibernate.service` and **never activates `hibernate.target`** —
|
||||||
|
journal-confirmed: at the phase-2 transition (`Performing sleep operation 'hibernate'`
|
||||||
|
from the same `systemd-sleep` PID) there is no target, no "Starting System Hibernate",
|
||||||
|
no unit/`system-sleep` hook at all. So `nomarchy-unlock-before-encrypted-hibernate`
|
||||||
|
(`wantedBy = hibernate.target`) never fires for s2h, whereas direct hibernate *does*
|
||||||
|
reach the target and unlock. (2) The deeper problem: phase-1 (the RAM suspend) *must*
|
||||||
|
lock (`nomarchy-lock-before-sleep` is `wantedBy` `suspend-then-hibernate.target`), so
|
||||||
|
**hyprlock is already up** before phase-2 — and a live Wayland session-lock **cannot be
|
||||||
|
safely dropped** (idle.nix: killing the locker trips hyprlock's "go to a tty" failsafe).
|
||||||
|
The whole unlock-before-hibernate design only works because for direct hibernate hyprlock
|
||||||
|
is *never up*; s2h violates that premise, and there is no systemd event between the two
|
||||||
|
phases to un-ring the bell.
|
||||||
|
|
||||||
|
**Scope.** Encrypted disk + the s2h auto-hibernate path only (the default idle path on
|
||||||
|
battery). Direct `systemctl hibernate`/Power ▸ Hibernate is fine. Not a security hole —
|
||||||
|
the redundant lock is the *safe* failure (never leaves you unlocked).
|
||||||
|
|
||||||
|
**Options (all have a cost).** (a) Accept it — safe default, one extra password.
|
||||||
|
(b) Skip locking on s2h for encrypted — removes the redundant lock but leaves the ≤1h
|
||||||
|
RAM-suspend window **unlocked** (real exposure; advise against). (c) A **safe external
|
||||||
|
hyprlock-dismiss** — the only clean fix, gated on whether current hyprlock exposes an
|
||||||
|
IPC/socket to unlock without the tty-failsafe (needs investigating; may not exist).
|
||||||
|
|
||||||
|
**Intersection:** shares the s2h switch with **#155** — flipping
|
||||||
|
`nomarchy.system.power.suspendThenHibernate = false` on a box makes *both* the redundant
|
||||||
|
lock and the #155 crash exposure disappear (cost: no auto-hibernate-on-idle). Positioning:
|
||||||
|
correctness gap in a shipped v1 feature (**VISION § Theme C**, hibernate/sleep confidence).
|
||||||
|
Files: `modules/nixos/default.nix` (~257–286), `modules/home/idle.nix` (hypridle: no
|
||||||
|
`unlock_cmd`; the design comment).
|
||||||
|
|
||||||
### 146. `[watch]` hypridle hangs instead of exiting when its compositor vanishes
|
### 146. `[watch]` hypridle hangs instead of exiting when its compositor vanishes
|
||||||
|
|
||||||
**Re-measured 2026-07-20 (dev box; user journal is persistent back to 2026-05-01,
|
**Re-measured 2026-07-20 (dev box; user journal is persistent back to 2026-05-01,
|
||||||
|
|||||||
Reference in New Issue
Block a user