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.
Lock screen retries fingerprint PAM every 250ms with no backoff, preventing fprintd recovery
Reported by kirkules1000010 · filed Sep 2, 2026Closed upstream on 2026-10-04 by the bot omarchybot; the closing comment says it was fixed by PR #7158. GitHub close reason: completed.
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?
- Not yet mapped to any requirement or component.
- 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?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.
Original report
What happens
shell/plugins/lock/Service.qml restarts the omarchy-lock-fingerprint PAM session on a fixed 250ms timer from both failure paths:
// handleFingerprintFinished(), line 226
} else if (fingerprintConfigured) {
fingerprintRetryTimer.restart()
}
// PamContext.onError, line 352
onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}
// line 356
Timer {
id: fingerprintRetryTimer
interval: 250
repeat: false
onTriggered: root.startFingerprint()
}There is no backoff and no cap on consecutive failures. When PAM fails immediately rather than blocking for a scan, this becomes a ~4/sec loop that spawns a fresh PAM subprocess each time.
I hit this when fprintd was left holding a stale device object after a suspend/resume, so every Claim returned net.reactivated.Fprint.Error.AlreadyInUse instantly. One lock session produced 176 denied claims:
fprintd[87058]: Authorization denied to :1.588 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed
fprintd[87058]: Authorization denied to :1.589 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed
... (176 total)with the matching storm on the shell side:
omarchy-shell[96668]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
omarchy-shell[96733]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
omarchy-shell[96736]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
...Why it matters
The retry loop keeps the reader permanently busy, so fprintd can neither suspend the device nor re-initialize it, and the fault cannot self-heal. fprintd logged:
Unexpected error while suspending device: The device is still busy with another operation, please try again later.The wedged daemon then ignored SIGTERM and needed SIGKILL. Recovery required a manual systemctl stop fprintd.
The retry loop is not the root cause of my stale device object — that was fprintd being D-Bus activated during the suspend transition and so failing to install its logind sleep-delay inhibitor. But the loop is what turned a recoverable glitch into a stuck lock screen.
Steps to reproduce
- Enroll a fingerprint so
omarchy-lock-fingerprintis active. - Put fprintd into a state where
Claimfails immediately. Easiest reliable way: hold a claim on the device from another client, sopam_fprintdreturnsAlreadyInUsewithout blocking. - Lock the screen.
- Watch
journalctl -f— a new PAM subprocess roughly every 250ms for as long as the screen stays locked.
Expected
Back off on repeated immediate failures, or cap consecutive retries, so a rejected scan (retry is correct) is distinguished from an unusable device (retry is futile and keeps the device busy). An exponential backoff, or simply pausing the fingerprint path after N consecutive sub-threshold failures and leaving password auth available, would prevent the loop.
System
- Omarchy 4.0.2-1
- fprintd 1.94.5-2, libfprint 1.94.100-1
- Sensor: Synaptics Prometheus MIS Touch Fingerprint Reader (
06cb:00bd)
View raw text
## What happens
`shell/plugins/lock/Service.qml` restarts the `omarchy-lock-fingerprint` PAM session on a fixed 250ms timer from both failure paths:
```qml
// handleFingerprintFinished(), line 226
} else if (fingerprintConfigured) {
fingerprintRetryTimer.restart()
}
// PamContext.onError, line 352
onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}
// line 356
Timer {
id: fingerprintRetryTimer
interval: 250
repeat: false
onTriggered: root.startFingerprint()
}
```
There is no backoff and no cap on consecutive failures. When PAM fails *immediately* rather than blocking for a scan, this becomes a ~4/sec loop that spawns a fresh PAM subprocess each time.
I hit this when fprintd was left holding a stale device object after a suspend/resume, so every `Claim` returned `net.reactivated.Fprint.Error.AlreadyInUse` instantly. One lock session produced 176 denied claims:
```
fprintd[87058]: Authorization denied to :1.588 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed
fprintd[87058]: Authorization denied to :1.589 to call method 'Claim' for device 'Synaptics Sensors': Device was already claimed
... (176 total)
```
with the matching storm on the shell side:
```
omarchy-shell[96668]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
omarchy-shell[96733]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
omarchy-shell[96736]: quickshell.service.pam.subprocess: Starting pam session for user "ktr" with config "omarchy-lock-fingerprint" in dir "/etc/pam.d"
...
```
## Why it matters
The retry loop keeps the reader permanently busy, so fprintd can neither suspend the device nor re-initialize it, and the fault cannot self-heal. fprintd logged:
```
Unexpected error while suspending device: The device is still busy with another operation, please try again later.
```
The wedged daemon then ignored SIGTERM and needed SIGKILL. Recovery required a manual `systemctl stop fprintd`.
The retry loop is not the root cause of my stale device object — that was fprintd being D-Bus activated during the suspend transition and so failing to install its logind sleep-delay inhibitor. But the loop is what turned a recoverable glitch into a stuck lock screen.
## Steps to reproduce
1. Enroll a fingerprint so `omarchy-lock-fingerprint` is active.
2. Put fprintd into a state where `Claim` fails immediately. Easiest reliable way: hold a claim on the device from another client, so `pam_fprintd` returns `AlreadyInUse` without blocking.
3. Lock the screen.
4. Watch `journalctl -f` — a new PAM subprocess roughly every 250ms for as long as the screen stays locked.
## Expected
Back off on repeated immediate failures, or cap consecutive retries, so a rejected scan (retry is correct) is distinguished from an unusable device (retry is futile and keeps the device busy). An exponential backoff, or simply pausing the fingerprint path after N consecutive sub-threshold failures and leaving password auth available, would prevent the loop.
## System
- Omarchy 4.0.2-1
- fprintd 1.94.5-2, libfprint 1.94.100-1
- Sensor: Synaptics Prometheus MIS Touch Fingerprint Reader (`06cb:00bd`)
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
- Fixed bypr/10653· confirmed
- Fixed bypr/12461· confirmed
- Related PRpr/10393· confirmed
- Fixed bypr/11273· confirmed
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.
No decision has been recorded yet.