diff --git a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts index 733594baf7..35b3829ed3 100644 --- a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts @@ -206,6 +206,40 @@ describe('SessionPersistenceJsonl: format helpers', () => { await fiber.dispose() }) + it('keeps a non-object header line a corruption, not a format refusal', async () => { + const absoluteRoot = await freshRoot() + const ctx = new Context() + await ctx.plugin(SessionStore) + const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' }) + // Valid JSON that is no object carries no version to compare, so the + // version guard must pass it through to the corruption diagnostics. + const id = SessionId('scalar-header') + const path = rawLogPath(resolve(absoluteRoot), '/work', id) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, '42\n') + const failure = await ctx.sessionPersistence.load(id).then(() => undefined, (error: unknown) => error as Error) + expect(failure?.name).not.toBe('SessionFormatUnsupportedError') + expect(failure?.message).toContain('first line is not a session header') + await fiber.dispose() + }) + + it('names a foreign-version header by its stringified non-string id', async () => { + const absoluteRoot = await freshRoot() + const ctx = new Context() + await ctx.plugin(SessionStore) + const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' }) + // A future header's id field is as untrusted as the rest of its shape: + // the refusal must still name the session it read, not crash on the type. + const id = SessionId('numeric-id') + const path = rawLogPath(resolve(absoluteRoot), '/work', id) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, `${JSON.stringify({ type: 'session', version: 42, id: 123 })}\n`) + const failure = await ctx.sessionPersistence.load(id).then(() => undefined, (error: unknown) => error as Error) + expect(failure?.name).toBe('SessionFormatUnsupportedError') + expect(failure?.message).toContain('session "123" uses log format v42') + await fiber.dispose() + }) + it('points a format refusal at the raw log path', async () => { const absoluteRoot = await freshRoot() const ctx = new Context()