test(agent-core-v2): stop the reconcile loop during the sessionIndex read baseline - #2625
Conversation
…read baseline The baseline gates warm reads on behavioral work counts, including zero directory listings inside each counting window. The service's background reconcile loop (60s interval) runs an authoritative scan on every tick — two storage.list calls — and once a slow CI runner stretches the test past that interval, a tick lands inside a counting window on every attempt and is attributed to the read under test, failing fsLists === 0 even with the retry (observed on run 30975794688: 168s across two attempts, fsLists = 2 both times). Freeze the loop right after prepare() via a new stopReconcileLoop() test hook (sibling of reconcileNow/reprojectNow). The only remaining directory listing sources inside a window are the fallback read paths themselves, so a non-zero count is deterministically a real regression again.
|
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78d2f01ec8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| /** Test hook: stop the background reconcile loop, so measurement windows | ||
| * contain only the operations under test. */ |
There was a problem hiding this comment.
Remove the method-level test-hook comment
This new JSDoc sits beside a method in an implementation file. The scoped packages/agent-core-v2/AGENTS.md comment convention requires comments to live only in the top-of-file /** */ block and never beside functions or methods, so this note should be removed or folded into the file header if it is important.
AGENTS.md reference: packages/agent-core-v2/AGENTS.md:L17-L17
Useful? React with 👍 / 👎.
Related Issue
No linked issue — the problem is explained below. Observed on CI run 30975794688 (PR #2599, unrelated changes), shard
test (2).Problem
FileSessionIndex (read model) > baseline: warm listRecent(limit=20) at 1k vs 10k vs 50k sessionsflakes on slow CI runners withAssertionError: expected 2 to be +0at theexpect(op.fsLists).toBe(0)assertion.The baseline gates warm reads on behavioral work counts, including "zero directory listings inside each counting window". But
FileSessionIndexstarts a background reconcile loop (RECONCILE_INTERVAL_MS = 60_000) once ready, and every tick unconditionally runs the projector's authoritative scan, which enumerates workspace + session directories — exactly twostorage.listcalls for the single-workspace test setup. Locally the test finishes in ~12s so the first tick never fires; on a loaded shared runner the test takes ~84s per attempt, so a tick lands inside a counting window on essentially every attempt and its two listings get attributed to the read under test. The existingretry: 1cannot absorb that — both attempts fail the same way (168s total in the observed run).What changed
stopReconcileLoop()test hook onFileSessionIndex(sibling of the existingreconcileNow/reprojectNowtest/ops hooks) that cancels the reconcileIntervalTimer.prepare(), before any measurement, and the comment block now describes this instead of claiming the retry absorbs a tick.This makes the gate deterministic rather than relaxing it: after
prepare()+stopReconcileLoop(), the only remainingstorage.listcallers that could fire inside a counting window are the fallback read paths themselves (projectorprojectruns duringprepare,reconcileis stopped), sofsLists > 0can once again only mean a real regression. The reconcile loop itself is production behavior — it repairs drift the best-effort mirror misses (externalstate.jsonedits/deletions, dropped flushes) and stays covered by the dedicatedreconciliation repairs external edits and deletions of state.jsontest.Verified:
pnpm vitest run test/app/sessionIndex/sessionIndex.test.ts— 29/29 pass;tsc --noEmitclean. Note the race itself cannot be reproduced locally (local runs finish well under the 60s tick interval); the fix removes the only background listing source, so runtime no longer matters.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.