Skip to content

Validate/correct header dates: epoch↔ISO consistency and @Date vs git creation #31

Description

@Shinrai

Problem

Two header-date gaps let inconsistent dates accumulate silently:

  1. 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.
  2. @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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions