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.
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
/**
|
||||
* Drift trap for the compaction-checkpoint recognition rule.
|
||||
* Behavioral half of the compaction-checkpoint drift trap.
|
||||
*
|
||||
* `TranscriptAdapter` restates the compaction seam's checkpoint source as a
|
||||
* local literal because it cannot import `dsh-compact` in any form: a VALUE
|
||||
* import fails the client purity gate, and a TYPE-ONLY import fails typecheck —
|
||||
* `dsh-compact`'s root reaches `dsh-session`'s root, whose cordis `Context`
|
||||
* merge declares the HOST `sessions: SessionStore` against the client program's
|
||||
* `sessions: ISessions` (`TS2717`). This spec runs in the client TEST program,
|
||||
* which does not carry that collision, and it is the only thing keeping the two
|
||||
* implementations from drifting: it drives the adapter with a checkpoint built
|
||||
* from the canonical `COMPACT_CHECKPOINT_SOURCE` itself, so renaming the seam's
|
||||
* plugin fails HERE instead of silently deleting every compaction marker from
|
||||
* the web transcript.
|
||||
* `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'
|
||||
|
||||
@@ -225,7 +225,7 @@ describe('TranscriptAdapter', () => {
|
||||
|
||||
it.each([
|
||||
['absent provenance', undefined],
|
||||
['malformed summary blocks', compactSummary(1, [{ type: 'image', data: 'nope' }])],
|
||||
['text-less summary blocks', compactSummary(1, [{ type: 'image', data: 'nope' }])],
|
||||
['a whitespace-only summary', compactSummary(1, [{ type: 'text', text: ' ' }])],
|
||||
['an empty summary array', compactSummary(1, [])],
|
||||
['a non-array summary', compactSummary(1, 'plain string')],
|
||||
@@ -240,6 +240,19 @@ describe('TranscriptAdapter', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('keeps the text of a mixed-block summary, skipping the blocks it cannot render', () => {
|
||||
// ContentBlock is merge-extensible and the payload type is ContentBlock[],
|
||||
// so a non-text block must not discard recoverable text beside it.
|
||||
const adapter = new TranscriptAdapter()
|
||||
adapter.reset([
|
||||
compactSummary(1, [{ type: 'text', text: '可用摘要' }, { type: 'image', data: 'nope' }]),
|
||||
checkpoint(2, 1, { start: 0, end: 0, sourceEventSeqs: [1, 0] }),
|
||||
])
|
||||
expect(adapter.nodes()).toEqual([
|
||||
{ kind: 'compaction', seq: 2, time: 1_700_000_000_002, summary: '可用摘要' },
|
||||
])
|
||||
})
|
||||
|
||||
it('leaves the summary null when the checkpoint records no provenance at all', () => {
|
||||
const adapter = new TranscriptAdapter()
|
||||
adapter.reset([at(2, {
|
||||
|
||||
Reference in New Issue
Block a user