PhotoDropMac 0.1.0 (deprecated — use 0.1.3)
Warning
Deprecated — superseded by 0.1.3. Please download that instead.
Three things are missing from this build:
- Manifest durability under concurrent ingests, fixed in 0.1.3. Ten
photodrop ingestprocesses started at once left two manifests out of ten. - Manifest durability for back-to-back ingests, fixed in 0.1.2. Job filenames resolved only to the second, so two ingests finishing in the same second overwrote each other's manifest.
- The app icon, added in 0.1.1. This build shows the generic blank icon.
Signing and notarization are identical across every release — no security or Gatekeeper difference, and nothing here is unsafe to run. It stays downloadable for reproducibility.
The files are fine — the risk is that verification silently covers fewer of them. A manifest-based verify reports success over whatever records survive, so it can print ✓ All 1 file … and exit 0 for a larger library. Check the count it reports against what you actually have. Every copied file also carries its own checksum as an extended attribute, independent of any manifest:
photodrop verify <library> --xattrLibraries written by this version remain fully valid, and 0.1.3 verifies them unchanged.
First public release of PhotoDropMac — a native macOS app that ingests photos from removable memory cards into a date-organized library, with streaming hash verification, content-based deduplication, and any number of mirror destinations.
Install: download the DMG, drag to Applications. It's Developer ID-signed and notarized, and both the disk image and the app inside it carry a stapled notarization ticket — so it opens with no Gatekeeper warning even on a Mac that's offline at first launch.
What it does
- Ingest — scan a card, preview the year/day folder tree or cull in a contact sheet, then copy each photo bundle (RAW + its sidecars, JPEG pair, and audio note move together, all-or-nothing) with a tee-hashed xxHash64 verify on every file.
- Dedup — content-based across the whole destination root, so a renamed earlier import is still recognized.
- Mirrors — primary plus any number of archive destinations, each independently verified (3-2-1 backups).
- Receipts — every ingest writes a JSON + CSV manifest of what landed and its checksums, and stamps each file with its own checksum xattr.
- Verify & heal — re-check a library against its manifests (or against the per-file xattrs, which survive a reorg).
healreports which damaged files can be restored from a mirror and where from; it never writes to your library, only emits a script you review and run. photodropCLI —ingest,verify, andhealheadless, embedded in the app bundle and covered by the same notarization. Scheduled background verification via a launchd agent.
Security
This release ships the results of a red-team review of the manifest trust boundary. No earlier build was ever published, so nothing below ever reached users — but the issues are worth naming since they shape how the tool now treats data it didn't write.
A manifest is unauthenticated data sitting inside the library it describes, and verify/heal accept a target you didn't necessarily create — a shared library, a folder on a card, or a .json passed straight to the CLI. It's now treated as untrusted input:
- Path containment (
a20395b) — manifest-recorded paths are confined to the library root. Previously a../../../..entry made verify hash arbitrary files on disk and could makeheal's restore script overwrite them. The restore script also no longer lets control characters in a filename forge what looks like a command, and it lists every directory it will copy from so the review it asks for is actually possible. - Manifest conflicts (
da870c2) — when two manifests disagree about a file's checksum, that's reported rather than silently resolved in favour of whichever claims to be newest. Ordering came from a field inside the file itself, so planting one manifest could relabel a tampered file as verified. - Hardening (
c2cfc22) — the hash cache now requires an exact nanosecond timestamp match before reusing a digest (a false match could silently skip a photo, invisibly to later verification); CSV filenames can't act as spreadsheet formulas; and the symlink defense in discovery is documented and tested.
Verification coverage grew from 111 to 123 tests, including regression tests for each of the above.
Behaviour note: if you delete a file from your library and re-ingest different content to the same path, verify now reports CONFLICT rather than passing silently. The library's own records genuinely disagree at that point, and that's what the report says.
Requirements
macOS 14.0 or later. Unsandboxed by design — it needs arbitrary card→destination filesystem access and calls diskutil to eject cards.
Verifying this download
SHA-256 c32e5596c5e6e23f444519859af91b049317855955bbaf225883ade619a652b9
PhotoDropMac-0.1.0.dmg
shasum -a 256 PhotoDropMac-0.1.0.dmg
xcrun stapler validate PhotoDropMac-0.1.0.dmg
spctl -a -t exec -vvv /Applications/PhotoDropMac.app # → source=Notarized Developer ID