Index the library's faces, and group them into people

Wires dr-face to dr-catalog: a background sweep that reads the proxy the
grid already built, detects, aligns, embeds and stores, then a clustering
pass that turns those embeddings into suggested people.

Detection runs on the Large thumbnail tier and nowhere else. That is what
makes the feature affordable -- a browsed library has already paid for
its proxies, so face indexing adds no RAW decode that was not already
happening -- and it is why an image whose proxy is missing is skipped
rather than fetched: requesting one here would put face indexing on the
network path FR-CULL-8 keeps it off.

The sweep keeps no cursor. It asks the catalog what is missing, so it
resumes after process death with no repeated work beyond the in-flight
image, and cancelling is dropping the receiver.

recluster writes only the suggested half. Confirmed faces go in as
anchors and come back untouched, and a cluster of one stays nameless --
naming every stray face would fill the People view with noise the user
then has to dismiss.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-26 20:49:30 +02:00
co-authored by Claude Opus 5
parent 00e78dc2ac
commit 2ac069a6b3
7 changed files with 536 additions and 37 deletions
+3
View File
@@ -31,6 +31,9 @@ dr-ingest.workspace = true
dr-film.workspace = true
dr-pipeline.workspace = true
dr-catalog.workspace = true
# The face pipeline, with the ONNX runtime: this is the layer that actually
# runs the models over the library (docs/faces.md).
dr-face = { workspace = true, features = ["inference"] }
dr-thumbs.workspace = true
# The library module writes scan results straight into the catalog, so it
# needs the same SQLite types dr-catalog exposes.