fix(local-dev): rebuild a source edited in the stamp's timestamp tick - #7079
Merged
Yicong-Huang merged 1 commit intoJul 30, 2026
Merged
Conversation
The dirty-source fast filter treated "source mtime equal to the build stamp's" as clean, so an edit landing in the same filesystem timestamp tick as the stamp write was never rebuilt: `auto` reported `everything up-to-date` and bounced nothing. The window is one tick wide, but the stamp is written at the end of a build and the natural next action is editing the file you were just building, so it is hit in normal use — how wide the tick is depends on the filesystem and kernel clock granularity, not on how fast anyone types. Both implementations had it. `svc_src_changed` used `find -newer "$stamp"`, where `-newer` is strictly newer; `tui.py`'s `_newest_mtime_after` used a strict `>`. The shell side is the consequential half — it is what gates the rebuild, while tui.py only colours the SRC column. It now compares against a throwaway marker one second behind the stamp, because `find` has no portable "not older than". The stamp itself keeps its real mtime, so the mtime refresh at the end of the slow path still converges. tui.py can say what it means, so it uses `>=`. Both directions stay conservative rather than wrong: widening the filter only enlarges the candidate set, and the content hash underneath — which was always correct — makes the actual decision. It also self-heals, because the first tick after a build takes the hash path once, finds the content unchanged, and bumps the stamp past the sources. This also fixes `test_is_dirty_after_seed_then_edit`, which had been failing on any filesystem whose granularity is coarser than its two consecutive writes; the new test forces the colliding mtime with `os.utime` so it no longer depends on the platform. Closes apache#7075
Contributor
Backport auto-label reportThis
|
Contributor
Automated Reviewer SuggestionsBased on the
|
aglinxinyuan
approved these changes
Jul 29, 2026
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.
What changes were proposed in this PR?
The dirty-source fast filter treated "source mtime equal to the build stamp's" as clean, so an edit landing in the same filesystem timestamp tick as the stamp write was never rebuilt —
autoreportedeverything up-to-dateand bounced nothing.The window is one tick wide, which sounds negligible but isn't: the stamp is written at the end of a build, and the natural next action is editing the file you were just building. How wide the tick is depends on the filesystem and kernel clock granularity, not on how fast anyone types.
Both implementations had it, and the shell one is the consequential half — it gates the rebuild, while
tui.pyonly colours theSRCcolumn:main.shsvc_src_changedfind … -newer "$stamp"(strictly newer)tui.py_newest_mtime_afterst_mtime > stamp_mtime>=The two fixes differ because the two languages can express different things:
findhas no portable "not older than", so the shell borrows one second of slack via a marker; Python can say exactly what it means, so it uses>=. The marker is a throwaway — the stamp itself keeps its real mtime, so the mtime refresh at the end of the slow path converges exactly as before.Both directions stay conservative rather than wrong. Widening the filter only enlarges the candidate set; the content hash underneath — which was always correct — still makes the decision. And it self-heals: the first tick after a build takes the hash path once, finds the content unchanged, and bumps the stamp past the sources, so later ticks are cheap again. A source that is genuinely older than the stamp is not dragged in by the slack (asserted below).
Any related issues, documentation, discussions?
Closes #7075
How was this PR tested?
The bug's own symptom was an existing test that failed only on some filesystems. This PR adds a deterministic version of it —
os.utimeforces the colliding mtime instead of racing for it — so it holds on every platform:That count matters: before this change the suite was
1 failed, 42 passedon this machine, the failure beingtest_is_dirty_after_seed_then_edit, which had been hitting the same bug by accident wherever the filesystem granularity was coarser than its two consecutive writes. It now passes for the right reason rather than by platform luck.The shell side is covered by the mechanism it actually uses, with the colliding mtime forced by
touch -r:The first of those characterises the bug itself, so it will start failing if a future
findlearns to include equal mtimes — at which point the marker can go.Reproduction outside the suite, for the record:
Not covered: an end-to-end
autothat rebuilds off a same-tick edit. Forcing that on the real stack means winning the same race the test now sidesteps, so the suite's deterministic version is the check that carries the weight here.Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 5)