mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(session-query): make persisted observation non-mutating
This commit is contained in:
@@ -438,11 +438,12 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
persisted = materializePersistenceSnapshots(before)
|
||||
for (const entry of persisted.values()) {
|
||||
if (canReuseIndexed && indexed.get(entry.header.id)?.revision === entry.revision) continue
|
||||
// `load()` may durably repair an interrupted tail. Never invoke it
|
||||
// for a session currently owned by the live store: a checkpointed
|
||||
// open turn is active, not crash-interrupted.
|
||||
// Skip work already shadowed by a live owner. `inspect()` is
|
||||
// non-mutating, so an owner attaching after this check cannot cause
|
||||
// crash-repair side effects; the live-membership retry below makes
|
||||
// the returned observation live-preferred.
|
||||
if (initiallyLive.has(entry.header.id) || this.ctx.sessions.get(entry.header.id) !== undefined) continue
|
||||
const loaded = await waitWithAbort(persistence.load(entry.header.id), signal)
|
||||
const loaded = await waitWithAbort(persistence.inspect(entry.header.id), signal)
|
||||
assertSessionHeadersCompatible(entry.header, loaded.meta)
|
||||
entry.loaded = observeSession(loaded.meta, loaded.events)
|
||||
}
|
||||
|
||||
@@ -60,8 +60,9 @@ export async function openSearchDatabase(path: string, journalMode: JournalMode)
|
||||
if (applicationId === 0 && userTables.length > 0) {
|
||||
throw new Error(`session-search database at "${actual}" is not an empty or recognized derived index`)
|
||||
}
|
||||
if (applicationId === SESSION_QUERY_SQLITE_APPLICATION_ID && version !== SESSION_QUERY_SQLITE_SCHEMA_VERSION) {
|
||||
resetDerivedSchema(db, actual, userTables)
|
||||
if (applicationId === SESSION_QUERY_SQLITE_APPLICATION_ID) {
|
||||
assertDerivedUserTables(actual, userTables)
|
||||
if (version !== SESSION_QUERY_SQLITE_SCHEMA_VERSION) resetDerivedSchema(db, userTables)
|
||||
}
|
||||
// Apply mutating pragmas only after refusing foreign or canonical files.
|
||||
// journalMode is a validated closed union, not caller-controlled SQL.
|
||||
@@ -82,13 +83,16 @@ function listUserTables(db: DatabaseSync): string[] {
|
||||
return rows.map(row => row.name)
|
||||
}
|
||||
|
||||
function resetDerivedSchema(db: DatabaseSync, path: string, userTables: readonly string[]): void {
|
||||
function assertDerivedUserTables(path: string, userTables: readonly string[]): void {
|
||||
const unknownTables = userTables.filter(name => !DERIVED_USER_TABLES.has(name))
|
||||
if (unknownTables.length > 0) {
|
||||
throw new Error(
|
||||
`session-search database at "${path}" has unrecognized user tables: ${unknownTables.join(', ')}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function resetDerivedSchema(db: DatabaseSync, userTables: readonly string[]): void {
|
||||
for (const name of userTables) {
|
||||
db.exec(`DROP TABLE IF EXISTS ${quoteIdentifier(name)}`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user