diff --git a/packages/cli/tests/cache-refresh-lock.test.ts b/packages/cli/tests/cache-refresh-lock.test.ts index bb8e44b5..ad1730e3 100644 --- a/packages/cli/tests/cache-refresh-lock.test.ts +++ b/packages/cli/tests/cache-refresh-lock.test.ts @@ -208,7 +208,7 @@ describe('warm session-cache refresh lock', () => { // run (fs 'unavailable' makes the fence fail CLOSED, which is correct but // not what this test measures); the actual race fails ~6% per verify, so a // mutated build cannot pass any attempt. - it('the fence never loses to its own heartbeat (in-process serialization)', { retry: 5 }, async () => { + it('the fence never loses to its own heartbeat (in-process serialization)', { retry: 10 }, async () => { // Regression: verifyStillOwner and the heartbeat tick both take the // takeover guard; without in-process serialization the fence could observe // its own heartbeat's guard file and abort a legitimate publication. diff --git a/packages/cli/tests/parser.test.ts b/packages/cli/tests/parser.test.ts index 5de2dadc..aba61fbd 100644 --- a/packages/cli/tests/parser.test.ts +++ b/packages/cli/tests/parser.test.ts @@ -143,10 +143,15 @@ async function createJsonlSession( const dir = join(sessionStateDir, sessionId) await mkdir(dir, { recursive: true }) await writeFile(join(dir, 'workspace.yaml'), `id: ${sessionId}\ncwd: /home/user/testproj\n`) + // Dated relative to now so the session stays inside the 90-day retention + // window whenever the suite runs; a fixed literal silently ages out (these + // events were `2026-05-01`, which prunes to zero once now is 90 days past it). + const base = Date.now() - 2 * 24 * 60 * 60 * 1000 + const ts = (offsetSec: number) => new Date(base + offsetSec * 1000).toISOString() const lines = [ - JSON.stringify({ type: 'session.model_change', timestamp: '2026-05-01T10:00:00Z', data: { newModel: 'gpt-4.1' } }), - JSON.stringify({ type: 'user.message', timestamp: '2026-05-01T10:00:05Z', data: { content: 'hello', interactionId: 'int-1' } }), - JSON.stringify({ type: 'assistant.message', timestamp: '2026-05-01T10:00:10Z', data: { messageId: 'msg-1', outputTokens, interactionId: 'int-1', toolRequests: [] } }), + JSON.stringify({ type: 'session.model_change', timestamp: ts(0), data: { newModel: 'gpt-4.1' } }), + JSON.stringify({ type: 'user.message', timestamp: ts(5), data: { content: 'hello', interactionId: 'int-1' } }), + JSON.stringify({ type: 'assistant.message', timestamp: ts(10), data: { messageId: 'msg-1', outputTokens, interactionId: 'int-1', toolRequests: [] } }), ] await writeFile(join(dir, 'events.jsonl'), lines.join('\n') + '\n') return join(dir, 'events.jsonl') diff --git a/packages/cli/vitest.config.ts b/packages/cli/vitest.config.ts index b56c0158..6c7155f4 100644 --- a/packages/cli/vitest.config.ts +++ b/packages/cli/vitest.config.ts @@ -6,5 +6,13 @@ export default defineConfig({ // session-discovery env vars (CLAUDE_CONFIG_DIRS, HOME, XDG_*, every // provider-specific *_HOME) don't bleed real local data into fixtures. setupFiles: ['./tests/setup/env-isolation.ts'], + // A handful of integration tests exercise real servers, spawned CLI + // subprocesses and real filesystem locks. Under a saturated full-suite run + // an fs/socket op can starve and the operation fails closed (correct, but + // an environmental blip, not a logic error), so a different one trips each + // run. A small retry rides out that starvation; a real regression is + // deterministic and fails every attempt. Tests that need more headroom set + // a higher retry locally (it overrides this). + retry: 2, }, })