La décision architecturale unique qui façonne tout le reste de cette application est simple à énoncer et compliquée à construire : 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 exclut tous les outils qui « organisent » les fichiers en les déplaçant ou en les renommant. Elle exclut aussi de stocker le moindre état dérivé (vignettes, empreintes de visage, frontières d'événements) près des originaux. Tout ce que l'application apprend sur une archive doit vivre ailleurs, et j'ai donc dû décider tôt où serait 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 ce qui a le plus compté en pratique. Pendant le développement, il y a eu deux plantages matériels, de vraies coupures de courant et non des pannes simulées, en pleine é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 est revenue dans un état cohérent au lancement suivant et a repris à peu près où elle s'était arrêtée, sans aucune réparation manuelle. Avec 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 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 du même événement), et après elles la couverture a atteint 98,1 %. Les deux derniers pourcents sont le plancher : certains fichiers ne portent aucun signal de date, ni dans le fichier ni autour, et aucune chaîne de solutions de repli ne peut en inventer un.
Consultable avant même d'avoir fini de comprendre
Des originaux en lecture seule avec l'état dérivé ailleurs règlent le problème de sécurité. Reste un problème de patience : une étude complète d'une grande archive prend des heures, et personne ne veut regarder une barre de progression avant de voir une seule photo. La bibliothèque devient consultable dans les minutes qui suivent le moment où l'on pointe l'application vers un disque, parce qu'une passe précoce met en place assez d'index et de vignettes pour une navigation de base. Les passes plus profondes (regroupement des visages, nommage des événements, empreintes derrière la recherche par sens) continuent de tourner derrière et enrichissent les réponses pendant que tu regardes déjà des photos.
La gouvernance des ressources est une règle, pas une suggestion
Une étude qui lit quelques centaines de milliers de fichiers est un travail lourd, et un travail lourd en arrière-plan sur le seul Mac de quelqu'un, c'est ainsi qu'une IA locale devient un portable qui chauffe pendant qu'on essaie de s'en servir. Les limites sont des règles strictes : 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 qui recule en quelques secondes dès que l'utilisateur redevient actif, un plafond sur l'utilisation de la mémoire, et une pause en cas de pression sur la batterie ou la température. Une étude complète sur un Mac de base ne devrait pas être quelque chose qu'on peut sentir. Si ça l'est, c'est un bug.
Des originaux en lecture seule, un état dérivé sur le disque interne, une journalisation résistante aux plantages et des limites de ressources qui tiennent s'additionnent en une position d'ingénierie simple. L'IA tourne sur l'appareil, et au-delà il n'y a aucun serveur à qui faire confiance, donc chacune de ces garanties n'a besoin d'être vraie que pour une seule machine, posée sur ton bureau, celle à qui tu fais déjà confiance pour tout le reste.