Filed by the os-dev seat while implementing #7439 (session session_01KbJQ1y1J12nZxYzFWhP8Q3, PR #7764). Recording, not claiming — no assignee, no grade, no domain:*. Sub-issue of #7307 because it lands inside that card's completion scope: whoever burns down the remaining ledger will follow exactly the remediation this describes.
The remediation the guard prints can itself create a flake
vitest.setup.network-escape-guard.ts ends its failure message with:
Fix: serve the probe from a double rather than the network. See packages/plugin-report/src/__tests__/DatasetReportRenderer.test.tsx for the shape (vi.stubGlobal('fetch', router) + vi.unstubAllGlobals()).
That pairing is safe only when nothing the component started is still in flight at teardown. It is not safe otherwise, and #7439 is the measured counter-example: RecordDetailView.approvalDeclaredActions.test.tsx had the prescribed shape — one vi.unstubAllGlobals(), vi.stubGlobal present — and still escaped intermittently, because a decision carrying refreshAfter: true makes the record page re-read the approval state after the test body has returned. The prescribed teardown restored the real fetch while that read was pending.
Two facts measured on e546222b3 while fixing #7439, both of which apply to any file the burn-down touches:
- This file's
afterEach runs FIRST. Vitest runs afterEach in reverse registration order, so a teardown written in the test file runs before the root setup's RTL cleanup() and before the guard's own assertion. A probe registered right after it reported fetch is still the double? false on all 13 tests — the real fetch is back while the tree is still mounted and has not been unmounted yet. So any fetch that cleanup()'s act-flush triggers escapes too, not just genuinely late ones.
- The escape is attributed to the test that had already finished. The guard reads
expect.getState().currentTestName at fetch time, so a probe landing in the teardown window names the test that just passed. That is correct attribution, but it reads like the test body did it.
Why it is worth a line
The message is the repo's canonical instruction for this class and the burn-down card is 21 files of following it. A file whose component does post-action re-reads (any refreshAfter, any notifyDataChanged consumer) will pass on the fixer's machine and go intermittently red in CI, which is how #7439 arrived — as an unrelated PR's red, costing that PR its enqueue window.
Suggested direction, not a disposition
Add one clause to the guard's Fix: text: keep the double installed for the whole file when the component under test can issue a read after the test body returns, and say that a teardown written in the test file runs before RTL cleanup(). PR #7764 has a worked example of the hoisted-double shape and a comment explaining why it must outlive afterEach.
⛔ Not proposing any change to KNOWN_ESCAPES — that list only shrinks, and nothing here adds to it.
Generated by Claude Code
Filed by the
os-devseat while implementing #7439 (sessionsession_01KbJQ1y1J12nZxYzFWhP8Q3, PR #7764). Recording, not claiming — no assignee, no grade, nodomain:*. Sub-issue of #7307 because it lands inside that card's completion scope: whoever burns down the remaining ledger will follow exactly the remediation this describes.The remediation the guard prints can itself create a flake
vitest.setup.network-escape-guard.tsends its failure message with:That pairing is safe only when nothing the component started is still in flight at teardown. It is not safe otherwise, and #7439 is the measured counter-example:
RecordDetailView.approvalDeclaredActions.test.tsxhad the prescribed shape — onevi.unstubAllGlobals(),vi.stubGlobalpresent — and still escaped intermittently, because a decision carryingrefreshAfter: truemakes the record page re-read the approval state after the test body has returned. The prescribed teardown restored the realfetchwhile that read was pending.Two facts measured on
e546222b3while fixing #7439, both of which apply to any file the burn-down touches:afterEachruns FIRST. Vitest runsafterEachin reverse registration order, so a teardown written in the test file runs before the root setup's RTLcleanup()and before the guard's own assertion. A probe registered right after it reportedfetch is still the double? falseon all 13 tests — the realfetchis back while the tree is still mounted and has not been unmounted yet. So any fetch thatcleanup()'s act-flush triggers escapes too, not just genuinely late ones.expect.getState().currentTestNameat fetch time, so a probe landing in the teardown window names the test that just passed. That is correct attribution, but it reads like the test body did it.Why it is worth a line
The message is the repo's canonical instruction for this class and the burn-down card is 21 files of following it. A file whose component does post-action re-reads (any
refreshAfter, anynotifyDataChangedconsumer) will pass on the fixer's machine and go intermittently red in CI, which is how #7439 arrived — as an unrelated PR's red, costing that PR its enqueue window.Suggested direction, not a disposition
Add one clause to the guard's
Fix:text: keep the double installed for the whole file when the component under test can issue a read after the test body returns, and say that a teardown written in the test file runs before RTLcleanup(). PR #7764 has a worked example of the hoisted-double shape and a comment explaining why it must outliveafterEach.⛔ Not proposing any change to
KNOWN_ESCAPES— that list only shrinks, and nothing here adds to it.Generated by Claude Code