The rail was drawing an empty square for every person: cover was
hardcoded to a default image. That is the one place a portrait matters
most, because the rail is how the user decides which unnamed group to
open first, and a list of "Unnamed (24 faces)" rows tells them nothing.
The portrait is the person's confirmed face with the largest crop_px --
the most source pixels the face actually occupied, so the one they have
the best chance of recognising -- falling back to a suggestion so a
freshly clustered group still has a face beside it.
Cached in the controller, because every mutating action reloads the whole
screen and cutting a portrait costs a JPEG decode per person. Without the
cache, confirming one face would re-decode a proxy for every person in
the library, and the rail does not change when a suggestion is accepted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>