fetch_face_pool was wiping 952 hand-classified rows when re-run from
a Python without deepface installed (it reset every gender to None).
Now:
- Loads existing manifest by id and overlays only fetch-owned fields,
so gender/race/age/excluded survive a refetch.
- deepface pass tags only records that don't already have a gender;
deepface unavailable means "leave existing tags alone" not "reset".
- New --shrink flag required to drop ids >= --count. Default refuses
to shrink the pool silently.
- Atomic write via tmp + os.replace so an interrupted run can't
corrupt the manifest.
- Dedupes duplicate id lines (root cause of the 2497-row manifest
backing a 1000-face pool).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>