From db0b43bf86b492999454b6163bb80f916c280d5e Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 28 Jul 2026 21:40:51 +0800 Subject: [PATCH] persistence: advance schemas after removing policy columns The simplification deletes sandbox_mode and approval_policy from the parent branch's SQLite layouts. Restoring master's older version numbers would violate the monotonic schema contract and could make a database created by the parent look current under a different layout. Advance durable session persistence from schema 11 to 12 and the disposable session-query index from 6 to 7. The former rejects the incompatible parent layout; the latter resets its derived tables through the existing version-mismatch path. JSONL shares SESSION_FORMAT_VERSION 0 during pre-release, so explicitly reject the retired sandboxMode and approvalPolicy header fields instead of silently dropping the only inherited policy facts from a parent-produced child log. New logs carry those facts as ordinary seeded events. Focused JSONL, SQLite persistence, and SQLite query suites cover all affected source lines and branches. --- .../session-persistence-jsonl/src/format.ts | 3 +++ .../session-persistence-jsonl/tests/jsonl.spec.ts | 6 ++++++ .../session-persistence-sqlite/src/schema.ts | 2 +- .../session-persistence-sqlite/tests/sqlite.spec.ts | 2 +- packages/session-query/session-query-sqlite/src/schema.ts | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/session-persistence/session-persistence-jsonl/src/format.ts b/packages/session-persistence/session-persistence-jsonl/src/format.ts index 03e8b15da0..f7d338877d 100644 --- a/packages/session-persistence/session-persistence-jsonl/src/format.ts +++ b/packages/session-persistence/session-persistence-jsonl/src/format.ts @@ -64,6 +64,9 @@ export function toHeaderLine(header: SessionHeader): HeaderLine { * @returns the header, absent optional fields omitted. */ export function fromHeaderLine(line: HeaderLine): SessionHeader { + if (Object.hasOwn(line, 'sandboxMode') || Object.hasOwn(line, 'approvalPolicy')) { + throw new Error('session header uses retired policy baseline fields') + } return { version: line.version, id: line.id, diff --git a/packages/session-persistence/session-persistence-jsonl/tests/jsonl.spec.ts b/packages/session-persistence/session-persistence-jsonl/tests/jsonl.spec.ts index f57b105a8b..5171bb8585 100644 --- a/packages/session-persistence/session-persistence-jsonl/tests/jsonl.spec.ts +++ b/packages/session-persistence/session-persistence-jsonl/tests/jsonl.spec.ts @@ -1023,6 +1023,12 @@ describe('SessionPersistenceJsonl: edge cases', () => { expect(ids).toContain('big') }) + it.each(['sandboxMode', 'approvalPolicy'] as const)('rejects the retired %s header field', (field) => { + const line = { ...toHeaderLine(meta('retired-policy-header')), [field]: 'read-only' } + expect(() => scanLog(Buffer.from(`${JSON.stringify(line)}\n`))) + .toThrow(/retired policy baseline fields/) + }) + it('list rejects a header whose cwd does not identify its physical log', async () => { const m = meta('misplaced', '/stored') await ctx.sessionPersistence.create(m) diff --git a/packages/session-persistence/session-persistence-sqlite/src/schema.ts b/packages/session-persistence/session-persistence-sqlite/src/schema.ts index 754d9d7e63..bdbd657e3e 100644 --- a/packages/session-persistence/session-persistence-sqlite/src/schema.ts +++ b/packages/session-persistence/session-persistence-sqlite/src/schema.ts @@ -17,7 +17,7 @@ import type { SessionEvent, SessionId, SessionHeader, SurfaceOp } from '@deepsee * layout; orthogonal to a session's own `version` (which versions the EVENT * vocabulary, stored per session in the `sessions` row). */ -export const SCHEMA_VERSION = 10 +export const SCHEMA_VERSION = 12 /** SQLite application id protecting unrelated databases from persistence writes. */ export const SESSION_PERSISTENCE_SQLITE_APPLICATION_ID = 0x44534850 diff --git a/packages/session-persistence/session-persistence-sqlite/tests/sqlite.spec.ts b/packages/session-persistence/session-persistence-sqlite/tests/sqlite.spec.ts index 82f00519ba..ddc46880cf 100644 --- a/packages/session-persistence/session-persistence-sqlite/tests/sqlite.spec.ts +++ b/packages/session-persistence/session-persistence-sqlite/tests/sqlite.spec.ts @@ -609,7 +609,7 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { }) it('exposes the schema version constant', () => { - expect(SCHEMA_VERSION).toBe(10) + expect(SCHEMA_VERSION).toBe(12) }) it('keeps the revision stable for an empty repair hook', async () => { diff --git a/packages/session-query/session-query-sqlite/src/schema.ts b/packages/session-query/session-query-sqlite/src/schema.ts index 47f6374ba6..f5c2d81bcf 100644 --- a/packages/session-query/session-query-sqlite/src/schema.ts +++ b/packages/session-query/session-query-sqlite/src/schema.ts @@ -5,7 +5,7 @@ import { mkdir, open } from 'node:fs/promises' import { dirname, resolve } from 'node:path' /** Current derived-index schema version. Incompatible versions reset in place. */ -export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 5 +export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 7 /** SQLite application id protecting unrelated databases from derived resets. */ export const SESSION_QUERY_SQLITE_APPLICATION_ID = 0x44534851