You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] watch-dot-root.test.ts case 1 is wall-clock-timed and ejected an unrelated PR from the merge queue — the queue's full-suite load is where it bites #7369
Observation-class finding, recorded by the domain:identity PM seat while triaging a merge-queue ejection. Filed unassigned, no domain:* label — routing is the triage seat's call. Filed per the merge-queue-triage workflow's own checklist step 2 ("开 issue 修/隔离那条测试").
What happened
Merge-queue build 31366863728 failed and ejected PR #7333 (removed_from_merge_queue 2026-08-10T07:56:20Z, not merged). The failing job was Test Core (2/3):
FAIL test/watch-dot-root.test.ts > FileSystemRepository watcher — dot-rooted watch root (#7150)
> sees an external edit when the root is under a dot-directory
The ejected PR cannot have caused it.#7333 changes exactly three files, all in @objectstack/plugin-audit plus one changeset:
The failing test is in @objectstack/metadata-fs. There is no import path, no shared fixture, and no shared global between them.
Why the queue is where it surfaces
The merge queue runs the full suite; PR-side CI runs the affected subset. #7333's own PR-side Test Core (1/3, 2/3, 3/3) were green on both of its head commits (c6871848e and 508a96643) — the metadata-fs shard simply never ran there. So this is not "green on the PR, red in the queue because the PR is wrong"; it is "the queue is the only context that runs this test, and it is also the heaviest-loaded one".
Why the case is load-sensitive by construction
packages/metadata-fs/test/watch-dot-root.test.ts:118-147 measures a real chokidar watcher against wall-clock sleeps:
constsink=collectEvents(repo);// Past the 200ms self-write suppression window of the put above.awaitsleep(400);awaitfs.writeFile(path.join(root,'view','case_grid.json'),…);awaitPromise.race([sink.first,sleep(EVENT_WAIT_MS)]);awaitsink.stop();expect(sink.events).toHaveLength(1);
Two fixed budgets decide the outcome, and both are wall-clock:
sleep(400) must clear a 200ms self-write suppression window. Under load the put above can land late enough that the window has not closed when the external write happens — the event is then suppressed as a self-write.
Promise.race([sink.first, sleep(EVENT_WAIT_MS)]) gives up after a fixed budget. A late inotify delivery yields zero events.
Either way toHaveLength(1) fails on 0. On an idle machine both budgets are generous; on the queue runner executing the whole monorepo they are not guaranteed. Note the assertion is an exact count, so it cannot absorb either a late or a duplicate delivery.
Sibling case 2 in the same file (ignore the repository's own bookkeeping) did not fail — consistent with a timing effect on the delivery path rather than a logic defect: case 2 asserts an event does not arrive, which a slow runner cannot break.
What I did NOT establish
Being honest about the limit of the evidence, because the checklist's "flaky 实锤" bar is a second sighting and I do not have one:
I did not reproduce it locally, and I did not run it under artificial load. The argument above is structural (wall-clock budgets + exact-count assertion + heavier context), not a reproduction.
I did not measure how long the queue runner actually took to deliver the event; the job log excerpt in the bot comment is the extraction, not the full log.
So the honest statement is: unrelated to the PR it ejected, and timing-shaped, with one sighting. If it ejects a second unrelated PR, that is the confirmation.
Age
The test is new: it landed 2026-08-10T04:12:38Z in 684ab2218 — fix(metadata-fs): scope the watcher's dotfile ignore to paths relative to the root (#7150) (#7208) — under four hours before this ejection. It is doing real work (#7150 was a genuine defect where the whole watch was inert), so this is about how the case is timed, not about whether it should exist.
Suggested dispositions (for triage to grade and size)
A — wait for the event instead of racing a fixed budget. Poll for sink.events.length > 0 up to the case timeout rather than Promise.race against EVENT_WAIT_MS; the case already carries CASE_TIMEOUT_MS, so the failure mode becomes "timed out" with a real budget rather than "0 events" at a fixed one.
B — relax the exact count, keep the identity. Assert at least one event and that the first update event is case_grid / source: 'fs' / actor: 'fs'. Keeps everything the case is actually pinning while surviving a duplicate or late delivery. ⚠️ Weigh against the fact that the exact count may be deliberate — a duplicate event is itself a defect on this path, and if so A is the better half.
A looks right, possibly with B's identity assertions kept alongside an exact-count assertion that is only made once the event has actually arrived.
Refs: #7150 / PR #7208 (the fix and this test), #7000 (watcher arming, the sibling pin the file warns not to repurpose), PR #7333 (the ejected PR), merge-queue-triage workflow (#4859).
Observation-class finding, recorded by the
domain:identityPM seat while triaging a merge-queue ejection. Filed unassigned, nodomain:*label — routing is the triage seat's call. Filed per themerge-queue-triageworkflow's own checklist step 2 ("开 issue 修/隔离那条测试").What happened
Merge-queue build 31366863728 failed and ejected PR #7333 (
removed_from_merge_queue2026-08-10T07:56:20Z, not merged). The failing job was Test Core (2/3):The ejected PR cannot have caused it. #7333 changes exactly three files, all in
@objectstack/plugin-auditplus one changeset:The failing test is in
@objectstack/metadata-fs. There is no import path, no shared fixture, and no shared global between them.Why the queue is where it surfaces
The merge queue runs the full suite; PR-side CI runs the affected subset. #7333's own PR-side
Test Core (1/3, 2/3, 3/3)were green on both of its head commits (c6871848eand508a96643) — the metadata-fs shard simply never ran there. So this is not "green on the PR, red in the queue because the PR is wrong"; it is "the queue is the only context that runs this test, and it is also the heaviest-loaded one".Why the case is load-sensitive by construction
packages/metadata-fs/test/watch-dot-root.test.ts:118-147measures a real chokidar watcher against wall-clock sleeps:Two fixed budgets decide the outcome, and both are wall-clock:
sleep(400)must clear a 200ms self-write suppression window. Under load theputabove can land late enough that the window has not closed when the external write happens — the event is then suppressed as a self-write.Promise.race([sink.first, sleep(EVENT_WAIT_MS)])gives up after a fixed budget. A late inotify delivery yields zero events.Either way
toHaveLength(1)fails on0. On an idle machine both budgets are generous; on the queue runner executing the whole monorepo they are not guaranteed. Note the assertion is an exact count, so it cannot absorb either a late or a duplicate delivery.Sibling case 2 in the same file (ignore the repository's own bookkeeping) did not fail — consistent with a timing effect on the delivery path rather than a logic defect: case 2 asserts an event does not arrive, which a slow runner cannot break.
What I did NOT establish
Being honest about the limit of the evidence, because the checklist's "flaky 实锤" bar is a second sighting and I do not have one:
merge-queue-triagecomments of the 60 most recently updated PRs.watch-dot-rootappears in exactly one — fix(plugin-audit): resolve reference titles inactivityMilestonessummary tokens (#7290) #7333's own. So this is a first recorded occurrence, not a confirmed repeat.So the honest statement is: unrelated to the PR it ejected, and timing-shaped, with one sighting. If it ejects a second unrelated PR, that is the confirmation.
Age
The test is new: it landed 2026-08-10T04:12:38Z in
684ab2218—fix(metadata-fs): scope the watcher's dotfile ignore to paths relative to the root (#7150) (#7208)— under four hours before this ejection. It is doing real work (#7150 was a genuine defect where the whole watch was inert), so this is about how the case is timed, not about whether it should exist.Suggested dispositions (for triage to grade and size)
sink.events.length > 0up to the case timeout rather thanPromise.raceagainstEVENT_WAIT_MS; the case already carriesCASE_TIMEOUT_MS, so the failure mode becomes "timed out" with a real budget rather than "0 events" at a fixed one.updateevent iscase_grid/source: 'fs'/actor: 'fs'. Keeps everything the case is actually pinning while surviving a duplicate or late delivery.ignoreddotfile regex matches the.objectstacksegment of the root path #7150 bought.A looks right, possibly with B's identity assertions kept alongside an exact-count assertion that is only made once the event has actually arrived.
Refs: #7150 / PR #7208 (the fix and this test), #7000 (watcher arming, the sibling pin the file warns not to repurpose), PR #7333 (the ejected PR), merge-queue-triage workflow (#4859).