diff --git a/packages/session/session-format-v0-to-v1/src/validation.ts b/packages/session/session-format-v0-to-v1/src/validation.ts index 123653e6b1..7fc5f8ed5a 100644 --- a/packages/session/session-format-v0-to-v1/src/validation.ts +++ b/packages/session/session-format-v0-to-v1/src/validation.ts @@ -191,7 +191,7 @@ function assertSurfaceMetadata(record: Record, s if (replacement['op'] !== 'replace') throw new SessionFormatError(`${type} ${seq} surfaceOp must replace`) const start = sessionFormatCount(replacement['start'], `${type} ${seq} surface start`) const end = sessionFormatCount(replacement['end'], `${type} ${seq} surface end`) - if (start > end || end >= seq) throw new SessionFormatError(`${type} ${seq} has an invalid surface replacement`) + if (start >= seq || end >= seq) throw new SessionFormatError(`${type} ${seq} has an invalid surface replacement`) } /** diff --git a/packages/session/session-format-v0-to-v1/tests/relationships.spec.ts b/packages/session/session-format-v0-to-v1/tests/relationships.spec.ts index 7f7ef30821..8710b27868 100644 --- a/packages/session/session-format-v0-to-v1/tests/relationships.spec.ts +++ b/packages/session/session-format-v0-to-v1/tests/relationships.spec.ts @@ -112,6 +112,24 @@ describe('released v1 whole-artifact relationships', () => { expect(decode(rows).events).toEqual(rows) }) + it('accepts a surface-position range whose sequence values descend', () => { + const rows = [ + { type: 'user/message', seq: 0, time: 1, data: user('zero'), surfaceOp: 'append' }, + { type: 'user/message', seq: 1, time: 2, data: user('one'), surfaceOp: 'append' }, + { type: 'user/message', seq: 2, time: 3, data: user('two'), surfaceOp: 'append' }, + { + type: 'user/message', seq: 3, time: 4, data: user('first replacement'), + sourceEventSeqs: [0, 1], surfaceOp: { op: 'replace', start: 0, end: 1 }, + }, + { + type: 'user/message', seq: 4, time: 5, data: user('second replacement'), + sourceEventSeqs: [3, 2], surfaceOp: { op: 'replace', start: 3, end: 2 }, + }, + ] + + expect(decode(rows).events).toEqual(rows) + }) + it('keeps the latest request provider across later steps and turns', () => { const rows = [ { type: 'turn/start', seq: 0, time: 1, data: { turn: 1 } }, diff --git a/packages/session/session-format-v0-to-v1/tests/validation.spec.ts b/packages/session/session-format-v0-to-v1/tests/validation.spec.ts index 307a9634f2..2b80321e60 100644 --- a/packages/session/session-format-v0-to-v1/tests/validation.spec.ts +++ b/packages/session/session-format-v0-to-v1/tests/validation.spec.ts @@ -524,7 +524,7 @@ describe('released event and payload inventory', () => { { sourceEventSeqs: [], surfaceOp: 'append' }, { surfaceOp: null }, { surfaceOp: { op: 'append', start: 0, end: 1 } }, - { surfaceOp: { op: 'replace', start: 2, end: 1 } }, + { surfaceOp: { op: 'replace', start: 3, end: 1 } }, { surfaceOp: { op: 'replace', start: 1, end: 3 } }, ] for (const metadata of surfaceVariants) {