Live guidanceyour webcam, a different engine’s eyes, and this project’s rules

The frame is mirrored on the way in, the way pipeline/camera.py mirrors its frames before measuring them — so what you are looking at is exactly what was measured. It is thrown away immediately afterwards and never leaves the tab.

What is actually being fed to the rules

A real rule engine given a plausible-looking number returns a real-looking verdict, and there is no way to tell it apart from a true one. So every input is listed with where it came from. Same measurement means the definition in pipeline/traits.py, recomputed here on this page’s own pixels. Approximated means this project’s formula applied to a different model’s landmarks — the arithmetic is the same, the inputs are not, and a threshold tuned against the other model does not mean quite the same thing. Not measured means exactly that: the value is passed as null, and guidance.py skips a rule whose input is None rather than judging on a guess.

inputvalue provenancehow it is obtained

The one that is missing

The app’s qualityScore is eDifFIQA, a neural network scored over the face crop, and it was the fairest of the quality signals this project measured (1.21× across race groups, against 2.15× for the brightness gate it replaced). There is no landmark arithmetic that approximates it, so it is not approximated. It is null, which means the quality rule never fires on this page and the “Good quality” checklist row is an absence rather than a pass — the row says so.

Where the assets come from

The MediaPipe runtime and the landmark model are loaded from a pinned CDN version rather than vendored into this repository. Together they are about 23 MB — roughly 9.4 MB of WebAssembly for each of the SIMD and non-SIMD builds, plus a 3.7 MB model — and committing that much third-party binary to source control to serve one demo page is a worse trade than pinning an exact version. The version is fixed, not floating, so the page cannot change behaviour under you. If the CDN is unreachable the page says so plainly at the top and disables the Start button; it does not fall back to anything, because there is nothing honest to fall back to.

What this is not showing you

The part of this project that is genuinely hard is not on this page and cannot be. Recognition here is an LBPH model held in a 328 MB trainer.yml, built from enrolled photographs and matched against a gallery, with a confidence threshold that has to scale with how many people are enrolled. None of that runs in a tab, and a page that mimed it — a box drawn on a face, a name chosen from a list, a confidence number invented to sit beside it — would be telling you something untrue about the system it claims to demonstrate.

What is real here is the decision layer. The rules you are watching fire are the ones that run in front of the camera the server owns, in the same order, against the same thresholds, and the measurements they are reading are labelled with exactly how close they are to the ones the real pipeline would hand them.

What the attendance system does

None of it on this page: it needs the camera the server owns, ~196 MB of pretrained weights and a 328 MB trainer.yml. This is what python app.py puts on 127.0.0.1:5001, and every item names the endpoint and the command-line equivalent that does it.

The threshold those matches are compared against is not a constant — it scales with how many people are enrolled, and past about 1,646 there is no sufficient threshold at all. The slider demo plots that curve →