Addresses ce-code-review findings on the photo-editor media-API work:
- P0 (#1): PhotoRenumberer now renumbers EVERY on-disk image, using the
client manifest only as preferred ORDER and appending any omitted image
at the end. A stale/incomplete `order` (e.g. a second browser tab)
previously left an unlisted photo at a target slot for phase-2's
rename() to silently overwrite — verified data loss, now impossible.
The reorder route inherits the guard; create/reconcile is unchanged.
- P2 (#3): unique per-call token in the .reorder-tmp-* name so two
concurrent renumbers on one folder can't collide and clobber bytes.
- P3 (#7): de-duplicate the manifest so a repeated name can't shift/drop
a photo.
- P2 (#2): applyReorder + doDelete split the two failure stages — a failed
refresh AFTER a committed reorder/delete no longer reverts to a stale or
ghost state, it reconciles to disk. A DELETE 404 is treated as success
so a retried ghost cell converges.
- P2 (#4): both custom routes call requirePermission('api.pages.write')
so the GHSA-x7hm API-key scope cap applies (owner already holds it, so
the owner-only behaviour is unchanged).
- P3 (#8): refresh stale comments (photo-01..NN; drop editLoadPhotos ref).
PhotoRenumberer's 7-case unit suite still passes and the data-loss repro
now preserves all bytes. Assets rebuilt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>