Guidance pipeline/guidance.py
Fourteen rules, tried in a fixed order; the first one that fires is the only thing the person is told. Move a slider past a threshold and watch which instruction takes over — the order is the design, so the chain below shows every rule that is firing, not just the winner.
The priority chain
Every rule, in the order RULES declares
them. The first that fires is what the person sees; the ones under it
are real problems that are being held back so the instruction stays a
single thing to do.
The checklist
What the sidebar shows underneath: eleven checks, each
pass or fail, so a refusal is never a mystery. This is a different list
from the chain above — parts.eyeMismatch appears
here and in no rule.
Calibration analysis/calibration.py
A threshold swept on a small enrollment is misleading: with
three people there are three ways to be wrong, so almost anything scores
zero false matches. The table below was counted over
, and the recommendation scales with how many people
you have enrolled — that is the birthday problem, and it is why
recommend_threshold takes a gallery size instead of returning
a constant.
Click or drag on either chart to move the gallery size. Both are one series against the same axis; the numbers behind them are in the table underneath.
The measured table, and its risk at this gallery size
| threshold | false-match rate per pair | chance in a gallery of |
|---|
These are impostor rates only. The corpus has one image per person, so it cannot measure the other half — a threshold that never confuses two people may also fail to recognise the right one. And the risk is not evenly shared: at threshold , of faces falsely match somebody against of faces, a × gap. SFace’s own published operating point is , which at any real gallery size is far too loose.