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: PAM info messages from the fingerprint stack are never surfaced (no fingerprint text element exists)
Reported by awluko · filed Oct 1, 2026 · open at source
At a glance
- 1 · What is claimed?
- ConfirmedReproducible: a fingerprint PAM info message reaches the lock service, which keeps nothing of it; the lock view has no element that could show it
- Not confirmedAffects the lock component
- 2 · What does it affect?
- 3 · Is it reproducible?
- An engine-executed run exited 1 and showed the defect signal. See reproducer
- 4 · What remains unclear?
- Open question for maintainers: Open decision: should the lock screen show the fingerprint stack's PAM messages (for example 'Remove your finger, and try touching the sensor again')? Options: (A) keep the current behaviour, indicator only; (B) show info messages as a transient line near the field (the report's ask); (C) show only error messages; (D) show them in the existing notice slot under the field, where 'Fingerprint reader unavailable' appears today.
- Open question for maintainers: The decision is the Omarchy maintainers'; a draft requirement listing these options sits on this report's branch (report/cmupntnla003f49w4drywtcgj), and approving one option = merging that draft into the baseline with the chosen text.
- Affects the lock component — no requirement of the lock component is confirmed as violated
- 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. So far: not a duplicate of another report — decided by agents · verified; in the audited area (lock) — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Open question — draft spec awaiting a decision
Shall the lock screen show the fingerprint stack's PAM messages, for example 'Remove your finger, and try touching the sensor again'?
(upstream quattro 035ce29f) the fingerprint PamContext relays the message, but its onPamMessage handler only records that the reader was reached (Service.qml:557-559); no property keeps the text, and LockView.qml has no element for it (the indicator, LockView.qml:241-255, is a glyph).
- AKeep the current behaviour, indicator only
- BThe lock view shall show a PAM info message as a transient line near the password field
- CShow only PAM error messages
- DShow them in the notice slot under the field, where 'Fingerprint reader unavailable' appears today
Approving this draft means choosing one option; its text then replaces this description.
Why this is an open question
Raised by omacom/omarchy#13954 (proof inbox R-2145). The validation (report/cmupntnla003f49w4drywtcgj, rval-ce7d70641a2df7ddf321f526f7108171) ran a real PAM conversation that sends the message and showed that neither the service nor the view keeps it. SW-REQ-260912-41VV covers the indicator and the unavailable notice only.
Proposed on this report's branch @ 1c14d76a9e · specs/software/requirements/SW-REQ-261005-EWWP.req.yaml · not part of the audited spec until approved and merged
Written after the validation was sealed at 805809b03b: the seal covers the reproducer and the observed behaviour, not this proposed text.
Original report
Lock screen: PAM info messages from the fingerprint stack are not surfaced
Summary
Service.qml wires onPamMessage for the password PAM stack but not for the
fingerprint PAM stack. As a result every PAM info/error message pam_fprintd
sends is discarded. The lock screen has no fingerprint text element at all, so
the user sees nothing: not the standing "Place your right index finger on the
fingerprint reader" instruction, and not the module's guidance when something
goes wrong — most importantly "Remove your finger, and try touching the sensor
again".
The practical effect: when a press produces no usable image, the lock screen
gives no feedback whatsoever — no message, no state change, nothing. There is no
visible difference between "the sensor saw nothing", "the sensor saw an
unusable image" and "the session timed out". The user has no reason to change
what they are doing, and typically presses harder or holds longer, which
reproduces the same failure.
Environment
Omarchy 4.0.0.alpha
file: /usr/share/omarchy/shell/plugins/lock/Service.qml
fprintd 1.94.5, libfprint-tod 1.95.2+tod1
device: Broadcom ControlVault3+ (0a5c:5865), press-type sensor
Steps to reproduce
- Enroll a fingerprint; confirm it verifies normally (
fprintd-verifymatches
in ~1s).
2. Lock the screen and press with a smudge or partial contact, so the driver
returns verify-remove-and-retry.
3. Watch the lock screen text while this happens.
Observed
The journal shows the module sending the hint:
09:12:45.807 fprintd: Line: 450 status 89 :
09:12:45.808 quickshell.service.pam.subprocess:
Relaying pam message: "Remove your finger, and try touching the sensor again"
echo: 1 error: 1 responseRequired: 0
09:12:46.396 quickshell.service.pam.subprocess:
Relaying pam message: "Verification timed out"
The message is relayed to the frontend successfully. The lock screen displays
nothing at all — it does not change state or show any text. The only
fingerprint-related element in the UI is a static icon:
LockView.qml:204-210
id: fingerprintIcon
objectName: "fingerprintIndicator"
visible: root.fingerprintConfigured
text: ""
That icon is a static nerd-font glyph marking the sensor's presence. It has no
message binding and never changes in response to PAM traffic. The only text
element in the view is the password prompt:
LockView.qml:189
text: root.authenticatingPassword ? "Checking…"
: (root.failureMessage.length > 0 ? root.failureMessage
: root.placeholderText)
and failureMessage is only ever set by handlePasswordFailure(), so it cannot
carry a fingerprint message.
Expected
The fingerprint stack's PAM info/error messages should reach the lock screen UI,
at minimum as a transient hint line, the same way the password stack's messages
are handled.
Root cause
/usr/share/omarchy/shell/plugins/lock/Service.qml, the password stack at
line 319:
PamContext {
id: passwordPam
config: "omarchy-lock-password"
user: root.userName
onResponseRequiredChanged: root.respondToPasswordPrompt()
onPamMessage: root.respondToPasswordPrompt() // <-- present here
...
and the fingerprint stack at line 341:
PamContext {
id: fingerprintPam
config: "omarchy-lock-fingerprint"
user: root.userName
onCompleted: function(result) {
root.handleFingerprintFinished(result)
}
onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}
}
There is no onPamMessage (and no onResponseRequiredChanged) onfingerprintPam. fingerprintPam is never read back into any UI property —
the only references to it elsewhere are fingerprintPam.abort() (lines 125, 385)
and the .start() call in startFingerprint(). So even if onPamMessage were
added, there is currently no property for the text to land in; failureMessage
is set only by handlePasswordFailure() (line 205).
Impact
- The lock screen is entirely silent about the fingerprint stack. A failed press
and an idle 10-30 second timeout look identical from the outside.
- The one actionable instruction (`Remove your finger, and try touching the
sensor again`) never reaches the person who needs it.
- Reinforces the impression that the reader is unreliable, when in fact it is
behaving per spec and the module is emitting correct guidance.
- The user's only diagnostic signal is "did it unlock or not", which makes a
correctable press error indistinguishable from a hardware fault.
Suggested fix
Add message handling to the fingerprint stack and surface it, e.g.:
PamContext {
id: fingerprintPam
config: "omarchy-lock-fingerprint"
user: root.userName
onPamMessage: root.handleFingerprintMessage(text, type)
...
and a fingerprintMessage property consumed by LockView.qml. Note there is no
existing fingerprint text element to hang this on — the only fingerprint UI is
the static fingerprintIndicator icon, so this needs a new text element (or a
reuse of the password field's text line, which would be confusing since that
field is for the password). It also needs care to avoid the hint being cleared
by the next VerifyStatus signal, which fires on every scan result.
Relationship to existing issues
This is distinct from, and complements, the two open fingerprint lock-screen reports:
- #13906 (250 ms retry loop when the reader is unavailable) and #13944
(thermal guard disabling the reader after ~3 min locked) both concern the *retry
loop* and reader availability. This report is about something orthogonal: even
while the reader is healthy and a session is active, the lock screen has no
fingerprint text element at all, so the guidance pam_fprintd emits is discarded.
- Not a duplicate of #13944. Verified on this machine that the thermal guard
never fires (journalctl | grep -ci overheat → 0 matches) and the reader does not
re-enumerate pathologically (4 enumerations over 3 days, normal resume behavior).
The symptom here appears with a healthy reader and a healthy session.
- Different code path. #13906 / #13944 point at fingerprintRetryTimer and
handleFingerprintFinished; this points at the absent onPamMessage on the
fingerprint PamContext (~line 341) and the absent fingerprint text element in
LockView.qml.
Notes
- Duplicate check: searched
basecamp/omarchyissues for "fingerprint" in
titles; no existing issue covering PAM message surfacing.
- Related but distinct upstream problem: fprintd has no case for
verify-remove-and-retry, so it returns PAM_AUTH_ERR instead of retrying.
Surfacing the message does not fix that, but it does make the failure
understandable to the user rather than looking like a dead sensor. I'm filing
that separately with fprintd.
- This is the lock-screen half of the symptom "fingerprint only works about half
the time"; the other half is the fprintd-side session abort.
- Willing to test a patch and provide journal output before/after.
View raw text
# Lock screen: PAM info messages from the fingerprint stack are not surfaced
## Summary
`Service.qml` wires `onPamMessage` for the password PAM stack but not for the
fingerprint PAM stack. As a result every PAM info/error message `pam_fprintd`
sends is discarded. The lock screen has no fingerprint text element at all, so
the user sees nothing: not the standing "Place your right index finger on the
fingerprint reader" instruction, and not the module's guidance when something
goes wrong — most importantly "Remove your finger, and try touching the sensor
again".
The practical effect: when a press produces no usable image, the lock screen
gives no feedback whatsoever — no message, no state change, nothing. There is no
visible difference between "the sensor saw nothing", "the sensor saw an
unusable image" and "the session timed out". The user has no reason to change
what they are doing, and typically presses harder or holds longer, which
reproduces the same failure.
## Environment
Omarchy 4.0.0.alpha
file: /usr/share/omarchy/shell/plugins/lock/Service.qml
fprintd 1.94.5, libfprint-tod 1.95.2+tod1
device: Broadcom ControlVault3+ (0a5c:5865), press-type sensor
## Steps to reproduce
1. Enroll a fingerprint; confirm it verifies normally (`fprintd-verify` matches
in ~1s).
2. Lock the screen and press with a smudge or partial contact, so the driver
returns `verify-remove-and-retry`.
3. Watch the lock screen text while this happens.
## Observed
The journal shows the module sending the hint:
09:12:45.807 fprintd: Line: 450 status 89 :
09:12:45.808 quickshell.service.pam.subprocess:
Relaying pam message: "Remove your finger, and try touching the sensor again"
echo: 1 error: 1 responseRequired: 0
09:12:46.396 quickshell.service.pam.subprocess:
Relaying pam message: "Verification timed out"
The message is relayed to the frontend successfully. The lock screen displays
nothing at all — it does not change state or show any text. The only
fingerprint-related element in the UI is a static icon:
LockView.qml:204-210
id: fingerprintIcon
objectName: "fingerprintIndicator"
visible: root.fingerprintConfigured
text: ""
That icon is a static nerd-font glyph marking the sensor's presence. It has no
message binding and never changes in response to PAM traffic. The only text
element in the view is the password prompt:
LockView.qml:189
text: root.authenticatingPassword ? "Checking…"
: (root.failureMessage.length > 0 ? root.failureMessage
: root.placeholderText)
and `failureMessage` is only ever set by `handlePasswordFailure()`, so it cannot
carry a fingerprint message.
## Expected
The fingerprint stack's PAM info/error messages should reach the lock screen UI,
at minimum as a transient hint line, the same way the password stack's messages
are handled.
## Root cause
`/usr/share/omarchy/shell/plugins/lock/Service.qml`, the password stack at
line 319:
PamContext {
id: passwordPam
config: "omarchy-lock-password"
user: root.userName
onResponseRequiredChanged: root.respondToPasswordPrompt()
onPamMessage: root.respondToPasswordPrompt() // <-- present here
...
and the fingerprint stack at line 341:
PamContext {
id: fingerprintPam
config: "omarchy-lock-fingerprint"
user: root.userName
onCompleted: function(result) {
root.handleFingerprintFinished(result)
}
onError: function(error) {
root.fingerprintAuthenticating = false
if (root.lockRequested && root.fingerprintConfigured) fingerprintRetryTimer.restart()
}
}
There is no `onPamMessage` (and no `onResponseRequiredChanged`) on
`fingerprintPam`. `fingerprintPam` is never read back into any UI property —
the only references to it elsewhere are `fingerprintPam.abort()` (lines 125, 385)
and the `.start()` call in `startFingerprint()`. So even if `onPamMessage` were
added, there is currently no property for the text to land in; `failureMessage`
is set only by `handlePasswordFailure()` (line 205).
## Impact
- The lock screen is entirely silent about the fingerprint stack. A failed press
and an idle 10-30 second timeout look identical from the outside.
- The one actionable instruction (`Remove your finger, and try touching the
sensor again`) never reaches the person who needs it.
- Reinforces the impression that the reader is unreliable, when in fact it is
behaving per spec and the module is emitting correct guidance.
- The user's only diagnostic signal is "did it unlock or not", which makes a
correctable press error indistinguishable from a hardware fault.
## Suggested fix
Add message handling to the fingerprint stack and surface it, e.g.:
PamContext {
id: fingerprintPam
config: "omarchy-lock-fingerprint"
user: root.userName
onPamMessage: root.handleFingerprintMessage(text, type)
...
and a `fingerprintMessage` property consumed by `LockView.qml`. Note there is no
existing fingerprint text element to hang this on — the only fingerprint UI is
the static `fingerprintIndicator` icon, so this needs a new text element (or a
reuse of the password field's text line, which would be confusing since that
field is for the password). It also needs care to avoid the hint being cleared
by the next `VerifyStatus` signal, which fires on every scan result.
## Relationship to existing issues
This is distinct from, and complements, the two open fingerprint lock-screen reports:
- **#13906** (250 ms retry loop when the reader is unavailable) and **#13944**
(thermal guard disabling the reader after ~3 min locked) both concern the *retry
loop* and reader availability. This report is about something orthogonal: even
while the reader is healthy and a session is active, the lock screen has no
fingerprint text element at all, so the guidance `pam_fprintd` emits is discarded.
- **Not a duplicate of #13944.** Verified on this machine that the thermal guard
never fires (`journalctl | grep -ci overheat` → 0 matches) and the reader does not
re-enumerate pathologically (4 enumerations over 3 days, normal resume behavior).
The symptom here appears with a healthy reader and a healthy session.
- **Different code path.** #13906 / #13944 point at `fingerprintRetryTimer` and
`handleFingerprintFinished`; this points at the absent `onPamMessage` on the
fingerprint `PamContext` (~line 341) and the absent fingerprint text element in
`LockView.qml`.
## Notes
- Duplicate check: searched `basecamp/omarchy` issues for "fingerprint" in
titles; no existing issue covering PAM message surfacing.
- Related but distinct upstream problem: fprintd has no case for
`verify-remove-and-retry`, so it returns `PAM_AUTH_ERR` instead of retrying.
Surfacing the message does not fix that, but it does make the failure
understandable to the user rather than looking like a dead sensor. I'm filing
that separately with fprintd.
- This is the lock-screen half of the symptom "fingerprint only works about half
the time"; the other half is the fprintd-side session abort.
- Willing to test a patch and provide journal output before/after.
Validation
AI validator claude-code (claude-opus-5.5) · evaluated revision 1 at product commit 1e43373287af · sealed 2026-10-05T14:30:11Z
Validation of omacom/omarchy#13954 on quattro-proof 1e433732 (upstream quattro 035ce29f product code plus the proof layer). The reported behaviour reproduces end to end with a real PAM conversation: the reproducer runs quickshell in a private user + mount namespace whose /etc/pam.d holds an omarchy-lock-fingerprint stack that sends the report's message ('Remove your finger, and try touching the sensor again', via pam_echo) and then fails. The fingerprint PamContext of Service.qml relays the message (message delivered, messageIsError false), but its onPamMessage handler only records that the reader was reached (Service.qml:557-559 upstream); no Service property keeps the text, and LockView.qml's only string input is failureMessage, which only handlePasswordFailure sets (Service.qml:346-355). With fingerprint configured the view shows the placeholder and the indicator glyph (LockView.qml:241-255) and nothing else. SW-REQ-260912-41VV covers the indicator and the 'Fingerprint reader unavailable' notice; no requirement says whether PAM messages are shown. Whether they should be is an open specification question for the maintainers (the report asks for at least a transient hint line). The reproducer starts the fingerprint PAM directly: startFingerprint() also waits for a secured session lock, which the headless fixture does not take.
- ConfirmedReproducible
Reproducible: a fingerprint PAM info message reaches the lock service, which keeps nothing of it; the lock view has no element that could show it
Engine: engine-executed run exited 1 and showed the defect signal
Evidence: file test/reports/report-cmupntnla003f49w4drywtcgj.sh
Validator's rationale (commentary): Observed with a real PAM conversation (pam_echo) in a private namespace: the PamContext relays the text; afterwards no Service string property holds it and LockView exposes only failureMessage. Whether messages should be shown is the open question below.
Affects the lock component
Engine: no requirement of the lock component is confirmed as violated
Engine reference checks at 805809b03bf7 (10/10 ok)
- okcommit805809b03bf788ec7f179533b38494e8f0bb3da7
- okbase commit1e43373287afbd6dca4674ad463d5b5db7812358
- okbase ancestry1e43373287afbd6dca4674ad463d5b5db7812358
- okproduct code untouchedthis report's reproducer branch
- okbranchthis report's reproducer branch
- okfiletest/reports/report-cmupntnla003f49w4drywtcgj.qml
- okfiletest/reports/report-cmupntnla003f49w4drywtcgj.sh
- okrequirementSW-REQ-260912-41VV
- okrequirementSW-REQ-261004-296X
- okcomponentlock
The engine's own check, at validation time, that the commits, the reproducer branch (touching only reproducer files), the reproducer files and every mapped requirement / component / known issue really exist.
Validator-authored hypothesis. Each claim's verification is engine-computed: confirmed only from an engine-executed reproducer run recorded in this record, refuted when recorded evidence contradicts it. Prose is commentary. The disposition of the report is a human decision.
Reproducer
bash test/reports/report-cmupntnla003f49w4drywtcgj.sh
Setup failure: exit 2 means the reproducer could not set up (e.g. the product did not build) — such a run decides nothing.
Defect signal: output contains AS-REPORTED:
AS-REPORTED: a fingerprint PAM message is relayed to the lock service, which keeps nothing of it; the lock view has no element that could show it
Observed on this tree (quickshell 0.3.1, lock plugin shell/plugins/lock):
- the fingerprint PamContext relayed 1 message(s): [{"text":"Remove your finger, and try touching the sensor again","error":false}]
- Service.qml string properties holding the message after the attempt: []; failureMessage=""
- LockView.qml string inputs that could carry a message: ["failureMessage"] (failureMessage is set only by handlePasswordFailure)
- LockView with fingerprint configured shows ["Enter Password",""] (the indicator glyph and the password placeholder)
AS-REPORTED: a fingerprint PAM message is relayed to the lock service, which keeps nothing of it; the lock view has no element that could show it
Needs: linux · quickshell (0.3.x) and jq on PATH; a sway binary for a private headless compositor (PROOF_ENV_DIR/sysroot/usr/bin/sway, else sway on PATH); the script exits 2 with SETUP: otherwise. Nothing to build: the QML is loaded straight from the worktree · unshare -Urm (unprivileged user + mount namespaces) for the private PAM stack; pam_echo, pam_deny and pam_permit modules · ran on linux/amd64
Linked
- Related PRpr/11162· confirmed
- Fixed bypr/11952· confirmed
- Fixed bypr/12690· confirmed
- Related PRpr/12291· confirmed
- Related PRpr/13918· 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.
- Decided by agents · verified: not a duplicate of another report
- Decided by agents · verified: in the audited area (lock)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.