Symptom
Tests failed on main (run 31857852887, after the merge of PR #1453) with a single failing test:
FAIL src/commands/consult/__tests__/agy-auth-cache.test.ts
> gemini lane burst behaviour (#1077 regression)
> re-probes after the unauth TTL lapses, recovering once the user signs in
AssertionError: expected null to be 'unauth' // at line 325
The same commit passed on the PR branch, and PR #1453 does not touch consult. This is a timing flake, not a regression.
Root cause
The test sets CODEV_AGY_AUTH_CACHE_TTL_UNAUTH_MS = '50' and then asserts, immediately after runLane(1) returns, that the cached verdict is still 'unauth':
process.env.CODEV_AGY_AUTH_CACHE_TTL_UNAUTH_MS = '50';
...
await runLane(1);
expect(checkCachedAgyAuth(fakeAgy)).toBe('unauth'); // line 325 — flaky
checkCachedAgyAuth returns null once Date.now() - entry.checkedAt >= ttl (agy-auth-cache.ts:185). The verdict is recorded partway through the lane run, so on a loaded CI runner more than 50ms can elapse between recording and the assertion, and the entry has already expired by the time it is read.
The 50ms TTL is what the test needs for its second half (letting the verdict lapse so the lane re-probes). The first assertion is the only one racing the clock.
Suggested fix directions
- Use vitest fake timers (or an injectable clock in
agy-auth-cache.ts) so the TTL lapse is advanced deterministically instead of via a real 80ms sleep, or
- Drop/relax the pre-lapse assertion at line 325 (e.g. accept
'unauth' or null, since the recovery behaviour under test is fully covered by the post-lapse assertions), or
- Raise the test TTL enough to clear runner jitter (e.g. 1000ms TTL, 1500ms sleep) at the cost of a slightly slower test.
Evidence
Symptom
Testsfailed onmain(run 31857852887, after the merge of PR #1453) with a single failing test:The same commit passed on the PR branch, and PR #1453 does not touch consult. This is a timing flake, not a regression.
Root cause
The test sets
CODEV_AGY_AUTH_CACHE_TTL_UNAUTH_MS = '50'and then asserts, immediately afterrunLane(1)returns, that the cached verdict is still'unauth':checkCachedAgyAuthreturnsnullonceDate.now() - entry.checkedAt >= ttl(agy-auth-cache.ts:185). The verdict is recorded partway through the lane run, so on a loaded CI runner more than 50ms can elapse between recording and the assertion, and the entry has already expired by the time it is read.The 50ms TTL is what the test needs for its second half (letting the verdict lapse so the lane re-probes). The first assertion is the only one racing the clock.
Suggested fix directions
agy-auth-cache.ts) so the TTL lapse is advanced deterministically instead of via a real 80ms sleep, or'unauth'ornull, since the recovery behaviour under test is fully covered by the post-lapse assertions), orEvidence
Testsall green; the failure appeared on an unrelated Stream Deck change.