docs: RETRACT the #127 cause — the diagnosis was a measurement artifact; fix stands
All checks were successful
Check / eval (push) Successful in 3m30s

The "blank + hypridle deadlock = the brick" cause published this morning is
retracted everywhere it was asserted: ROADMAP, hyprland.nix's comment, #146,
HARDWARE-QUEUE and two commit messages (a2151f4, 321ccf7). It rested on two
pieces of evidence and both were artifacts of how I measured:

- "19 disconnects in 11 days": 18 of 19 are hypridle's noisy goodbye while
  systemd DELIBERATELY stops it — each bracketed by `Stopped hypridle` /
  `Started hypridle`, healthy replacement seconds later.
- "Jul 14: CRITICAL at 13:08:17, then eleven hours of silence": an artifact of
  grepping ONE PID. systemd logged `Stopped hypridle` 13:08:17 and `Started
  hypridle` 13:09:00; PID 1678 ran fine all evening, invisible to the filter.

Decisive: at the incident (before the 12:51:34 mitigation commit) hypridle had
NO disconnect at all and had been healthy since Jul 14 13:09. It should have
fired on-resume normally. The deadlock theory never had a case.

The FIX stands on its own evidence and is untouched: the options really were
off, hypridle's on-resume really was the only caller of `dpms on`, and input now
wakes the screen with hypridle deliberately stopped (4s docked / 6s clamshell).
Removing a proven single point of failure never needed a story about why the
daemon might fail — which is exactly why it survived the story being wrong.

#127 is RESTORED to NOW (deleted this morning as "shipped"; only the fix
shipped). Its cause is open and the lead is the dead Ctrl+Alt+F3 — neither
DPMS-off nor a dead hypridle can break VT switching, so something was wedged
below the compositor holding DRM master. Every theory so far has been about the
wake path, i.e. a symptom of the screen already being black.

#146 → [watch], near-dead: one genuine zombie ever (verified by ps/ss, not
grep); upstream #171 is real but its impact path closed when #147's stray linger
went. Re-measure properly before building anything; close unbuilt if zero.

Also closes the #127 hardware-queue entry: Bernardo ran the real 10-min idle —
19:27:58 dpms off (genuine timeout, shipped config, and it BLANKED = the revert
working) -> mouse -> 19:32:14 `done enabled=1 first=DP-2`, clamshell, the
incident geometry, one healthy hypridle throughout. All 4 steps pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 19:39:27 +01:00
parent 90f0faf87b
commit bdc86d0f41
5 changed files with 214 additions and 83 deletions

View File

