Repository navigation
test: stabilize QueryGuard keepalive interruption test - #2323
Merged
Merged
Conversation
Contributor
jatmn
commented
Oct 22, 2026
jatmn
left a comment
Collaborator
Author
There was a problem hiding this comment.
— jatmn's PR Review agent
Test-only stabilization for QueryGuard keepalive idle timing in codexShim.interruption.test.ts. The diff is surgical (one file, no production paths). I verified fake-timer scoping, the 249/250 ms boundary, and that the test still guards against keepalive-driven idle resets. Clear the merge-readiness items before landing.
Merge readiness
- Rebase onto current
main. Livemainis75c73ea3811f359a8bad23b073bd4713846ea833(docs: add CONTRIBUTING notes for CI caching and subprocess test timeouts (#2322)). This head branches from1c42a10628df59cdaaf3a75a89978737f592721a, so it does not include that docs commit. Rebase (or mergemainforward) before merge so the upgrade-plan stack stays current. - Mark the PR ready for review. GitHub still lists this PR as a draft (
draft: true). Mark it ready when you want the merge gate to treat it as landable. - Merge-base decision:
live-base-three-dot— reviewed range1c42a10628df59cdaaf3a75a89978737f592721a..1cf50c499d2e2d231d1eb026c49c8cd65cb0abf5(one commit). No scope creep in the diff. - CI at head
1cf50c499d2e2d231d1eb026c49c8cd65cb0abf5:changes,pr-intent-scan,smoke-and-tests,dedicated-tests,typecheck, all eightunit-testsshards, launcher compatibility jobs — success.CodeQL (actions),CodeQL (javascript-typescript), andAnalyze (javascript-typescript)— success. AggregateCodeQLcheck — success.web— skipped (expected for this path set). Commit status contextCodeRabbit— success (“Review approved”). No PR-owned failing required checks on this head.
Test fix verification
- Fake timer scope and cleanup:
jest.useFakeTimers()runs only insidekeepalives and parsed-but-ignored frames cannot reset QueryGuard.jest.useRealTimers()runs in the testfinallybefore trace/env cleanup. The next test in the same file still uses realsetIntervaltiming and passed in a full-file local run (14/14) and CI. - Real event-loop yield:
nextTurn()wraps hostsetImmediatecaptured before fake timers, so eachjest.advanceTimersByTimeis followed by a real turn. That drainsdriveQueryEvents/ stream parsing between ticks instead of racing the monotonic idle deadline against a backed-up interval queue. - 249 ms / 250 ms boundary: The loop advances through 249 ms of synthetic time with
settled === false, then the final 1 ms triggers idle timeout withsettled === trueandoutcome.timeout.elapsedMs === 250, matchingidleTimeoutMs: 250and QueryGuard’sperformance.now()-based idle math. - Regression sensitivity: Production keepalives and ignored parsed frames must not call
registerActivity(only yielded query events do). If idle fired too early, the 249 ms assertion would fail; if keepalives incorrectly extended activity, the 250 ms settled assertion orelapsedMscheck would fail; existing assertions still requiregetEmissionCount() > 3, ignored/control frame trace counts, and idlereasonwith onlymessage_startyielded.
Automated review audit
| Source | Thread / check ID | Status on head | Disposition |
|---|---|---|---|
| CodeRabbit | Issue comment #6330167366 | Summary / in-progress UI only; no review line comments | Drift — nothing actionable to promote |
| CodeRabbit | Commit status context CodeRabbit |
Review approved | No open bot findings |
| CodeQL | Check runs CodeQL, CodeQL (javascript-typescript), Analyze (javascript-typescript) on 1cf50c499d2e2d231d1eb026c49c8cd65cb0abf5 |
Completed success | Drift — no PR-introduced alert; test-only diff |
| CodeQL | Earlier aggregate neutral “configuration not found” note |
Superseded by successful javascript-typescript run on head | Drift — environmental, not author fix |
Findings
🟢 Thanks for the contribution. I do not see any actionable issues from my review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
keepalives and parsed-but-ignored frames cannot reset QueryGuardinsrc/services/api/codexShim.interruption.test.ts.elapsedMsis 250). All four frame variants, the 25 ms interval, the 250/500/1,500 ms deadlines, and every existing assertion are unchanged. Cleanup restores real timers and settles the consumption promise before restoring trace state.main.Impact
Testing
Repro and fix, fresh processes with isolated
HOME/TMPDIR:bun test --isolate --feature=UNATTENDED_RETRY --max-concurrency=1 ./src/services/api/codexShim.interruption.test.tsEvery "before" failure was this test (two or three emissions, then the idle deadline fired). On the rebased head, I repeated the 24-worker batch: 32/32 passed.
Whole suite in one process:
bun test --isolate --feature=UNATTENDED_RETRY --max-concurrency=1, run twice on the final head: 10,485 pass, 0 fail, 3 skip across 780 files each time.bun run check: passbun run typecheck,bun run typecheck:type-tests: passnode bin/openclaude --version,NODE_DISABLE_COMPILE_CACHE=1 node bin/openclaude --version: passbun run security:pr-scan -- --base FETCH_HEAD --head HEAD: passgit diff --check: cleanbun run checkabove ran on the previousmain. After rebasing onto the currentmain, whose two new commits don't touch this file, I reran the changed file together withsrc/utils/ShellCommand.test.ts10/10, plusbun run typecheck,bun run check:static, and the intent scan, all passing. In two earlier heavy-contention batches (before the final clean ones), a different, untouched test in the same file hit Bun's default per-test timeout once; it didn't recur in the final batches.Notes
Summary by CodeRabbit