diff --git a/packages/session-persistence/session-persistence/src/coordinator.ts b/packages/session-persistence/session-persistence/src/coordinator.ts index e350beec3a..4c6d940888 100644 --- a/packages/session-persistence/session-persistence/src/coordinator.ts +++ b/packages/session-persistence/session-persistence/src/coordinator.ts @@ -273,6 +273,7 @@ function migrateLegacyTurnStartEvent(event: SessionEvent, id: SessionId): Sessio function migrateLegacyTurnEndEvent(event: SessionEvent, id: SessionId): SessionEvent { if (event.type !== 'turn/end') return event const data = asRecord(event.data) + /* v8 ignore next -- a non-record current envelope cannot match a legacy shape. */ if (data === undefined) return event const malformed = (): never => { throw new Error(`session "${id}" contains malformed pre-react-loop turn/end at seq ${event.seq}`) @@ -328,7 +329,6 @@ function migrateLegacyTurnEndEvent(event: SessionEvent, id: SessionId): SessionE break } default: - /* v8 ignore next -- turn-end reasons are merge-extensible beyond the current vocabulary. */ return event } diff --git a/packages/session-persistence/session-persistence/tests/coordinator-contract.ts b/packages/session-persistence/session-persistence/tests/coordinator-contract.ts index a5e799130e..fc86d0ef1b 100644 --- a/packages/session-persistence/session-persistence/tests/coordinator-contract.ts +++ b/packages/session-persistence/session-persistence/tests/coordinator-contract.ts @@ -559,6 +559,20 @@ export function runCoordinatorContract(name: string, makeFixture: () => Promise< content: [{ type: 'text', text: 'flat steering' }], }, }) + + const extendedId = SessionId('current-extended-turn-end') + await ctx.sessionPersistence.create(meta(extendedId, WORK)) + await ctx.sessionPersistence.append(extendedId, [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, + { + type: 'turn/end', seq: 1, time: 2, + data: { turn: 1, reason: { kind: 'extension-reason' } }, + } as unknown as SessionEvent, + ]) + expect((await ctx.sessionPersistence.inspect(extendedId)).events[1]).toMatchObject({ + type: 'turn/end', + data: { reason: { kind: 'extension-reason' } }, + }) } finally { await fiber.dispose() await fix.cleanup()