The scanner moved to howdy-next 3.x, which is the branch that is actually maintained — and it is faster, because the Python interpreter is no longer on the scan path.
- Native
howdy-compareinstead of howdy 2.x'scompare.py: 1.88 s per unlock over five consecutive runs (5/5 matched, max 1.90 s), against 2.9–3.1 s on the same machine and camera. About 0.9 s of the old number was interpreter startup plus numpy/cv2/dlib imports. - Recognition engine is YuNet + SFace (ONNX), not dlib. The match knob is
[face] sface_threshold, notcertainty, and the sudoers line names the new helper. ⚠️ Upgrading requires re-enrolling your face —sudo howdy add. howdy-next keeps models in its own location, so an upgraded machine has a working camera and no enrolled face.- Two exit codes were classified wrong, and the fix is the point of this release. Exit 10 is "no model for this user", not a backend fault — mapping it to "Camera unavailable" is exactly how a healthy webcam came to look broken during this migration. It now says "No face enrolled" and names the fix. Exit 11 is the scan window expiring, and howdy-next has no separate no-match code, so it reads "didn't recognize you" rather than a timeout.
lockNoScanIPC command: engage the lock without starting a scan, for a lid daemon locking a laptop that is already shut. That used to burn several seconds of camera time and land on "too dark" — a message for someone who can see the screen, drawn on a closed panel. The scan happens on the followingwake.- Fixed: an unlock that went through the watchdog left the lock screen pinned over the desktop.
forceUnlock()clearedfadingbut leftoverlayArmedtofadeAnim.onStopped, andstop()emits nothing when the animation never ran — which is precisely that path. The overlay stayed mapped at full opacity and, being input-transparent, produced a working cursor under a frozen lock screen until the daemon was killed from a tty.
Full list in CHANGELOG.md.
🤖 100% vibecoded.