The single architectural decision that shapes everything else in this app is small to state and inconvenient to build around: the photo drive is opened strictly read-only and is never written to. No sidecar file next to the originals, no hidden metadata folder, no rename, no moved duplicate. The drive that comes in is the drive that goes back out, byte for byte.
That constraint rules out every tool that "organizes" files by moving or renaming them. It also rules out storing derived state (thumbnails, face embeddings, event boundaries) anywhere near the originals. Everything the app learns about an archive has to live somewhere else, so I had to decide early where that would be.
Everything derived lives on the internal disk
The answer is SQLite, on the Mac's internal disk, not the external drive. The index (dates, faces, event boundaries, embeddings for search) and the thumbnail cache both live there, fully separate from the archive itself. Delete the app's data directory and the archive is provably untouched, because nothing about the archive ever depended on that directory existing. Reinstall from scratch and the app rebuilds its understanding by reading the drive again, not by needing to trust a backup of its own state.
SQLite's write-ahead log mattered most in practice. During development there were two hard crashes, real power cuts rather than simulated faults, mid-write while the study was running against a real archive. Both times WAL journaling meant zero data loss: the database came back in a consistent state on the next launch and picked up roughly where it left off, with no manual repair. With an external drive, a background study running for hours, and a household where the cable occasionally gets bumped, it was tested for real, twice, before launch.
What "read it" actually recovers
A read-only guarantee is only as useful as what you can extract while honoring it, and metadata in a real family archive is messier than a clean test set. On the founding archive, 92% of files carried usable EXIF dates outright. The remaining 8% needed fallbacks, file system timestamps, folder-name dates, inference from neighboring photos in the same event, and after those fallbacks, coverage reached 98.1%. The last two percent is the floor: some files carry no date signal in the file or around it, and no fallback chain can invent one.
Browsable before it's finished understanding
Read-only originals with derived state elsewhere solve the safety problem. There is also a patience problem: a full study of a large archive takes hours, and nobody wants to watch a progress bar before seeing a single photo. The library becomes browsable within minutes of pointing the app at a drive, because an early pass puts enough of the index and thumbnails in place for basic browsing. The deeper passes (face clustering, event naming, the embeddings behind meaning-search) keep running behind that and fill in richer answers while you look at photos.
Resource governance is a rule, not a suggestion
A study that reads a few hundred thousand files is heavy work, and heavy background work on someone's only Mac is how local AI turns into a laptop that runs hot while you're trying to use it. The limits are hard rules: background QoS scheduling so the study never competes with foreground work, worker counts that back off within seconds of the user becoming active, a ceiling on memory use, and a pause under battery or thermal pressure. A full study on a base Mac shouldn't be something you can feel. If it is, that's a bug.
Read-only originals, derived state on the internal disk, crash-safe journaling, and resource limits that hold add up to a plain engineering position. The AI runs on-device, and beyond that there is no server to trust, so each of these guarantees only has to be true of one machine on your desk, the one you already trust with everything else.