4. aspect_profile had the same root cause as edges/centering but no guard.
On the cased photo it reported 5.8% off standard -- the CASE's
proportions -- and the UI would surface that as a trimming hint about a
card it never measured. This one is more directly load-bearing than the
other two, since the measurement IS the detected box. Now refuses, with
both consumers (prompt block and UI hint) checking reliable.
5. _decode_images could KeyError/raise out of a plain read on a malformed
row, and separately b64decode returns b'' rather than raising on some
corrupt input -- which would have fed a zero-byte 'photo' into grading
to fail confusingly deep in the pipeline. Both now degrade to the
existing re-pick path.
6. _last_used_own_key is instance state on a handler that serves every
request on a keep-alive connection, so it outlives the request that set
it. Currently safe (every logging path assigns first), but a future path
that logged without reaching the assignment would bill the previous
request's payer. Cleared up-front now.
Full regression suite re-run: die-cut exclusion, uniform cards, centering,
aspect, cased-photo refusals, and the store layer all still behave.