The filename date class becomes first-class (ADR-0001, ticket #116): a file whose name matches any existing pattern is in the class — the name is the original date of record and now resolves before EXIF / container dates are consulted.
resolve_date_taken / resolve_dates_batch
+ filename_class_resolved # in-class names resolve here (before EXIF)
+ Wall (screenshot/dash/compact) -> offset cascade (tag -> GPS -> server zone)
+ Utc (unix-timestamp names) -> true instant, tz_source = utc_direct
exif_prior_resolved # out-of-class only
exiftool (single subprocess) # out-of-class only (in-class files skip it)
fs_time # out-of-class only
pubenumFilenameDate{Wall(NaiveDateTime),// device clock, needs the cascade
Utc(DateTime<Utc>),// already a true instant
}implFilenameDate{fnlegacy_datetime(self)-> DateTime<Utc>// wall-as-UTC / epoch
fnlegacy_timestamp(self)-> i64// what the legacy column stores
}
No patterns added or removed — every existing pattern keeps its regex and gains an explicit convention. The legacy date_taken value is byte-identical to the pre-migration interpretation at all seven consumer call sites.
Evidence
Before: filename rows resolved after EXIF/exiftool and stayed unclassified (date_utc = NULL); a Screenshot_2014-…-named file with a 2021 EXIF date showed under 2021.
After: five new waterfall-seam tests pin the contract:
Two-axis code review (standards + spec sub-agents): spec axis clean, all acceptance criteria verified; standards axis no violations, 3 of 4 P2 judgement calls applied in the diff.
Merge Danger
Door: two-way. Revert restores the old waterfall; the legacy column is untouched for existing rows, and the new-contract columns only gain values that were NULL before.
Blast Radius: ingest + per-tick drain waterfall only. One deliberate behavior change for new in-class files that also carry EXIF: their legacy date_taken now comes from the filename (wall-as-UTC / epoch) instead of the EXIF date — that is the point of the ticket. Existing rows are never rewritten.
## Summary
The filename date class becomes first-class (ADR-0001, ticket #116): a file whose name matches any existing pattern is *in the class* — the name is the original date of record and now resolves **before** EXIF / container dates are consulted.
```
resolve_date_taken / resolve_dates_batch
+ filename_class_resolved # in-class names resolve here (before EXIF)
+ Wall (screenshot/dash/compact) -> offset cascade (tag -> GPS -> server zone)
+ Utc (unix-timestamp names) -> true instant, tz_source = utc_direct
exif_prior_resolved # out-of-class only
exiftool (single subprocess) # out-of-class only (in-class files skip it)
fs_time # out-of-class only
```
```rust
pub enum FilenameDate {
Wall(NaiveDateTime), // device clock, needs the cascade
Utc(DateTime<Utc>), // already a true instant
}
impl FilenameDate {
fn legacy_datetime(self) -> DateTime<Utc> // wall-as-UTC / epoch
fn legacy_timestamp(self) -> i64 // what the legacy column stores
}
```
No patterns added or removed — every existing pattern keeps its regex and gains an explicit convention. The legacy `date_taken` value is byte-identical to the pre-migration interpretation at all seven consumer call sites.
## Evidence
- **Before:** filename rows resolved *after* EXIF/exiftool and stayed unclassified (`date_utc = NULL`); a `Screenshot_2014-…`-named file with a 2021 EXIF date showed under 2021.
- **After:** five new waterfall-seam tests pin the contract:
- `filename_class_wall_without_evidence_assumes_server_zone`
- `filename_class_wall_outranks_exif_and_uses_its_evidence` (the inversion: 2020 EXIF ignored, 2015 filename wall used with the prior's offset tag)
- `filename_class_wall_gps_evidence_uses_capture_zone`
- `filename_class_timestamp_is_utc_direct`
- `in_class_video_name_resolves_without_exiftool`
- Out-of-class EXIF-wins unchanged: `resolve_uses_prior_exif_when_present` et al. still pass untouched.
- `cargo test`: 639 lib + 716 integration, 0 failed. `cargo fmt --check` + `cargo clippy --all-targets` clean.
- Two-axis code review (standards + spec sub-agents): spec axis clean, all acceptance criteria verified; standards axis no violations, 3 of 4 P2 judgement calls applied in the diff.
## Merge Danger
**Door:** two-way. Revert restores the old waterfall; the legacy column is untouched for existing rows, and the new-contract columns only gain values that were NULL before.
**Blast Radius:** ingest + per-tick drain waterfall only. One deliberate behavior change for *new* in-class files that also carry EXIF: their legacy `date_taken` now comes from the filename (wall-as-UTC / epoch) instead of the EXIF date — that is the point of the ticket. Existing rows are never rewritten.
The wayfinding doc pointed at a .../dependencies/blocked_by subpath
that 404s, and the working call needs the blocker's owner+repo in the
JSON body (omitting them 404s with 'repository does not exist').
Verified against Gitea 1.27: POST/DELETE .../issues/<child>/dependencies
with {"index", "owner", "repo"}.
The filename date class is now first-class (ADR-0001):
- memories::extract_date_from_filename returns FilenameDate:
Wall(NaiveDateTime) for the screenshot/dash/compact patterns,
Utc(DateTime<Utc>) for the unix-timestamp patterns. No patterns
added or removed; every existing pattern carries its convention.
- Waterfall inversion in both resolve_date_taken and
resolve_dates_batch: an in-class name is the original date of
record and resolves BEFORE EXIF / container dates are consulted
(shared filename_class_resolved step; in-class files skip
exiftool entirely). Wall patterns run the offset cascade over the
kamadak prior's evidence (empty evidence -> server-zone
assumption, so a class file always resolves); timestamp patterns
are true instants (tz_source utc_direct, no offset).
- Legacy date_taken stays byte-identical: wall-as-UTC for wall
patterns, epoch for timestamp patterns, via
FilenameDate::legacy_datetime / legacy_timestamp at the seven
consumer call sites.
- Out-of-class files keep the global EXIF-wins waterfall unchanged.
- CLAUDE.md waterfall section rewritten (step 0 = filename class;
the EXIF-beats-filename note becomes out-of-class-only).
Tests: five new waterfall-seam tests (wall no-evidence ->
assumed_server; wall outranks EXIF with offset-tag evidence;
wall GPS evidence; timestamp utc_direct; in-class video name
resolves without exiftool) plus enum-shape assertions in every
extractor test. Code-reviewed on both axes (standards: no
violations, 3 of 4 P2 notes applied; spec: all acceptance
criteria verified, no scope creep).
716 integration + 639 lib tests pass; fmt + clippy clean.
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.
Summary
The filename date class becomes first-class (ADR-0001, ticket #116): a file whose name matches any existing pattern is in the class — the name is the original date of record and now resolves before EXIF / container dates are consulted.
No patterns added or removed — every existing pattern keeps its regex and gains an explicit convention. The legacy
date_takenvalue is byte-identical to the pre-migration interpretation at all seven consumer call sites.Evidence
date_utc = NULL); aScreenshot_2014-…-named file with a 2021 EXIF date showed under 2021.filename_class_wall_without_evidence_assumes_server_zonefilename_class_wall_outranks_exif_and_uses_its_evidence(the inversion: 2020 EXIF ignored, 2015 filename wall used with the prior's offset tag)filename_class_wall_gps_evidence_uses_capture_zonefilename_class_timestamp_is_utc_directin_class_video_name_resolves_without_exiftoolresolve_uses_prior_exif_when_presentet al. still pass untouched.cargo test: 639 lib + 716 integration, 0 failed.cargo fmt --check+cargo clippy --all-targetsclean.Merge Danger
Door: two-way. Revert restores the old waterfall; the legacy column is untouched for existing rows, and the new-contract columns only gain values that were NULL before.
Blast Radius: ingest + per-tick drain waterfall only. One deliberate behavior change for new in-class files that also carry EXIF: their legacy
date_takennow comes from the filename (wall-as-UTC / epoch) instead of the EXIF date — that is the point of the ticket. Existing rows are never rewritten.The wayfinding doc pointed at a .../dependencies/blocked_by subpath that 404s, and the working call needs the blocker's owner+repo in the JSON body (omitting them 404s with 'repository does not exist'). Verified against Gitea 1.27: POST/DELETE .../issues/<child>/dependencies with {"index", "owner", "repo"}.