Noise floor
Uses raw_score, because ui_score is a compressed display scale. SD within 5 sets of retakes, each at one spot under one light with nothing changed, pooled across the sets (22 photos). Each set keeps its own average, so a light change between sets never counts as noise. MDC95 = 1.96 × √2 × SD: a change beyond it happens by chance under 5% of the time.
Sets: Session 1, desk spot (6), Session 3, ceiling light (other room) (4), Session 4A, ceiling light (4), Session 4B, desk lamp (4), Session 4C, desk lamp, after moisturizer (4). The window session is left out because every photo in it is backlit. Sending the same file twice returned identical scores, so the API adds no jitter of its own.
Capture conditions
Measured on a fixed central face box and the background strips beside the head. Face brightness is divided by background brightness, so a uniform exposure change cancels out, and light colour is read from the background, which skincare does not change. Limits sit between what same-spot retakes and a different room and light produced on the first 15 photos.
| Check | Limit | Same spot and light, largest | Different room and light, range |
|---|
| Face brightnessFace brightness divided by the background beside the head, so exposure changes cancel out | ±10.0% | 5.7% | 8.4% to 98.1% |
| BacklightShare of blown-out pixels in the background beside the head | 15.0% max | 0.2% | 0.0% to 64.0%56.1% to 64.0% when one photo has the window behind the head |
| Light colourRed-to-blue ratio of the background beside the head (skincare does not change it) | ±2.0% | 1.0% | 0.5% to 5.7% |
No single check catches every change. Of the 210 ordered photo pairs, the 42 taken at the same spot under the same light (30 desk spot, 12 ceiling light) all pass, and the 168 that cross setups or include a backlit window photo are all blocked. These counts are in-sample. Run npm run calibrate for the full printout.
Claim type policy
Which metrics each product category may make claims about. A configurable policy a brand's compliance team would edit, not a regulation. “Appearance” means the badge carries the label “appearance with product on”.
| Category | Moisture | Pore | Wrinkle | Radiance |
|---|
moisturizer | Skin | No claim | No claim | Skin |
serum | Skin | Skin | Skin | Skin |
foundationmakeup | No claim | Appearance | No claim | Appearance |
cleanser | No claim | Skin | No claim | No claim |
sunscreen | No claim | No claim | No claim | No claim |
Later-evening check, before and after a design change
Twelve more photos of the same face from a different evening, four shots each under three setups:
- A. Ceiling light only. Phone held closer: the face is larger in frame and no ceiling is visible.
- B. Same room, desk lamp instead of the ceiling light. Phone re-positioned lower and tilted up: the ceiling is in frame and the face is smaller.
- C. Same desk lamp as B, similar framing (a little less ceiling in frame), about 20 minutes after washing the face and applying a moisturizer.
| Pairs (ordered) | Expected | Version 1, limits frozen | Version 2, current |
|---|
| Same setup (A-A, B-B, C-C) | Pass | 32/36 pass (88.9%)fails: face brightness 4 | 32/36 pass (88.9%)fails: face brightness 4 |
| Different light (A-B, A-C) | Blocked | 64/64 blocked (100.0%) | 64/64 blocked (100.0%) |
| Same lamp, before and after moisturizer (B-C) | Pass | 10/32 pass (31.3%)fails: light colour 15, face brightness 7 | 26/32 pass (81.3%)fails: face brightness 6 |
Version 1 was frozen on the first 15 photos and never saw these twelve, so its column is a true held-out result. It read light colour from the face and face brightness on its own. After washing and moisturizer the face measured redder, which it read as warmer light, and it blocked most same-lamp pairs.
Version 2 reads light colour from the background and divides face brightness by background brightness. These twelve photos showed us why version 1 failed, so they informed the change and its column is not a strict held-out result. The limit values (10%, 15%, 2%) were checked on the first 15 photos only and not tuned to make any case pass. The remaining failures are real: in set B the face got brighter from shot to shot relative to the background under the same lamp.
The same photos made the noise floor wider. Under the session 1 floor, 6 of 18 same-setup pairs moved moisture past it and 10 of 18 moved wrinkle past it, where about 1 in 20 is expected. With the pooled floor, 3, 3, 3 and 0 of 18 still do, for moisture, pore, wrinkle and radiance. That count is in-sample, and the floor may still be too tight.
What these numbers don't show
Everything here comes from one face and one phone. The face box is fixed: an offline face detector found one face in each of the 17 demo images and the box sat inside it left to right, but its top edge reaches the forehead and, in the window photos, the hairline. We kept the fixed box because the detector would add about 300 MB of dependencies and change every stored measurement. A brand would recalibrate with retakes from its own users and devices before relying on these limits.