sage: row 172 brief, the board-held sign-out wait under gate load (P19 366, #1670, mos-0858); cause section open until traced

This commit is contained in:
jason.woltje committed 2026-10-19 14:21:35 -05:00
1 parent d58c9c5cda
commit 4d9114ab4c
1 file changed
+50
@@ -0,0 +1,50 @@
# Brief: the board-held sign-out wait times out under gate load
P19 366, Gitea #1670, queue row 172 (added by Sage on Mos's ruling mos-0858). It goes right after row 171. If row 171's gate trips
on this flake twice, this row moves ahead of 171's rerun loop and lands first. Owner Sage, since tracing the cause
needs the heavy-run slot. Reviewer Darkwing, gate owner Sage. Line numbers are at origin/refactor d58c9c5cd.
## The problem
`packages/webui/tests/board-held.test.mjs:163`, the sign-out test, fails in the full gate and passes on its own. On row
170's gate it stopped runs 1 and 3 of 3 complete runs, both at the same place:
```
Error: Condition timed out: !document.querySelector("#signed-out").hidden
at async out (board-held.test.mjs:168:5)
at async TestContext.<anonymous> (board-held.test.mjs:220:5)
```
Line 220 is the module-read step: `window.__redirect.push('/api/queue'), location.hash = '#/queue'`, then `out()`. The
wait helper (:73) polls 100 times at 50 ms, so the page has about 5 s of its own time to show the sign-out line. The
logs are on P19 366 (comments 279 and 280) and in `/mnt/storage/scratch/sage-r170/out-run1/` and `out-run3/`.
What reading the code rules out (bus.js and app.js at d58c9c5cd):
- The redirect itself is immediate. The test's fetch stub answers `/api/queue` with an opaque redirect without touching
the server, and `fetchApi` (bus.js:46) calls `signOut()` on it.
- The page never reads `/api/queue` for real before the push, so a slow `reads.queue()` subprocess isn't in the path.
- Before the queue read, `render(true)` (bus.js:1059) does one real read, `/api/bus/messages`, from the in-process
broker. That read and the hashchange dispatch are the only steps that can wait on something.
## The cause
Not yet established. The row stays queued until it is. Mos's ruling: the fix goes after the cause of the wait under
load, such as ordering, a shared browser or the event it waits on, and a longer timeout alone won't do. This section
gets the cause, with the trace that shows it, and the brief is re-pinned before the row moves to briefed.
Step 1, Sage, on the slot. Run the webui suite under the gate's load, with the test's page timeline traced:
the hashchange time, each fetch's start and end with its path, the `mosaic-signed-out` event time, and the
`#signed-out` unhide time. Repeat until the failure reproduces. Record what the page was waiting on when the 5 s ran out.
## The change
Written with the cause. It fixes the ordering or the wait condition that the trace shows. It doesn't raise the
helper's 100 × 50 ms budget as the fix.
## Acceptance
- The cause, its trace and the fix go in the candidate packet. The fix's test (or the changed test) fails on
d58c9c5cd under the traced condition and passes on the candidate.
- The webui suite passes 10 times in a row under the gate's load on the candidate, run by the gate owner.
- Full gate green on Sage's gate.