Uh oh!
There was an error while loading. Please reload this page.
fix(pm): give git-history self-test windows a complete instant, not an approxidated bare date - #10811
Merged
os-zhuang merged 1 commit intoAug 21, 2026
Conversation
… a bare date `git rev-list --since=2026-06-20` is an approxidate: git fills the missing time of day from the CURRENT wall clock, not from midnight. The self-test's fixture stamps its 40 commits at 12:00:00Z, so the `--since` edge swept across c19 (2026-06-20T12:00:00Z) once a day — 21 commits before 12:00 UTC, 20 after. The self-test was therefore green every morning and red every afternoon, failing `Lint & Repo Gates` for every PR in the repo and getting queued PRs evicted on rebuild. Every window edge in the self-test is now a complete UTC instant (`2026-06-20T00:00:00Z`), which git parses exactly and never approxidates. Placing each edge at 00:00:00Z also leaves 12 h — half the fixture's daily cadence, the widest gap available — between it and the nearest commit stamp. A new case recomputes both properties from the window constants, so the defect class cannot return silently. The tool's own `--since` handling is unchanged; only the question the test asks is. Counts stay exact (21 / 3 / 5) — no assertion was loosened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
os-zhuang
marked this pull request as ready for review
August 21, 2026 12:20
os-zhuang
enabled auto-merge
August 21, 2026 12:20
Uh oh!
There was an error while loading. Please reload this page.
os-zhuang
deleted the
claude/issue-10807-git-history-selftest-approxidate
branch
August 21, 2026 12:41
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 freeto 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.
Fixes#10807
scripts/pm/git-history.mjs --self-testhas been red onmainevery day after12:00 UTC, failing
Lint & Repo Gatesfor every PR in the repo and gettingqueued PRs evicted on rebuild. It is not a code regression.
Root cause, re-derived here
git rev-list --since=2026-06-20is an approxidate: git fills the missingtime of day from the current wall clock, not from midnight. The self-test's
fixture stamps its 40 commits at
12:00:00Z, one per day, and asks for--since=2026-06-20 --until=2026-07-11expecting 21. So the--sinceedgesweeps across
c19once a day.Reproduced standalone at 12:09:40Z with a fresh fixture of identical stamps and
the identical window:
c19is the dropped commit, and it is exactly the--sinceboundary. All threefailures are the same off-by-one: the wide window answers 20 instead of 21
(twice), and the narrow
--since=2026-07-08window answers 2 instead of 3because it collides with
c37the same way.The fix
Every window edge in the self-test is now a complete UTC instant
(
2026-06-20T00:00:00Z), which git parses exactly and never approxidates. Theedges are named constants, used by the CLI invocations, the raw-git baseline and
the
historyHorizonreadings alike, so a window is spelled in exactly one place.Placing each edge at
00:00:00Zalso puts it 12 h from the nearest commitstamp — half the fixture's daily cadence, the widest gap available. A new case
recomputes both properties (complete-instant shape, and edge-to-stamp distance)
from the constants rather than asserting about them, so re-cadencing the fixture
or moving a window re-runs the check instead of dating it.
Why not the alternatives. Moving the fixture stamps off 12:00 relocates the
collision instead of removing it, and leaves the edges approxidated — midnight
stamps are one timezone away from the same bug. Choosing boundaries that merely
sit between stamps helps only while the edges stay bare: an approxidated edge
still moves with the clock, so the property would hold by luck rather than by
construction. The chosen fix removes the wall clock from the computation
outright, and then also takes the maximum-separation placement. Note that
collect-release-notes.sh --self-test, which runs over an identical 40-commitfixture in the same
lint.ymlstep, has always spelled its window this way andis green right now — this change makes the two consistent.
No assertion was loosened: the counts stay exact (21 / 3 / 5). The tool's
behaviour is unchanged —
resolveSincehands--sinceto git verbatim andDate.parseonly validates it, so the complete instant survives both; the defectwas in the question the test asked, not in the tool.
Proof it is not just "green right now"
A green run proves nothing here — the bug produces exactly that evidence for
twelve hours a day. Clock-faking was available: stock git reads
GIT_TEST_DATE_NOW(epoch seconds) as "now" for approxidate resolution, which isprecisely the mechanism under test. The self-test's git subprocesses inherit it.
noworigin/main)The pre-fix column flips at exactly 12:00 UTC, reproducing the transition CI
pinned between 11:57:14Z (success) and 12:02:35Z (failure). That flip is what
makes the fixed column meaningful: it proves the faked clock really reaches the
git processes inside the self-test, so the all-day green is a measurement rather
than a no-op.
Ablation. Reverted the fix with
git checkout origin/main -- scripts/pm/git-history.mjs,confirmed on disk by anchor count (bare
--since=2026-06-20', '--untilback to 4occurrences,
WINDOW_SINCEto 0) rather than by an editor's exit code; thefailure returned at the red time of day exactly as tabulated. Restored from the
branch and confirmed byte-identical: blob
4520ae27c0ff49163525b0f49616e46209a39207before and after,
git status --porcelainempty.Gates, all at
33f00f8287Exit codes captured with
cmd > file 2>&1; ec=$?, never read through a pipe.entry-guardandparse-guardwere run by hand becausedispatch-gatesisblind to them — it reports
check:parse-guardas unreachable by construction(its declared population
scriptsis refused as too generic for want of a pathseparator), and
entry-guarddoes not appear at all.No changeset: gate tooling publishes nothing.
skip-changesetapplied additively.Swept for other instances of the same defect class
Checked whether anything else in the repo hands a bare
YYYY-MM-DDto git.Nothing else is affected, and nothing else is currently red:
scripts/collect-release-notes.sh— identical 40-commit 12:00Z fixture, butalready spells its window
2026-06-20T00:00:00Z/2026-07-11T00:00:00Z.Ran it at 12:12:31Z: exit 0, all cases passed.
scripts/check-engine-split-ratio.mjs— relative windows (<N> days ago) withthe fixture re-dated to end today and ≥1 day of slack at both edges, so no edge
sits knife-edge on a stamp. Ran it at 12:12:45Z: exit 0, all cases passed.
scripts/pm/check-governed-merges.mjsandcheck-engine-split-ratio.mjs'sproduction paths build their
--sincewithnew Date(...).toISOString(), whichis already a complete instant.
Worth noting: both of those self-tests run in the same
lint.ymlstep, aftergit-history.mjs. Because the step is a singlerun:block underbash -e, thefirst failure aborts it — so neither has actually executed in CI since 12:00Z
today. They are green; they were merely masked.
Generated by Claude Code
Generated by Claude Code