Skip to content

Header-only rewrites must not touch @Last modified by/time; @Author is never changed unless forced #127

Description

@Shinrai

Required behaviour (maintainer decision, 2026-10-04)

  1. @Author is the original author and is never changed unless explicitly forced (forceAuthorUpdate). Missing or unrecognised @Author values may still be filled in.
  2. @Last modified by and @Last modified time record the last real edit to the file's content. Running fix-headers on a file whose content (everything outside the header) wasn't edited must not change either field, even when fix-headers rewrites other parts of the header: converting the date format (normalizeDateFormat), repairing an epoch, adding the frame/spacing/margin, fixing @Date (fixCreatedDate), filename, project name, copyright year, and so on. Example: converting 2026-03-01 17:59:32 -08:00 to 2026-03-01T17:59:32-08:00 must not change @Last modified by or @Last modified time.
  3. When the content was edited, @Last modified by becomes the editor (the identity fix-headers detects for the run) and @Last modified time the edit time. With that in place, forceLastModifiedAuthorUpdate shouldn't be needed for normal use.

Problem today

Any header change restamps @Last modified time. With useGpgSignerAuthor + forceAuthorUpdate + forceLastModifiedAuthorUpdate (the shared CLDMV config), whoever runs the tool also becomes @Author and @Last modified by of every file. Reproduced on 2026-10-04 in CLDMV/slothlet (CLDMV/slothlet#569): a dry run as Jane Contributor with no signing key would rewrite all 1150 headers' @Author and @Last modified by to Jane.

Implementation notes

  • "Content edited" needs a definition that works in a writing run. Suggested: compare the file's body (header stripped) with the body at HEAD (git show HEAD:<path>). If they differ, or the file isn't tracked yet, it was edited and gets restamped. If they're the same, keep the existing last-modified values, even if the header itself changes. Outside a git repo, fall back to the current behaviour.
  • Consider also using the last commit that changed the body (not only header lines) as the source when a header has no last-modified fields.
  • Add tests covering: header-only normalisation with no restamp; a body edit restamping with the runner's identity; @Author preserved for a different runner; forceAuthorUpdate still replacing it; untracked/new files.
  • This changes output for every consumer, so it needs a release note.

Related: CLDMV/configs#15 (drop the force options from the shared config).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: highNeeds attention soon — not blocking, but don't let it sitstatus: implementedBuilt and deployed, but not yet fully tested/verifiedtype: feature requestA request to add new functionality that does not currently exist

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions