If you move, rename or delete photos outside Kestrel, it now notices and offers to repair the link rather than quietly showing you the wrong thing. v(Ruddy Turnstone) is primarily a stability and data-integrity release: alongside the new Repair dialog it carries the largest round of crash-recovery, atomic-write and security fixes Kestrel has shipped, plus a scene grid that reflects the culling decisions you actually made.
Desktop App — Major Changes
- Kestrel notices when a folder and its analysis data have drifted apart, and offers to fix it. Analysis lives in a
.kestrelfolder beside your photos, and until now the filesystem could quietly break that link: move a keeper into a subfolder, rename a file, or delete one, and Kestrel would keep describing photos that were no longer there. After every folder load it now compares the folder against its database in the background, marks affected folders with an amber warning in the folder tree, and offers a Repair dialog. Renamed photos are matched and shown asold → newpairs for you to confirm; photos found one level down can be followed with a single click; photos it genuinely can't find get two explicit answers — I moved them, which carries your ratings and culling decisions across, or I deleted them, which clears the orphaned rows. Every repair takes a backup first. - Nothing is ever offered unless the folder was actually read. A disconnected external drive, an unresponsive network share or a stale macOS folder permission produces an empty listing that looks exactly like "every photo was deleted". In that case Kestrel says it couldn't read the folder, states plainly that nothing was changed, and offers no buttons at all.
- A photo is now identified by its name and its file size. Filename alone couldn't tell a re-shot
IMG_0005.CR3from the one analyzed a week earlier, so the new photo was skipped as "already analyzed" while the grid kept showing metadata for a photo that no longer existed. Analysis now compares both. Folders analyzed by older builds are upgraded in place the next time you analyze them — nothing to migrate by hand. - The scene grid represents your decisions, not just Kestrel's scores. A scene's thumbnail is now the best photo you accepted, or failing that the best one you haven't rejected — a scene no longer advertises a photo you already threw out. Scenes you haven't touched keep exactly the thumbnail they always had. Hovering a scene's image count breaks it down as accepted, undecided and rejected, and the old "only manually reviewed" checkbox became a three-way Review state filter so you can pull up only the scenes still needing work.
- 7/8/9 join Z/X/C for Accept, Undecided and Reject. They sit directly above the 1–5 rating keys on a numpad, so a whole review pass fits on one hand. Suggested by a user.
Desktop App — Data Integrity & Stability
- Culling decisions made while analysis was running could be erased by the next per-image save — a second photo culled during a run was wiped by the save that followed it. Fixed, with regression tests.
- Sidecars you edited elsewhere are no longer silently overwritten. Kestrel records a content fingerprint of each
.xmpas it writes it; if you edited that sidecar in Lightroom or darktable afterwards, the next metadata pass skips it and reports the conflict so you decide explicitly. Sidecars are also written to a temp file and swapped into place, so a crash mid-write can't leave one half-written. - When analysis dies inside a native library, the log now says where. A hard failure inside the model runtime, LibRaw or OpenCV never unwinds to an error handler, so the hardest crashes used to arrive with no context. Kestrel now records each setup stage as it happens and logs which execution providers were actually granted, so the last line of the log names the stage and backend the process died in.
- Manual star ratings are no longer dropped when upgrading a folder from a legacy database.
- Rejecting or restoring a photo never overwrites a file already at the destination; conflicts and skips are now reported honestly rather than claiming everything moved.
- A second culling pass no longer destroys the first pass's Undo point — backups are rotated under timestamped names.
- Scene data, the UI's CSV, cloud pack-merge results and database backups are all written and restored atomically, with Windows lock retries. A corrupt scene-data file is reported as an error rather than read as empty, which would have overwritten your ratings.
- Long browsing sessions no longer grow in memory without bound, cancelling an analysis releases decoding threads promptly, and a transient file lock on the database no longer ends an entire run.
- Fewer false "Kestrel didn't close properly" prompts, and crash tracebacks work again in packaged builds.
- Corrected the Olympus ORF magic bytes, so EXIF now reads correctly on the affected Olympus RAW files.
Security
- The folder-repair paths treat the analysis database as untrusted input, since it travels with a shared photo folder: file deletions and copies are confined to Kestrel's own
.kestreldirectory and to image files, so a crafted database can't reach your originals. - An interrupted repair now unwinds everything it staged, so a failed attempt can't leave a folder in a state that refuses every retry.
- Perch upload paths are jailed properly, opening a Perch gallery link goes through the same URL allowlist as every other external link, and Pillow was updated to 12.3.0 to pick up upstream security fixes.
Feedback? Please visit projectkestrel.org/contact or use the in-app feedback feature!