The replayed walk and the harness that measures it disagreed with the
phone in two ways, so every live number taken from them was measuring a
different pipeline than the one that ships.
The server cut a window `PAN_LONG_EDGE` tall, which on image6 shows one
shelf row: a 720 px band reaches 52 of 66 enrolled facings and gives
every other SKU 0% coverage, which reads as a matcher failure when it is
only the crop. It now spans the sample's full height and pans
horizontally, and `PAN_STEP` is expressed in sent-frame pixels so the
pace survives the downscale.
`stream_client.py` had the same window bug plus a box-mapping bug: it
added the pan offset but never divided by the downscale, so a `--width`
below the source size shrank every box and the evaluator matched the
wrong facing. It now scales the window itself (so the frame it sends is
byte-for-byte the app's 720x1280), records that scale per frame, and
divides by it when mapping a label box back to source coordinates. The
pan accumulator is clamped at the reversal: a negative `pan_x` satisfied
`<= 0` on every later frame and flipped the direction each time, parking
the window at the left edge.
Measured through the real server at the app's geometry: 57 of 66
enrolled facings covered (86%) at 94% precision, 9 distinct SKUs.