Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions tests/fixtures/legacy-anthropic-0200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
{
"provenance": "Synthetic body decoded by the pinned 0.1.200 kernel; no private corpus content",
"body": {
"messages": [
{
"role": "user",
"content": "Summarize this synthetic lookup."
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "synthetic-call-1",
"name": "lookup",
"input": {
"key": "invented"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "synthetic-call-1",
"content": "invented lookup result"
}
]
},
{
"role": "user",
"content": "Synthetic tail 0."
},
{
"role": "assistant",
"content": "Synthetic tail 1."
},
{
"role": "user",
"content": "Synthetic tail 2."
},
{
"role": "assistant",
"content": "Synthetic tail 3."
},
{
"role": "user",
"content": "Synthetic tail 4."
},
{
"role": "assistant",
"content": "Synthetic tail 5."
},
{
"role": "user",
"content": "Synthetic tail 6."
},
{
"role": "assistant",
"content": "Synthetic tail 7."
},
{
"role": "user",
"content": "Synthetic tail 8."
},
{
"role": "assistant",
"content": "Synthetic tail 9."
}
]
},
"legacyMessages": [
{
"id": "h_dd37bf0d01f1f2c2",
"role": "user",
"contentType": "text",
"text": "Summarize this synthetic lookup.",
"wireIndex": 0
},
{
"id": "h_ad375fbf578d70f4",
"role": "assistant",
"contentType": "tool-call",
"toolName": "lookup",
"toolCallId": "synthetic-call-1",
"text": "{\"key\":\"invented\"}",
"wireIndex": 1
},
{
"id": "h_5acf06bd84245dbd",
"role": "tool",
"contentType": "tool-result",
"toolCallId": "synthetic-call-1",
"text": "invented lookup result",
"toolName": "lookup",
"wireIndex": 2
},
{
"id": "h_dd7c34c8f76f8de0",
"role": "user",
"contentType": "text",
"text": "Synthetic tail 0.",
"wireIndex": 3
},
{
"id": "h_ecbe503530c507a1",
"role": "assistant",
"contentType": "text",
"text": "Synthetic tail 1.",
"wireIndex": 4
},
{
"id": "h_91cd90107009cd4c",
"role": "user",
"contentType": "text",
"text": "Synthetic tail 2.",
"wireIndex": 5
},
{
"id": "h_cc36cc6011d0bf55",
"role": "assistant",
"contentType": "text",
"text": "Synthetic tail 3.",
"wireIndex": 6
},
{
"id": "h_39dc1e2dc520545c",
"role": "user",
"contentType": "text",
"text": "Synthetic tail 4.",
"wireIndex": 7
},
{
"id": "h_fa8ed6aa56f9e474",
"role": "assistant",
"contentType": "text",
"text": "Synthetic tail 5.",
"wireIndex": 8
},
{
"id": "h_f5b2ff5752bc2354",
"role": "user",
"contentType": "text",
"text": "Synthetic tail 6.",
"wireIndex": 9
},
{
"id": "h_3309f696e463ee67",
"role": "assistant",
"contentType": "text",
"text": "Synthetic tail 7.",
"wireIndex": 10
},
{
"id": "h_377cfa6ea7c6261e",
"role": "user",
"contentType": "text",
"text": "Synthetic tail 8.",
"wireIndex": 11
},
{
"id": "h_ec73340115ef30cb",
"role": "assistant",
"contentType": "text",
"text": "Synthetic tail 9.",
"wireIndex": 12
}
],
"coveredIds": [
"h_ad375fbf578d70f4",
"h_5acf06bd84245dbd"
]
}
74 changes: 74 additions & 0 deletions tests/legacy-anthropic-identity-replay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { anthropicToCore, type AnthropicRequestBody } from 'acp-kernel/wire';
import { createInitialState, prune, type CoreMessage } from 'acp-kernel';
import { normalizedIdentity, normalizedIdentityNoToolCallId, reconcileFoldCoverage } from '../src/fold-reconcile.js';
import type { Session } from '../src/session.js';

const fixture = JSON.parse(readFileSync(new URL('./fixtures/legacy-anthropic-0200.json', import.meta.url), 'utf8')) as {
body: AnthropicRequestBody;
legacyMessages: CoreMessage[];
coveredIds: string[];
};

function legacySession(): Session {
// A valid legacy coverage shape with no surviving anchors for this old pair.
// The 13-message resend clears the auxiliary-side-request guard. Persisted
// lastMessages is empty, as in the affected legacy envelope. No private
// messages, anchors, summaries or identifiers are included in this fixture.
const state = createInitialState();
state.blocks.push({
blockId: 'b1', runId: 'synthetic-fold', tier: 1,
summary: 'The synthetic lookup completed.',
directMessageIds: [...fixture.coveredIds],
effectiveMessageIds: [...fixture.coveredIds], directBlockIds: [],
compressedTokens: 20, createdAt: 1700000000000,
survivedCount: 0, generation: 'old', active: true,
});
return {
id: 'synthetic-legacy-replay',
state,
metadata: { foldAnchorOrder: fixture.legacyMessages.map(message => message.id), foldAnchors: {} },
lastMessages: [],
} as unknown as Session;
}

test('legacy IDs still match persisted coverage without surviving anchors', () => {
const session = legacySession();
const messages = structuredClone(fixture.legacyMessages);
const result = reconcileFoldCoverage(session, messages, { mode: 'repair' });
assert.equal(result.missing, 0);
assert.equal(result.unmatched, 0);
assert.equal(prune(messages, session.state).filter(message => message.toolCallId === 'synthetic-call-1').length, 0);
});

test('synthetic old and current decoders preserve the same message payloads', () => {
const current = anthropicToCore(structuredClone(fixture.body)).msgs;
const withoutIds = (messages: CoreMessage[]) => messages.map(({ id: _id, ...payload }) => payload);
assert.deepEqual(withoutIds(current), withoutIds(fixture.legacyMessages));
assert.equal(current.length, 13);
assert.equal(fixture.coveredIds.length, 2);
});

test('surviving tool anchors recover the same current replay', () => {
const session = legacySession();
session.metadata.foldAnchors = Object.fromEntries(fixture.legacyMessages.map(message => [message.id, {
n: normalizedIdentity(message), r: message.role, b: message.text?.length ?? 0,
...(message.toolCallId ? { t: message.toolCallId, m: normalizedIdentityNoToolCallId(message) } : {}),
}]));
const current = anthropicToCore(structuredClone(fixture.body)).msgs;
const result = reconcileFoldCoverage(session, current, { mode: 'repair' });
assert.equal(result.unmatched, 0);
assert.equal(prune(current, session.state).filter(message => message.toolCallId === 'synthetic-call-1').length, 0);
});

test('unchanged Anthropic replay keeps legacy folded tool coverage after upgrade', () => {
const session = legacySession();
const current = anthropicToCore(structuredClone(fixture.body)).msgs;
const result = reconcileFoldCoverage(session, current, { mode: 'repair' });
assert.equal(prune(current, session.state).filter(message => message.toolCallId === 'synthetic-call-1').length, 0,
'already-folded tool messages must stay folded on unchanged replay');
assert.equal(result.unmatched, 0,
'unchanged tool-call/result payloads must not re-enter the wire unfolded after upgrading persisted legacy coverage');
});
Loading