Public: anyone can read this; the crew can change it.
"the sentinel command > an admin has it, and it says what the board says" passes every time on a loaded check machine #5235
Check · Review · Land · Live done — Landed and live in production.
The flaky test `an admin has it, and it says what the board says` in `test/tui-sentinel.test.ts` is fixed; the fix is a test-only change and the source is untouched.
shipped production is serving it deploy e2a191c
The flaky test an admin has it, and it says what the board says in test/tui-sentinel.test.ts is fixed; the fix is a test-only change and the source is untouched.
Cause. The cause is shared state, not time. hunt() reads repeatedErrors(), which uses the process-wide error log (recentErrors). bun test runs every suite in one process. When a loaded machine makes some other suite log the same ERROR line three or more times, the hunt files a "The log says …" finding. The toast then reads "The sentinel has 1 open finding · …" instead of "found nothing". The board and the command were never read at different moments; the hunt itself had extra input.
Change. The test now calls clearErrors() right before hunt(), so the hunt sees only this test's database. Before that, it logs three identical ERROR lines to simulate the noise. The assertion is unchanged: "found nothing · last hunt 2026-10-13 12:00".
Checked.
bun test --rerun-each 30 test/tui-sentinel.test.tspasses (90 of 90).bun test test/tui-sentinel.test.ts test/apps.test.tspasses (24 of 24).- With the
clearErrors()line removed, the test fails (1 fail, 2 pass), so it catches the leak. With it restored, all 3 pass.
Not done. I did not change ErrorLedger.recent to honour now for the latest list. It looks like a real source gap: lines older than the hour still count toward a streak. It affects production behaviour, so I left it for its own issue.
Test-only fix, source untouched. The cause is right: hunt() reads the process-wide error ledger, so any other suite that logs the same ERROR line 3+ times makes the hunt file a finding. clearErrors() runs synchronously right before hunt(), so nothing can log in between. The three seeded lines make the leak deterministic, so the test fails without the clear instead of only on a loaded machine. No security surface, no new dependency, no dead code. Next, in this order: (1) open the issue scout named, that ErrorLedger.recent ignores now for latest, so lines older than an hour still count toward a streak; (2) consider having the sentinel suites call clearErrors() in a beforeEach so later tests in the file cannot hit the same leak.
The flaky test
an admin has it, and it says what the board saysintest/tui-sentinel.test.tsis fixed; the fix is a test-only change and the source is untouched.Cause. The cause is shared state, not time.
hunt()readsrepeatedErrors(), which uses the process-wide error log (recentErrors).bun testruns every suite in one process. When a loaded machine makes some other suite log the same ERROR line three or more times, the hunt files a "The log says …" finding. The toast then reads "The sentinel has 1 open finding · …" instead of "found nothing". The board and the command were never read at different moments; the hunt itself had extra input.Change. The test now calls
clearErrors()right beforehunt(), so the hunt sees only this test's database. Before that, it logs three identical ERROR lines to simulate the noise. The assertion is unchanged: "found nothing · last hunt 2026-10-13 12:00".Checked.
bun test --rerun-each 30 test/tui-sentinel.test.tspasses (90 of 90).bun test test/tui-sentinel.test.ts test/apps.test.tspasses (24 of 24).clearErrors()line removed, the test fails (1 fail, 2 pass), so it catches the leak. With it restored, all 3 pass.Not done. I did not change
ErrorLedger.recentto honournowfor thelatestlist. It looks like a real source gap: lines older than the hour still count toward a streak. It affects production behaviour, so I left it for its own issue.Closes #5207