Problem
Two header-date gaps let inconsistent dates accumulate silently:
- The parenthesized unix-epoch is never checked against the ISO datetime.
toDatePayload() (src/utils/time.mjs:39) computes the epoch independently, and for an existing header extractHeaderCreatedAt() / extractHeaderLastModifiedAt() (src/core/fix-headers.mjs:152, :174) copy the date-string and epoch straight back out with no cross-check. So a header like @Date: 2026-08-24T00:00:00-08:00 (1756022400) (epoch = 2025-08-24) is never flagged or corrected.
@Date (creation) is never git-corrected once present. Precedence at src/core/fix-headers.mjs:286 is existingCreatedAt || gitCreated || filesystem, so an existing @Date is preserved verbatim; fix:headers only ever maintains @Last modified time. A wrong/stale creation date persists forever.
There's also a format inconsistency: git-sourced dates use %aI (…T…, src/utils/git.mjs:93,119) while filesystem/now dates use the space form from formatDateWithTimezone() (src/utils/time.mjs:24), so a single file can carry two shapes — which makes hand-authored headers easy to get wrong.
Real impact: a repo-wide scan of @cldmv/slothlet found 49 files with an epoch that doesn't match its ISO string (mostly timezone/hour drift, a handful with the wrong year — including, ironically, tools/dev/fix-headers.mjs itself).
Ask
- Add a
--check mode that validates each managed header and exits non-zero on drift (today there's only write + --dry-run, and --dry-run always exits 0 — src/cli.mjs:286), so it can gate CI.
- Validate: (a) epoch decodes to the ISO string shown (local, no git — catches all 49); (b)
@Date == git first-commit (getGitCreationDate, src/utils/git.mjs:92); (c) @Last modified time == git last-commit (advisory).
- In fix mode, autocorrect a stale/inconsistent
@Date from git instead of preserving it, and normalize to one canonical date shape (suggest the git %aI T-form).
Design constraint
needsUpdate is a byte-diff of a freshly-rendered header vs the file (src/core/fix-headers.mjs:291-325), which already causes a repo-wide @Last modified restamp on an author/identity mismatch. The date checks must compare epoch-vs-ISO and @Date-vs-git independently of that content/identity diff, so --check reports genuine date drift only and never trips on an identity delta. Layer on top of the in-flight fix/preserve-last-modified-identity branch.
Surfaced while addressing review comments on CLDMV/slothlet#306.
Problem
Two header-date gaps let inconsistent dates accumulate silently:
toDatePayload()(src/utils/time.mjs:39) computes the epoch independently, and for an existing headerextractHeaderCreatedAt()/extractHeaderLastModifiedAt()(src/core/fix-headers.mjs:152,:174) copy the date-string and epoch straight back out with no cross-check. So a header like@Date: 2026-08-24T00:00:00-08:00 (1756022400)(epoch = 2025-08-24) is never flagged or corrected.@Date(creation) is never git-corrected once present. Precedence atsrc/core/fix-headers.mjs:286isexistingCreatedAt || gitCreated || filesystem, so an existing@Dateis preserved verbatim;fix:headersonly ever maintains@Last modified time. A wrong/stale creation date persists forever.There's also a format inconsistency: git-sourced dates use
%aI(…T…,src/utils/git.mjs:93,119) while filesystem/now dates use the space form fromformatDateWithTimezone()(src/utils/time.mjs:24), so a single file can carry two shapes — which makes hand-authored headers easy to get wrong.Real impact: a repo-wide scan of
@cldmv/slothletfound 49 files with an epoch that doesn't match its ISO string (mostly timezone/hour drift, a handful with the wrong year — including, ironically,tools/dev/fix-headers.mjsitself).Ask
--checkmode that validates each managed header and exits non-zero on drift (today there's only write +--dry-run, and--dry-runalways exits 0 —src/cli.mjs:286), so it can gate CI.@Date== git first-commit (getGitCreationDate,src/utils/git.mjs:92); (c)@Last modified time== git last-commit (advisory).@Datefrom git instead of preserving it, and normalize to one canonical date shape (suggest the git%aIT-form).Design constraint
needsUpdateis a byte-diff of a freshly-rendered header vs the file (src/core/fix-headers.mjs:291-325), which already causes a repo-wide@Last modifiedrestamp on an author/identity mismatch. The date checks must compare epoch-vs-ISO and@Date-vs-git independently of that content/identity diff, so--checkreports genuine date drift only and never trips on an identity delta. Layer on top of the in-flightfix/preserve-last-modified-identitybranch.Surfaced while addressing review comments on CLDMV/slothlet#306.