Spell a UTC commit time one way, whichever git produced it - #662
Open
MongLong0214 wants to merge 5 commits into
Open
Spell a UTC commit time one way, whichever git produced it#662MongLong0214 wants to merge 5 commits into
MongLong0214 wants to merge 5 commits into
Conversation
`committedAt` is a documented field of the --json output and its value was a raw slice of git's `%cI`. Git changed how it renders a zero offset — 2.39.5 writes `+00:00`, 2.50.1 writes `Z` — so the same commit read differently depending on the machine. Measured on one commit object with both gits, and `git >= 2.9` is the floor this product declares, so 2.39 is not an exotic configuration: it is Debian stable. A consumer comparing strings, matching a pattern, or feeding a strict parser therefore got different answers about one repository. The value is now canonicalised where it is produced, which is all three places: the scan path and both index readers. Only the UTC spelling is touched. A real offset says where the commit was made and is left exactly as git wrote it. Blast: module Undo: easy Certainty: firm Ruled-out: normalise every timestamp to UTC | an offset carries where the commit happened, and discarding it to gain uniformity loses a fact the record is entitled to keep Ruled-out: canonicalise at the JSON boundary only | the index stores the same field, so the two routes would then disagree with each other rather than with git Limit: this pins the spelling, not the clock; nothing here makes two gits agree about anything else in `%cI` Provenance: authored Record-Id: r-committedat650 Verified: negative control — making the function return its input reproduces the failure, restoring it passes; 224 cases across git, stale and query; the ordering key `%ct` is untouched, so no comparison changes
CommitLore — record lintTrailers: clean — 5 commits in Trailer violations fail this check. Active constraints are informational — they are what the repository already decided, not a verdict on this PR. |
# Conflicts: # dist/commitlore.mjs # installer/canonical-artifact.json
Provenance: authored Record-Id: r-canon650m Verified: docker linux/amd64 npm ci + build + artifact:manifest; artifact:verify reports cb1dc4bd; 93 cases across git and doctor against the rebuilt bundle
This was referenced Aug 14, 2026
# Conflicts: # dist/commitlore.mjs # installer/canonical-artifact.json
Provenance: authored Record-Id: r-canon650m2 Verified: the worktree carried no uncommitted source before building, which is what made the previous artifact wrong on another branch; docker linux/amd64 npm ci + build + artifact:manifest; artifact:verify reports 30485348; 48 cases across git and doctor-snapshot
MongLong0214
added a commit
that referenced
this pull request
Aug 14, 2026
Two tests pin that the library and the shipped binary render one report identically, and that NO_COLOR changes nothing but colour. Since #661 they also counted `mcp-runtime-identity`, which enumerates live processes — so under a parallel suite it can flip between `ok` and `warn` between two runs, and the numbered warning list gains or loses an entry with every number after it shifting. That is what #662 kept failing on, on Node 22 only, while passing everywhere it was run alone. Not a defect in that branch, and not a Node difference: the suite's own parallelism was the variable. #664 canonicalised the totals and the runtime detail line and left this open in its own commit — whether the numbering also shifts was a question only CI could answer. It answered. Canonicalising the numbering too would hide it until the next check reads the machine; leaving such a check out of a format comparison is the statement that is actually true about what these tests measure. The list comes from the registry rather than being written out, so a new check cannot fall out of these comparisons without somebody choosing it. Blast: local Undo: easy Certainty: firm Ruled-out: canonicalise the numbered list as well | it covers this instance and not the class, and the class is "a check whose status depends on the machine appears in a byte comparison" Ruled-out: refresh the snapshots | the output depended on the machine, so a refresh moves the failure to whichever environment the snapshot was not taken in Limit: this exempts one check from two tests; the check itself is still exercised by its own regressions and by the pinned report, which runs through the seam with an empty runtime list Provenance: authored Record-Id: r-formatcompare661 Verified: 35 cases in doctor-snapshot; artifact:verify unchanged at b52a10c6 because no source changed; the worktree held no uncommitted source when it was built
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #650.
The defect
committedAtis a documented field of the--jsonoutput, and its value was a raw slice of git's%cI. Git changed how it renders a zero offset, so one commit object reads two ways:git >= 2.9is the floor this product declares (runtime-git-trailers.ts:25), and 2.39.5 is Debian stable's git. A consumer comparing strings, matching a pattern, or feeding a strict parser gets different answers about one repository depending on the machine that answered.The fix
Canonicalised where the value is produced — all three places, so the scan path and both index readers cannot drift apart from each other while agreeing with git.
Only the UTC spelling is touched. A real offset says where the commit was made and is left exactly as git wrote it.
Why not at the JSON boundary
The index stores the same field. Canonicalising only on the way out would leave the two routes disagreeing with each other rather than with git — trading one inconsistency for a worse one.
Negative control
Making the function return its input reproduces the failure; restoring it passes. 224 cases across
git,staleandquery.Ordering is untouched:
%ctis the sort key and this never sees it.Found by
Running the suite inside
node:22.23.2-bookwormwhile diagnosing something unrelated. CI never saw it becausegit-matrixruns onlyubuntu-latestandmacos-latest, both of which carry a recent git — a matrix that exists to vary git, not varying it across the range the product claims. That half is recorded in #650 and is not fixed here.