fix(idle): #127 — input wakes the screen compositor-side; revert the clamshell skip
All checks were successful
Check / eval (push) Successful in 3m33s
All checks were successful
Check / eval (push) Successful in 3m33s
The idle brick was never DPMS. Hyprland ships misc:key_press_enables_dpms
and misc:mouse_move_enables_dpms OFF, so hypridle's on-resume was the ONLY
caller of `dpms on` in the session — an idle daemon with the display held
hostage behind it. hypridle then deadlocks on an unfixed upstream bug
(hyprwm/hypridle#171, "Disconnected from pollfd id 1", open since 2025-09,
absent from 0.1.7 and main) and hangs WITHOUT exiting, so Restart=always
never fires and systemd still reports it active (running). Blank + deadlock
= a black seat no keypress can escape. That was the brick: two mundane bugs,
not one exotic DRM state. 19 disconnects in 11 days on the dev box, incl.
the incident day; the compositor is healthy through all of them.
Both options on, so the wake lives in the compositor where no daemon can
lose it — a dead hypridle now costs auto-lock, not the machine. The #127
clamshell DPMS-off skip (060bf52) is therefore reverted: idle blanks again
in every dock/lid state, and the 27" panels stop being held lit all night
under a static lock screen. #135 (an option to opt back in) is retired
unbuilt — there is nothing left to opt into.
TEST B's first run was invalid and nearly bought the wrong answer: it ran
`hyprctl dispatch dpms off` by hand, which no wake path watches, so "input
did not wake it" was guaranteed on any hardware. The undocked control
returning the SAME result — where the theory demanded a difference — is what
exposed it. Driven through hypridle instead, input wakes it in all three
configurations, including clamshell-docked on the sole live output.
Filed from the diagnosis: #146 (hypridle dies silently, systemd calls it
healthy — the surviving bug) and #147 (a re-login leaves session units dead;
graphical-session.target never re-enters, which is why Waybar already runs
from exec-once).
V3 on the incident hardware (AMD dev box, clamshell): hypridle deliberately
stopped, `dpms off` -> keypress woke it in 6s; the identical test before the
options stayed black the full 45s. V1: nix flake check, checks.option-docs,
checks.clamshell-logind, checks.docking-ux, checks.display-profiles; read the
emitted hyprland.conf/hypridle.conf rather than the source.
V3 pending: the fix is proven via runtime `hyprctl keyword`, not yet from our
own Nix — HARDWARE-QUEUE re-checks it after nomarchy-home + relogin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
221
agent/BACKLOG.md
221
agent/BACKLOG.md
@@ -31,163 +31,8 @@ post-boot sessions). Preserve separation: the installer bake failure and the
|
||||
flake pin are different root causes even when they show up on the same machine.
|
||||
(Terminal / Ghostty-on-Acer → shipped as Kitty-only, #95.)
|
||||
|
||||
### 127. `[blocked:hw]` Docked idle: black screens, no wake, undock does not restore panel
|
||||
|
||||
Bernardo 2026-07-15 (AMD dev box, docked): left the laptop docked; after a
|
||||
few minutes of idle it appeared to "sleep". Then:
|
||||
|
||||
1. External keyboard/mouse did **not** wake any display.
|
||||
2. Unplugging the external monitor did **not** turn the laptop panel back
|
||||
on (dock mode has eDP disabled — undock *should* re-enable it).
|
||||
3. The machine was still alive: Caps Lock LED toggled on the keyboard.
|
||||
|
||||
This also killed a long agent session (looked like a "crash" from the
|
||||
outside). Separate from awake undock recovery (HARDWARE-QUEUE round 8):
|
||||
the failure is **idle while docked**, then no path back to a usable panel.
|
||||
|
||||
**Likely shape (code-side, unconfirmed on the incident):** on AC, hypridle
|
||||
does **not** call `systemctl suspend` (`onAc || suspend` — only battery
|
||||
suspends at 15 min). Idle path is lock @5 min + `dpms off` @10 min
|
||||
(`modules/home/idle.nix`). Caps Lock working fits **DPMS/lock blackout**
|
||||
better than deep S3. Dock mode has already disabled eDP; recovery then
|
||||
needs either (a) input → hypridle `on-resume` / `dpms on` on the external,
|
||||
or (b) undock → `nomarchy-display-transition undock` re-enabling the
|
||||
panel. Both failed. `after_sleep_cmd` only does `hyprctl dispatch dpms on`
|
||||
and never re-enables a disabled internal.
|
||||
|
||||
**Progress 2026-07-15:**
|
||||
- Recovery tooling: undock ends with `dpms on`; `nomarchy-display-wake` /
|
||||
`nomarchy-display-dump` (SUPER+SHIFT+D; TTY if it works).
|
||||
- **Mitigation (shipped):** do **not** DPMS-off when **clamshell** — if any
|
||||
laptop internal (eDP/LVDS/DSI) exists in `monitors all` but is not
|
||||
enabled, the 10 min listener skips blanking. Lock at 5 min still runs;
|
||||
undocked laptops still DPMS-off as before. Bernardo: Ctrl+Alt+F3 did
|
||||
not yield a usable TTY on the original brick, so prevention > dump path.
|
||||
- **Scope settled (#136, 2026-07-16):** the gate is *clamshell*, not
|
||||
"docked" — and Bernardo confirms the incident was exactly that, **laptop
|
||||
closed**. So the code matched the evidence and only the wording
|
||||
overclaimed; that is fixed (idle.nix, ROADMAP, and the journal line, now
|
||||
`dpms-off skipped: clamshell`). Docked with the lid **open** still blanks
|
||||
and is untested — not exempted, not claimed safe.
|
||||
- **Revisit later (LATER):** intentional DPMS-when-clamshell once wake is
|
||||
proven trustworthy (monitor power-save without a brick). Tracked as
|
||||
**#135** (state key + the surface to delete this by), downstream of the
|
||||
hardware test below.
|
||||
- **Caveat the test must settle:** the mitigation is a cure for an
|
||||
**unconfirmed cause**. "Blanking the only live output caused the brick"
|
||||
is inference from one incident, shipped at V1. If DPMS-off is not the
|
||||
trigger, we are paying a permanent behaviour cost (docked externals never
|
||||
sleep) and the brick is still live — so confirming the cause outranks
|
||||
#135/#136.
|
||||
- **Symptom 2 is SOLVED, and it was not DPMS (ff5017e, 2026-07-16).** Bernardo
|
||||
reproduced "unplugging did not turn the laptop panel back on" live, minutes
|
||||
after TEST A — with **no blanking involved at all** (the mitigation had kept
|
||||
the external lit). Cause: `awaiting_lid_open` is set by every successful
|
||||
undock and cleared only when the external is gone **and** the lid is open, so
|
||||
a clamshell undock **latches** it; a re-dock clears its sibling
|
||||
`undock_pending` but not the latch, and the next departure is then silently
|
||||
dropped by the `[ -z "$awaiting_lid_open" ]` guard. His journal shows the
|
||||
first undock logging *nothing*, a release the instant he lifted the lid, then
|
||||
a clean undock. Replaying the sequence with the lid never opened: 1 of 3
|
||||
undocks ran; fixed, 3 of 3. **What this does to the theory:** the original
|
||||
brick may simply have been an ordinary blank plus a recovery that could not
|
||||
run — two mundane bugs, not one exotic DRM state. TEST B is now the only
|
||||
thing standing between that hypothesis and the truth, and it is a much safer
|
||||
test with the latch fixed (an undock is a real escape hatch again).
|
||||
|
||||
**Pass (current mitigation):** clamshell-docked on AC, idle past 10+ min →
|
||||
external stays lit under hyprlock (journal: `dpms-off skipped: clamshell`);
|
||||
undocked still blanks at 10 min and wakes on input. Full original pass (wake
|
||||
after DPMS-while-clamshell) deferred to the LATER revisit.
|
||||
|
||||
---
|
||||
|
||||
### The two tests, exactly (2026-07-16)
|
||||
|
||||
**There is no SSH lifeline on this box** (`sshd` inactive), which is why test B
|
||||
self-recovers instead of relying on one. If you would rather have the net, turn
|
||||
`services.openssh.enable = true` on for the day and keep a phone SSH client
|
||||
open — then a brick is a nuisance, not a reboot.
|
||||
|
||||
**Test A — does the mitigation hold? (safe, ~15 min, unattended)**
|
||||
1. Docked, **lid closed**, on AC. Leave it completely alone for 12 minutes.
|
||||
2. Expect: at 5 min the external shows hyprlock; at 10 min it **stays lit**.
|
||||
3. Then: `journalctl --user -b -t nomarchy-idle --since '-15 min'`
|
||||
→ one `dpms-off skipped: clamshell (internal eDP-1 present but off)`.
|
||||
4. Now open the lid / undock, idle 11 min → the panel **should** blank, and
|
||||
wake on a keypress. That half must still work; the mitigation is not
|
||||
supposed to have disabled blanking everywhere.
|
||||
|
||||
**Test B — was DPMS-off actually the trigger? (the decisive one; bounded)**
|
||||
This is the test that outranks everything else here, because the mitigation is
|
||||
a cure for an *inferred* cause. Docked, **lid closed**, from a terminal on the
|
||||
external:
|
||||
|
||||
```sh
|
||||
( sleep 45
|
||||
hyprctl dispatch dpms on
|
||||
hyprctl reload # re-enables every output (the #142 hammer)
|
||||
) >/tmp/dpms-test.log 2>&1 &
|
||||
hyprctl dispatch dpms off
|
||||
```
|
||||
|
||||
The screen goes black. Then, in order:
|
||||
1. **Press keys / move the mouse** in the first ~40s. Does it come back?
|
||||
(In the incident it did not — this is the exact step that failed.)
|
||||
2. **Wait for the 45s auto-recovery.** Does the external return by itself?
|
||||
3. If it is still dark, **open the lid** — the `reload` should have re-enabled
|
||||
eDP even if the external stayed dead.
|
||||
4. Afterwards:
|
||||
`journalctl --user -b -t nomarchy-idle -t nomarchy-display-watch --since '-5 min'`
|
||||
|
||||
**What each outcome means — all three are useful:**
|
||||
- **Input wakes it** → DPMS-off is **not** the trigger. The mitigation is a
|
||||
permanent behaviour cost buying nothing, the brick is still live and
|
||||
un-diagnosed → revert the skip, **#135 never exists**, and hunt the real
|
||||
cause (hyprlock? hypridle's own resume path? the dock's DP link?).
|
||||
- **Dark until the 45s recovery, then fine** → the compositor was alive and
|
||||
`dpms on` works, so blanking-while-clamshell *is* the trigger and the
|
||||
mitigation is right → **#135 becomes the way to opt back in**.
|
||||
- **Dark even after recovery** (lid needed) → the original brick, reproduced
|
||||
**deterministically and on demand**. That is the best outcome: it turns a
|
||||
once-off incident into something bisectable (try it without hyprlock, with
|
||||
the lid open, on the internal only …).
|
||||
|
||||
Note the deliberate omission: this runs `dpms off` **by hand** rather than
|
||||
waiting for hypridle, precisely because the shipped mitigation would otherwise
|
||||
skip it. Same command, same state, no rebuild.
|
||||
|
||||
**Fallback if the cause resists (Bernardo 2026-07-16):** diagnosing stays the
|
||||
preference — DPMS when docked is the outcome we want. But the mitigation as
|
||||
shipped holds a near-static lock screen on the externals indefinitely, so if
|
||||
the cause cannot be pinned down, a **screensaver while docked** is the
|
||||
consolation prize: it protects the panels (burn-in — the same cost #135
|
||||
names) without re-entering the blanking path that bricked the session. Not a
|
||||
new item: it is the "if diagnosis fails" branch of this one, and #135's state
|
||||
key is where it would land.
|
||||
|
||||
## NEXT
|
||||
|
||||
### 135. Give the #127 DPMS mitigation a state key (and a way back)
|
||||
|
||||
The shipped mitigation is hardcoded policy: docked (clamshell) externals now
|
||||
**never** blank, and hyprlock has no timeout of its own, so they stay lit
|
||||
indefinitely. Two real costs land on the user — a couple of 27" panels at
|
||||
~60–100W all night, and **OLED burn-in** from a near-static lock screen held
|
||||
for hours. Today there is no way to opt back in, which also breaks the
|
||||
in-flake-state rule that settings are menu-writable.
|
||||
|
||||
Add `settings.idle.dpmsWhenDocked` (default **false** = today's safe
|
||||
behaviour), read by `modules/home/idle.nix`'s `dpmsOff` gate, with a
|
||||
Preferences row. The real point is not the option: it gives the mitigation a
|
||||
**named surface to delete** once wake is proven, instead of an unowned LATER
|
||||
note that quietly becomes the product. Whoever removes the mitigation removes
|
||||
the key in the same commit.
|
||||
|
||||
**Order:** after the #127 hardware test. If DPMS-off turns out not to be the
|
||||
trigger, the mitigation is reverted wholesale and this key never exists —
|
||||
building it first risks shipping an option for a policy we withdraw.
|
||||
|
||||
### 143. Rofi keeps the selected *row number* when the search changes, so the highlight lands on an unrelated entry
|
||||
|
||||
Bernardo 2026-07-16, and his repro is exact: open the app menu, type `ca`, move
|
||||
@@ -246,14 +91,6 @@ the next lock bump, that is fine — nothing here rots meanwhile.
|
||||
|
||||
## LATER
|
||||
|
||||
- **DPMS when docked (revisit #127):** today we **skip** display blanking
|
||||
while any laptop internal is present-but-disabled (dock/clamshell), so
|
||||
idle only locks. That avoids blanking the sole external and the brick
|
||||
where wake/TTY failed (2026-07-15). Revisit when we want monitor
|
||||
power-save on dock again: re-enable DPMS-off for that mode only if
|
||||
`nomarchy-display-wake` (or better) reliably restores the external and
|
||||
undock-while-black restores eDP on the AMD dock setup — without
|
||||
depending on SSH. Until then, leave the skip in `modules/home/idle.nix`.
|
||||
- **Wallpapers artifact split** (ROADMAP § Faster switches — decided,
|
||||
deferred): pinned `Nomarchy-wallpapers` input so a state write stops
|
||||
re-copying 86 MB. Follow-on: pre-built theme variants if switches are
|
||||
@@ -299,6 +136,64 @@ high-ROI, etc.) live in the journal + ROADMAP — not here.*
|
||||
|
||||
### Product / day-2
|
||||
|
||||
### 146. hypridle dies silently and systemd calls it healthy
|
||||
|
||||
Fell out of the #127 diagnosis (2026-07-16, ROADMAP § "#127 solved"), and it is
|
||||
the bug that was actually behind the brick — the DPMS gate we just reverted was
|
||||
only ever a symptom shield. hypridle hits an unfixed upstream deadlock
|
||||
(hyprwm/hypridle#171, "Disconnected from pollfd id 1" — open since 2025-09, in
|
||||
neither 0.1.7 nor main; upstream's own reporter saw 10-hour hangs) and then
|
||||
**hangs without exiting**, so `Restart=always` never fires and `systemctl
|
||||
--user is-active` still says `active (running)`. On the dev box: **19 times in
|
||||
11 days**, including the incident day. Jul 14 is the clean example — locking
|
||||
normally at 13:02, `CRITICAL` at 13:08:17, then eleven hours of silence, with
|
||||
D-Bus receive queues visibly backing up (48 KB unread) because nothing was
|
||||
reading them. The compositor is *fine* through all of it (no other session unit
|
||||
dies in the same second), so this is not the compositor's death taking it down.
|
||||
|
||||
Now that input wakes the screen compositor-side this is no longer brick-class,
|
||||
but it is not cosmetic either: a silently dead hypridle means **no auto-lock**
|
||||
(Bernardo sat unlocked for 25 min on 2026-07-16 without knowing), no blank, no
|
||||
idle suspend. Cost: systemd can't see it — `WatchdogSec` needs `sd_notify`
|
||||
hypridle doesn't implement, and the process never exits — so detection has to be
|
||||
external: a guard watching for the `CRITICAL` line, or a liveness probe on its
|
||||
Wayland fd, then `systemctl --user restart hypridle`. **Sequence it after #147**:
|
||||
today's disconnect was the compositor dying, and restarting hypridle into a dead
|
||||
compositor just fail-loops into `start-limit-hit` exactly as cliphist does. The
|
||||
trigger is still unknown — *not* dock/undock (no display-watch activity in the
|
||||
3 min before any of them) and *not* a D-Bus quota disconnect (no broker errors).
|
||||
Worth a reproducer + an upstream comment on #171: it has sat ten months on
|
||||
vaxerski's "that will cause a segfault no?", and we have better data than the
|
||||
reporter did.
|
||||
|
||||
### 147. A re-login leaves the session's user units dead, and nothing brings them back
|
||||
|
||||
Bernardo, 2026-07-16: after re-logging in, Waybar took 5+ seconds and
|
||||
nomarchy-doctor reported cliphist, network-manager-applet and udiskie failing.
|
||||
Root cause is the session lifecycle, not those apps. Hyprland exited at
|
||||
17:25:39 and the replacement came up at **17:25:52** — a 13-second gap — but
|
||||
`graphical-session.target` never re-entered (its `ActiveEnterTimestamp` still
|
||||
read 08:03:32, from the *morning's* session). So: units with a restart policy
|
||||
burn their start limit inside that gap against a Wayland socket that does not
|
||||
exist yet (cliphist's journal is explicit — `wl-paste: Failed to connect to a
|
||||
Wayland server`, 5 restarts in one second, `start-limit-hit` at 17:25:40,
|
||||
twelve seconds before the new compositor existed); units without one
|
||||
(nm-applet, udiskie) simply die once and stay dead forever. Nothing re-enters
|
||||
the target, so nothing recovers.
|
||||
|
||||
We have already paid for this once without naming it: `modules/home/hyprland.nix`
|
||||
launches Waybar from `exec-once` rather than a unit, and the comment there says
|
||||
why — "bound to graphical-session.target the unit raced Hyprland's IPC on
|
||||
relogin". That is this bug, worked around for one service; the 5-second Waybar
|
||||
start is the workaround being slow instead of failing. Fix is the standard
|
||||
wiring the repo never adopted: the compositor imports `WAYLAND_DISPLAY` +
|
||||
`HYPRLAND_INSTANCE_SIGNATURE` into the user manager and starts/stops a
|
||||
`hyprland-session.target` on entry/exit (Home Manager's
|
||||
`wayland.windowManager.hyprland.systemd.enable`, or uwsm). Cost: touches how
|
||||
every session service is bound, so it wants a VM pass and a real relogin on
|
||||
hardware — but it would let Waybar go back to being a unit and unblock #144's
|
||||
guard.
|
||||
|
||||
### 120. A netinstall ISO, next to the fat offline one
|
||||
|
||||
**Deferred to PROPOSED 2026-07-16 (Bernardo): not now.** Nothing below is
|
||||
|
||||
@@ -16,7 +16,7 @@ Run these first when you have a laptop session (AMD dev box unless noted):
|
||||
| # | Item | Why first |
|
||||
|---|------|-----------|
|
||||
| 1 | **#115** suspend-then-hibernate | Just shipped; quick path is minutes (battery vs AC + `nomarchy-suspend`) |
|
||||
| 2 | **#127** docked idle blackout | Real incident; capture path before it bit-rots |
|
||||
| 2 | **#127** fix from config (not runtime keyword) | Cause found + fixed 2026-07-16; confirm our Nix emits it and it survives a relogin |
|
||||
| 3 | **Docking recovery round 8** + headphone jack-follow | Same dock session; relogin once, then undock ×5 + jack |
|
||||
| 4 | **#104** airplane mode | Fast radio smoke after `nomarchy-home` |
|
||||
| 5 | **#101** charge-limit USB-C burst | Dock plug/unplug storm; pairs with #3 |
|
||||
@@ -49,36 +49,36 @@ Everything else below stays open; order is convenience, not a gate.
|
||||
restores **only** the radios that were on before. If Wi-Fi was already
|
||||
off, it must stay off after disengage. Glyph must **not** appear when
|
||||
airplane is off.
|
||||
- [ ] **#127 clamshell idle — TEST A, the mitigation holds (AMD dev box)** —
|
||||
**Context:** original brick = clamshell-docked idle → black, no input
|
||||
wake, undock no eDP, Caps Lock alive; Ctrl+Alt+F3 gave no usable TTY.
|
||||
**Shipped mitigation:** skip DPMS-off while clamshell (internal
|
||||
present-but-disabled); lock at 5m still.
|
||||
**After `nomarchy-home` + relogin:**
|
||||
1. Dock, **lid closed** (eDP in `hyprctl monitors all -j`, absent from
|
||||
`hyprctl monitors`).
|
||||
2. Leave it entirely alone past 10+ min.
|
||||
3. **Pass:** external still shows hyprlock (not black power-save);
|
||||
`journalctl --user -t nomarchy-idle --since '-20 min'` has
|
||||
`dpms-off skipped: clamshell`.
|
||||
4. Undocked control: eDP only → at 10 min it *does* blank; input wakes.
|
||||
Optional: `nomarchy-display-dump` / SUPER+SHIFT+D for other display faults.
|
||||
- [ ] **#127 TEST B — was DPMS-off the trigger at all? (AMD dev box)** —
|
||||
**This one outranks #135**: the mitigation is a cure for an *inferred*
|
||||
cause, and if the inference is wrong we are paying for it forever while
|
||||
the brick stays live. Bounded and self-recovering (there is no sshd on
|
||||
that box). Full protocol + how to read each outcome: **BACKLOG #127 §
|
||||
"The two tests, exactly"**. In short — docked, lid closed:
|
||||
```sh
|
||||
( sleep 45; hyprctl dispatch dpms on; hyprctl reload ) &
|
||||
hyprctl dispatch dpms off
|
||||
```
|
||||
then (1) try to wake it with input in the first ~40s, (2) let the 45s
|
||||
recovery run, (3) open the lid if still dark. **Input wakes it** → the
|
||||
mitigation is pointless, revert it and #135 never exists. **Dark until
|
||||
recovery** → mitigation confirmed, #135 is the opt-in. **Dark after
|
||||
recovery** → the brick, now reproducible on demand, which is the best
|
||||
outcome available.
|
||||
- [x] **#127 TESTS A + B — ANSWERED 2026-07-16 (AMD dev box), both closed.**
|
||||
TEST B ran and DPMS-off is **not** the trigger: with hypridle driving the
|
||||
blank, input woke it in all three configurations including clamshell-docked
|
||||
on the sole live output. The mitigation was reverted and #135 retired
|
||||
unbuilt, which also voids TEST A (its premise — the skip — no longer
|
||||
exists). Real cause: Hyprland's input→DPMS options ship off, so hypridle's
|
||||
`on-resume` was the only caller of `dpms on`, and hypridle deadlocks
|
||||
(hyprwm/hypridle#171) without exiting. Full record: ROADMAP § "#127
|
||||
solved"; the surviving bug is BACKLOG #146. **Method note worth keeping:**
|
||||
the *first* TEST B was invalid — it ran `dpms off` by hand, which no wake
|
||||
path watches, so its "input did not wake it" was guaranteed regardless of
|
||||
hardware. Drive the real code path or measure nothing.
|
||||
- [ ] **#127 fix from config, not a runtime keyword (AMD dev box)** —
|
||||
the fix was proven with `hyprctl keyword` (runtime-only); this checks our
|
||||
Nix actually emits it and that it survives a session. **After
|
||||
`nomarchy-home` + relogin:**
|
||||
1. `hyprctl getoption misc:key_press_enables_dpms` and
|
||||
`misc:mouse_move_enables_dpms` → both `int: 1` with **no** manual
|
||||
keyword set.
|
||||
2. Docked, **lid closed**, idle 10+ min → the external **blanks** (it no
|
||||
longer stays lit; that is the revert working).
|
||||
3. Press a key → it comes back. `journalctl --user -t
|
||||
nomarchy-display-wake --since '-15 min'` shows a `done enabled=…` line
|
||||
(hypridle's on-resume also ran).
|
||||
4. The one that matters — the brick condition on purpose:
|
||||
`systemctl --user stop hypridle`, then
|
||||
`( sleep 45; hyprctl dispatch dpms on ) &` and
|
||||
`hyprctl dispatch dpms off`. **Pass:** a keypress wakes it with
|
||||
hypridle stopped (it did in 6s on 2026-07-16 via runtime keyword).
|
||||
Then `systemctl --user start hypridle`.
|
||||
- [ ] **#96 battery-limit row on threshold-less firmware (Acer M5-481T)** —
|
||||
on the Acer (live or installed session with the commit carrying this
|
||||
entry): open System (`SUPER+CTRL+I`). **Pass:** a "Battery limit" row
|
||||
|
||||
@@ -19,6 +19,39 @@ Template:
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-16 — #127 SOLVED: the brick was never DPMS, and TEST B's first run lied
|
||||
- **Task:** #127 TEST B (Bernardo ran it), then the whole sweep his result forced.
|
||||
- **Read this if nothing else — the test measured nothing, and said so.** His run
|
||||
reported "input never wakes it" **docked *and* undocked alike**, and that tie is
|
||||
the tell: the theory demanded those differ. It ran `dpms off` **by hand**, which
|
||||
no wake path watches, so "input didn't wake it" was guaranteed on any hardware
|
||||
in any dock state. Re-run *through* hypridle so `on-resume` is actually armed:
|
||||
input woke it in all 3 configs, **including clamshell on the sole live output**
|
||||
(`done enabled=1 first=DP-2`) — the incident's exact geometry. Put the mechanism
|
||||
under test inside the circuit, or you are measuring your own scaffolding.
|
||||
- **Real cause:** Hyprland ships `misc:{key_press,mouse_move}_enables_dpms` **off**,
|
||||
so hypridle's `on-resume` was the ONLY caller of `dpms on` anywhere in the session
|
||||
— and hypridle deadlocks (hyprwm/hypridle#171, open since 2025-09, in neither
|
||||
0.1.7 nor main) **without exiting**, so `Restart=always` never fires and systemd
|
||||
still reports it active. Blank + deadlock = a black seat no key escapes. **19× in
|
||||
11 days** on his box, incl. the incident day. Two mundane bugs, not one exotic one.
|
||||
- **Did:** both options on — structural: the wake moves into the compositor where no
|
||||
daemon can lose it, so a dead hypridle costs auto-lock, not the machine. Reverted
|
||||
the clamshell skip; **#135 retired unbuilt**; ROADMAP § "#127 solved"; filed #146
|
||||
(hypridle mortality) + #147 (relogin leaves session units dead) → PROPOSED.
|
||||
- **Verified: V3 on the incident hardware.** Clamshell, hypridle **deliberately
|
||||
stopped** (brick condition on purpose), `dpms off` → keypress woke it in **6s**;
|
||||
the identical test before the options stayed black the full 45s. V1: `flake check`
|
||||
+ `option-docs`/`clamshell-logind`/`docking-ux`/`display-profiles` pass, and I read
|
||||
the **emitted** configs, not the source (`key_press_enables_dpms=true`;
|
||||
`on-timeout=hyprctl dispatch dpms off`, skip script gone).
|
||||
- **Pending:** V3 — proven via runtime `hyprctl keyword`, NOT from our Nix yet;
|
||||
HARDWARE-QUEUE entry re-checks after `nomarchy-home` + relogin. Ctrl+Alt+F3 dead
|
||||
during the incident is still unexplained (upstream co-symptom, hypridle#145).
|
||||
- **Next suggestion:** #147 before #146 — a guard that restarts hypridle into a dead
|
||||
compositor just fail-loops into `start-limit-hit` exactly like cliphist does. Both
|
||||
are PROPOSED; Bernardo triages.
|
||||
|
||||
## 2026-07-16 — #129/#130 buttons; #133; #132; branding; and a latch bug from TEST A
|
||||
- **Task:** Bernardo triaged the queue (#136 settled, #130 decided, #143 → wait,
|
||||
#120 → PROPOSED), then #133, #132, the codename drop, and #129+#130.
|
||||
|
||||
Reference in New Issue
Block a user