Groundwork for Enhance "Animate" (#208): a video made from a photo.
- Version linking reads the XMP link from MP4 / MOV too (top-level uuid box
with the XMP UUID, mdat seeked over), at ingest and on Enhance approve.
- New kind `animated`, a derived clip (CLIP_KINDS): hidden behind the photo
like a version, but not counted in photo_version_counts / version_count,
never a display choice (400 clip_not_displayable), and listed as `clips`
in GET /image/versions. Approve returns the clip entry.
- Templates whose imageapi:save is ImageApiSaveVideoVersion report
output "video" in /enhance/templates (no enhance.toml change). Previews
already relay ComfyUI's content type (video/mp4).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XMP (PNG iTXt DerivedFrom, native chunk reader) then file-name convention
links at ingest; unlinked name candidates are retried each tick. Versions
are hidden from /photos (SQL for the recursive listing, hidden-row set for
the walk and tag branches), /memories, reels, /photos/exif, the GPS summary,
unified search and the media gauges while their original is reachable in the
view; include_versions=true lists them. /photos gains the parallel arrays
photo_display_paths / photo_version_counts, memories / search hits /
/photos/exif rows gain display_path / version_count, all skipped when empty.
GET /image/versions and PUT /image/versions/display (library optional).
Tags and favorites on a version path bind to the original; faces, CLIP and
duplicate grouping skip version hashes; insight generation redirects to the
original. Orphan GC and the back-ref refresh cover the new tables.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>