Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
Suspend unusable on Lenovo IdeaPad Slim 3 15AMN8: s2idle resume leaves NVMe rejecting all I/O, root goes read-only
Reported by Chillbruhhh · filed Sep 22, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- AreaOutside the audited area· Decided by agents · verified
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
System details
AMD Ryzen 5 7520U, Radeon 610M (Mendocino, DCN 3.1.6), Lenovo IdeaPad Slim 3 15AMN8 (82XQ), BIOS L1CN47WW, Omarchy 4.0.4-1, kernel 7.2.5-3-omarchy, Hyprland 0.56.2, NVMe Micron MTFDKCD512QGN-1BN1AABLA fw 1001V8LN, btrfs-on-LUKS root.
What's wrong?
Suspend is unusable on this machine. The laptop never actually sleeps — every attempt to suspend ends in an unbootable system that needs a hard power cycle.
s2idle is the only sleep state this platform offers (/sys/power/mem_sleep is [s2idle], no deep/S3). On resume the kernel comes back fine, but the NVMe drive refuses all I/O with Access Denied (sct 0x2 / sc 0x86) DNR. btrfs immediately remounts root read-only and the machine is dead in the water: a clean reboot can't complete, because systemd can't unmount a filesystem whose device rejects every command.
What a user actually sees when they close the lid and reopen it: a black screen, or a lock screen that never accepts the password (PAM can't read from disk). Both look like compositor or authentication bugs. They aren't — they're downstream of storage being gone. That misdirection is the main reason I'm filing this here: anyone running Omarchy on this laptop will hit it and will start debugging Hyprland. I lost hours to exactly that before finding the real cause.
The kernel itself already knows this model is troublesome, and says so at boot:
Using s2idle quirk to avoid IdeaPad Slim 3 15AMN8 platform firmware bugSteps to reproduce
- Boot normally. Confirm zero I/O errors.
sudo systemctl suspend- Wait ~40 s, wake with a keypress.
- Kernel resumes; within ~0.5 s all I/O returns
Access Denied. findmnt -no OPTIONS /showsro;/sys/fs/btrfs/*/devinfo/*/error_statsclimbs.- Only a hard power cycle recovers it. A clean reboot hangs on unmount.
Kernel log across one suspend/resume cycle
Zero I/O errors occurred in the 4+ minutes before the suspend.
[ 245.866331] PM: suspend entry (s2idle)
[ 247.631462] PM: suspend-to-idle
[ 247.632877] Timekeeping suspended for 40.569 seconds
[ 247.632877] PM: resume from suspend-to-idle
[ 247.838716] nvme nvme0: 8/0/0 default/read/poll queues <-- controller resumes cleanly
[ 248.304856] nvme0n1: Read(0x2) @ LBA 6302432, 32 blocks,
Access Denied (sct 0x2 / sc 0x86) DNR <-- 0.47 s later, first I/O refused
[ 248.30xxxx] critical medium error, dev nvme0n1, sector 6302432 op 0x0:(READ)
[ 263.161007] BTRFS error (device dm-0 state EA):
bdev /dev/mapper/root errs: wr 673, rd 18, flush 0, corrupt 0, gen 0- The NVMe driver re-initialises its queues successfully. No controller reset, no command timeout, no probe failure, no PCIe AER error.
- The PCI device stays enumerated in D0 with
nvme0 state: livethroughout — it never leaves the bus. - The refusal carries DNR (Do Not Retry): a considered rejection, not a transient fault.
The drive contradicts itself (so this is firmware, not dying hardware)
After a power cycle, the same drive reports:
nvme smart-log:critical_warning 0, `media_errors 0`,percentage_used 0%,num_err_log_entries 0nvme error-log: all 64 entries empty (error_count 0) — the controller logged nothing at allbtrfs scrub: clean, three times, ~12.5 GiB at 1.56 GiB/s- Every previously "unreadable" file reads back byte-perfect
So the drive reports Media and Data Integrity Errors to the host for LBAs it subsequently reads without fault, while recording zero errors internally and passing SMART. Those statements can't all be true, which points at the drive's firmware.
Ruled out (each tested, each still failed)
| Hypothesis | How it was eliminated |
|---|---|
| Failing SSD | SMART media_errors 0, 0% wear, 3 clean scrubs, full-speed reads |
| Controller drops off PCIe bus | Device present, power_state: D0, state: live during the failure |
| NVMe APST (deep idle states) | nvme_core.default_ps_max_latency_us=0 applied and verified live — still failed |
| PCIe D3cold on suspend | d3cold_allowed=0 (runtime sysfs) — still failed |
| TCG OPAL / BitLocker hardware lock | sedutil-cli --query: LockingEnabled = N, Locked = N, drive is Pyrite 2.0 (no media encryption) |
| Namespace write protect | Feature 0x84 unsupported — Invalid Field in Command |
Display/PSR (amdgpu.dcdebugmask=0x10) | GPU and compositor survive; hyprctl responds, outputs stay connected, session alive over SSH |
| Console suspend interaction | console_suspend=N — still failed |
| Compositor/session involvement | Fails identically with the session alive and reachable over SSH |
Note for anyone else debugging this
journalctl is useless for the resume itself — once the filesystem goes read-only, journald physically cannot write the PM: suspend exit record. So every failure looks like a full platform hang in the journal even though the kernel resumed fine (uptime stays continuous, Wi-Fi reassociates, SSH works, compositor keeps running). Set sysctl -w kernel.dmesg_restrict=0 before testing and read dmesg over SSH afterwards — that's the only way to see what actually happened.
Workaround
Hibernate works, because it powers the drive down fully and cold-initialises it on resume:
# /etc/systemd/logind.conf.d/50-lid-hibernate.conf
[Login]
HandleLidSwitch=hibernate
HandleLidSwitchDocked=hibernateHandleLidSwitchDocked is required: with an external display attached, logind treats the machine as docked and ignores HandleLidSwitch entirely.
(Caveat on my setup: hibernate succeeded initially but cold-booted on a later attempt — swap is 5.6 GiB against 5.6 GiB of RAM with zram at higher priority, likely too tight. Growing the swapfile changes resume_offset.)
To block the failure entirely while leaving the machine usable:
# /etc/systemd/logind.conf.d/40-no-suspend.conf
[Login]
HandleLidSwitch=ignore
HandleLidSwitchDocked=ignore
HandleSuspendKey=ignoreWith this in place the machine ran 1 day 16 hours with no incident.
Why this matters beyond the one laptop
With suspend unavailable, closing the lid delivers neither sleep nor meaningful power saving. Measured on battery, lid closed, session locked, machine genuinely idle (load 0.13, CPU ~1.0 GHz, powersave governor, power-profiles-daemon at power-saver):
| configuration | draw |
|---|---|
HandleLidSwitch=ignore — panel dimmed but dpms: On | 5396 mW |
HandleLidSwitch=lock — panel enabled: disabled, dpms: Off | 5271 mW |
| + Wi-Fi powersave enabled | 5045 mW |
Powering the panel fully off saved ~125 mW and Wi-Fi power management ~226 mW — together about 6.5%. The display was never the drain. ~5 W is this platform's idle floor; the real savings on this hardware come from s0ix/s2idle, precisely the path this bug makes unusable. Roughly 7-8 hours to flat with the lid closed, versus zero drain if hibernated.
Possible Omarchy-side actions
I recognise the root cause is drive firmware on specific Lenovo hardware rather than anything Omarchy does wrong, and no kernel parameter available to the OS changes it. Suggesting anyway, since Omarchy is what users are running when they hit it:
- Detect this hardware and default the lid action to hibernate, or ship a note — so the failure mode doesn't present as a compositor bug.
- On hardware where suspend is unusable, `HandleLidSwitch=lock` is a strictly better fallback than `ignore`: it locks the session and powers the panel down (the behaviour a user expects from closing a laptop), even though it can't deliver sleep. With
ignore, the panel stays powered (dpms: On) while merely appearing off — confusing and wasteful. fwupddoes enumerate the drive (NVME\VEN_1344&DEV_5425&SUBSYS_13441100, current1001V8LN), so an SSD firmware update may fix it outright. Lenovo publishes nothing to LVFS for the82XQBIOS, but the SSD is a separate device — worth checking before anyone blames the OS.
omarchy-debug --no-sudo --print (trimmed)
Omarchy Package: omarchy 4.0.4-1
System:
Kernel 7.2.5-3-omarchy arch x86_64 clocksource hpet avail acpi_pm
parameters cryptdevice=PARTUUID=...:root root=/dev/mapper/root
zswap.enabled=0 rootflags=subvol=@ rw rootfstype=btrfs rtc_cmos.use_acpi_alarm=1
resume=/dev/mapper/root resume_offset=1928852 initramfs_async=0 quiet splash loglevel=0
systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0
nvme_core.default_ps_max_latency_us=0
Desktop Hyprland v 0.56.2 vt 1 dm SDDM Distro Omarchy
Machine:
Type Laptop System LENOVO product 82XQ v IdeaPad Slim 3 15AMN8
Mobo LENOVO model LNVNB161216 v SDK0T76465WIN
Firmware UEFI vendor LENOVO v L1CN47WW date 06/10/2025
CPU:
Info model AMD Ryzen 5 7520U with Radeon Graphics arch Zen 2 family 0x17 (23)
model-id 0xA0 (160) stepping 0 microcode 0x8A0000A
Topology cores 4 threads 8 Speed (MHz) min/max 423/2801
scaling driver amd-pstate-epp governor powersave
Graphics:
Device-1 AMD Mendocino [Radeon 610M] driver amdgpu arch RDNA-2 bus-ID 04:00.0 chip-ID 1002:1506
Display wayland compositor Hyprland v 0.56.2 driver gpu amdgpu
Monitor-1 eDP-1 model Lenovo 0x9052 res 1920x1080 dpi 142
Network:
Device-1 MEDIATEK driver mt7921e pcie gen 1 speed 2.5 GT/s bus-ID 02:00.0 chip-ID 14c3:7920
Drives:
ID-1 /dev/nvme0n1 vendor Micron model MTFDKCD512QGN-1BN1AABLA size 476.94 GiB
tech SSD fw-rev 1001V8LN temp 28.9 C scheme GPT
Partition:
ID-1 / raw-size 474.92 GiB fs btrfs dev /dev/dm-0 mapped root
ID-2 /boot raw-size 2 GiB fs vfat dev /dev/nvme0n1p1
Swap:
Kernel swappiness 150 zswap no
ID-1 swap-1 type file size 5.6 GiB priority 0 file /swap/swapfile
ID-2 swap-2 type zram size 5.6 GiB priority 100 comp zstdView raw text
### System details
AMD Ryzen 5 7520U, Radeon 610M (Mendocino, DCN 3.1.6), Lenovo IdeaPad Slim 3 15AMN8 (`82XQ`), BIOS `L1CN47WW`, Omarchy 4.0.4-1, kernel `7.2.5-3-omarchy`, Hyprland 0.56.2, NVMe Micron `MTFDKCD512QGN-1BN1AABLA` fw `1001V8LN`, btrfs-on-LUKS root.
### What's wrong?
**Suspend is unusable on this machine. The laptop never actually sleeps — every attempt to suspend ends in an unbootable system that needs a hard power cycle.**
`s2idle` is the only sleep state this platform offers (`/sys/power/mem_sleep` is `[s2idle]`, no `deep`/S3). On resume the kernel comes back fine, but the NVMe drive refuses **all** I/O with `Access Denied (sct 0x2 / sc 0x86) DNR`. btrfs immediately remounts root read-only and the machine is dead in the water: a clean reboot can't complete, because systemd can't unmount a filesystem whose device rejects every command.
What a user actually sees when they close the lid and reopen it: a black screen, or a lock screen that never accepts the password (PAM can't read from disk). Both look like compositor or authentication bugs. They aren't — they're downstream of storage being gone. **That misdirection is the main reason I'm filing this here:** anyone running Omarchy on this laptop will hit it and will start debugging Hyprland. I lost hours to exactly that before finding the real cause.
The kernel itself already knows this model is troublesome, and says so at boot:
```
Using s2idle quirk to avoid IdeaPad Slim 3 15AMN8 platform firmware bug
```
#### Steps to reproduce
1. Boot normally. Confirm zero I/O errors.
2. `sudo systemctl suspend`
3. Wait ~40 s, wake with a keypress.
4. Kernel resumes; within ~0.5 s all I/O returns `Access Denied`.
5. `findmnt -no OPTIONS /` shows `ro`; `/sys/fs/btrfs/*/devinfo/*/error_stats` climbs.
6. Only a hard power cycle recovers it. A clean reboot hangs on unmount.
#### Kernel log across one suspend/resume cycle
Zero I/O errors occurred in the 4+ minutes before the suspend.
```
[ 245.866331] PM: suspend entry (s2idle)
[ 247.631462] PM: suspend-to-idle
[ 247.632877] Timekeeping suspended for 40.569 seconds
[ 247.632877] PM: resume from suspend-to-idle
[ 247.838716] nvme nvme0: 8/0/0 default/read/poll queues <-- controller resumes cleanly
[ 248.304856] nvme0n1: Read(0x2) @ LBA 6302432, 32 blocks,
Access Denied (sct 0x2 / sc 0x86) DNR <-- 0.47 s later, first I/O refused
[ 248.30xxxx] critical medium error, dev nvme0n1, sector 6302432 op 0x0:(READ)
[ 263.161007] BTRFS error (device dm-0 state EA):
bdev /dev/mapper/root errs: wr 673, rd 18, flush 0, corrupt 0, gen 0
```
- The NVMe driver **re-initialises its queues successfully**. No controller reset, no command timeout, no probe failure, no PCIe AER error.
- The PCI device stays enumerated in **D0** with `nvme0 state: live` throughout — it never leaves the bus.
- The refusal carries **DNR** (Do Not Retry): a considered rejection, not a transient fault.
#### The drive contradicts itself (so this is firmware, not dying hardware)
After a power cycle, the same drive reports:
- `nvme smart-log`: `critical_warning 0`, **`media_errors 0`**, `percentage_used 0%`, `num_err_log_entries 0`
- `nvme error-log`: **all 64 entries empty** (`error_count 0`) — the controller logged nothing at all
- `btrfs scrub`: clean, three times, ~12.5 GiB at 1.56 GiB/s
- Every previously "unreadable" file reads back **byte-perfect**
So the drive reports *Media and Data Integrity Errors* to the host for LBAs it subsequently reads without fault, while recording zero errors internally and passing SMART. Those statements can't all be true, which points at the drive's firmware.
#### Ruled out (each tested, each still failed)
| Hypothesis | How it was eliminated |
|---|---|
| Failing SSD | SMART `media_errors 0`, 0% wear, 3 clean scrubs, full-speed reads |
| Controller drops off PCIe bus | Device present, `power_state: D0`, `state: live` during the failure |
| NVMe APST (deep idle states) | `nvme_core.default_ps_max_latency_us=0` applied and verified live — still failed |
| PCIe D3cold on suspend | `d3cold_allowed=0` (runtime sysfs) — still failed |
| TCG OPAL / BitLocker hardware lock | `sedutil-cli --query`: `LockingEnabled = N`, `Locked = N`, drive is Pyrite 2.0 (no media encryption) |
| Namespace write protect | Feature `0x84` unsupported — `Invalid Field in Command` |
| Display/PSR (`amdgpu.dcdebugmask=0x10`) | GPU and compositor survive; `hyprctl` responds, outputs stay `connected`, session alive over SSH |
| Console suspend interaction | `console_suspend=N` — still failed |
| Compositor/session involvement | Fails identically with the session alive and reachable over SSH |
#### Note for anyone else debugging this
`journalctl` is useless for the resume itself — once the filesystem goes read-only, `journald` physically cannot write the `PM: suspend exit` record. So every failure *looks* like a full platform hang in the journal even though the kernel resumed fine (uptime stays continuous, Wi-Fi reassociates, SSH works, compositor keeps running). Set `sysctl -w kernel.dmesg_restrict=0` **before** testing and read `dmesg` over SSH afterwards — that's the only way to see what actually happened.
#### Workaround
**Hibernate** works, because it powers the drive down fully and cold-initialises it on resume:
```ini
# /etc/systemd/logind.conf.d/50-lid-hibernate.conf
[Login]
HandleLidSwitch=hibernate
HandleLidSwitchDocked=hibernate
```
`HandleLidSwitchDocked` is required: with an external display attached, logind treats the machine as docked and ignores `HandleLidSwitch` entirely.
(Caveat on my setup: hibernate succeeded initially but cold-booted on a later attempt — swap is 5.6 GiB against 5.6 GiB of RAM with zram at higher priority, likely too tight. Growing the swapfile changes `resume_offset`.)
To block the failure entirely while leaving the machine usable:
```ini
# /etc/systemd/logind.conf.d/40-no-suspend.conf
[Login]
HandleLidSwitch=ignore
HandleLidSwitchDocked=ignore
HandleSuspendKey=ignore
```
With this in place the machine ran **1 day 16 hours** with no incident.
#### Why this matters beyond the one laptop
With suspend unavailable, closing the lid delivers neither sleep nor meaningful power saving. Measured on battery, lid closed, session locked, machine genuinely idle (load 0.13, CPU ~1.0 GHz, `powersave` governor, `power-profiles-daemon` at `power-saver`):
| configuration | draw |
|---|---|
| `HandleLidSwitch=ignore` — panel dimmed but `dpms: On` | **5396 mW** |
| `HandleLidSwitch=lock` — panel `enabled: disabled`, `dpms: Off` | 5271 mW |
| + Wi-Fi powersave enabled | **5045 mW** |
Powering the panel fully off saved ~125 mW and Wi-Fi power management ~226 mW — together about 6.5%. The display was never the drain. **~5 W is this platform's idle floor**; the real savings on this hardware come from s0ix/s2idle, precisely the path this bug makes unusable. Roughly 7-8 hours to flat with the lid closed, versus zero drain if hibernated.
#### Possible Omarchy-side actions
I recognise the root cause is drive firmware on specific Lenovo hardware rather than anything Omarchy does wrong, and no kernel parameter available to the OS changes it. Suggesting anyway, since Omarchy is what users are running when they hit it:
1. **Detect this hardware and default the lid action to hibernate**, or ship a note — so the failure mode doesn't present as a compositor bug.
2. On hardware where suspend is unusable, **`HandleLidSwitch=lock` is a strictly better fallback than `ignore`**: it locks the session and powers the panel down (the behaviour a user expects from closing a laptop), even though it can't deliver sleep. With `ignore`, the panel stays powered (`dpms: On`) while merely appearing off — confusing and wasteful.
3. `fwupd` does enumerate the drive (`NVME\VEN_1344&DEV_5425&SUBSYS_13441100`, current `1001V8LN`), so an SSD firmware update may fix it outright. Lenovo publishes nothing to LVFS for the `82XQ` BIOS, but the SSD is a separate device — worth checking before anyone blames the OS.
<details>
<summary><code>omarchy-debug --no-sudo --print</code> (trimmed)</summary>
```
Omarchy Package: omarchy 4.0.4-1
System:
Kernel 7.2.5-3-omarchy arch x86_64 clocksource hpet avail acpi_pm
parameters cryptdevice=PARTUUID=...:root root=/dev/mapper/root
zswap.enabled=0 rootflags=subvol=@ rw rootfstype=btrfs rtc_cmos.use_acpi_alarm=1
resume=/dev/mapper/root resume_offset=1928852 initramfs_async=0 quiet splash loglevel=0
systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0
nvme_core.default_ps_max_latency_us=0
Desktop Hyprland v 0.56.2 vt 1 dm SDDM Distro Omarchy
Machine:
Type Laptop System LENOVO product 82XQ v IdeaPad Slim 3 15AMN8
Mobo LENOVO model LNVNB161216 v SDK0T76465WIN
Firmware UEFI vendor LENOVO v L1CN47WW date 06/10/2025
CPU:
Info model AMD Ryzen 5 7520U with Radeon Graphics arch Zen 2 family 0x17 (23)
model-id 0xA0 (160) stepping 0 microcode 0x8A0000A
Topology cores 4 threads 8 Speed (MHz) min/max 423/2801
scaling driver amd-pstate-epp governor powersave
Graphics:
Device-1 AMD Mendocino [Radeon 610M] driver amdgpu arch RDNA-2 bus-ID 04:00.0 chip-ID 1002:1506
Display wayland compositor Hyprland v 0.56.2 driver gpu amdgpu
Monitor-1 eDP-1 model Lenovo 0x9052 res 1920x1080 dpi 142
Network:
Device-1 MEDIATEK driver mt7921e pcie gen 1 speed 2.5 GT/s bus-ID 02:00.0 chip-ID 14c3:7920
Drives:
ID-1 /dev/nvme0n1 vendor Micron model MTFDKCD512QGN-1BN1AABLA size 476.94 GiB
tech SSD fw-rev 1001V8LN temp 28.9 C scheme GPT
Partition:
ID-1 / raw-size 474.92 GiB fs btrfs dev /dev/dm-0 mapped root
ID-2 /boot raw-size 2 GiB fs vfat dev /dev/nvme0n1p1
Swap:
Kernel swappiness 150 zswap no
ID-1 swap-1 type file size 5.6 GiB priority 0 file /swap/swapfile
ID-2 swap-2 type zram size 5.6 GiB priority 100 comp zstd
```
</details>
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Out of scopeDecided by agents · verified · 2026-10-09 19:28 UTC