Dates: pre-cutover audit utility for the filename date class #117

Closed
opened 2026-09-24 22:54:32 +00:00 by cameron · 1 comment
Owner

Parent

ImageApi #113 — SPEC: true-instant date contract (ADR-0001).

What to build

A one-shot, operator-run audit utility (following the repo's existing utility-binary pattern, e.g. the cleanup binary) that lists every file matching a filename-class pattern: the file's current stored date and date source, and the date/source/offset-source the re-based resolver would assign it. It reads the live database and walks the libraries (honor the library exclusions and the online gate — offline libraries are reported, not processed). It changes nothing.

Purpose: the filename class is a documented inversion of EXIF-wins and depends on the operator's memory of "what these filenames mean." This report is the human spot-check that gates the production backfill drain — the operator reviews it, fixes any mis-tagged pattern or misclassified file, and only then starts the drain.

Acceptance criteria

  • Running the utility against the live library prints one row per filename-class file: current date + source, proposed date + source + offset-source, and the matched pattern name.
  • Files outside the class are not listed.
  • Offline/unavailable libraries are reported as skipped, never processed partially and never cause an error.
  • The utility is strictly read-only (no writes to any table).
  • Output is stable-sorted (by library, then path) so two runs diff cleanly.
  • A run against a fixture library with seeded mixed-convention rows shows the proposed-vs-current delta correctly (a seeded EXIF row whose filename says otherwise shows the inversion; a seeded unix-timestamp name shows utc_direct).

Blocked by

  • ImageApi #116 (filename date class conventions + priority)
## Parent ImageApi #113 — SPEC: true-instant date contract (ADR-0001). ## What to build A one-shot, operator-run audit utility (following the repo's existing utility-binary pattern, e.g. the cleanup binary) that lists every file matching a filename-class pattern: the file's current stored date and date source, and the date/source/offset-source the re-based resolver would assign it. It reads the live database and walks the libraries (honor the library exclusions and the online gate — offline libraries are reported, not processed). It changes nothing. Purpose: the filename class is a documented inversion of EXIF-wins and depends on the operator's memory of "what these filenames mean." This report is the human spot-check that gates the production backfill drain — the operator reviews it, fixes any mis-tagged pattern or misclassified file, and only then starts the drain. ## Acceptance criteria - [ ] Running the utility against the live library prints one row per filename-class file: current date + source, proposed date + source + offset-source, and the matched pattern name. - [ ] Files outside the class are not listed. - [ ] Offline/unavailable libraries are reported as skipped, never processed partially and never cause an error. - [ ] The utility is strictly read-only (no writes to any table). - [ ] Output is stable-sorted (by library, then path) so two runs diff cleanly. - [ ] A run against a fixture library with seeded mixed-convention rows shows the proposed-vs-current delta correctly (a seeded EXIF row whose filename says otherwise shows the inversion; a seeded unix-timestamp name shows `utc_direct`). ## Blocked by - ImageApi #116 (filename date class conventions + priority)
cameron self-assigned this 2026-09-25 21:18:23 +00:00
Author
Owner

Resolved via PR #123 (master ← feature/filename-audit, commits 3aa6ce3, 89fc24c).

  • cargo run --bin filename_audit — strictly read-only (SELECTs only; verified in review), one entry per filename-class file: pattern, current date + source, proposed date + source + tz_source + numeric offset, * marking rows whose stored legacy date would change. Deterministic, stable-sorted by (library, path).
  • Proposed values mirror the drain exactly: resolve_dates_batch with empty priors (the #118 call shape), in-class path is subprocess-free (no exiftool), effective excludes = EXCLUDED_DIRS ∪ per-library column, probe_online gate with had_data from the image_exif count — disabled and offline libraries reported as skipped, never partially processed.
  • memories::match_filename_date canonical matcher (reports which pattern matched); extract_date_from_filename is now a thin, byte-for-byte behavior-preserving wrapper.
  • Evidence: 6 new tests (inversion fixture asserting stored-exif vs proposed-filename with -240m offset, utc_direct with no offset, exclusions, offline/disabled skip, stable sort, report determinism). 645 lib + 718 integration pass; fmt/clippy clean. Two-axis review: spec 6/6 + invariants 5/5 PASS; standards ship-with-fixes, all 6 findings applied.

The operator runs it against prod before starting the #118 drain; the report is the gating artifact.

**Resolved** via PR #123 (`master` ← `feature/filename-audit`, commits `3aa6ce3`, `89fc24c`). - `cargo run --bin filename_audit` — strictly read-only (SELECTs only; verified in review), one entry per filename-class file: pattern, current date + source, proposed date + source + tz_source + **numeric offset**, `*` marking rows whose stored legacy date would change. Deterministic, stable-sorted by (library, path). - Proposed values mirror the drain exactly: `resolve_dates_batch` with empty priors (the #118 call shape), in-class path is subprocess-free (no exiftool), effective excludes = `EXCLUDED_DIRS` ∪ per-library column, `probe_online` gate with `had_data` from the `image_exif` count — disabled and offline libraries reported as skipped, never partially processed. - `memories::match_filename_date` canonical matcher (reports which pattern matched); `extract_date_from_filename` is now a thin, byte-for-byte behavior-preserving wrapper. - Evidence: 6 new tests (inversion fixture asserting stored-exif vs proposed-filename with -240m offset, `utc_direct` with no offset, exclusions, offline/disabled skip, stable sort, report determinism). 645 lib + 718 integration pass; fmt/clippy clean. Two-axis review: spec 6/6 + invariants 5/5 PASS; standards ship-with-fixes, all 6 findings applied. The operator runs it against prod before starting the #118 drain; the report is the gating artifact.
cameron added the wayfinder:task label 2026-09-30 00:47:17 +00:00
Sign in to join this conversation.