Scene sky-change test: stay inside the timeout under load (bake each sky once) #162

Merged
void merged 2 commits from void/scene-test-flake into dev 2026-11-14 02:47:34 +00:00
Member

Follow-up ratatoskr:follow_up:chat-mind-20261114T014146289Z-t13. The flaky test is src/app/features/scene/index.test.ts "a sky change at any point of a build...".

Cause: a timeout in the test, not a race in the scene. The test sweeps 21 microtask offsets; each iteration builds up to three scenes, and createRidgeScene is mocked but ridgeSkyFor is not, so every build bakes the real physical sky (atmosphere LUTs, tens of ms). Alone it takes 3.4 s against vitest's 5 s default; any CPU load (the full suite, another job) pushes it past: "Test timed out in 5000ms", captured under a 6-way concurrent run. No assertion failed, so the scene code (Nibu's) is not implicated and is untouched.

Fix: the test bakes each state's sky once (a memoizing wrapper around ridgeSkyFor for the single-argument call; the clock is fixed in beforeEach, so a state always draws the same sky). Each build still receives the sky ridgeSkyFor makes for its state; assertions are unchanged. The sweep now takes well under a second.

Evidence: before, 1 failure in 30 runs under 6-way load (and the 1-in-3 seen in the full suite on a loaded machine); after, 48 of 48 pass under the same 6-way load, plus 22 clean runs alone. Mutation: removing the stale-build check (mine !== generation) in index.ts still fails the test, so it still bites; restored.

Test file only. Docs/scene code untouched.

🤖 Generated with Claude Code

Follow-up `ratatoskr:follow_up:chat-mind-20261114T014146289Z-t13`. The flaky test is `src/app/features/scene/index.test.ts` "a sky change at any point of a build...". **Cause: a timeout in the test, not a race in the scene.** The test sweeps 21 microtask offsets; each iteration builds up to three scenes, and `createRidgeScene` is mocked but `ridgeSkyFor` is not, so every build bakes the real physical sky (atmosphere LUTs, tens of ms). Alone it takes 3.4 s against vitest's 5 s default; any CPU load (the full suite, another job) pushes it past: "Test timed out in 5000ms", captured under a 6-way concurrent run. No assertion failed, so the scene code (Nibu's) is not implicated and is untouched. **Fix:** the test bakes each state's sky once (a memoizing wrapper around `ridgeSkyFor` for the single-argument call; the clock is fixed in `beforeEach`, so a state always draws the same sky). Each build still receives the sky `ridgeSkyFor` makes for its state; assertions are unchanged. The sweep now takes well under a second. **Evidence:** before, 1 failure in 30 runs under 6-way load (and the 1-in-3 seen in the full suite on a loaded machine); after, 48 of 48 pass under the same 6-way load, plus 22 clean runs alone. Mutation: removing the stale-build check (`mine !== generation`) in `index.ts` still fails the test, so it still bites; restored. Test file only. Docs/scene code untouched. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Scene sky-change sweep: bake each state's sky once so the test stays inside its timeout under load
Some checks failed
Build pull request / Build pull request (pull_request) Has been cancelled
1b101c2889
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Scene test: pin the stand-down of a replaced rebuild deterministically
All checks were successful
Build pull request / Build pull request (pull_request) Successful in 3m44s
a61252e664
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Member

Soul pass 1: NOT READY: with the memoized bake the stand-down guard in rebuild (if (getSkyState() !== next) return;) was only caught by the old slow bakes, so removing it passed. Fixed: a new deterministic test pins it (exactly two builds for day then dusk; fails 3/3 under that mutation). Soul pass 2: READY; seven further mutations of index.ts fail the new file at least as often as the original. Known gap that predates this PR: removing off() from dispose passes both files.

Soul pass 1: NOT READY: with the memoized bake the stand-down guard in `rebuild` (`if (getSkyState() !== next) return;`) was only caught by the old slow bakes, so removing it passed. Fixed: a new deterministic test pins it (exactly two builds for day then dusk; fails 3/3 under that mutation). Soul pass 2: READY; seven further mutations of index.ts fail the new file at least as often as the original. Known gap that predates this PR: removing `off()` from `dispose` passes both files.
void merged commit 934f82386d into dev 2026-11-14 02:47:34 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Ratatoskr!162
No description provided.