Files
deepseek-harness/packages/client/runtime/tests/compact-checkpoint-pin.spec.ts
T
Hypatia May 91ee264e16 round 2: pin checkpoint recognition at compile time
Move COMPACT_CHECKPOINT_SOURCE and isCompactCheckpointSource into a
cordis-free src/checkpoint.ts leaf, re-exported from the root so every
host-side consumer keeps its import. The client can then type-import the
leaf without reaching dsh-session's root, whose Context merge declares the
host sessions service and collides with the client's -- the dsh-commands/brand
shape. Renaming the plugin id now fails the client typecheck.

Also: keep recoverable summary text when a compact/summary mixes text with
other block types, and capture the seeded-history provenance seqs from the
pushes that produce them instead of deriving them by arithmetic.
2026-07-30 14:07:08 +08:00

51 lines
2.3 KiB
TypeScript

/**
* Behavioral half of the compaction-checkpoint drift trap.
*
* `TranscriptAdapter` pins its plugin literal to the seam's own declaration at
* compile time through a type-only import of `dsh-compact/checkpoint`, so
* renaming the seam's plugin already fails `tsc`. This spec covers the same
* drift from the other side — end to end through the adapter, driving it with a
* checkpoint built from the canonical `COMPACT_CHECKPOINT_SOURCE` **value** and
* checking the seam's own predicate agrees. It runs in the client TEST program,
* which can value-import the package root; a `packages/client/*` package
* program cannot, because that root reaches `dsh-session`'s root and collides
* the host `Context.sessions` merge (`TS2717`).
*/
import { COMPACT_CHECKPOINT_SOURCE, isCompactCheckpointSource } from '@deepseek-ai/dsh-compact'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import { describe, expect, it } from 'vitest'
import type { SessionEvent } from '@deepseek-ai/dsh-session/types'
import { TranscriptAdapter } from '../src/client/sessions/transcript-adapter.ts'
/** A replacement user message stamped with the seam's own canonical source. */
function canonicalCheckpoint(seq: number): SessionEvent {
return {
type: 'user/message',
seq,
time: 1_700_000_000_000 + seq,
surfaceOp: { op: 'replace', start: 0, end: 0 },
sourceEventSeqs: [0],
data: createUserMessage({
content: [{ type: 'text', text: '<context_checkpoint>model only</context_checkpoint>' }],
source: COMPACT_CHECKPOINT_SOURCE,
}),
} as unknown as SessionEvent
}
describe('compaction checkpoint recognition', () => {
it('recognizes a checkpoint carrying the seam-canonical source', () => {
const adapter = new TranscriptAdapter()
adapter.reset([canonicalCheckpoint(1)])
expect(adapter.nodes()).toEqual([{ kind: 'compaction', seq: 1, time: 1_700_000_000_001, summary: null }])
})
it('agrees with the seam s own predicate on the source it recognizes', () => {
// Both sides answer the same question about the same value: if the seam
// renames its plugin, this equality is what breaks.
const checkpoint = canonicalCheckpoint(1)
expect(checkpoint.type === 'user/message' && isCompactCheckpointSource(checkpoint.data.source)).toBe(true)
expect(COMPACT_CHECKPOINT_SOURCE).toEqual({ kind: 'plugin', plugin: 'compact' })
})
})