La décision architecturale unique qui façonne tout le reste de cette application est simple à énoncer et compliquée à vraiment construire autour : le disque photo est ouvert strictement en lecture seule, et on n'y écrit jamais. Pas de fichier annexe à côté des originaux, pas de dossier caché de métadonnées, pas de renommage, pas de doublon déplacé. Le disque qui entre est le disque qui ressort, octet pour octet.
Cette contrainte semble être un simple bonus jusqu'à ce qu'on remarque ce qu'elle exclut. Elle exclut toute la catégorie d'outils qui « organisent » tes fichiers en les déplaçant ou en les renommant. Elle exclut de stocker le moindre état dérivé — vignettes, empreintes de visage, frontières d'événements — n'importe où près des originaux. Tout ce que l'application apprend sur une archive doit vivre entièrement ailleurs, ce qui a voulu dire décider, tôt, où allait être cet « ailleurs ».
Tout ce qui est dérivé vit sur le disque interne
La réponse, c'est SQLite, sur le disque interne du Mac, pas sur le disque externe. L'index (dates, visages, frontières d'événements, empreintes pour la recherche) et le cache de vignettes vivent tous les deux là, complètement séparés de l'archive elle-même. Supprime le dossier de données de l'application et l'archive est prouvée intacte, parce que rien dans l'archive n'a jamais dépendu de l'existence de ce dossier. Réinstalle à partir de zéro, et l'application reconstruit sa compréhension en relisant le disque, pas en devant faire confiance à une sauvegarde de son propre état.
Le journal d'écriture anticipée (« write-ahead log ») de SQLite est l'élément précis qui a le plus compté en pratique, pas seulement en théorie. Pendant le développement, il y a eu deux plantages matériels bien réels — de vraies coupures de courant, pas un test simulé d'injection de panne — en plein milieu d'une écriture, pendant que l'étude tournait sur une vraie archive. Les deux fois, la journalisation WAL a signifié zéro perte de données : la base de données est revenue dans un état cohérent au lancement suivant, a repris à peu près où elle s'était arrêtée, et n'a nécessité aucune réparation manuelle. C'est le genre de garantie qu'on préfère avoir eu besoin sans l'avoir testée soi-même, mais entre un disque externe, une étude en arrière-plan qui tourne pendant des heures, et un foyer où le câble se fait parfois bousculer, elle a été testée pour de vrai, deux fois, avant le lancement.
Ce que « le lire » récupère vraiment
Une garantie de lecture seule ne vaut que ce qu'on peut vraiment en extraire en la respectant, et les métadonnées d'une vraie archive familiale sont plus désordonnées qu'un jeu de test propre. Sur l'archive fondatrice, 92 % des fichiers portaient d'emblée des dates EXIF utilisables. Les 8 % restants avaient besoin de solutions de repli — horodatages du système de fichiers, dates dans le nom des dossiers, inférence à partir des photos voisines dans le même événement — et après ces solutions de repli, la couverture a atteint 98,1 %. Ces deux derniers pourcents sont le plancher honnête : certains fichiers ne portent tout simplement aucun signal nulle part, ni dans le fichier ni autour, et aucune chaîne de solutions de repli n'en invente un à partir de rien.
Consultable avant même d'avoir fini de comprendre
La lecture seule et l'état dérivé ailleurs résolvent le problème de sécurité, mais il y a un problème de patience distinct : une étude complète d'une grande archive prend des heures, et personne ne veut fixer une barre de progression avant de pouvoir regarder une seule photo. La bibliothèque devient consultable dans les minutes qui suivent le moment où l'on pointe l'application vers un disque pour la première fois — une passe précoce met en place assez d'index et assez de vignettes pour rendre la navigation de base réelle, pas une simple maquette. Les passes plus profondes (regroupement des visages, nommage des événements, les empreintes qui alimentent la recherche par sens) continuent de tourner derrière, remplissant discrètement des réponses plus riches pendant que tu regardes déjà des photos, plutôt que de bloquer le premier moment utile derrière le dernier, le plus coûteux.
La gouvernance des ressources est une règle, pas une suggestion
Le dernier élément est celui qu'il est facile de négliger et coûteux de mal négliger : une étude qui lit et comprend quelques centaines de milliers de fichiers est un vrai travail lourd, et un travail lourd en arrière-plan sur le seul Mac de quelqu'un, alors qu'il essaie de l'utiliser pour autre chose, c'est comme ça qu'une « IA locale respectueuse de la vie privée » se transforme en « pourquoi mon ordinateur portable chauffe comme un radiateur ». La règle ici est stricte, pas juste du mieux possible : une planification en priorité arrière-plan (QoS) pour que l'étude ne rivalise jamais avec le travail au premier plan, un nombre de tâches parallèles adaptatif qui recule en quelques secondes dès que l'utilisateur redevient actif, un plafond strict sur l'utilisation de la mémoire, et une mise en pause pure et simple en cas de pression sur la batterie ou la température. Une étude complète qui tourne sur un Mac de base ne devrait pas être quelque chose qu'on peut sentir. Si ça l'est, c'est un bug, pas un compromis.
Tout ça — des originaux en lecture seule, un état dérivé sur le disque interne, une journalisation résistante aux plantages, des limites de ressources qui tiennent vraiment — s'additionne en une thèse d'ingénierie plutôt peu glamour : ce qu'il y a d'intéressant dans le « local d'abord », ce n'est pas que l'IA tourne sur l'appareil plutôt que sur un serveur, même si c'est le cas. C'est qu'il n'y a aucun serveur à qui faire confiance pour commencer, ce qui veut dire que chacune de ces garanties n'a besoin d'être vraie que pour une seule machine, posée sur ton bureau, à qui tu fais déjà confiance pour tout le reste.