Merge master: pluggable storage, and a name that anchors

Conflicts were docs/traceability.md alone, and it is generated — so it
was regenerated rather than hand-merged. dr-face was untouched on the
other side; ui/dr-ui/src/faces.rs and identity_ui.rs auto-merged, the
first around recluster's anchoring and the second around load_faces.

Worth recording because the two branches met on the same problem from
different ends. Master's "Let a name hold a group together" is the fix
for the sixteen Catherines — fourteen of them empty — that this branch
found while measuring the library and reported without fixing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 12:30:01 +02:00
co-authored by Claude Opus 5
54 changed files with 6173 additions and 986 deletions
+5 -11
View File
@@ -355,15 +355,10 @@ fn to_slint_image(width: u32, height: u32, rgba: &[u8]) -> slint::Image {
/// boundary would not be.
/// What the whole-library face pass needs to reach the server.
///
/// Credentials and not just paths, because the pass fetches its own pixels: an
/// A connection and not just paths, because the pass fetches its own pixels: an
/// image with no proxy is the ordinary case, not one to skip (see
/// `library::spawn_face_sweep`).
pub type SweepPaths = (
dr_sync_nextcloud::AppCredentials,
String,
std::path::PathBuf,
std::path::PathBuf,
);
pub type SweepPaths = (dr_sync::Connection, std::path::PathBuf, std::path::PathBuf);
/// The detector and embedder files, when both are present.
pub type ModelPaths = (std::path::PathBuf, std::path::PathBuf);
@@ -689,7 +684,7 @@ pub fn wire<S, M, P>(
if ctl.regroup.borrow().is_some() {
return;
}
let Some((_, _, catalog_path, _)) = paths() else {
let Some((_, catalog_path, _)) = paths() else {
return;
};
@@ -781,7 +776,7 @@ pub fn wire<S, M, P>(
w.set_identity_model_missing(true);
return;
};
let Some((creds, user_id, catalog_path, store_dir)) = paths() else {
let Some((conn, catalog_path, store_dir)) = paths() else {
return;
};
@@ -790,8 +785,7 @@ pub fn wire<S, M, P>(
*ctl.activity.borrow_mut() =
Some(activity.begin(crate::activity::Kind::Index, "Indexing faces"));
*ctl.sweep.borrow_mut() = Some(crate::library::spawn_face_sweep(
creds,
user_id,
conn,
catalog_path,
store_dir,
detector,