The copy cache trusted a change time it had seen as proof the file had not
changed. NTFS stamps ChangeTime from Windows' clock tick, not the precise
clock: on the Windows box, 300 ms of back-to-back same-size writes got a
new ChangeTime only every ~0.5 ms (2147 of 2691 writes kept the previous
stamp; diffs 0.5/1.0/1.5 ms). A rewrite in the tick of the comparison kept
the stamp the cache saw, so the cached relation was reused. That, not write
merging, is why TestCodexArchivedSameSizeRewriteInvalidatesDiscovery failed
19 of 300 runs on Windows, alone as well as in the full package.
A comparison is now cached only when both files' change times are more than
a second older than the moment it started (codexStampSettle); a file changed
more recently is compared again next time. A later rewrite then lands in a
later tick and changes the stamp. Change times are compared as times
(Windows FILETIME converted).
TestCodexSameTickRewriteIsNotCached gives every write one change time and a
clock 10 ms into that tick. With the settle rule taken out (cacheable = both
stamps present), it fails: "a rewrite in the tick of the comparison reused
its stale relation". With it, it passes, and the second half checks settled
copies are still compared once, not every time.
TestCodexArchivedDiscoveryCacheAndAppend moves its clock a minute on so the
just-written copies count as settled.
The Windows CI step now runs the Codex copy tests (CodexArchived,
CodexSameTick, CodexPlainTwin), which it had never run.
Run: Windows 11 box (cross-built sessions.test.exe, sandbox USERPROFILE/
APPDATA/TEMP): old binary 19/300 failures of the reported test; new binary
0/1000 for the three Codex copy tests, and the Windows CI regex x5 with
testdata passes. macOS: go test -race ./internal/sessions, -race -count=30 of
the Codex copy tests, go vet (darwin, GOOS=linux, GOOS=windows), gofmt -l.
Not run: Linux with a coarse ctime clock (kernels before 6.13); the rule
covers it the same way.