Two prod rows (uv-prod-long.mp4, uv-prod-long-v2.mp4) never get date_utc. Legacy source is exiftool, but every date tag in the file is 0000:00:00 00:00:00. The re-resolution lands on fs_time, and backfill_utc_dates refuses fs_time over a tag-sourced legacy date, assuming exiftool failed on the file. It didn't fail. The file has no date, so the rows stay unconverted and go back through exiftool every tick.
Change
date_resolver::resolve_dates_batch_report returns BatchResolution { resolved, exiftool_read }. exiftool_read holds the paths exiftool returned an error-free entry for. resolve_dates_batch is now a thin wrapper, so other callers don't change.
exiftool now also gets -Error. Under -q, a per-file read error such as File format error or Error opening file otherwise only goes to stderr, and the file's JSON entry looks like a clean read with no tags. Entries with ExifTool:Error don't count as read.
backfill_utc_dates: the guard is now utc_resolution_is_faithful. fs_time over a legacy exiftool row is allowed only if exiftool read the file during this pass. It is still refused when:
the file has no entry or got a read error (exiftool crashed, partial output, unreadable file)
the legacy source is exif (kamadak-exif). A different reader found that date, so exiftool coming up empty doesn't prove the date was bogus.
backfill_missing_date_taken doesn't have this gap. It has no such guard and already writes fs_time for date_taken IS NULL rows.
Tests
utc_resolution_fs_time_over_tag_date_needs_an_exiftool_read: truth table for the guard (hermetic).
parse_payload_flags_read_errors_not_zero_dates: an all-zero payload counts as a clean read with no date, and ExifTool:Error sets the error flag (hermetic).
utc_backfill_legacy_exiftool_row_with_only_zero_dates_converts_to_fs_time: an ffmpeg mp4 with zeroed QuickTime/Track dates converts to its fs time (utc_direct) and the legacy pair stays frozen. A binary-junk file with an exiftool File format error stays unresolved (needs ffmpeg + exiftool).
Full suite: 871 lib tests pass. Clippy --all-targets is clean.
## Problem
Two prod rows (`uv-prod-long.mp4`, `uv-prod-long-v2.mp4`) never get `date_utc`. Legacy source is `exiftool`, but every date tag in the file is `0000:00:00 00:00:00`. The re-resolution lands on `fs_time`, and `backfill_utc_dates` refuses fs_time over a tag-sourced legacy date, assuming exiftool failed on the file. It didn't fail. The file has no date, so the rows stay unconverted and go back through exiftool every tick.
## Change
- `date_resolver::resolve_dates_batch_report` returns `BatchResolution { resolved, exiftool_read }`. `exiftool_read` holds the paths exiftool returned an error-free entry for. `resolve_dates_batch` is now a thin wrapper, so other callers don't change.
- exiftool now also gets `-Error`. Under `-q`, a per-file read error such as `File format error` or `Error opening file` otherwise only goes to stderr, and the file's JSON entry looks like a clean read with no tags. Entries with `ExifTool:Error` don't count as read.
- `backfill_utc_dates`: the guard is now `utc_resolution_is_faithful`. fs_time over a legacy `exiftool` row is allowed only if exiftool read the file during this pass. It is still refused when:
- the file has no entry or got a read error (exiftool crashed, partial output, unreadable file)
- the legacy source is `exif` (kamadak-exif). A different reader found that date, so exiftool coming up empty doesn't prove the date was bogus.
- `backfill_missing_date_taken` doesn't have this gap. It has no such guard and already writes fs_time for `date_taken IS NULL` rows.
## Tests
- `utc_resolution_fs_time_over_tag_date_needs_an_exiftool_read`: truth table for the guard (hermetic).
- `parse_payload_flags_read_errors_not_zero_dates`: an all-zero payload counts as a clean read with no date, and `ExifTool:Error` sets the error flag (hermetic).
- `utc_backfill_legacy_exiftool_row_with_only_zero_dates_converts_to_fs_time`: an ffmpeg mp4 with zeroed QuickTime/Track dates converts to its fs time (`utc_direct`) and the legacy pair stays frozen. A binary-junk file with an exiftool `File format error` stays unresolved (needs ffmpeg + exiftool).
- Full suite: 871 lib tests pass. Clippy `--all-targets` is clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
backfill_utc_dates refused any fs_time re-resolution of a tag-dated row,
assuming exiftool had failed on the file. Files whose date tags are all
0000:00:00 (e.g. uv-prod-long.mp4) were read fine and simply have no
date, so they sat unconverted and re-ran through exiftool every tick.
resolve_dates_batch_report now also returns the paths exiftool read
without error (-Error surfaces ExifTool:Error in the JSON). The drain
lets fs_time stand for an exiftool-legacy row only when exiftool read
the file; read errors / missing entries and kamadak exif-legacy rows
keep refusing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cameron
merged commit fdbcc75391 into master2026-10-17 16:35:12 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Two prod rows (
uv-prod-long.mp4,uv-prod-long-v2.mp4) never getdate_utc. Legacy source isexiftool, but every date tag in the file is0000:00:00 00:00:00. The re-resolution lands onfs_time, andbackfill_utc_datesrefuses fs_time over a tag-sourced legacy date, assuming exiftool failed on the file. It didn't fail. The file has no date, so the rows stay unconverted and go back through exiftool every tick.Change
date_resolver::resolve_dates_batch_reportreturnsBatchResolution { resolved, exiftool_read }.exiftool_readholds the paths exiftool returned an error-free entry for.resolve_dates_batchis now a thin wrapper, so other callers don't change.-Error. Under-q, a per-file read error such asFile format errororError opening fileotherwise only goes to stderr, and the file's JSON entry looks like a clean read with no tags. Entries withExifTool:Errordon't count as read.backfill_utc_dates: the guard is nowutc_resolution_is_faithful. fs_time over a legacyexiftoolrow is allowed only if exiftool read the file during this pass. It is still refused when:exif(kamadak-exif). A different reader found that date, so exiftool coming up empty doesn't prove the date was bogus.backfill_missing_date_takendoesn't have this gap. It has no such guard and already writes fs_time fordate_taken IS NULLrows.Tests
utc_resolution_fs_time_over_tag_date_needs_an_exiftool_read: truth table for the guard (hermetic).parse_payload_flags_read_errors_not_zero_dates: an all-zero payload counts as a clean read with no date, andExifTool:Errorsets the error flag (hermetic).utc_backfill_legacy_exiftool_row_with_only_zero_dates_converts_to_fs_time: an ffmpeg mp4 with zeroed QuickTime/Track dates converts to its fs time (utc_direct) and the legacy pair stays frozen. A binary-junk file with an exiftoolFile format errorstays unresolved (needs ffmpeg + exiftool).--all-targetsis clean.🤖 Generated with Claude Code