fpenrol.sh: no enrolment ever received the position guidance this script claims
pos() was eval'ing over the script's positional parameters from inside a function, where $1 is the function's own argument. So `pos 3` printed "3" and `pos 10` printed "100": every run this script has ever driven printed sample numbers where positions should have been. That rewrites an earlier conclusion rather than just fixing a bug. No enrolment on this device had ever been guided, including the one that produced the best template measured so far -- its spread came entirely from the config's overlap band refusing near-duplicates, not from anything this script said. The paired-test attribution drops a contributor, and the 30-sample run becomes directly comparable to it because both were equally unguided. Prompts are therefore opt-in now, behind FPENROL_GUIDE=1. The first run where they actually fired steered the finger to edges, tips and hard rolls, needed 74 presses for 30 accepts, and produced a template that matched 0 of 10 taps. Prompting a user toward positions they never use in a real tap builds a template of positions they never use in a real tap. The default is the instruction that worked: press as you would to unlock, and let the refusals move you. The stage count comes from the daemon's num-enroll-stages property rather than a second hardcoded 20.
This commit is contained in:
parent
36085c1b18
commit
a44e0963ce
1 changed files with 87 additions and 35 deletions
|
|
@ -7,54 +7,106 @@
|
|||
# roughly one position, and it matches roughly one frame in seven -- against
|
||||
# 47-75% for the template the research harness enrolled. The algorithm was
|
||||
# given ten near-duplicate images of one spot, so it recognises that spot and
|
||||
# little else. It accepted them because our config set none of stock's
|
||||
# enrolment-quality keys and the trustlet's own defaults accept anything;
|
||||
# those keys are now set, so the algorithm enforces the spread too.
|
||||
# little else.
|
||||
#
|
||||
# This walks a different contact position per accepted sample. It reads
|
||||
# fprintd-enroll's per-stage output and prompts the next position as each
|
||||
# stage passes, so the guidance tracks what the trustlet ACCEPTED rather than
|
||||
# how many times you pressed.
|
||||
#
|
||||
# TWO BUGS FIXED 2026-09-03, both of which had silently disabled a feature
|
||||
# this script claims to provide:
|
||||
#
|
||||
# 1. `pos()` was `eval "printf '%s' \"\$$1\""` over the script's positional
|
||||
# parameters. Inside a FUNCTION, `$1` is the function's own argument, so
|
||||
# `pos 3` printed "3" and `pos 10` printed `${1}0` = "100". Every run this
|
||||
# script ever drove -- including the one that produced the 7/10 template --
|
||||
# printed sample numbers where positions should have been, so NO enrolment
|
||||
# has ever actually received position guidance. The spread in those
|
||||
# templates came from the config's overlap band refusing near-duplicates,
|
||||
# not from anything this script said. Positions now live in a newline
|
||||
# list indexed with sed, which has no interaction with $1 at all.
|
||||
#
|
||||
# 2. The sample count was hardcoded to 20 while the daemon was configured for
|
||||
# 30, so the counter froze at 20/20 and the run looked like it had hung or
|
||||
# been clamped. It had not: all 30 samples were taken. The count now comes
|
||||
# from the daemon's own num-enroll-stages property, which it reads from the
|
||||
# same config the trustlet is given.
|
||||
F=${1:-right-middle-finger}
|
||||
|
||||
# Position prompts are OPT-IN: FPENROL_GUIDE=1. The one template that verified
|
||||
# well (right-middle, 20 samples, 7/10 quick taps) was enrolled with NO prompts
|
||||
# -- the pos() bug meant none were ever shown -- and the algorithm's own
|
||||
# overlap band did the spreading. The first run where prompts actually fired
|
||||
# (right-middle, 30 samples, edges/tips/rolled-hard) needed 74 presses for 30
|
||||
# accepts and then matched 0/10. Prompting a user toward positions they never
|
||||
# use in a real tap builds a template of positions they never use in a real
|
||||
# tap. Without prompts, the instruction is the one that worked: press the way
|
||||
# you would to unlock, and let the REFUSED messages move you.
|
||||
GUIDE=${FPENROL_GUIDE:-0}
|
||||
|
||||
# The daemon is the authority on how many stages there are.
|
||||
STAGES=$(busctl get-property net.reactivated.Fprint \
|
||||
/net/reactivated/Fprint/Device/0 \
|
||||
net.reactivated.Fprint.Device num-enroll-stages 2>/dev/null \
|
||||
| awk '{print $2}')
|
||||
case "$STAGES" in
|
||||
''|*[!0-9]*) STAGES=20
|
||||
echo "warning: could not read num-enroll-stages; assuming $STAGES" ;;
|
||||
esac
|
||||
|
||||
POSITIONS='centre of the pad
|
||||
slightly LEFT of centre
|
||||
slightly RIGHT of centre
|
||||
higher up, toward the TIP
|
||||
lower down, toward the JOINT
|
||||
centre, rolled LEFT
|
||||
centre, rolled RIGHT
|
||||
tip, rolled slightly left
|
||||
joint, rolled slightly right
|
||||
centre, a little firmer
|
||||
far LEFT edge of the pad
|
||||
far RIGHT edge of the pad
|
||||
very tip of the finger
|
||||
well down toward the joint
|
||||
upper left of the pad
|
||||
upper right of the pad
|
||||
lower left of the pad
|
||||
lower right of the pad
|
||||
centre, rolled hard left
|
||||
centre, rolled hard right'
|
||||
NPOS=$(printf '%s\n' "$POSITIONS" | wc -l)
|
||||
|
||||
# More samples than positions is expected at 30. Cycle, and say so, rather
|
||||
# than printing nothing -- printing nothing is what hid bug 1 for two sessions.
|
||||
pos() {
|
||||
n=$(( ($1 - 1) % NPOS + 1 ))
|
||||
printf '%s' "$(printf '%s\n' "$POSITIONS" | sed -n "${n}p")"
|
||||
[ "$1" -gt "$NPOS" ] && printf ' (again, press slightly differently)'
|
||||
}
|
||||
|
||||
i=1
|
||||
# Twenty positions, stock's sample count. The config now enforces stock's
|
||||
# coverage and overlap thresholds, so a sample that does not move enough from
|
||||
# the last one is REFUSED by the algorithm rather than stored -- the guidance
|
||||
# and the enforcement finally agree.
|
||||
set -- "centre of the pad" \
|
||||
"slightly LEFT of centre" \
|
||||
"slightly RIGHT of centre" \
|
||||
"higher up, toward the TIP" \
|
||||
"lower down, toward the JOINT" \
|
||||
"centre, rolled LEFT" \
|
||||
"centre, rolled RIGHT" \
|
||||
"tip, rolled slightly left" \
|
||||
"joint, rolled slightly right" \
|
||||
"centre, a little firmer" \
|
||||
"far LEFT edge of the pad" \
|
||||
"far RIGHT edge of the pad" \
|
||||
"very tip of the finger" \
|
||||
"well down toward the joint" \
|
||||
"upper left of the pad" \
|
||||
"upper right of the pad" \
|
||||
"lower left of the pad" \
|
||||
"lower right of the pad" \
|
||||
"centre, rolled hard left" \
|
||||
"centre, rolled hard right"
|
||||
echo "enrolling $F with position guidance -- 20 samples (stock's count)"
|
||||
if [ "$GUIDE" = 1 ]; then
|
||||
echo "enrolling $F with position guidance -- $STAGES samples (from the daemon)"
|
||||
echo "press FLAT and firm, hold about a second, then LIFT fully."
|
||||
prompt() { echo ">>> sample $1/$STAGES: $(pos $1)"; }
|
||||
else
|
||||
echo "enrolling $F -- $STAGES samples (from the daemon), NO position prompts"
|
||||
echo "press the way you would to UNLOCK the phone. When a sample is REFUSED,"
|
||||
echo "shift a little from where you were; otherwise do not think about it."
|
||||
prompt() { echo ">>> sample $1/$STAGES"; }
|
||||
fi
|
||||
echo
|
||||
# The reader runs in a subshell, so `shift` there cannot advance the caller's
|
||||
# list. Index into it instead.
|
||||
pos() { eval "printf '%s' \"\$$1\""; }
|
||||
echo ">>> sample 1/20: $(pos 1)"
|
||||
prompt 1
|
||||
fprintd-enroll -f "$F" user 2>&1 | while IFS= read -r line; do
|
||||
case "$line" in
|
||||
*enroll-stage-passed*)
|
||||
i=$((i+1))
|
||||
if [ "$i" -le 20 ]; then
|
||||
if [ "$i" -le "$STAGES" ]; then
|
||||
echo " accepted."
|
||||
prompt "$i"
|
||||
else
|
||||
echo " accepted."
|
||||
echo ">>> sample $i/20: $(pos $i)"
|
||||
fi ;;
|
||||
*enroll-retry-scan*) echo " REFUSED -- move further from the last position, or press flatter" ;;
|
||||
*enroll-completed*) echo; echo "COMPLETED." ;;
|
||||
|
|
|
|||
Loading…
Reference in a new issue