Required behaviour (maintainer decision, 2026-10-04)
@Author is the original author and is never changed unless explicitly forced (forceAuthorUpdate). Missing or unrecognised @Author values may still be filled in.
@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.
- 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).
Required behaviour (maintainer decision, 2026-10-04)
@Authoris the original author and is never changed unless explicitly forced (forceAuthorUpdate). Missing or unrecognised@Authorvalues may still be filled in.@Last modified byand@Last modified timerecord 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: converting2026-03-01 17:59:32 -08:00to2026-03-01T17:59:32-08:00must not change@Last modified byor@Last modified time.@Last modified bybecomes the editor (the identity fix-headers detects for the run) and@Last modified timethe edit time. With that in place,forceLastModifiedAuthorUpdateshouldn't be needed for normal use.Problem today
Any header change restamps
@Last modified time. WithuseGpgSignerAuthor+forceAuthorUpdate+forceLastModifiedAuthorUpdate(the shared CLDMV config), whoever runs the tool also becomes@Authorand@Last modified byof every file. Reproduced on 2026-10-04 in CLDMV/slothlet (CLDMV/slothlet#569): a dry run asJane Contributorwith no signing key would rewrite all 1150 headers'@Authorand@Last modified byto Jane.Implementation notes
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.@Authorpreserved for a different runner;forceAuthorUpdatestill replacing it; untracked/new files.Related: CLDMV/configs#15 (drop the force options from the shared config).