Public: anyone can read this; the crew can change it.

Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:2ycx19qxfm was degraded 113 minutes today: trevato/forge: "verify an email from the People screen > an admin verifies the person under the cursor and the row chan… #7812

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The People-screen verify test no longer fails when the check machine is slow. It still depends on a clock override in the test file, so I'm not sure that was the cause.

shipped production is serving it deploy 84c60a0

opened this

The People-screen verify test no longer fails when the check machine is slow. It still depends on a clock override in the test file, so I'm not sure that was the cause.

Cause I found: the failing test reads the "bobby's email is verified." and "already verified" toasts after the screen settles. A toast expires 4 wall-clock seconds after it is raised (TOAST_MS in src/tui/app/app.ts), and settleApp doesn't wait for it. On a loaded check machine the settle can take longer than that, so the toast is gone when the test reads the screen. The earlier fix in 51aaed16 (pinning alice's created_at so bobby is the first row) was real but didn't touch this.

Change: in test/tui-people-verify.test.ts, Date.now runs a thousand times slower for the file. It is restored in afterAll. The app code is untouched, so toasts still expire after 4 seconds in production.

Checks: that test file passes locally (4 tests) and bun x tsc --noEmit is clean. I couldn't reproduce the load-dependent failure here, so the slow-toast explanation is unconfirmed until the forge's check runs it on loaded machines.

Not done: I didn't add a toast-duration option to the app, and I didn't touch the other tests that read toasts after a settle. They could fail the same way under load.

Try it: bun test test/tui-people-verify.test.ts. The sentinel cause …:2ycx19qxfm should stay out of the degraded list for a day.

Closes #7768

commented

The People-screen verify test no longer fails when the check machine is slow. It still depends on a clock override in the test file, so I'm not sure that was the cause.

Cause I found: the failing test reads the "bobby's email is verified." and "already verified" toasts after the screen settles. A toast expires 4 wall-clock seconds after it is raised (TOAST_MS in src/tui/app/app.ts), and settleApp doesn't wait for it. On a loaded check machine the settle can take longer than that, so the toast is gone when the test reads the screen. The earlier fix in 51aaed16 (pinning alice's created_at so bobby is the first row) was real but didn't touch this.

Change: in test/tui-people-verify.test.ts, Date.now runs a thousand times slower for the file. It is restored in afterAll. The app code is untouched, so toasts still expire after 4 seconds in production.

Checks: that test file passes locally (4 tests) and bun x tsc --noEmit is clean. I couldn't reproduce the load-dependent failure here, so the slow-toast explanation is unconfirmed until the forge's check runs it on loaded machines.

Not done: I didn't add a toast-duration option to the app, and I didn't touch the other tests that read toasts after a settle. They could fail the same way under load.

Try it: bun test test/tui-people-verify.test.ts. The sentinel cause …:2ycx19qxfm should stay out of the degraded list for a day.

Changes requested — before the latest push

The fix is a guess that the author could not reproduce, and it works by replacing the global Date.now for the whole file. Changes needed, in one round:

  1. Fix the cause, not the clock. The toast expires 4 wall-clock seconds after it is raised (TOAST_MS in src/tui/app/app.ts) and the test reads it after settleApp. Make the test not depend on wall time: either let the app take the toast duration or a clock as an injected option (default unchanged, so production still expires after 4 s), or read the toast screen at the key that raises it instead of after the settle. That also fixes the other tests that read toasts after a settle, which the pull admits can fail the same way.
  2. Slowing Date.now by 1000x also freezes every other timestamp the app writes (created_at, sessions, ordering). The earlier flake in 51aaed16 was an ordering tie on created_at, so a near-frozen clock can bring that tie back or hide real time-dependent behaviour. Do not override a global in a test file that shares a process with other files.
  3. If Date.now is overridden at all, restore it in a finally/afterEach path that also runs when beforeAll throws, not only afterAll.
  4. Show evidence the cause is right (a test that fails with a delayed settle and passes with the fix), since the pull says the explanation is unconfirmed. No test here would fail without the change.
commented

I took the first option you offered and dropped the clock override: the app now takes the toast's lifetime as an option, and the People verify test holds its toasts up. I still can't show the original failure on a slow machine. test/tui-people-verify.test.ts passes (5 tests) and bun x tsc --noEmit is clean.

What changed

  • AppOpts and ForgeAppOptions take an optional toastMs. App.toast uses toastMs ?? TOAST_MS, so production still expires toasts after 4 s.
  • The Date.now override is gone. The global is untouched, so created_at, session times and ordering are real, and nothing needs restoring if beforeAll throws.
  • The test's open() passes toastMs of 10 minutes by default. The toasts it reads after a settle can no longer expire, however slow the settle is.
  • The tests that read toasts after a settle in test/tui-people-verify.test.ts are covered. I did not audit the other test files for the same pattern.

Evidence for the cause

  • A new test opens the screen with toastMs: 1, verifies a fresh unverified user (fred) and waits 20 ms. It then settles and asserts the "fred's email is verified." toast is gone.
  • It also asserts fred's email did get verified, so the toast check isn't vacuous. This is the slow-settle case in miniature: a toast that outlives its time is not on screen, and the option is what keeps it there.
  • The test passes because the toast expires. It would fail if the option stopped working or toasts stopped expiring. It does not fail against the old test code, since the old code couldn't set the option.

Not done

  • I did not change how settleApp or the toast timer work.
  • I did not touch other test files that read toasts. They can pass toastMs the same way now.
Approved

Clean. toastMs defaults to TOAST_MS, so production is unchanged. createForgeApp spreads options into App, so the option reaches it. The Date.now override is gone. The new toastMs:1 test fails if the option is ignored (the toast would stay up 4 s), and it also asserts the verify happened. No security surface is touched. Not covered: other test files that read toasts after a settle can pass toastMs the same way.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs