Merge remote-tracking branch 'origin/master' into worktree-export-jsdoc-gate

# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
This commit is contained in:
Tianyi Cui
2026-07-07 17:17:03 +08:00
14 changed files with 476 additions and 60 deletions

View File

@@ -23,6 +23,15 @@ afterEach(async () => {
for (const d of dirs.splice(0)) await rm(d, { recursive: true, force: true })
})
function appendClosedTurn(session: Session): void {
session.append('turn/start', { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } })
session.append('user/message', {
content: [{ type: 'text', text: 'hello' }],
source: { kind: 'user' },
}, { surfaceOp: 'append' })
session.append('turn/end', { turn: 1, reason: { kind: 'completed' } })
}
// Run the shared backend contract against the real JSONL backend.
runPersistenceContract('jsonl', async () => {
const dir = await mkdtemp(join(tmpdir(), 'dsh-jsonl-'))
@@ -131,6 +140,23 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
expect(loaded.events).toEqual(log) // chunks preserved, contiguous seqs
})
it('persists a forked child seed through the existing session write path', async () => {
const source = ctx.sessions.create(SessionId('persist-parent'), { meta: { cwd: '/workspace' } })
appendClosedTurn(source)
const child = ctx.sessions.fork(source, undefined, SessionId('persist-child'))
await ctx.parallel('session/flush', child)
const loaded = await ctx.sessionPersistence.load(child.id)
expect(loaded.events).toEqual(source.events)
expect(loaded.meta).toMatchObject({
id: SessionId('persist-child'),
cwd: '/workspace',
parentSession: SessionId('persist-parent'),
seedLength: source.events.length,
})
})
it('crash recovery: load preserves the interrupted turn and closes it with a synthetic turn/end {interrupted}', async () => {
const m = meta('crash', '/proj')
await ctx.sessionPersistence.create(m)