diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff86bcc..3fc2174 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,9 @@ jobs: git init -q git remote add origin https://github.com/deepseek-ai/deepseek-harness.git git fetch --depth 1 -q origin \ - refs/tags/dsh-v0.1.2-rc.1:refs/tags/dsh-v0.1.2-rc.1 + refs/tags/dsh-v0.1.2-rc.1:refs/tags/dsh-v0.1.2-rc.1 \ + refs/tags/dsh-v0.1.3-alpha.2:refs/tags/dsh-v0.1.3-alpha.2 \ + refs/tags/dsh-v0.1.5-alpha.1:refs/tags/dsh-v0.1.5-alpha.1 - name: Test run: DSH_REPO="$PWD/.tmp/dsh-repo" pnpm test diff --git a/tests/baselines.ts b/tests/baselines.ts index 70ed98b..5dd32a7 100644 --- a/tests/baselines.ts +++ b/tests/baselines.ts @@ -16,7 +16,7 @@ */ /** The supported dsh tags, in lockstep with the BASELINES entries below. */ -export type BaselineId = 'v0.1.2-rc.1' +export type BaselineId = 'v0.1.2-rc.1' | 'v0.1.3-alpha.2' | 'v0.1.5-alpha.1' /** The harness web half's client faces, as far as the compat probes consume them. */ export interface ClientSeam { @@ -59,6 +59,16 @@ export interface Baseline { * own generation. */ session: string + /** + * The durable-event families THIS line's log carries that the host fold + * switches on — the probe asserts every one exists in the tag's + * `KNOWN_SESSION_EVENT_TYPES`. The fold reads a UNION of generations + * (V0 `assistant/chunk` + `tool/code-dispatch`; V2 `assistant/attempt`; V3 + * `system/message` + `tool/ptc-dispatch`), and no single line carries them + * all, so the list is per baseline by construction; the matrix also asserts + * the union covers the fold's whole vocabulary. + */ + foldEventTypes: readonly string[] client: ClientSeam /** * The step-boundary identity guard's host seam (src/host/stepIdentity.ts): @@ -75,11 +85,17 @@ export interface Baseline { export const BASELINES: readonly Baseline[] = [ { - // The `next`-channel release candidate — the newest declared dsh release. + // Session format V0 — the oldest supported line (the plugin's original target). id: 'v0.1.2-rc.1', tag: 'dsh-v0.1.2-rc.1', cordis: '4.0.2', session: '0.1.2-rc.1', + foldEventTypes: [ + 'request/header', 'request/context', 'step/start', 'step/end', + 'user/message', 'tool/call', 'tool/result', 'assistant/message', 'assistant/chunk', + 'tool/code-dispatch', + 'plan/mode', 'compaction/summary', 'compaction/prune', + ], client: { imageFaceMethod: 'imageUrl', markdownChrome: 'labels', @@ -104,4 +120,83 @@ export const BASELINES: readonly Baseline[] = [ prependProofFile: 'packages/context/time-context/src/index.ts', }, }, + { + // Session format V2: the assistant stream moved INTO the settlement + // (`assistant/message.data.stream` / `assistant/attempt.data.stream`), so + // `assistant/chunk` no longer exists and the fold's first-token source + // changes while every other V0 seam stays. + id: 'v0.1.3-alpha.2', + tag: 'dsh-v0.1.3-alpha.2', + cordis: '4.0.2', + session: '0.1.3-alpha.2', + foldEventTypes: [ + 'request/header', 'request/context', 'step/start', 'step/end', + 'user/message', 'tool/call', 'tool/result', 'assistant/message', 'assistant/attempt', + 'tool/code-dispatch', + 'plan/mode', 'compaction/summary', 'compaction/prune', + ], + client: { + imageFaceMethod: 'imageUrl', + markdownChrome: 'labels', + platformModules: [ + 'react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', '@deepseek-ai/cordis', + '@deepseek-ai/dsh-client-store', + '@deepseek-ai/dsh-client-ui-slots', + '@deepseek-ai/dsh-client-ui-primitives', + ], + detailChannel: { + hostRpcFile: 'packages/client/connection/src/rpc.ts', + hostRpcNeedle: 'HostConnectionRpc', + clientRpcFile: 'packages/client/connection/src/client/rpc.ts', + clientRpcNeedle: 'call(channel, endpoint, payload', + registryFile: 'packages/session/session-projection/src/index.ts', + registryNeedle: 'stateOf<', + }, + }, + stepGuard: { + loopFile: 'packages/core/agent-loop/src/agent.ts', + loopNeedles: ["'agent/pre-step'", "append('user/message'"], + prependProofFile: 'packages/context/time-context/src/index.ts', + }, + }, + { + // Session format V3: the system prompt became a surface node + // (`system/message`) and left `request/header.header.system`; replacement + // endpoints renamed to `startSeq`/`endSeq`; the PTC vocabulary renamed to + // `tool/ptc-dispatch`; the shell seeds one more platform module. + id: 'v0.1.5-alpha.1', + tag: 'dsh-v0.1.5-alpha.1', + cordis: '4.0.2', + session: '0.1.5-alpha.1', + foldEventTypes: [ + 'request/header', 'request/context', 'step/start', 'step/end', + 'user/message', 'tool/call', 'tool/result', 'assistant/message', 'assistant/attempt', + 'tool/ptc-dispatch', + 'plan/mode', 'compaction/summary', 'compaction/prune', 'system/message', + ], + client: { + imageFaceMethod: 'imageUrl', + markdownChrome: 'labels', + platformModules: [ + 'react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', '@deepseek-ai/cordis', + '@deepseek-ai/dsh-client-store', + '@deepseek-ai/dsh-client-ui-slots', + '@deepseek-ai/dsh-client-ui-primitives', + '@deepseek-ai/dsh-client-ui-dockkit', + ], + detailChannel: { + hostRpcFile: 'packages/client/connection/src/rpc.ts', + hostRpcNeedle: 'HostConnectionRpc', + clientRpcFile: 'packages/client/connection/src/client/rpc.ts', + clientRpcNeedle: 'call(channel, endpoint, payload', + registryFile: 'packages/session/session-projection/src/index.ts', + registryNeedle: 'stateOf<', + }, + }, + stepGuard: { + loopFile: 'packages/core/agent-loop/src/agent.ts', + loopNeedles: ["'agent/pre-step'", "append('user/message'"], + prependProofFile: 'packages/context/time-context/src/index.ts', + }, + }, ] diff --git a/tests/compat/matrix.spec.ts b/tests/compat/matrix.spec.ts index 49d8ea0..a76f9e9 100644 --- a/tests/compat/matrix.spec.ts +++ b/tests/compat/matrix.spec.ts @@ -30,6 +30,17 @@ if (reasons.length > 0) { // bundle requires at runtime must be seeded by EACH baseline's platform // module table — a require the shell cannot answer is a guaranteed boot // crash on that generation. +describe('compat matrix — the per-baseline fold vocabularies', () => { + test('their union covers every event family the fold switches on', () => { + const union = new Set(BASELINES.flatMap(baseline => baseline.foldEventTypes)) + assert.deepEqual( + staging.FOLD_EVENT_TYPES.filter(type => !union.has(type)), + [], + 'a fold case no baseline declares would go unprobed', + ) + }) +}) + describe.skipIf(staging.artifactsMissing())('compat matrix — bundle requires vs baseline module tables', () => { test.each(BASELINES)('$id: the platform module table answers every bundle require', (baseline) => { assert.deepEqual( @@ -128,9 +139,9 @@ describe.skipIf(reasons.length > 0)('compat matrix — real dsh sources per base assert.equal(staging.dshHasString(baseline.tag, baseline.client.markdownChrome, 'packages/client/ui-primitives/src/markdown/MarkdownText.tsx'), true) }) - test('host: the fold\'s event vocabulary exists in the durable log', async () => { + test('host: the fold\'s event vocabulary for this generation exists in the durable log', async () => { const known = await staging.knownEventTypesOf(baseline) - const missing = staging.FOLD_EVENT_TYPES.filter(type => !known.has(type)) + const missing = baseline.foldEventTypes.filter(type => !known.has(type)) assert.deepEqual(missing, []) }) diff --git a/tests/compat/staging.ts b/tests/compat/staging.ts index 9d94095..8c97042 100644 --- a/tests/compat/staging.ts +++ b/tests/compat/staging.ts @@ -268,12 +268,21 @@ export const SLOT_SEAMS = [ 'settings.plugin.item', ] as const -/** The event families the host fold switches on (src/host/fold.ts). */ +/** + * The event families the host fold switches on (src/host/fold.ts) — the UNION + * over every supported generation. No single harness line carries them all + * (`assistant/chunk` and `tool/code-dispatch` are V0/V2-only; `system/message` + * and `tool/ptc-dispatch` are V3-only), so the per-baseline probe asserts the + * baseline's own `foldEventTypes` subset, and a matrix test asserts this union + * equals the baselines' union — a fold case added without a baseline list + * fails loudly instead of going unprobed. + */ export const FOLD_EVENT_TYPES = [ 'request/header', 'request/context', 'step/start', 'step/end', 'user/message', 'tool/call', 'tool/result', 'assistant/message', - 'tool/code-dispatch', - 'plan/mode', 'compaction/summary', 'compaction/prune', + 'assistant/chunk', 'assistant/attempt', + 'tool/code-dispatch', 'tool/ptc-dispatch', + 'plan/mode', 'compaction/summary', 'compaction/prune', 'system/message', ] as const /** The tag's durable-event vocabulary (packages/core/session/src/known-event-types.ts). */