fix(session-projection-cache): coldSnapshot honors not-found with zero registered units

Review finding (PR #791): with no projection definitions registered,
restoreFloor() is undefined and the fast path returned a successful empty
snapshot without touching persistence — a nonexistent session 'succeeded',
violating the documented not-found contract in that supported topology.
The no-unit branch now probes readFrom(id, 0): an absent log rejects with
the seam's not-found, a present one dates the empty cut at its stored end.
This commit is contained in:
imccyu
2026-07-28 11:44:19 +08:00
parent 54c893d7af
commit 1ef7c9473c
2 changed files with 29 additions and 1 deletions

View File

@@ -252,4 +252,26 @@ describe('SessionProjectionCache cold read', () => {
const { cache } = await harness()
await expect(cache.coldSnapshot(SessionId('absent'))).rejects.toThrow('not found')
})
it('holds the not-found contract with zero registered units, and dates the empty cut for a present log', async () => {
// Same composition minus any registered unit: restoreFloor is undefined,
// yet coldSnapshot must still reject for an absent log (probe read) and
// serve an empty cut at the stored end for a present one.
const pool = new MemoryMediaPool()
const logs = new Map([['bare', storedLog([['a']])]]) // seqs 0..2
const ctx = new Context()
contexts.push(ctx)
await ctx.plugin(Storage)
ctx.storage.backend.register('memory', new MemoryStorageBackend(pool))
const facility = new DomainFacility(ctx, { backend: 'memory', routes: {} })
ctx.storage.mount('domain', facility)
ctx.provide('storageDomain', facility)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
ctx.provide('sessionPersistence', fakePersistence(logs) as never)
await ctx.plugin(SessionProjectionCache, { writeEveryEvents: 100, writeIntervalMs: 60_000 })
await expect(ctx.sessionProjectionCache.coldSnapshot(SessionId('absent'))).rejects.toThrow('not found')
await expect(ctx.sessionProjectionCache.coldSnapshot(SessionId('bare')))
.resolves.toEqual({ asOfSeq: 2, values: {} })
})
})