@@ -622,10 +622,12 @@ Design/decision records and a running log of shipped work (items marked
that could not run — two mundane bugs, not one exotic DRM state. The shipped
DPMS mitigation may therefore be treating the wrong cause; #127's TEST B is
what decides, and it is far safer now that an undock works again.
**It did decide, the same day: the hunch was right on both counts** — the
mitigation *was* treating the wrong cause and is now reverted, and the brick
*was* two mundane bugs (an ordinary blank + a wake path that had died). See
"#127 solved" below.
**It did decide, the same day — half of the hunch was right.** The mitigation
*was* treating the wrong cause and is now reverted (blanking while clamshell
is provably innocent). But "an ordinary blank + a recovery that could not run"
is **not** established: the wake path had a real single point of failure, which
is fixed, yet nothing shows it had failed *during the incident*. The brick's
cause is still open. See "#127's WAKE PATH fixed" below.
- ✓ **The #107 compat shim is pinned (#133, 2026-07-16):** `mkFlake` prefers
`state.json` and still accepts the legacy `theme-state.json`, because a
machine only migrates on its next menu write — but nothing evaluated a
@@ -727,19 +729,19 @@ Design/decision records and a running log of shipped work (items marked
`nomarchy-suspend` (hypridle + Power menu). LUKS: unlock session before
encrypted hibernate phase so resume is LUKS-only (not hyprlock twice).
Menu row self-gates on CanHibernate. V3: HARDWARE-QUEUE bag-carry test.
- ✓ **#127 solved — the idle brick was never DPMS (2026-07-16, AMD dev box):**
the clamshell DPMS-off skip (060bf52, and its #136 wording fix) is
**reverted**; idle blanks again in every dock/lid state. Hyprland ships
`misc:key_press_enables_dpms` and `misc:mouse_move_enables_dpms` **off**, and
nothing else in the session calls `dpms on` — so hypridle's `on-resume` was
the *only* thing that could un-blank a screen: 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 is the brick: two mundane bugs, not one exotic DRM state — the same
shape as the #100 latch above.
- ✓ **#127's WAKE PATH fixed — but the brick's cause is still open (2026-07-16,
AMD dev box).** Read the title carefully: the fix below is proven and shipped;
the *diagnosis* published alongside it on the day was **wrong and is retracted
in place** (see "What was claimed, and why it was wrong" below). The clamshell
DPMS-off skip (060bf52, and its #136 wording fix) is **reverted**; idle blanks
again in every dock/lid state.
**What is true and load-bearing.** Hyprland ships `misc:key_press_enables_dpms`
and `misc:mouse_move_enables_dpms` **off**, and nothing else in the session
calls `dpms on` — so hypridle's `on-resume` was the *only* thing that could
un-blank a screen: an idle daemon with the display held hostage behind it.
That is a real single point of failure, and it is now gone. It needed no story
about *why* the daemon might fail to justify removing it — which is exactly
why the fix survived its own diagnosis being wrong.
**Evidence, on the incident hardware.** With hypridle driving the blank,
input woke it in all three configurations — including clamshell-docked on the
sole live output (`nomarchy-display-wake done enabled=1 first=DP-2`), which
@@ -760,10 +762,41 @@ Design/decision records and a running log of shipped work (items marked
(an option to opt back into DPMS-when-clamshell) is therefore **retired
unbuilt** — there is nothing left to opt into, and the 27" panels stop being
held lit all night under a static lock screen.
**Still open:** hypridle's silent death is its own bug (~2×/week on this box;
no auto-lock is a security cost even when the screen is recoverable), and the
incident's dead Ctrl+Alt+F3 remains unexplained — a known co-symptom upstream
(hyprwm/hypridle#145) but not accounted for here. Tooling kept:
**What was claimed, and why it was wrong (retracted the same day).** This
entry, `hyprland.nix`'s comment and two commit messages all said the brick was
"blank + hypridle deadlock": hypridle hitting hyprwm/hypridle#171, hanging
without exiting so `Restart=always` never fires, leaving a blanked seat with
nothing left to call `dpms on`. Cited evidence: "19 disconnects in 11 days",
and Jul 14 as the clean example — "locking normally at 13:02, `CRITICAL` at
13:08:17, then eleven hours of silence". **All of it was an artifact of how it
was measured.** 18 of the 19 `Disconnected from pollfd id 1` lines are
hypridle's noisy goodbye while systemd *deliberately stops it* — each one
bracketed by `Stopped hypridle` / `Started hypridle`, with a healthy
replacement seconds later. The "eleven hours of silence" came from grepping a
single PID (`hypridle[1679]`): systemd logged `Stopped hypridle` at 13:08:17
and `Started hypridle` at 13:09:00, and PID 1678 ran fine all evening where
the filter could not see it. Only **one** genuine zombie has ever existed here
(2026-07-16 17:25:39, verified by process inspection — `ps`, `ss` showing
unread D-Bus queues, `NRestarts=0` — not by grep), and it needed stray
pre-migration linger to persist (BACKLOG #147). **The decisive fact:** at the
time of the brick (before the 12:51:34 mitigation commit) hypridle had **no
disconnect at all** — it had been running healthily since Jul 14 13:09. It
should have fired `on-resume` normally. The deadlock theory never had a case.
**The lesson is the same one this entry teaches about TEST B**, which is what
makes it worth the space: the invalid test measured its own scaffolding, and
so did the diagnosis that replaced it — a grep that could only see one PID,
and a rate that counted normal shutdown noise. Both times the error was
inferring where checking was available and cheap. Verify the instrument before
believing the reading, *especially* when the reading confirms the theory.
**Still open — #127's cause, now the lead question (BACKLOG #127).** We know
the wake path had a single point of failure and we removed it; we do **not**
know what actually bricked the machine. The **dead Ctrl+Alt+F3 is the strongest
clue and points away from everything examined so far**: neither DPMS-off nor a
dead hypridle can break VT switching, so something was wedged below the
compositor — DRM master, most likely. Also unknown: whether the machine had
been relogged-in between Jul 14 13:09 and the incident (Bernardo does not
recall), which is the one fact that would say whether hypridle was ever a
suspect worth having. Tooling kept:
`nomarchy-display-wake` / `nomarchy-display-dump`.
- ✓ **Generation prune (#128):** weekly `nomarchy-gen-prune` (system + HM):
delete only gens older than **14 days** that are also beyond the **3 most