@jskit-ai/assistant-core 0.1.212 → 0.1.214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/examples/conversation/package.json +5 -5
  2. package/fixtures/responsive-assistant/ConversationFixture.vue +7 -1
  3. package/package.json +5 -5
  4. package/src/client/conversation/AssistantConversationElement.vue +5 -1
  5. package/src/client/conversation/AssistantTranscript.vue +10 -1
  6. package/src/server/conversation/agentRun.js +38 -11
  7. package/src/server/conversation/claudeHistory.js +40 -5
  8. package/src/server/conversation/claudeProcess.js +28 -4
  9. package/src/server/conversation/claudeTools.js +11 -2
  10. package/src/server/conversation/claudeTurn.js +213 -23
  11. package/src/server/conversation/codexConfiguration.js +1 -1
  12. package/src/server/conversation/codexHistoryAdapter.js +11 -4
  13. package/src/server/conversation/codexNotificationQueue.js +11 -2
  14. package/src/server/conversation/codexObservationControl.js +8 -8
  15. package/src/server/conversation/codexOutput.js +20 -15
  16. package/src/server/conversation/codexProvider.js +40 -3
  17. package/src/server/conversation/codexProviderOwner.js +110 -1
  18. package/src/server/conversation/codexTurn.js +3 -0
  19. package/src/server/conversation/continuity.js +24 -6
  20. package/src/server/conversation/index.js +1 -1
  21. package/src/server/conversation/nativeHistoryExport.js +97 -0
  22. package/src/server/conversation/openCodeClient.js +47 -1
  23. package/src/server/conversation/openCodeRuntime.js +183 -28
  24. package/src/server/conversation/openCodeTurn.js +65 -24
  25. package/src/server/conversation/providers/api.js +7 -0
  26. package/src/server/conversation/providers/claudeDriver.js +52 -7
  27. package/src/server/conversation/providers/codex.js +19 -2
  28. package/src/server/conversation/providers/codexDriver.js +92 -14
  29. package/src/server/conversation/providers/opencodeDriver.js +31 -9
  30. package/src/server/conversation/runtime.js +424 -65
  31. package/src/server/conversation/runtimeStateUpgrade.js +77 -2
  32. package/src/server/conversation/streams.js +25 -5
  33. package/src/server/conversation/tools.js +2 -2
  34. package/src/server/conversation/transcript.js +23 -8
  35. package/src/server/hosts/claudeHistory.js +1 -0
  36. package/src/server/hosts/claudeProcess.js +1 -0
  37. package/src/server/hosts/codexProvider.js +3 -0
  38. package/src/server/hosts/nativeHistory.js +1 -0
  39. package/src/server/hosts/openCodeClient.js +1 -0
  40. package/src/server/hosts/openCodeTurn.js +1 -0
  41. package/src/server/index.js +1 -1
  42. package/src/server/lib/assistantToolLoop.js +99 -2
  43. package/test/aiConnectionClient.test.js +57 -0
  44. package/test/assistantBoundedToolLoop.test.js +332 -0
  45. package/test/assistantScroll.browser.test.js +151 -0
  46. package/test/claudeConversationSession.test.js +1417 -3
  47. package/test/claudeProcess.test.js +175 -0
  48. package/test/claudeTurn.test.js +466 -0
  49. package/test/codexConversationSession.test.js +1257 -12
  50. package/test/codexHistoryAdapter.test.js +74 -1
  51. package/test/codexTurn.test.js +282 -1
  52. package/test/conversation.test.js +83 -0
  53. package/test/conversationAgentRun.test.js +181 -0
  54. package/test/conversationRuntime.test.js +95 -0
  55. package/test/conversationRuntimeStateUpgrade.test.js +89 -0
  56. package/test/conversationStreaming.test.js +85 -0
  57. package/test/conversationTools.test.js +165 -1
  58. package/test/openCodeClient.test.js +186 -0
  59. package/test/openCodeRuntime.test.js +372 -0
  60. package/test/opencodeConversationSession.test.js +637 -5
@@ -6,6 +6,7 @@ import path from "node:path";
6
6
  import { createConversationRuntime, createFileConversationStorage, upgradeConversationRuntimeState } from "../src/server/conversation/index.js";
7
7
  import { createLocalConversationExecution } from "../src/server/conversation/localExecution.js";
8
8
  import { createClaudeConversationDriver } from "../src/server/conversation/providers/claudeDriver.js";
9
+ import { conversationRequestText } from "../src/server/conversation/continuity.js";
9
10
  import { createActionCatalogue } from "@jskit-ai/kernel/server/actions";
10
11
  import { createSchema } from "json-rest-schema";
11
12
 
@@ -231,6 +232,8 @@ async function fixture(t, options = {}) {
231
232
  import path from "node:path";
232
233
  const args = process.argv.slice(2);
233
234
  const structuredResponse = ${JSON.stringify(options.structuredResponse || null)};
235
+ const nativeToolUse = ${JSON.stringify(options.nativeToolUse || null)};
236
+ const applicationEventBehavior = ${JSON.stringify(options.applicationEventBehavior || null)};
234
237
  const option = name => args[args.indexOf(name) + 1];
235
238
  const log = value => appendFileSync(process.env.TEST_TRACE, JSON.stringify(value) + "\\n");
236
239
  const emit = value => process.stdout.write(JSON.stringify(value) + "\\n");
@@ -273,7 +276,7 @@ async function fixture(t, options = {}) {
273
276
  : frame.message.content.filter(part => part.type === "text").map(part => part.text).join(" ");
274
277
  let answer = { type: "assistant", uuid: frame.uuid + "-answer", message: { content: [{ type: "text", text: "Answer: " + text }] } };
275
278
  if (structuredResponse) answer.message.content[0].text = JSON.stringify(structuredResponse);
276
- if (text === "lost") { record(answer); return; }
279
+ if (text === "lost" || text === applicationEventBehavior?.lost) { record(answer); return; }
277
280
  if (text.startsWith("/goal ")) {
278
281
  const condition = text.slice(6);
279
282
  record({ type: "attachment", timestamp: new Date().toISOString(),
@@ -284,7 +287,14 @@ async function fixture(t, options = {}) {
284
287
  return;
285
288
  }
286
289
  emit(frame);
287
- if (text === "wait") return;
290
+ if (nativeToolUse) {
291
+ const use = { type: "assistant", session_id: id, uuid: frame.uuid + "-native-tool",
292
+ ...(nativeToolUse.parentToolUseId ? { parent_tool_use_id: nativeToolUse.parentToolUseId } : {}), message: { content: [
293
+ { type: "tool_use", id: frame.uuid + "-native-tool", name: nativeToolUse.name, input: nativeToolUse.input }
294
+ ] } };
295
+ record(use); emit(use);
296
+ }
297
+ if (text === "wait" || text === applicationEventBehavior?.wait) return;
288
298
  if (text === "steering") {
289
299
  answer.message.content[0].text = "Initial progress";
290
300
  answer.message.id = frame.uuid + "-before";
@@ -305,6 +315,9 @@ async function fixture(t, options = {}) {
305
315
  const invoke = async (name, input) => {
306
316
  const toolId = frame.uuid + "-tool-" + (++sequence);
307
317
  const use = { type: "assistant", uuid: toolId, message: { content: [{ type: "tool_use", id: toolId, name: "mcp__application__" + name, input }] } };
318
+ if (sequence === 1 && ${JSON.stringify(options.toolProgress || "")}) {
319
+ use.message.content.unshift({ type: "text", text: ${JSON.stringify(options.toolProgress || "")} });
320
+ }
308
321
  record(use); emit(use);
309
322
  return request({ subtype: "mcp_message", server_name: "application", message: {
310
323
  jsonrpc: "2.0", id: sequence, method: "tools/call",
@@ -343,7 +356,7 @@ async function fixture(t, options = {}) {
343
356
  CLAUDE_CONFIG_DIR: path.join(directory, "claude"), TEST_TRACE: trace, TEST_ACCOUNT: account, ...options.environment };
344
357
  function runtime() {
345
358
  const value = createConversationRuntime({ engine: "claude", storage, authorize: options.authorize || (() => true), actions: options.actions,
346
- connections: options.connections, attachments: options.attachments,
359
+ connections: options.connections, attachments: options.attachments, persistCommentary: options.persistCommentary,
347
360
  host: { workdir: directory, env, commands: { claude: command }, execution: options.execution, nativeTools: options.nativeTools, commandWrapper: options.commandWrapper },
348
361
  limits: { admissionTimeoutMs: 150, ...options.limits } });
349
362
  runtimes.push(value);
@@ -1326,3 +1339,1404 @@ for (const savedStatus of ["cancelled", "failed", "unknown-tool", "interrupted"]
1326
1339
  assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
1327
1340
  });
1328
1341
  }
1342
+
1343
+ for (const saveFails of [false, true]) test(`Claude retains failed-start custody when binding save ${saveFails ? "fails" : "succeeds"}`, async t => {
1344
+ const local = createLocalConversationExecution();
1345
+ const executionId = "failed-owned-execution";
1346
+ const bindingError = new Error("Binding publication failed");
1347
+ const failure = Object.assign(new Error("Managed stream socket did not open"), {
1348
+ executionId, stopProof: { scopeEmpty: false }, cleanupFailed: true
1349
+ });
1350
+ let failStart = true;
1351
+ let allowStop = false;
1352
+ const stops = [];
1353
+ const f = await fixture(t, { execution: {
1354
+ start(options) {
1355
+ if (failStart && options.args.includes("--print")) throw failure;
1356
+ return local.start(options);
1357
+ },
1358
+ stop(id, options) {
1359
+ if (id !== executionId) return local.stop(id, options);
1360
+ stops.push(id);
1361
+ return Promise.resolve({ scopeEmpty: allowStop });
1362
+ }
1363
+ } });
1364
+ await f.first.close();
1365
+ const driver = createClaudeConversationDriver(f.driverOptions);
1366
+ const readBinding = () => f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding);
1367
+ let rejectSave = saveFails;
1368
+ const open = async () => driver.open({ binding: await readBinding(),
1369
+ async writeBinding(binding) {
1370
+ if (rejectSave && binding.executionId === executionId) throw bindingError;
1371
+ await f.storage.write("conversation", async tx => {
1372
+ const metadata = await tx.readMetadata();
1373
+ metadata.runtime.binding = binding;
1374
+ await tx.writeMetadata(metadata);
1375
+ });
1376
+ },
1377
+ onFailure() {}
1378
+ });
1379
+ const provider = await open();
1380
+ let reopened;
1381
+ const run = (owner, messageId, text) => owner.run({ configuration,
1382
+ input: { messageId, text }, signal: new AbortController().signal,
1383
+ beforeDispatch() {}, accept() {}, onEvent() {}, onMessage() {}
1384
+ });
1385
+ try {
1386
+ await assert.rejects(run(provider, "failed-start", "Never sent"), error => {
1387
+ assert.equal(error.code, "claude_stop_unconfirmed");
1388
+ assert.equal(error.cause, failure);
1389
+ assert.equal(error.cause.executionId, executionId);
1390
+ assert.equal(error.stopProof.scopeEmpty, false);
1391
+ assert.equal(error.cleanupFailed, true);
1392
+ if (saveFails) assert.equal(error.cause.bindingError, bindingError);
1393
+ return true;
1394
+ });
1395
+ assert.equal((await readBinding()).executionId, saveFails ? "" : executionId);
1396
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 0);
1397
+ assert.deepEqual(stops, [executionId]);
1398
+ if (!saveFails) {
1399
+ const restarted = createClaudeConversationDriver(f.driverOptions);
1400
+ await assert.rejects(restarted.open({ binding: await readBinding(),
1401
+ writeBinding() { assert.fail("Unconfirmed cleanup cannot release the saved binding."); },
1402
+ onFailure() {}
1403
+ }), /cleanup could not be confirmed/);
1404
+ assert.deepEqual(stops, [executionId, executionId]);
1405
+ assert.equal((await readBinding()).executionId, executionId);
1406
+ }
1407
+ const expectedStops = stops.length;
1408
+ await assert.rejects(provider.dispose(), /cleanup could not be confirmed/);
1409
+ assert.equal(stops.length, expectedStops + 1);
1410
+ assert.ok(stops.every(id => id === executionId));
1411
+ assert.equal((await readBinding()).executionId, saveFails ? "" : executionId);
1412
+ allowStop = true;
1413
+ rejectSave = false;
1414
+ await provider.dispose();
1415
+ assert.equal(stops.length, expectedStops + 2);
1416
+ assert.ok(stops.every(id => id === executionId));
1417
+ assert.equal((await readBinding()).executionId, "");
1418
+ failStart = false;
1419
+ reopened = await open();
1420
+ await run(reopened, "fresh-after-cleanup", "After cleanup");
1421
+ assert.deepEqual((await f.trace()).filter(row => row.frame?.type === "user").map(row => row.frame.message.content), ["After cleanup"]);
1422
+ } finally {
1423
+ allowStop = true;
1424
+ rejectSave = false;
1425
+ await provider.dispose();
1426
+ await reopened?.dispose();
1427
+ await local.close();
1428
+ }
1429
+ });
1430
+
1431
+ test("original scoped Claude history resumes from the authorized credential home while retaining its private scope", async t => {
1432
+ const f = await fixture(t);
1433
+ await f.first.close();
1434
+ const { realpath } = await import("node:fs/promises");
1435
+ const { createHash } = await import("node:crypto");
1436
+ const home = path.join(f.directory, "credential-home");
1437
+ const foreignHome = path.join(f.directory, "foreign-home");
1438
+ await mkdir(home);
1439
+ await mkdir(foreignHome);
1440
+ const env = { ...f.driverOptions.host.env, HOME: home };
1441
+ const scopeWorkdir = await realpath(f.directory);
1442
+ const readBinding = () => f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding);
1443
+ const writeBinding = binding => f.storage.write("conversation", async tx => {
1444
+ const metadata = await tx.readMetadata();
1445
+ metadata.runtime.binding = binding;
1446
+ await tx.writeMetadata(metadata);
1447
+ });
1448
+ const original = createClaudeConversationDriver({ ...f.driverOptions,
1449
+ host: { ...f.driverOptions.host, workdir: home, env } });
1450
+ await writeBinding(await original.createBinding());
1451
+ const run = (provider, messageId, text) => provider.run({ configuration,
1452
+ input: { messageId, text }, signal: new AbortController().signal,
1453
+ beforeDispatch() {}, accept() {}, onMessage() {}, onEvent() {}
1454
+ });
1455
+ const first = await original.open({ binding: await readBinding(), writeBinding, onFailure() {} });
1456
+ try { await run(first, "original", "Original scoped words"); }
1457
+ finally { await first.dispose(); }
1458
+ const receipt = await readBinding();
1459
+ assert.equal(receipt.workdir, await realpath(home));
1460
+ assert.equal(receipt.executionId, "");
1461
+ assert.equal(receipt.sent, true);
1462
+ // The original native-OAuth identity has the same exact tuple; only its
1463
+ // explicit hash label differs. API/connection tuples are not converted here.
1464
+ const originalAccount = "sha256:" + createHash("sha256")
1465
+ .update(JSON.stringify([receipt.configRoot, "claude.ai", "owner@example.test"])).digest("hex");
1466
+ assert.equal(originalAccount, "sha256:" + receipt.accountIdentity);
1467
+ const historyPath = path.join(receipt.configRoot, "projects", home.replace(/[^a-zA-Z0-9]/gu, "-"), receipt.conversationId + ".jsonl");
1468
+ const originalHistory = await readFile(historyPath, "utf8");
1469
+ assert.match(originalHistory, /Original scoped words/);
1470
+ const scoped = createClaudeConversationDriver({ ...f.driverOptions,
1471
+ host: { ...f.driverOptions.host, env } });
1472
+ await assert.rejects(scoped.open({ binding: receipt, writeBinding, onFailure() {} }), /another working directory or credential home/);
1473
+ const binding = { ...receipt, scopeWorkdir };
1474
+ for (const wrong of [{ ...binding, scopeWorkdir: await realpath(foreignHome) },
1475
+ { ...binding, scopeWorkdir: "" }, { ...binding, workdir: await realpath(foreignHome) },
1476
+ { ...binding, configRoot: foreignHome }]) {
1477
+ await assert.rejects(scoped.open({ binding: wrong, writeBinding, onFailure() {} }), /another working directory or credential home/);
1478
+ }
1479
+ const differentHome = createClaudeConversationDriver({ ...f.driverOptions,
1480
+ host: { ...f.driverOptions.host, env: { ...env, HOME: foreignHome } } });
1481
+ await assert.rejects(differentHome.open({ binding, writeBinding, onFailure() {} }), /another working directory or credential home/);
1482
+ assert.equal((await f.trace()).filter(row => row.args?.includes("--print")).length, 1);
1483
+ assert.equal(await readFile(historyPath, "utf8"), originalHistory);
1484
+ await writeBinding(binding);
1485
+ const resumed = await scoped.open({ binding: await readBinding(), writeBinding, onFailure() {} });
1486
+ try { await run(resumed, "resumed", "Continue original scope"); }
1487
+ finally { await resumed.dispose(); }
1488
+ const saved = await readBinding();
1489
+ assert.equal(saved.conversationId, receipt.conversationId);
1490
+ assert.equal(saved.scopeWorkdir, scopeWorkdir);
1491
+ assert.equal(saved.workdir, receipt.workdir);
1492
+ assert.equal(saved.accountIdentity, receipt.accountIdentity);
1493
+ assert.equal(saved.executionId, "");
1494
+ const starts = (await f.trace()).filter(row => row.args?.includes("--print"));
1495
+ assert.equal(starts.length, 2);
1496
+ assert.equal(starts[1].args[starts[1].args.indexOf("--resume") + 1], receipt.conversationId);
1497
+ assert.equal((await readFile(historyPath, "utf8")).startsWith(originalHistory), true);
1498
+ assert.deepEqual((await f.trace()).filter(row => row.frame?.type === "user").map(row => row.frame.message.content),
1499
+ ["Original scoped words", "Continue original scope"]);
1500
+ await writeFile(f.account, "another@example.test");
1501
+ const changed = await scoped.open({ binding: await readBinding(), writeBinding, onFailure() {} });
1502
+ try { await assert.rejects(run(changed, "foreign-account", "Must not send"), /another Claude account/); }
1503
+ finally { await changed.dispose(); }
1504
+ const api = createClaudeConversationDriver({ ...f.driverOptions,
1505
+ host: { ...f.driverOptions.host, env: { ...env, ANTHROPIC_AUTH_TOKEN: "different-api-identity" } } });
1506
+ const changedApi = await api.open({ binding: await readBinding(), writeBinding, onFailure() {} });
1507
+ try { await assert.rejects(run(changedApi, "foreign-api", "Must not send"), /another Claude account/); }
1508
+ finally { await changedApi.dispose(); }
1509
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 2);
1510
+ assert.equal((await f.trace()).filter(row => row.args?.includes("--print")).length, 2);
1511
+ assert.equal((await readBinding()).accountIdentity, receipt.accountIdentity);
1512
+ });
1513
+
1514
+ // Original accepted-output restart recovery must honor the same transient
1515
+ // transcript policy without changing native history, receipts or inference.
1516
+ for (const restoredPolicy of [undefined, false]) {
1517
+ test("Claude recovered commentary uses " + (restoredPolicy === false ? "transient" : "default") + " transcript policy", async t => {
1518
+ let executions = 0;
1519
+ const progress = "Checking the current number.";
1520
+ const context = { actor: { id: "owner" }, surface: "app", permissions: ["numbers.read"] };
1521
+ const options = { context, actions: applicationActions(async () => { executions++; return { value: 42 }; }),
1522
+ persistCommentary: false, toolProgress: progress };
1523
+ const f = await fixture(t, options);
1524
+ await f.conversation.send({ messageId: "recover-progress", text: "tools" });
1525
+ const finished = await f.conversation.wait();
1526
+ assert.deepEqual(finished.conversationLog[0].commentary, []);
1527
+ assert.equal(finished.conversationLog[0].metadata.applicationTools.length, 3);
1528
+ assert.equal(executions, 1);
1529
+ await f.first.close();
1530
+ await f.storage.write("conversation", async transaction => {
1531
+ const turn = await transaction.readTurn("000001");
1532
+ await transaction.updateTurnMetadata(turn.turnId, { runtime: { ...turn.metadata.runtime, status: "running" } });
1533
+ await transaction.replaceAssistant(turn.turnId, { ...turn.assistant, text: "Partial reply" });
1534
+ });
1535
+ options.persistCommentary = restoredPolicy;
1536
+ const reopened = await f.runtime().open({ id: "conversation", context });
1537
+ assert.equal((await reopened.inspectDelivery({ messageId: "recover-progress" })).recovered, true);
1538
+ const state = await reopened.read();
1539
+ assert.equal(state.conversationLog[0].assistant.text, finished.conversationLog[0].assistant.text);
1540
+ assert.deepEqual(state.conversationLog[0].commentary.map(message => message.text), restoredPolicy === false ? [] : [progress]);
1541
+ assert.equal(state.conversationLog[0].metadata.runtime.status, "interrupted");
1542
+ assert.deepEqual(state.conversationLog[0].metadata.applicationTools, finished.conversationLog[0].metadata.applicationTools);
1543
+ await reopened.inspectDelivery({ messageId: "recover-progress" });
1544
+ assert.deepEqual((await reopened.read()).conversationLog, state.conversationLog);
1545
+ assert.equal(executions, 1);
1546
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
1547
+ });
1548
+ }
1549
+
1550
+ // The original initialization-cancel case must join the process factory's
1551
+ // existing cleanup receipt, not reclaim an already-released execution by ID.
1552
+ test("Claude startup cancellation shares one cleanup receipt and keeps missing execution refusal", async t => {
1553
+ const local = createLocalConversationExecution();
1554
+ const started = Promise.withResolvers();
1555
+ const stops = [];
1556
+ let nativeExecutionId;
1557
+ const execution = {
1558
+ async start(options) {
1559
+ const native = await local.start(options);
1560
+ if (options.args.includes("--print")) {
1561
+ nativeExecutionId = native.id;
1562
+ started.resolve();
1563
+ }
1564
+ return native;
1565
+ },
1566
+ async stop(id, options) {
1567
+ stops.push(id);
1568
+ return local.stop(id, options);
1569
+ }
1570
+ };
1571
+ const f = await fixture(t, { execution, environment: { TEST_STARTUP_WAIT: "1" } });
1572
+ const sending = f.conversation.send(input);
1573
+ sending.catch(() => {});
1574
+ await started.promise;
1575
+ try {
1576
+ assert.equal(typeof nativeExecutionId, "string");
1577
+ await f.conversation.cancel();
1578
+ await assert.rejects(sending);
1579
+ assert.deepEqual(stops.filter(id => id === nativeExecutionId), [nativeExecutionId],
1580
+ "startup failure and cancellation join one verified native cleanup");
1581
+ assert.equal((await f.conversation.wait()).conversationLog.length, 0);
1582
+ const binding = await f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding);
1583
+ assert.equal(binding.executionId, "");
1584
+ await assert.rejects(local.stop("unowned-execution"), /does not own the requested execution/);
1585
+ await assert.rejects(local.stop(nativeExecutionId), /does not own the requested execution/,
1586
+ "only the actual cleanup owner retains its receipt; an absent local record is never proof");
1587
+ } finally {
1588
+ await local.close();
1589
+ }
1590
+ });
1591
+
1592
+ // Reuse the original controlled native CLI and its owned history/account roots.
1593
+ // The opt-in runtime is created only after the fixture's original runtime closes.
1594
+ const completedEnvelopeValue = { kind: "tool", text: "Checking.", toolName: "numbers_read", arguments: "{}" };
1595
+ const completedEnvelopeSchema = { type: "object", additionalProperties: false,
1596
+ properties: { kind: { type: "string", enum: ["reply", "tool"] }, text: { type: "string", maxLength: 64 },
1597
+ toolName: { type: "string", maxLength: 64 }, arguments: { type: "string", maxLength: 64 } },
1598
+ required: ["kind", "text", "toolName", "arguments"] };
1599
+ async function completedEnvelopeFixture(t, options = {}) {
1600
+ const context = options.context || { actor: { id: "owner" }, surface: "app", permissions: ["numbers.read"] };
1601
+ let effects = 0;
1602
+ const actions = applicationActions(async request => {
1603
+ effects++;
1604
+ return options.execute ? options.execute(request) : { value: 42 };
1605
+ });
1606
+ const f = await fixture(t, { ...options, context, actions, structuredResponse: completedEnvelopeValue,
1607
+ configuration: { ...configuration, outputSchema: completedEnvelopeSchema, ...options.configuration } });
1608
+ await f.first.close();
1609
+ let runtime;
1610
+ let conversation;
1611
+ async function reopen() {
1612
+ if (runtime) await runtime.close();
1613
+ runtime = createConversationRuntime({ engine: "claude", storage: f.storage, actions,
1614
+ authorize: options.authorize || (() => true), completedEnvelope: true, ...f.driverOptions });
1615
+ conversation = await runtime.open({ id: "conversation", context });
1616
+ return conversation;
1617
+ }
1618
+ await reopen();
1619
+ const controller = new AbortController();
1620
+ return { ...f, context, controller, effects: () => effects, reopen,
1621
+ get conversation() { return conversation; }, close: () => runtime.close(),
1622
+ async complete(messageId = "completed-response") {
1623
+ const receipt = await conversation.wake({ messageId, text: "Read a number" });
1624
+ const state = await conversation.wait();
1625
+ const turn = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1626
+ assert.equal(turn.metadata.runtime.status, "complete", state.error);
1627
+ assert.equal(turn.metadata.runtime.completedEnvelope, true);
1628
+ assert.equal(turn.assistant.text, JSON.stringify(completedEnvelopeValue));
1629
+ return { messageId, turnId: receipt.turnId };
1630
+ },
1631
+ prepare: receipt => conversation.prepareCompletedResponse(receipt, { signal: controller.signal }) };
1632
+ }
1633
+ const executeCompletedEnvelope = (prepared, argumentsText = "{}") => prepared.tools.execute({
1634
+ id: prepared.toolCallId, name: "numbers_read", arguments: argumentsText
1635
+ });
1636
+
1637
+ test("completed Claude envelopes reuse one durable receipt across prepared handles and restart", async t => {
1638
+ const f = await completedEnvelopeFixture(t);
1639
+ try {
1640
+ const receipt = await f.complete();
1641
+ const one = await f.prepare(receipt);
1642
+ const two = await f.prepare(receipt);
1643
+ const [first, second] = await Promise.all([executeCompletedEnvelope(one), executeCompletedEnvelope(two)]);
1644
+ assert.equal(first.ok, true);
1645
+ assert.deepEqual(second, first);
1646
+ assert.equal(f.effects(), 1);
1647
+ await assert.rejects(executeCompletedEnvelope(two, '{"different":true}'), /different arguments/);
1648
+ await assert.rejects(two.tools.execute({ id: "foreign-operation", name: "numbers_read", arguments: "{}" }), /different completed response identity/);
1649
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1650
+ assert.equal(saved.metadata.applicationTools.length, 1);
1651
+ assert.equal(saved.metadata.applicationTools[0].id, one.toolCallId);
1652
+ assert.equal(saved.metadata.applicationTools[0].status, "complete");
1653
+ await f.reopen();
1654
+ assert.deepEqual(await executeCompletedEnvelope(await f.prepare(receipt)), first);
1655
+ assert.equal(f.effects(), 1, "Restoring the completed response never repeats its action");
1656
+ const starts = (await f.trace()).filter(row => row.args?.includes("--print"));
1657
+ assert.equal(starts.length, 1, "Account/history inspection does not launch another native turn");
1658
+ assert.deepEqual(JSON.parse(starts[0].args.at(starts[0].args.indexOf("--mcp-config") + 1)), { mcpServers: {} });
1659
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
1660
+ } finally { await f.close(); }
1661
+ });
1662
+
1663
+ test("completed Claude response authority comes from canonical final custody, not native commentary equality", async t => {
1664
+ const f = await completedEnvelopeFixture(t);
1665
+ try {
1666
+ const receipt = await f.complete();
1667
+ const binding = await f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding);
1668
+ const project = path.join(f.driverOptions.host.env.CLAUDE_CONFIG_DIR, "projects", f.directory.replace(/[^a-zA-Z0-9]/gu, "-"));
1669
+ const historyPath = path.join(project, binding.conversationId + ".jsonl");
1670
+ const history = (await readFile(historyPath, "utf8")).trim().split("\n").map(row => JSON.parse(row));
1671
+ await writeFile(historyPath, history.filter(row => row.type !== "assistant").map(row => JSON.stringify(row)).join("\n") + "\n");
1672
+ assert.equal((await f.prepare(receipt)).text, JSON.stringify(completedEnvelopeValue),
1673
+ "StructuredOutput successful canonical completion can have no native assistant text");
1674
+ const prepared = await f.prepare(receipt);
1675
+ await f.storage.write("conversation", tx => tx.replaceAssistant(receipt.turnId, { text: "Changed final" }));
1676
+ await assert.rejects(executeCompletedEnvelope(prepared), /identity changed/);
1677
+ assert.equal(f.effects(), 0);
1678
+ } finally { await f.close(); }
1679
+ });
1680
+
1681
+ test("completed Claude envelopes refuse aborted or revoked worker authority before the effect", async t => {
1682
+ let eligible = true;
1683
+ const f = await completedEnvelopeFixture(t, { authorize: ({ operation }) => operation !== "tool" || eligible });
1684
+ try {
1685
+ const receipt = await f.complete();
1686
+ const prepared = await f.prepare(receipt);
1687
+ eligible = false;
1688
+ await assert.rejects(executeCompletedEnvelope(prepared), error => error.code === "conversation_forbidden");
1689
+ eligible = true;
1690
+ f.controller.abort(new Error("Original product worker stopped"));
1691
+ await assert.rejects(executeCompletedEnvelope(prepared), /Original product worker stopped/);
1692
+ assert.equal(f.effects(), 0);
1693
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.applicationTools?.length || 0, 0);
1694
+ } finally { eligible = true; await f.close(); }
1695
+ });
1696
+
1697
+ test("completed Claude invoked effects retain their result while Stop drains and worker authority is revoked", async t => {
1698
+ let eligible = true;
1699
+ const entered = Promise.withResolvers();
1700
+ const released = Promise.withResolvers();
1701
+ const f = await completedEnvelopeFixture(t, { authorize: ({ operation }) => operation !== "tool" || eligible,
1702
+ async execute() { entered.resolve(); await released.promise; return { value: 73 }; } });
1703
+ try {
1704
+ const receipt = await f.complete();
1705
+ const prepared = await f.prepare(receipt);
1706
+ const effect = executeCompletedEnvelope(prepared);
1707
+ await entered.promise;
1708
+ eligible = false;
1709
+ f.controller.abort(new Error("Original worker stopped after invocation"));
1710
+ let stopped = false;
1711
+ const stopping = f.conversation.cancel().then(result => { stopped = true; return result; });
1712
+ await Promise.resolve();
1713
+ assert.equal(stopped, false, "Stop joins the existing serial effect owner");
1714
+ released.resolve();
1715
+ const result = await effect;
1716
+ await stopping;
1717
+ assert.equal(result.ok, true);
1718
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1719
+ assert.equal(saved.metadata.applicationTools[0].status, "complete");
1720
+ assert.deepEqual(saved.metadata.applicationTools[0].result, result);
1721
+ assert.equal(f.effects(), 1, "Revoked invocation authority does not discard the original result receipt");
1722
+ } finally { released.resolve(); eligible = true; await f.close(); }
1723
+ });
1724
+
1725
+ function completedEnvelopeStorageFault(control) {
1726
+ return storage => ({ ...storage, write: (id, callback) => storage.write(id, transaction => callback({ ...transaction,
1727
+ async updateTurnMetadata(turnId, metadata) {
1728
+ if (metadata.applicationTools?.[0]?.status === control.status && control.fail) {
1729
+ control.fail = false;
1730
+ throw new Error("Completed application receipt storage offline");
1731
+ }
1732
+ return transaction.updateTurnMetadata(turnId, metadata);
1733
+ }
1734
+ })) });
1735
+ }
1736
+
1737
+ test("completed Claude reservation failure executes nothing and installs no result-save retry", async t => {
1738
+ const fault = { status: "running", fail: true };
1739
+ const f = await completedEnvelopeFixture(t, { wrapStorage: completedEnvelopeStorageFault(fault) });
1740
+ try {
1741
+ const receipt = await f.complete();
1742
+ const prepared = await f.prepare(receipt);
1743
+ await assert.rejects(executeCompletedEnvelope(prepared), /receipt storage offline/);
1744
+ assert.equal(f.effects(), 0);
1745
+ assert.deepEqual(await f.conversation.retrySave(), { saved: false });
1746
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.applicationTools?.length || 0, 0);
1747
+ assert.equal((await executeCompletedEnvelope(prepared)).ok, true);
1748
+ assert.equal(f.effects(), 1);
1749
+ } finally { await f.close(); }
1750
+ });
1751
+
1752
+ test("completed Claude result-save retry preserves the exact original result without re-execution", async t => {
1753
+ const fault = { status: "complete", fail: true };
1754
+ const f = await completedEnvelopeFixture(t, { wrapStorage: completedEnvelopeStorageFault(fault) });
1755
+ try {
1756
+ const receipt = await f.complete();
1757
+ const prepared = await f.prepare(receipt);
1758
+ await assert.rejects(executeCompletedEnvelope(prepared), /receipt storage offline/);
1759
+ assert.equal(f.effects(), 1);
1760
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.applicationTools[0].status, "running");
1761
+ await assert.rejects(executeCompletedEnvelope(prepared), error => error.code === "conversation_storage_unavailable");
1762
+ assert.deepEqual(await f.conversation.retrySave(), { saved: true });
1763
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1764
+ assert.equal(saved.metadata.applicationTools[0].status, "complete");
1765
+ assert.deepEqual(await executeCompletedEnvelope(prepared), saved.metadata.applicationTools[0].result);
1766
+ assert.equal(f.effects(), 1);
1767
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
1768
+ } finally { await f.close(); }
1769
+ });
1770
+
1771
+ test("completed Claude external account changes refuse repeatedly without fingerprint promotion", async t => {
1772
+ let apiKey = "completed-old-fixture-key";
1773
+ const f = await completedEnvelopeFixture(t, { configuration: { integrationId: "foreign", model: undefined, effort: "low" },
1774
+ connections: { resolve: async () => ({ providerId: "deepseek", model: "deepseek-flash", apiKey }) } });
1775
+ try {
1776
+ const receipt = await f.complete();
1777
+ const before = await f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding);
1778
+ apiKey = "completed-replaced-fixture-key";
1779
+ for (let attempt = 0; attempt < 2; attempt++) {
1780
+ await assert.rejects(f.prepare(receipt), /different account or provider connection/);
1781
+ assert.deepEqual(await f.storage.read("conversation", async tx => (await tx.readMetadata()).runtime.binding), before);
1782
+ }
1783
+ assert.equal(f.effects(), 0);
1784
+ assert.equal((await f.trace()).filter(row => row.frame?.request?.subtype === "interrupt").length, 0,
1785
+ "Completion inspection cannot stop/promote the old native binding");
1786
+ } finally { await f.close(); }
1787
+ });
1788
+
1789
+ test("completed Claude account inspection never creates a missing historical fingerprint", async t => {
1790
+ const f = await completedEnvelopeFixture(t);
1791
+ try {
1792
+ const receipt = await f.complete();
1793
+ await f.storage.write("conversation", async tx => {
1794
+ const metadata = await tx.readMetadata();
1795
+ delete metadata.runtime.binding.accountIdentity;
1796
+ await tx.writeMetadata(metadata);
1797
+ });
1798
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
1799
+ await assert.rejects(f.prepare(receipt), /no saved native account fingerprint/);
1800
+ assert.deepEqual(await f.storage.read("conversation", tx => tx.readMetadata()), before);
1801
+ await f.storage.write("conversation", async tx => {
1802
+ const metadata = await tx.readMetadata();
1803
+ metadata.runtime.binding.accountIdentity = "different-persisted-fixture-fingerprint";
1804
+ await tx.writeMetadata(metadata);
1805
+ });
1806
+ const mismatched = await f.storage.read("conversation", tx => tx.readMetadata());
1807
+ for (let attempt = 0; attempt < 2; attempt++) {
1808
+ await assert.rejects(f.prepare(receipt), /no longer matches its saved account fingerprint/);
1809
+ assert.deepEqual(await f.storage.read("conversation", tx => tx.readMetadata()), mismatched);
1810
+ }
1811
+ assert.equal(f.effects(), 0);
1812
+ } finally { await f.close(); }
1813
+ });
1814
+
1815
+ test("completed Claude envelopes refuse unmarked history and caller-supplied markers preserve ordinary tool policy", async t => {
1816
+ const f = await completedEnvelopeFixture(t);
1817
+ try {
1818
+ const receipt = await f.complete();
1819
+ await f.storage.write("conversation", async tx => {
1820
+ const turn = await tx.readTurn(receipt.turnId);
1821
+ const runtime = { ...turn.metadata.runtime };
1822
+ delete runtime.completedEnvelope;
1823
+ await tx.updateTurnMetadata(receipt.turnId, { runtime });
1824
+ });
1825
+ await assert.rejects(f.prepare(receipt), /no current verified receipt/);
1826
+ const ordinary = await f.conversation.send({ messageId: "ordinary-user", text: "tools", data: { completedEnvelope: true } });
1827
+ const state = await f.conversation.wait();
1828
+ const turn = state.conversationLog.find(row => row.turnId === ordinary.turnId);
1829
+ assert.equal(turn.metadata.runtime.completedEnvelope, undefined);
1830
+ assert.equal(turn.metadata.runtime.status, "complete", state.error);
1831
+ assert.deepEqual(turn.user.data, { completedEnvelope: true });
1832
+ const trace = await f.trace();
1833
+ const forged = trace.filter(row => row.frame?.type === "user").at(-1).frame.message.content;
1834
+ const forgedText = typeof forged === "string" ? forged : forged.filter(part => part.type === "text").map(part => part.text).join(" ");
1835
+ assert.match(forgedText, /\[Application data\]/);
1836
+ assert.match(forgedText, /"completedEnvelope":true/);
1837
+ assert.equal(f.effects(), 0, "Wrapped data is not the original fixture's exact tools trigger");
1838
+ await assert.rejects(f.prepare({ messageId: "ordinary-user", turnId: ordinary.turnId }), /no current verified receipt/);
1839
+ const plain = await f.conversation.send({ messageId: "ordinary-tools", text: "tools" });
1840
+ const final = await f.conversation.wait();
1841
+ const plainTurn = final.conversationLog.find(row => row.turnId === plain.turnId);
1842
+ assert.equal(plainTurn.metadata.runtime.completedEnvelope, undefined);
1843
+ assert.equal(plainTurn.metadata.runtime.status, "complete", final.error);
1844
+ assert.equal(plainTurn.metadata.applicationTools.length, 3, "Ordinary native discovery remains enabled in the opt-in runtime");
1845
+ assert.equal(f.effects(), 1);
1846
+ await assert.rejects(f.prepare({ messageId: "ordinary-tools", turnId: plain.turnId }), /no current verified receipt/);
1847
+ const starts = (await f.trace()).filter(row => row.args?.includes("--print"));
1848
+ assert.equal(starts.length, 2, "The existing comparator resumes once when application MCP availability changes");
1849
+ assert.deepEqual(JSON.parse(starts[0].args.at(starts[0].args.indexOf("--mcp-config") + 1)), { mcpServers: {} });
1850
+ assert.deepEqual(JSON.parse(starts[1].args.at(starts[1].args.indexOf("--mcp-config") + 1)), {
1851
+ mcpServers: { application: { type: "sdk", name: "application" } }
1852
+ });
1853
+ } finally { await f.close(); }
1854
+ });
1855
+
1856
+ test("completed Claude envelopes refuse successors, active native work and foreign binding custody", async t => {
1857
+ const f = await completedEnvelopeFixture(t);
1858
+ try {
1859
+ const old = await f.complete("older-response");
1860
+ const prepared = await f.prepare(old);
1861
+ const current = await f.complete("newer-response");
1862
+ await assert.rejects(executeCompletedEnvelope(prepared), /newer completed response/);
1863
+ const currentPrepared = await f.prepare(current);
1864
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
1865
+ await f.storage.write("conversation", tx => tx.writeMetadata({ ...before,
1866
+ runtime: { ...before.runtime, binding: { ...before.runtime.binding, conversationId: "foreign-native-session" } } }));
1867
+ await assert.rejects(f.prepare(current), /different native conversation or host scope/,
1868
+ "Initial inspection cannot authorize a changed canonical conversation using a cached native entry");
1869
+ await assert.rejects(executeCompletedEnvelope(currentPrepared));
1870
+ await f.storage.write("conversation", tx => tx.writeMetadata(before));
1871
+ await f.conversation.wake({ messageId: "active-response", text: "wait" });
1872
+ await assert.rejects(f.prepare(current), error => error.code === "conversation_busy");
1873
+ await f.conversation.cancel();
1874
+ await f.storage.write("conversation", async tx => {
1875
+ const metadata = await tx.readMetadata();
1876
+ metadata.runtime.request = { messageId: "new-pending-response", origin: "application", text: "Pending",
1877
+ at: new Date().toISOString(), attempted: false, completedEnvelope: true };
1878
+ await tx.writeMetadata(metadata);
1879
+ });
1880
+ await assert.rejects(f.prepare(current), /no current verified receipt/);
1881
+ assert.equal(f.effects(), 0);
1882
+ } finally { await f.close(); }
1883
+ });
1884
+
1885
+ test("completed Claude envelopes never backfill an old unmarked application reservation", async t => {
1886
+ const f = await completedEnvelopeFixture(t);
1887
+ try {
1888
+ await f.storage.write("conversation", async tx => {
1889
+ const metadata = await tx.readMetadata();
1890
+ metadata.runtime.request = { messageId: "old-unmarked", text: "Read a number", origin: "application",
1891
+ attachments: [], at: new Date().toISOString(), attempted: false };
1892
+ await tx.writeMetadata(metadata);
1893
+ });
1894
+ const receipt = await f.conversation.wake({ messageId: "old-unmarked", text: "Read a number", data: undefined });
1895
+ const state = await f.conversation.wait();
1896
+ const turn = state.conversationLog.find(row => row.turnId === receipt.turnId);
1897
+ assert.equal(turn.metadata.runtime.status, "complete", state.error);
1898
+ assert.equal(turn.metadata.runtime.completedEnvelope, undefined);
1899
+ await assert.rejects(f.prepare({ messageId: "old-unmarked", turnId: receipt.turnId, completedEnvelope: true }), /no current verified receipt/);
1900
+ assert.equal(f.effects(), 0);
1901
+ } finally { await f.close(); }
1902
+ });
1903
+
1904
+ test("completed Claude effect-boundary revocation records a verified not-executed result", async t => {
1905
+ let eligible = true;
1906
+ let revoke = false;
1907
+ const f = await completedEnvelopeFixture(t, {
1908
+ authorize: ({ operation }) => operation !== "tool" || eligible,
1909
+ wrapStorage: storage => ({ ...storage, write: (id, callback) => storage.write(id, transaction => callback({ ...transaction,
1910
+ async updateTurnMetadata(turnId, metadata) {
1911
+ await transaction.updateTurnMetadata(turnId, metadata);
1912
+ if (revoke && metadata.applicationTools?.[0]?.status === "running") eligible = false;
1913
+ }
1914
+ })) })
1915
+ });
1916
+ try {
1917
+ const receipt = await f.complete();
1918
+ const prepared = await f.prepare(receipt);
1919
+ revoke = true;
1920
+ await assert.rejects(executeCompletedEnvelope(prepared), error => error.code === "conversation_forbidden");
1921
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1922
+ assert.equal(saved.metadata.applicationTools[0].status, "not-executed");
1923
+ assert.equal(saved.metadata.applicationTools[0].result.error.code, "conversation_tool_not_executed");
1924
+ eligible = true;
1925
+ const result = await executeCompletedEnvelope(prepared);
1926
+ assert.deepEqual(result, saved.metadata.applicationTools[0].result);
1927
+ assert.equal(f.effects(), 0, "A saved non-effect receipt also deduplicates without execution");
1928
+ } finally { eligible = true; await f.close(); }
1929
+ });
1930
+
1931
+ test("completed Claude custody retains logical binding while existing process references refresh", async t => {
1932
+ const f = await completedEnvelopeFixture(t);
1933
+ try {
1934
+ const receipt = await f.complete();
1935
+ const prepared = await f.prepare(receipt);
1936
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
1937
+ await f.storage.write("conversation", tx => tx.writeMetadata({ ...before,
1938
+ runtime: { ...before.runtime, binding: { ...before.runtime.binding, executionId: "", processDirectory: "" } } }));
1939
+ try {
1940
+ assert.equal((await executeCompletedEnvelope(prepared)).ok, true);
1941
+ assert.equal(f.effects(), 1);
1942
+ const after = await f.storage.read("conversation", tx => tx.readMetadata());
1943
+ const persistent = ({ executionId, processDirectory, ...binding }) => binding;
1944
+ assert.deepEqual(persistent(after.runtime.binding), persistent(before.runtime.binding));
1945
+ } finally {
1946
+ await f.storage.write("conversation", async tx => {
1947
+ const current = await tx.readMetadata();
1948
+ current.runtime.binding = before.runtime.binding;
1949
+ await tx.writeMetadata(current);
1950
+ });
1951
+ }
1952
+ } finally { await f.close(); }
1953
+ });
1954
+
1955
+ test("completed Claude unknown application outcomes never replay after the actual action fails", async t => {
1956
+ const f = await completedEnvelopeFixture(t, { execute() { throw new Error("Actual application operation failed"); } });
1957
+ try {
1958
+ const receipt = await f.complete();
1959
+ const first = await f.prepare(receipt);
1960
+ const second = await f.prepare(receipt);
1961
+ await assert.rejects(executeCompletedEnvelope(first), error => error.code === "conversation_tool_outcome_unknown");
1962
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1963
+ assert.equal(saved.metadata.applicationTools[0].status, "unknown");
1964
+ assert.equal(saved.metadata.applicationTools[0].result.ok, false);
1965
+ assert.ok(saved.metadata.applicationTools[0].result.error.status >= 500);
1966
+ await assert.rejects(executeCompletedEnvelope(second), error => error.code === "conversation_tool_outcome_unknown");
1967
+ await f.reopen();
1968
+ await assert.rejects(executeCompletedEnvelope(await f.prepare(receipt)), error => error.code === "conversation_tool_outcome_unknown");
1969
+ assert.equal(f.effects(), 1);
1970
+ } finally { await f.close(); }
1971
+ });
1972
+
1973
+ test("completed Claude saved running application custody refuses an unconfirmed effect", async t => {
1974
+ const f = await completedEnvelopeFixture(t);
1975
+ try {
1976
+ const receipt = await f.complete();
1977
+ const prepared = await f.prepare(receipt);
1978
+ await f.storage.write("conversation", tx => tx.updateTurnMetadata(receipt.turnId, { applicationTools: [{
1979
+ id: prepared.toolCallId, name: "numbers_read", arguments: "{}", status: "running", at: new Date().toISOString()
1980
+ }] }));
1981
+ await assert.rejects(executeCompletedEnvelope(prepared), error => error.code === "conversation_tool_outcome_unknown");
1982
+ assert.equal(f.effects(), 0);
1983
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.applicationTools[0].status, "running");
1984
+ } finally { await f.close(); }
1985
+ });
1986
+
1987
+
1988
+ for (const name of ["numbers_read", "mcp__application__numbers_read", "StructuredOutput", "unrelated_native_tool"]) {
1989
+ test(`completed Claude native-tool tracking classifies the authorized name ${name} without publishing its arguments`, async t => {
1990
+ const privateArgument = "native-tool-private-argument-must-not-leak";
1991
+ const f = await completedEnvelopeFixture(t, { nativeToolUse: { name, input: { privateArgument } } });
1992
+ const events = [];
1993
+ await f.conversation.subscribe(event => events.push(event));
1994
+ try {
1995
+ const receipt = await f.complete();
1996
+ const expected = name === "numbers_read" || name === "mcp__application__numbers_read";
1997
+ assert.equal((await f.prepare(receipt)).nativeToolAttempt, expected);
1998
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
1999
+ assert.equal(saved.metadata.runtime.nativeToolAttempt, expected);
2000
+ assert.equal(saved.metadata.applicationTools, undefined, "Observing a native attempt does not execute an application action");
2001
+ assert.equal(f.effects(), 0);
2002
+ assert.equal(events.some(event => event.type === "provider-event"), false);
2003
+ assert.equal(JSON.stringify(events).includes(privateArgument), false);
2004
+ assert.equal(JSON.stringify(saved).includes(privateArgument), false);
2005
+ await f.reopen();
2006
+ assert.equal((await f.prepare(receipt)).nativeToolAttempt, expected, "A restart retains actual tracking evidence");
2007
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2008
+ } finally { await f.close(); }
2009
+ });
2010
+ }
2011
+
2012
+ test("completed Claude native-tool tracking refuses an older marked reservation with unknown evidence", async t => {
2013
+ const f = await completedEnvelopeFixture(t);
2014
+ try {
2015
+ await f.storage.write("conversation", async tx => {
2016
+ const metadata = await tx.readMetadata();
2017
+ metadata.runtime.request = { messageId: "old-marked-unknown", text: "Read a number", origin: "application",
2018
+ attachments: [], at: new Date().toISOString(), attempted: false, completedEnvelope: true };
2019
+ await tx.writeMetadata(metadata);
2020
+ });
2021
+ const receipt = await f.complete("old-marked-unknown");
2022
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2023
+ assert.equal(saved.metadata.runtime.nativeToolAttempt, undefined);
2024
+ await assert.rejects(f.prepare(receipt), /no native tool-attempt evidence/);
2025
+ await f.reopen();
2026
+ await assert.rejects(f.prepare(receipt), /no native tool-attempt evidence/);
2027
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.runtime.nativeToolAttempt, undefined);
2028
+ assert.equal(f.effects(), 0);
2029
+ } finally { await f.close(); }
2030
+ });
2031
+
2032
+ test("completed Claude native-tool tracking refuses lost evidence on an already completed receipt", async t => {
2033
+ const f = await completedEnvelopeFixture(t);
2034
+ try {
2035
+ const receipt = await f.complete();
2036
+ const prepared = await f.prepare(receipt);
2037
+ await f.storage.write("conversation", async tx => {
2038
+ const turn = await tx.readTurn(receipt.turnId);
2039
+ delete turn.metadata.runtime.nativeToolAttempt;
2040
+ await tx.updateTurnMetadata(receipt.turnId, { runtime: turn.metadata.runtime });
2041
+ });
2042
+ await assert.rejects(f.prepare(receipt), /no native tool-attempt evidence/);
2043
+ await assert.rejects(executeCompletedEnvelope(prepared), /no native tool-attempt evidence/);
2044
+ assert.equal(f.effects(), 0);
2045
+ } finally { await f.close(); }
2046
+ });
2047
+
2048
+ test("completed Claude native-tool tracking refuses marked and mixed steering before reserving a successor", async t => {
2049
+ const waitEvent = conversationRequestText({ text: "wait", origin: "application" });
2050
+ const f = await completedEnvelopeFixture(t, { applicationEventBehavior: { wait: waitEvent } });
2051
+ try {
2052
+ const marked = await f.conversation.wake({ messageId: "marked-working", text: "wait" });
2053
+ assert.equal((await f.conversation.read()).status, "working", "The exact application wait frame genuinely holds the native turn");
2054
+ const markedTurn = await f.storage.read("conversation", tx => tx.readTurn(marked.turnId));
2055
+ assert.equal(markedTurn.metadata.runtime.status, "running");
2056
+ assert.equal(markedTurn.assistant, null);
2057
+ assert.equal((await f.trace()).find(row => row.frame?.type === "user").frame.message.content, waitEvent);
2058
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2059
+ await assert.rejects(f.conversation.send({ messageId: "ordinary-steer", text: "Different instruction", steer: true }),
2060
+ error => error.code === "conversation_not_steerable");
2061
+ await assert.rejects(f.conversation.wake({ messageId: "marked-steer", text: "Different application instruction", steer: true }),
2062
+ error => error.code === "conversation_not_steerable");
2063
+ const after = await f.storage.read("conversation", tx => tx.readMetadata());
2064
+ assert.deepEqual(after.runtime.request, before.runtime.request);
2065
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2066
+ assert.equal((await f.trace()).filter(row => row.frame?.request?.subtype === "interrupt").length, 0);
2067
+ await f.conversation.cancel();
2068
+ const ordinaryReceipt = await f.conversation.send({ messageId: "ordinary-working", text: "wait" });
2069
+ assert.equal((await f.conversation.read()).status, "working");
2070
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(ordinaryReceipt.turnId))).metadata.runtime.status, "running");
2071
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").at(-1).frame.message.content, "wait");
2072
+ const ordinary = await f.storage.read("conversation", tx => tx.readMetadata());
2073
+ await assert.rejects(f.conversation.wake({ messageId: "mixed-marked", text: "New application response", steer: true }),
2074
+ error => error.code === "conversation_not_steerable");
2075
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.request, ordinary.runtime.request);
2076
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 2);
2077
+ assert.equal(f.effects(), 0);
2078
+ await f.conversation.cancel();
2079
+ } finally { await f.close(); }
2080
+ });
2081
+
2082
+ test("completed Claude native-tool tracking refuses steering a retained marked unconfirmed delivery", async t => {
2083
+ const lostEvent = conversationRequestText({ text: "lost", origin: "application" });
2084
+ const f = await completedEnvelopeFixture(t, { applicationEventBehavior: { lost: lostEvent } });
2085
+ try {
2086
+ await assert.rejects(f.conversation.wake({ messageId: "retained-marked", text: "lost" }), /not acknowledged/);
2087
+ assert.equal((await f.conversation.wait()).status, "unconfirmed");
2088
+ assert.equal((await f.trace()).find(row => row.frame?.type === "user").frame.message.content, lostEvent);
2089
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2090
+ assert.equal(before.runtime.request.completedEnvelope, true);
2091
+ assert.equal(before.runtime.request.attempted, true);
2092
+ await assert.rejects(f.conversation.send({ messageId: "retained-mixed-steer", text: "New instruction", steer: true }),
2093
+ error => error.code === "conversation_not_steerable");
2094
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.request, before.runtime.request);
2095
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2096
+ assert.equal(f.effects(), 0);
2097
+ } finally { await f.close(); }
2098
+ });
2099
+
2100
+ test("completed Claude native-tool tracking preserves ordinary native steering in the opted runtime", async t => {
2101
+ const f = await completedEnvelopeFixture(t);
2102
+ const progress = Promise.withResolvers();
2103
+ await f.conversation.subscribe(event => {
2104
+ if (event.type === "message" && event.text === "Initial progress") progress.resolve();
2105
+ });
2106
+ try {
2107
+ await f.conversation.send({ messageId: "ordinary-before", text: "steering" });
2108
+ await progress.promise;
2109
+ await f.conversation.send({ messageId: "ordinary-after", text: "Continue differently", steer: true });
2110
+ const state = await f.conversation.wait();
2111
+ assert.equal(state.error, "");
2112
+ assert.equal(state.conversationLog.length, 2);
2113
+ assert.equal(state.conversationLog[0].assistant.text, "Initial progress");
2114
+ assert.equal(state.conversationLog[1].assistant.text, JSON.stringify(completedEnvelopeValue));
2115
+ for (const turn of state.conversationLog) {
2116
+ assert.equal(turn.metadata.runtime.completedEnvelope, undefined);
2117
+ assert.equal(turn.metadata.runtime.nativeToolAttempt, undefined);
2118
+ }
2119
+ const trace = await f.trace();
2120
+ assert.equal(trace.filter(row => row.args?.includes("--print")).length, 1);
2121
+ assert.equal(trace.filter(row => row.frame?.type === "user").length, 2);
2122
+ assert.equal(trace.filter(row => row.frame?.request?.subtype === "interrupt").length, 1);
2123
+ assert.equal(f.effects(), 0);
2124
+ } finally { await f.close(); }
2125
+ });
2126
+
2127
+
2128
+ test("completed Claude native-tool tracking excludes nested-agent frames at the original receive owner", async t => {
2129
+ const privateArgument = "nested-tool-argument-must-not-leak";
2130
+ const f = await completedEnvelopeFixture(t, { nativeToolUse: { name: "mcp__application__numbers_read",
2131
+ input: { privateArgument }, parentToolUseId: "parent-native-tool" } });
2132
+ const events = [];
2133
+ await f.conversation.subscribe(event => events.push(event));
2134
+ try {
2135
+ const receipt = await f.complete();
2136
+ assert.equal((await f.prepare(receipt)).nativeToolAttempt, false);
2137
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2138
+ assert.equal(saved.metadata.runtime.nativeToolAttempt, false);
2139
+ assert.equal(JSON.stringify(events).includes(privateArgument), false);
2140
+ assert.equal(JSON.stringify(saved).includes(privateArgument), false);
2141
+ assert.equal(f.effects(), 0);
2142
+ } finally { await f.close(); }
2143
+ });
2144
+
2145
+ test("completed Claude native-tool tracking propagates its receipt write failure before effect preparation", async t => {
2146
+ let attempts = 0;
2147
+ const f = await completedEnvelopeFixture(t, { nativeToolUse: { name: "numbers_read", input: {} },
2148
+ wrapStorage: storage => ({ ...storage, write: (id, callback) => storage.write(id, transaction => callback({ ...transaction,
2149
+ async updateTurnMetadata(turnId, metadata) {
2150
+ if (metadata.runtime?.nativeToolAttempt === true) {
2151
+ attempts++;
2152
+ throw new Error("Native attempt persistence failed");
2153
+ }
2154
+ return transaction.updateTurnMetadata(turnId, metadata);
2155
+ }
2156
+ })) }) });
2157
+ const events = [];
2158
+ await f.conversation.subscribe(event => events.push(event));
2159
+ try {
2160
+ const receipt = await f.conversation.wake({ messageId: "native-attempt-write-failure", text: "Read a number" });
2161
+ const state = await f.conversation.wait();
2162
+ assert.equal(state.error, "Native attempt persistence failed");
2163
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2164
+ assert.equal(saved.metadata.runtime.status, "interrupted", "Original native failure cleanup stops the admitted turn before rejecting completion");
2165
+ assert.equal(saved.metadata.runtime.error, "Native attempt persistence failed");
2166
+ assert.equal(saved.assistant, null);
2167
+ const settled = events.filter(event => event.type === "settled").at(-1);
2168
+ assert.equal(settled.status, "interrupted");
2169
+ assert.equal(settled.error, "Native attempt persistence failed");
2170
+ assert.equal((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.binding.executionId, "");
2171
+ assert.equal(saved.metadata.runtime.nativeToolAttempt, false);
2172
+ assert.equal(attempts, 1, "The awaited native callback does not swallow or repeat a failed receipt write");
2173
+ await assert.rejects(f.prepare({ messageId: receipt.messageId, turnId: receipt.turnId }),
2174
+ error => error.code === "conversation_completed_response_unavailable");
2175
+ assert.equal(f.effects(), 0);
2176
+ } finally { await f.close(); }
2177
+ });
2178
+
2179
+ test("completed Claude native-tool tracking is part of the prepared immutable response identity", async t => {
2180
+ const f = await completedEnvelopeFixture(t);
2181
+ try {
2182
+ const receipt = await f.complete();
2183
+ const prepared = await f.prepare(receipt);
2184
+ assert.equal(prepared.nativeToolAttempt, false);
2185
+ await f.storage.write("conversation", async tx => {
2186
+ const turn = await tx.readTurn(receipt.turnId);
2187
+ await tx.updateTurnMetadata(receipt.turnId, { runtime: { ...turn.metadata.runtime, nativeToolAttempt: true } });
2188
+ });
2189
+ await assert.rejects(executeCompletedEnvelope(prepared), /completed response identity changed/);
2190
+ assert.equal(f.effects(), 0);
2191
+ } finally { await f.close(); }
2192
+ });
2193
+
2194
+
2195
+ test("completed Claude presentation pages hide internal carriers while preserving raw completion and current errors", async t => {
2196
+ const f = await completedEnvelopeFixture(t);
2197
+ try {
2198
+ await f.storage.write("conversation", tx => tx.appendMessage("000001", {
2199
+ role: "user", messageId: "product-a", text: "Visible A", at: "2026-10-10T00:00:00.000Z"
2200
+ }));
2201
+ const first = await f.complete("internal-a");
2202
+ await f.storage.write("conversation", tx => tx.appendMessage("000003", {
2203
+ role: "user", messageId: "product-b", text: "Visible B", at: "2026-10-10T00:00:01.000Z"
2204
+ }));
2205
+ const last = await f.complete("internal-b");
2206
+ const all = await f.conversation.read();
2207
+ assert.equal(all.status, "ready");
2208
+ assert.deepEqual(all.conversationLog.map(turn => turn.user.text), ["Visible A", "Visible B"]);
2209
+ const page = await f.conversation.read({ limit: 1, presentation: false });
2210
+ assert.deepEqual(page.conversationLog.map(turn => turn.turnId), ["000003"]);
2211
+ assert.equal(page.pagination.totalTurnCount, 2);
2212
+ assert.equal(page.pagination.count, 1);
2213
+ assert.equal(page.pagination.hasMoreBefore, true);
2214
+ assert.equal(page.pagination.nextBeforeTurnId, "000003");
2215
+ const older = await f.conversation.read({ limit: 1, beforeTurnId: page.pagination.nextBeforeTurnId });
2216
+ assert.deepEqual(older.conversationLog.map(turn => turn.turnId), ["000001"]);
2217
+ assert.equal(older.pagination.hasMoreBefore, false);
2218
+ await f.storage.write("conversation", async tx => {
2219
+ const turn = await tx.readTurn(last.turnId);
2220
+ await tx.updateTurnMetadata(last.turnId, { runtime: { ...turn.metadata.runtime, error: "Exact private completion error" } });
2221
+ });
2222
+ assert.equal((await f.conversation.read({ limit: 1, beforeTurnId: "000003" })).error, "Exact private completion error");
2223
+ for (const receipt of [first, last]) {
2224
+ const raw = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2225
+ assert.equal(raw.metadata.runtime.status, "complete");
2226
+ assert.equal(raw.metadata.runtime.completedEnvelope, true);
2227
+ assert.equal(raw.assistant.text, JSON.stringify(completedEnvelopeValue));
2228
+ }
2229
+ assert.equal((await f.storage.read("conversation", tx => tx.listTurnIds())).length, 4);
2230
+ assert.equal(f.effects(), 0);
2231
+ } finally { await f.close(); }
2232
+ });
2233
+
2234
+ test("completed Claude wake exclusions retain all product fingerprints only after the actual internal admission", async t => {
2235
+ const f = await completedEnvelopeFixture(t);
2236
+ try {
2237
+ await f.storage.write("conversation", async tx => {
2238
+ for (const [turnId, messageId, text] of [["000001", "batch-a", "Product A"], ["000002", "batch-b", "Product B"]]) {
2239
+ await tx.appendMessage(turnId, { role: "user", messageId, text, at: "2026-10-10T00:00:00.000Z" });
2240
+ }
2241
+ });
2242
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, {});
2243
+ const receipt = await f.conversation.wake({ messageId: "internal-batch", text: "Read a number" },
2244
+ { excludedMessageIds: ["batch-a", "batch-b"] });
2245
+ const state = await f.conversation.wait();
2246
+ assert.equal(state.status, "ready");
2247
+ assert.deepEqual(state.conversationLog.map(turn => turn.user.messageId), ["batch-a", "batch-b"]);
2248
+ const { claudeNativeMessageId } = await import("../src/server/conversation/claudeTurn.js");
2249
+ const nativeMessageId = claudeNativeMessageId(receipt.messageId);
2250
+ const frames = (await f.trace()).filter(row => row.frame?.type === "user" && row.frame.uuid === nativeMessageId);
2251
+ assert.equal(frames.length, 1, "The original Claude ID mapper identifies exactly one actual admitted native input");
2252
+ const frame = frames[0].frame;
2253
+ assert.equal(frame.uuid, nativeMessageId);
2254
+ assert.doesNotMatch(frame.message.content, /Product A|Product B/);
2255
+ const { runtime } = await f.storage.read("conversation", tx => tx.readMetadata());
2256
+ assert.ok(runtime.seen["000001/user/"]);
2257
+ assert.ok(runtime.seen["000002/user/"]);
2258
+ assert.equal(runtime.request, undefined);
2259
+ const internal = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2260
+ assert.equal(internal.system.messageId, "internal-batch");
2261
+ assert.equal(internal.metadata.runtime.completedEnvelope, true);
2262
+ assert.equal(internal.metadata.runtime.excludedMessageIds, undefined, "The capture belongs to the private pending request, not a permanent receipt promotion");
2263
+ assert.equal(internal.system.data, undefined);
2264
+ assert.equal(f.effects(), 0);
2265
+ } finally { await f.close(); }
2266
+ });
2267
+
2268
+ test("completed Claude retained wake exclusions cannot change on a same-ID retry or backfill old reservations", async t => {
2269
+ const lostEvent = conversationRequestText({ text: "lost", origin: "application" });
2270
+ const f = await completedEnvelopeFixture(t, { applicationEventBehavior: { lost: lostEvent } });
2271
+ try {
2272
+ const options = { excludedMessageIds: ["batch-a"] };
2273
+ await assert.rejects(f.conversation.wake({ messageId: "lost-exclusions", text: "lost" }, options), /not acknowledged/);
2274
+ options.excludedMessageIds.push("batch-b");
2275
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2276
+ assert.deepEqual(before.runtime.request.excludedMessageIds, ["batch-a"]);
2277
+ assert.equal(before.runtime.request.attempted, true);
2278
+ assert.deepEqual(before.runtime.seen, {});
2279
+ const visible = await f.conversation.read();
2280
+ assert.equal(visible.status, "unconfirmed");
2281
+ assert.equal(visible.pendingRequest, null);
2282
+ assert.deepEqual(visible.conversationLog, []);
2283
+ await f.reopen();
2284
+ const retained = await f.storage.read("conversation", tx => tx.readMetadata());
2285
+ assert.deepEqual(retained.runtime.request.excludedMessageIds, before.runtime.request.excludedMessageIds);
2286
+ assert.deepEqual(retained.runtime.request.seen, before.runtime.request.seen);
2287
+ assert.equal(retained.runtime.request.message, before.runtime.request.message);
2288
+ await assert.rejects(f.conversation.wake({ messageId: "lost-exclusions", text: "lost" }, options),
2289
+ error => error.code === "conversation_message_conflict");
2290
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.request, retained.runtime.request);
2291
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2292
+ await assert.rejects(f.conversation.wake({ messageId: "different-exclusions", text: "Read a number" }, { excludedMessageIds: ["batch-a"] }),
2293
+ error => ["conversation_delivery_uncertain", "conversation_not_steerable"].includes(error.code));
2294
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.request, retained.runtime.request);
2295
+ await f.storage.write("conversation", async tx => {
2296
+ const metadata = await tx.readMetadata();
2297
+ metadata.runtime.request = { messageId: "old-exclusions", origin: "application", text: "Read a number", attachments: [],
2298
+ at: "2026-10-10T00:00:00.000Z", attempted: false };
2299
+ await tx.writeMetadata(metadata);
2300
+ });
2301
+ const old = await f.storage.read("conversation", tx => tx.readMetadata());
2302
+ await assert.rejects(f.conversation.wake({ messageId: "old-exclusions", text: "Read a number" }, { excludedMessageIds: ["batch-a"] }),
2303
+ error => error.code === "conversation_message_conflict");
2304
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.request, old.runtime.request);
2305
+ assert.equal(f.effects(), 0);
2306
+ } finally { await f.close(); }
2307
+ });
2308
+
2309
+
2310
+ test("completed Claude subscribers keep trusted raw carriers while human reads omit private streams and pending input", async t => {
2311
+ const f = await completedEnvelopeFixture(t);
2312
+ const events = [];
2313
+ const observations = [];
2314
+ await f.conversation.subscribe(event => {
2315
+ events.push(event);
2316
+ if (event.type === "message" && event.completedEnvelope === true) observations.push(f.conversation.read());
2317
+ });
2318
+ try {
2319
+ const receipt = await f.complete();
2320
+ const raw = events.filter(event => event.type === "message" && event.status === "complete");
2321
+ assert.ok(raw.some(event => event.text === JSON.stringify(completedEnvelopeValue) && event.completedEnvelope === true));
2322
+ assert.ok(events.some(event => event.type === "message" && event.status === "inProgress" && event.completedEnvelope === true));
2323
+ assert.ok(observations.length);
2324
+ for (const state of await Promise.all(observations)) {
2325
+ assert.deepEqual(state.conversationLog, []);
2326
+ assert.equal(state.pendingRequest, null);
2327
+ assert.deepEqual(state.streaming.messages, []);
2328
+ }
2329
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).assistant.text,
2330
+ JSON.stringify(completedEnvelopeValue));
2331
+ await f.conversation.send({ messageId: "ordinary-data", text: "Hello", data: {
2332
+ completedEnvelope: true, excludedMessageIds: ["ordinary-data"]
2333
+ } });
2334
+ const ordinary = await f.conversation.wait();
2335
+ assert.equal(ordinary.conversationLog.length, 1);
2336
+ assert.equal(ordinary.conversationLog[0].metadata.runtime.completedEnvelope, undefined);
2337
+ assert.deepEqual(ordinary.conversationLog[0].user.data, { completedEnvelope: true, excludedMessageIds: ["ordinary-data"] });
2338
+ assert.ok(events.some(event => event.type === "message" && event.status === "complete" && event.completedEnvelope === undefined));
2339
+ assert.equal(f.effects(), 0);
2340
+ } finally { await f.close(); }
2341
+ });
2342
+
2343
+ test("completed Claude wake rejects invalid private exclusions without creating a native reservation", async t => {
2344
+ const f = await completedEnvelopeFixture(t);
2345
+ try {
2346
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2347
+ for (const excludedMessageIds of [null, [""], [" "], ["x".repeat(129)], ["duplicate", "duplicate"], [1]]) {
2348
+ await assert.rejects(f.conversation.wake({ messageId: "invalid-exclusions", text: "Read a number" }, { excludedMessageIds }),
2349
+ error => error.code === "conversation_invalid_message");
2350
+ assert.deepEqual(await f.storage.read("conversation", tx => tx.readMetadata()), before);
2351
+ }
2352
+ const trace = await f.trace().catch(error => { if (error.code === "ENOENT") return []; throw error; });
2353
+ assert.equal(trace.filter(row => row.frame?.type === "user").length, 0);
2354
+ assert.equal(f.effects(), 0);
2355
+ } finally { await f.close(); }
2356
+ });
2357
+
2358
+
2359
+ // A reply carrier uses the same original executable/native history fixture, not
2360
+ // a manufactured completion or a second product transcript implementation.
2361
+ async function completedReplyFixture(t, options = {}) {
2362
+ const value = { kind: "reply", text: " Verified plain reply. ", toolName: "", arguments: "" };
2363
+ const context = { actor: { id: "owner" }, surface: "app", permissions: ["numbers.read"] };
2364
+ let effects = 0;
2365
+ const actions = applicationActions(async () => { effects++; return { value: 42 }; });
2366
+ const f = await fixture(t, { ...options, context, actions, structuredResponse: value,
2367
+ configuration: { ...configuration, outputSchema: completedEnvelopeSchema } });
2368
+ await f.first.close();
2369
+ const { createConversationTranscript } = await import("../src/server/conversation/transcript.js");
2370
+ const transcript = createConversationTranscript({ storage: f.storage });
2371
+ let runtime;
2372
+ let conversation;
2373
+ async function reopen() {
2374
+ if (runtime) await runtime.close();
2375
+ runtime = createConversationRuntime({ engine: "claude", storage: f.storage, actions,
2376
+ authorize: options.authorize || (() => true), completedEnvelope: true, ...f.driverOptions });
2377
+ conversation = await runtime.open({ id: "conversation", context });
2378
+ }
2379
+ await reopen();
2380
+ const controller = new AbortController();
2381
+ return { ...f, transcript, value, controller, reopen, effects: () => effects,
2382
+ get conversation() { return conversation; }, close: () => runtime.close(),
2383
+ plain: (messageId, text = "Actual product user words") => transcript.writeConversationUserMessage("conversation", {
2384
+ messageId, text, data: { original: true }
2385
+ }),
2386
+ async complete(messageId = "completed-reply", excludedMessageIds = []) {
2387
+ const receipt = await conversation.wake({ messageId, text: "Give a reply" }, { excludedMessageIds });
2388
+ const state = await conversation.wait();
2389
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2390
+ assert.equal(saved.metadata.runtime.status, "complete", state.error);
2391
+ assert.equal(saved.metadata.runtime.completedEnvelope, true);
2392
+ assert.equal(saved.assistant.text, JSON.stringify(value));
2393
+ return { messageId, turnId: receipt.turnId };
2394
+ },
2395
+ prepare: receipt => conversation.prepareCompletedResponse(receipt, { signal: controller.signal }) };
2396
+ }
2397
+
2398
+ test("completed Claude prepared reply atomically publishes one plain final across handles and restart", async t => {
2399
+ const f = await completedReplyFixture(t);
2400
+ try {
2401
+ const plain = await f.plain("product-reply");
2402
+ const receipt = await f.complete("internal-reply", [plain.user.messageId]);
2403
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2404
+ const raw = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2405
+ const first = await f.prepare(receipt);
2406
+ const second = await f.prepare(receipt);
2407
+ first.text = JSON.stringify({ kind: "reply", text: "Caller supplied replacement" });
2408
+ const [one, two] = await Promise.all([first.publishReply({ turnId: plain.turnId }), second.publishReply({ turnId: plain.turnId })]);
2409
+ assert.deepEqual(two, one);
2410
+ assert.equal(one.assistant.text, "Verified plain reply.");
2411
+ assert.deepEqual(one.user, plain.user);
2412
+ assert.equal(one.metadata?.runtime?.engine, undefined);
2413
+ const { conversationMessageIdentity, conversationMessageVersion } = await import("../src/server/conversation/continuity.js");
2414
+ const identity = conversationMessageIdentity(plain.turnId, one.assistant);
2415
+ const after = await f.storage.read("conversation", tx => tx.readMetadata());
2416
+ assert.deepEqual(after.runtime.seen, { ...before.runtime.seen,
2417
+ [identity]: conversationMessageVersion(one.assistant, { includeData: true }) });
2418
+ const internal = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2419
+ assert.deepEqual(internal.assistant, raw.assistant);
2420
+ assert.deepEqual(internal.system, raw.system);
2421
+ assert.deepEqual(internal.metadata.runtime, { ...raw.metadata.runtime, publishedReplyTurnId: plain.turnId });
2422
+ assert.equal(internal.metadata.applicationTools, undefined);
2423
+ await assert.rejects(second.publishReply({ turnId: plain.turnId, text: "Untrusted text" }), TypeError);
2424
+ await f.reopen();
2425
+ assert.deepEqual(await (await f.prepare(receipt)).publishReply({ turnId: plain.turnId }), one);
2426
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, after.runtime.seen);
2427
+ assert.deepEqual((await f.conversation.read()).conversationLog.map(turn => turn.assistant?.text), ["Verified plain reply."]);
2428
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2429
+ assert.equal((await f.trace()).filter(row => row.args?.includes("--print")).length, 1);
2430
+ assert.equal(f.effects(), 0);
2431
+ } finally { await f.close(); }
2432
+ });
2433
+
2434
+ test("completed Claude prepared reply refuses foreign targets, existing finals and consumed identities", async t => {
2435
+ const f = await completedReplyFixture(t);
2436
+ try {
2437
+ const empty = await f.plain("empty-target");
2438
+ const populated = await f.plain("populated-target");
2439
+ await f.transcript.upsertConversationAssistantMessage("conversation", { turnId: populated.turnId, text: "Unassociated final" });
2440
+ const consumed = await f.plain("consumed-target");
2441
+ const owned = await f.plain("native-owned-target");
2442
+ const receipt = await f.complete("target-check", [empty.user.messageId, populated.user.messageId, consumed.user.messageId, owned.user.messageId]);
2443
+ await f.storage.write("conversation", async tx => {
2444
+ const metadata = await tx.readMetadata();
2445
+ metadata.runtime.seen[`${consumed.turnId}/assistant/`] = "Retained prior consumption";
2446
+ await tx.writeMetadata(metadata);
2447
+ await tx.updateTurnMetadata(owned.turnId, { runtime: { engine: "claude" } });
2448
+ });
2449
+ const prepared = await f.prepare(receipt);
2450
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2451
+ for (const turnId of ["missing", receipt.turnId, populated.turnId, consumed.turnId, owned.turnId]) {
2452
+ await assert.rejects(prepared.publishReply({ turnId }), error => error.code === "conversation_tool_receipt_conflict");
2453
+ }
2454
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(populated.turnId))).assistant.text, "Unassociated final");
2455
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(consumed.turnId))).assistant, null);
2456
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, before.runtime.seen);
2457
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.runtime.publishedReplyTurnId, undefined);
2458
+ const published = await prepared.publishReply({ turnId: empty.turnId });
2459
+ await assert.rejects((await f.prepare(receipt)).publishReply({ turnId: consumed.turnId }), /target or text changed/);
2460
+ assert.equal(published.assistant.text, "Verified plain reply.");
2461
+ assert.equal(f.effects(), 0);
2462
+ } finally { await f.close(); }
2463
+ });
2464
+
2465
+ test("completed Claude prepared reply refuses edited or cleared finals without rewriting consumption", async t => {
2466
+ const f = await completedReplyFixture(t);
2467
+ try {
2468
+ const plain = await f.plain("edited-target");
2469
+ const receipt = await f.complete("edit-check", [plain.user.messageId]);
2470
+ const prepared = await f.prepare(receipt);
2471
+ const published = await prepared.publishReply({ turnId: plain.turnId });
2472
+ const seen = (await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen;
2473
+ await f.transcript.upsertConversationAssistantMessage("conversation", { turnId: plain.turnId, text: "Actual user edit" });
2474
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }), /target or text changed/);
2475
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant.text, "Actual user edit");
2476
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, seen);
2477
+ // The original replaceAssistant owner clears this saved final, preserving
2478
+ // the persisted consumed version instead of acknowledging an edit.
2479
+ await f.storage.write("conversation", tx => tx.replaceAssistant(plain.turnId, { text: "" }));
2480
+ await f.reopen();
2481
+ await assert.rejects((await f.prepare(receipt)).publishReply({ turnId: plain.turnId }), /target or text changed/);
2482
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant.text, "");
2483
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, seen);
2484
+ assert.notEqual(published.assistant.text, "");
2485
+ assert.equal(f.effects(), 0);
2486
+ } finally { await f.close(); }
2487
+ });
2488
+
2489
+ test("completed Claude prepared reply rolls back final and cursor together when receipt persistence fails", async t => {
2490
+ let failPublication = false;
2491
+ let commits = 0;
2492
+ const f = await completedReplyFixture(t, { wrapStorage: storage => ({ ...storage,
2493
+ write: (id, callback) => storage.write(id, async tx => {
2494
+ let replaced = false;
2495
+ const result = await callback({ ...tx,
2496
+ async replaceAssistant(...args) { replaced = true; return tx.replaceAssistant(...args); },
2497
+ async updateTurnMetadata(turnId, patch) {
2498
+ if (failPublication && patch.runtime?.publishedReplyTurnId) throw new Error("Actual reply receipt write failed");
2499
+ return tx.updateTurnMetadata(turnId, patch);
2500
+ } });
2501
+ if (replaced) commits++;
2502
+ return result;
2503
+ }) }) });
2504
+ try {
2505
+ const plain = await f.plain("rollback-target");
2506
+ const receipt = await f.complete("rollback-check", [plain.user.messageId]);
2507
+ const prepared = await f.prepare(receipt);
2508
+ const before = await f.storage.read("conversation", tx => tx.readMetadata());
2509
+ const raw = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2510
+ commits = 0;
2511
+ failPublication = true;
2512
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }), /Actual reply receipt write failed/);
2513
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant, null);
2514
+ assert.deepEqual(await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId)), raw);
2515
+ assert.deepEqual((await f.storage.read("conversation", tx => tx.readMetadata())).runtime.seen, before.runtime.seen);
2516
+ assert.equal(commits, 0, "The failed nested upsert never commits independently");
2517
+ failPublication = false;
2518
+ const published = await prepared.publishReply({ turnId: plain.turnId });
2519
+ assert.equal(published.assistant.text, "Verified plain reply.");
2520
+ assert.equal(commits, 1, "Final, exact response link and assistant cursor share one storage commit");
2521
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2522
+ assert.equal(f.effects(), 0);
2523
+ } finally { failPublication = false; await f.close(); }
2524
+ });
2525
+
2526
+ test("completed Claude prepared reply checks live worker authority and account again before publication", async t => {
2527
+ let eligible = true;
2528
+ const f = await completedReplyFixture(t, { authorize: ({ operation }) => operation !== "tool" || eligible });
2529
+ try {
2530
+ const plain = await f.plain("authority-target");
2531
+ const receipt = await f.complete("authority-check", [plain.user.messageId]);
2532
+ const prepared = await f.prepare(receipt);
2533
+ eligible = false;
2534
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }), error => error.code === "conversation_forbidden");
2535
+ eligible = true;
2536
+ await writeFile(f.account, "different@example.test");
2537
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }));
2538
+ await writeFile(f.account, "owner@example.test");
2539
+ f.controller.abort(new Error("Original product worker stopped before reply"));
2540
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }), /Original product worker stopped before reply/);
2541
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant, null);
2542
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.runtime.publishedReplyTurnId, undefined);
2543
+ assert.equal(f.effects(), 0);
2544
+ } finally { eligible = true; await f.close(); }
2545
+ });
2546
+
2547
+ test("completed Claude receipt cannot publish a final and execute an application effect in either order", async t => {
2548
+ for (const effectFirst of [false, true]) {
2549
+ await t.test(effectFirst ? "effect before publication" : "publication before effect", async t => {
2550
+ const f = await completedReplyFixture(t);
2551
+ try {
2552
+ const plain = await f.plain("exclusive-target");
2553
+ const receipt = await f.complete("exclusive-check", [plain.user.messageId]);
2554
+ const one = await f.prepare(receipt);
2555
+ const two = await f.prepare(receipt);
2556
+ if (effectFirst) {
2557
+ assert.equal((await executeCompletedEnvelope(one)).ok, true);
2558
+ await assert.rejects(two.publishReply({ turnId: plain.turnId }), /does not own a plain reply/);
2559
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant, null);
2560
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.runtime.publishedReplyTurnId, undefined);
2561
+ assert.equal(f.effects(), 1);
2562
+ } else {
2563
+ await one.publishReply({ turnId: plain.turnId });
2564
+ await assert.rejects(executeCompletedEnvelope(two), /already published its plain reply/);
2565
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId))).metadata.applicationTools, undefined);
2566
+ assert.equal(f.effects(), 0);
2567
+ }
2568
+ } finally { await f.close(); }
2569
+ });
2570
+ }
2571
+ });
2572
+
2573
+ test("completed Claude prepared reply refuses a native application-tool misroute and a tool envelope", async t => {
2574
+ const f = await completedReplyFixture(t, { nativeToolUse: { name: "numbers_read", input: { privateArgument: "Not a reply" } } });
2575
+ try {
2576
+ const plain = await f.plain("misroute-target");
2577
+ const receipt = await f.complete("misroute-reply", [plain.user.messageId]);
2578
+ const prepared = await f.prepare(receipt);
2579
+ assert.equal(prepared.nativeToolAttempt, true);
2580
+ await assert.rejects(prepared.publishReply({ turnId: plain.turnId }), /does not own a plain reply/);
2581
+ assert.equal((await f.storage.read("conversation", tx => tx.readTurn(plain.turnId))).assistant, null);
2582
+ assert.equal(f.effects(), 0);
2583
+ } finally { await f.close(); }
2584
+ const tool = await completedEnvelopeFixture(t);
2585
+ try {
2586
+ const receipt = await tool.complete("tool-not-final");
2587
+ await tool.storage.write("conversation", tx => tx.appendMessage("000002", {
2588
+ role: "user", messageId: "tool-target", text: "Product words", at: "2026-10-10T00:00:00.000Z"
2589
+ }));
2590
+ await assert.rejects((await tool.prepare(receipt)).publishReply({ turnId: "000002" }), /does not own a plain reply/);
2591
+ assert.equal((await tool.storage.read("conversation", tx => tx.readTurn("000002"))).assistant, null);
2592
+ assert.equal(tool.effects(), 0);
2593
+ } finally { await tool.close(); }
2594
+ });
2595
+
2596
+
2597
+ // Wire capacity belongs to a trusted internal carrier; decoded human/tool fields
2598
+ // keep the original fixed-envelope bounds. Reuse the original native executable.
2599
+ const completedClaudeWireSchema = { type: "object", additionalProperties: false,
2600
+ required: ["kind", "text", "toolName", "arguments"], properties: {
2601
+ kind: { type: "string", enum: ["reply", "tool"] }, text: { type: "string", maxLength: 16000 },
2602
+ toolName: { type: "string", maxLength: 256 }, arguments: { type: "string", maxLength: 262144 }
2603
+ } };
2604
+ async function completedClaudeWireFixture(t, value, options = {}) {
2605
+ let effects = 0;
2606
+ const actions = applicationActions(async () => { effects++; return { value: 42 }; });
2607
+ const context = { actor: { id: "owner" }, surface: "app", permissions: ["numbers.read"] };
2608
+ const f = await fixture(t, { ...options, actions, context, structuredResponse: value,
2609
+ configuration: { ...configuration, outputSchema: options.outputSchema || completedClaudeWireSchema },
2610
+ limits: { maxFinalReplyCharacters: 16000, maxOutputCharacters: 1670455, ...options.limits } });
2611
+ await f.first.close();
2612
+ let runtime, conversation;
2613
+ async function reopen() {
2614
+ if (runtime) await runtime.close();
2615
+ runtime = createConversationRuntime({ engine: "claude", storage: f.storage, actions,
2616
+ authorize: () => true, completedEnvelope: true, ...f.driverOptions });
2617
+ try { conversation = await runtime.open({ id: "conversation", context }); }
2618
+ catch (error) { await runtime.close(); throw error; }
2619
+ }
2620
+ await reopen();
2621
+ return { ...f, reopen, effects: () => effects, get conversation() { return conversation; }, close: () => runtime.close() };
2622
+ }
2623
+
2624
+ for (const kind of ["tool", "reply"]) test(`completed Claude ${kind} wire preserves large decoded fields beyond the human cap`, async t => {
2625
+ const handover = "😀".repeat(20000);
2626
+ const argumentsText = JSON.stringify({ value: handover }).replace(/[\u0080-\uffff]/g,
2627
+ character => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
2628
+ const value = kind === "tool" ? { kind, text: "", toolName: "numbers_read", arguments: argumentsText }
2629
+ : { kind, text: "\u0000".repeat(16000), toolName: "", arguments: "" };
2630
+ const raw = JSON.stringify(value);
2631
+ assert.ok(raw.length > (kind === "tool" ? 280000 : 16000));
2632
+ if (kind === "tool") assert.equal(value.arguments.length, 240012);
2633
+ const f = await completedClaudeWireFixture(t, value);
2634
+ try {
2635
+ const receipt = await f.conversation.wake({ messageId: `large-claude-${kind}`, text: "Read the completed envelope" });
2636
+ const state = await f.conversation.wait();
2637
+ assert.equal(state.status, "ready", state.error);
2638
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2639
+ assert.equal(saved.metadata.runtime.status, "complete");
2640
+ assert.equal(saved.metadata.runtime.completedEnvelope, true);
2641
+ assert.equal(saved.system.origin, "application");
2642
+ assert.equal(saved.assistant.text, raw);
2643
+ const prepared = await f.conversation.prepareCompletedResponse(receipt, { signal: new AbortController().signal });
2644
+ assert.equal(prepared.text, raw);
2645
+ const { readAssistantResponseEnvelope } = await import("../src/server/lib/assistantToolLoop.js");
2646
+ const decoded = readAssistantResponseEnvelope(prepared.text);
2647
+ assert.deepEqual(decoded, value);
2648
+ if (kind === "tool") assert.equal(JSON.parse(decoded.arguments).value, handover);
2649
+ assert.equal(f.effects(), 0);
2650
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2651
+ assert.deepEqual((await f.conversation.read()).conversationLog, []);
2652
+ } finally { await f.close(); }
2653
+ });
2654
+
2655
+ test("completed Claude wire overflow remains bounded before any decoded effect", async t => {
2656
+ const value = { kind: "tool", text: "", toolName: "numbers_read", arguments: JSON.stringify({ content: "x".repeat(2000) }) };
2657
+ assert.ok(JSON.stringify(value).length > 2000);
2658
+ const f = await completedClaudeWireFixture(t, value, { outputSchema: completedEnvelopeSchema,
2659
+ limits: { maxOutputCharacters: 2000, maxFinalReplyCharacters: 16 } });
2660
+ try {
2661
+ const receipt = await f.conversation.wake({ messageId: "claude-wire-overflow", text: "Read the completed envelope" });
2662
+ const state = await f.conversation.wait();
2663
+ assert.equal(state.status, "ready", "The thread is idle after its failed admitted turn");
2664
+ assert.match(state.error, /output exceeded.*size limit|final reply limit/);
2665
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2666
+ assert.equal(receipt.status, "accepted");
2667
+ assert.equal(saved.metadata.runtime.status, "interrupted");
2668
+ assert.equal(saved.metadata.runtime.error, state.error);
2669
+ const metadata = await f.storage.read("conversation", tx => tx.readMetadata());
2670
+ assert.equal(metadata.runtime.binding.executionId, "", "The original verified Stop released its native execution");
2671
+ assert.ok((saved.assistant?.text.length || 0) <= 2000);
2672
+ assert.equal(saved.metadata.runtime.completedEnvelope, true);
2673
+ assert.notEqual(saved.assistant?.text, JSON.stringify(value));
2674
+ assert.equal(f.effects(), 0);
2675
+ } finally { await f.close(); }
2676
+ });
2677
+
2678
+ for (const forged of [false, true]) test(`ordinary Claude ${forged ? "forged-data" : "unmarked"} reply keeps its human cap in completed mode`, async t => {
2679
+ const value = { kind: "reply", text: "\u0000".repeat(16000), toolName: "", arguments: "" };
2680
+ const f = await completedClaudeWireFixture(t, value);
2681
+ try {
2682
+ const receipt = await f.conversation.send({ messageId: "ordinary-wire", text: "An ordinary request",
2683
+ ...(forged ? { data: { completedEnvelope: true } } : {}) });
2684
+ const state = await f.conversation.wait();
2685
+ assert.equal(state.status, "ready", "The thread is idle after its failed admitted turn");
2686
+ assert.match(state.error, /final reply limit/);
2687
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2688
+ assert.equal(receipt.status, "accepted");
2689
+ assert.equal(saved.metadata.runtime.status, "interrupted");
2690
+ assert.equal(saved.metadata.runtime.error, state.error);
2691
+ const metadata = await f.storage.read("conversation", tx => tx.readMetadata());
2692
+ assert.equal(metadata.runtime.binding.executionId, "", "The original verified Stop released its native execution");
2693
+ assert.ok((saved.assistant?.text.length || 0) <= 16000);
2694
+ assert.equal(saved.metadata.runtime.completedEnvelope, undefined);
2695
+ assert.equal(saved.user.origin, "user");
2696
+ if (forged) assert.deepEqual(saved.user.data, { completedEnvelope: true });
2697
+ assert.notEqual(saved.assistant?.text, JSON.stringify(value));
2698
+ assert.equal((await f.conversation.inspectDelivery({ messageId: receipt.messageId })).status, "accepted");
2699
+ assert.equal(f.effects(), 0);
2700
+ } finally { await f.close(); }
2701
+ });
2702
+
2703
+ test("completed Claude marked native recovery retains large raw output without replay", async t => {
2704
+ const value = { kind: "reply", text: "\u0000".repeat(16000), toolName: "", arguments: "" };
2705
+ const f = await completedClaudeWireFixture(t, value, { applicationEventBehavior: {
2706
+ lost: conversationRequestText({ text: "lost", origin: "application" }) } });
2707
+ try {
2708
+ await assert.rejects(f.conversation.wake({ messageId: "lost-marked-wire", text: "lost" }), /not acknowledged/);
2709
+ assert.equal((await f.conversation.read()).status, "unconfirmed");
2710
+ await f.reopen();
2711
+ const receipt = await f.conversation.inspectDelivery({ messageId: "lost-marked-wire" });
2712
+ assert.equal(receipt.status, "accepted");
2713
+ assert.equal(receipt.recovered, true);
2714
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2715
+ assert.equal(saved.metadata.runtime.completedEnvelope, true);
2716
+ assert.equal(saved.metadata.runtime.status, "interrupted", "An acknowledged history row is not a fabricated successful native result");
2717
+ assert.equal(saved.assistant.text, JSON.stringify(value));
2718
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2719
+ assert.equal(f.effects(), 0);
2720
+ } finally { await f.close(); }
2721
+ });
2722
+
2723
+ test("completed Claude marked native recovery retains admission but rejects wire overflow", async t => {
2724
+ const value = { kind: "tool", text: "", toolName: "numbers_read", arguments: JSON.stringify({ content: "x".repeat(2000) }) };
2725
+ const f = await completedClaudeWireFixture(t, value, { outputSchema: completedEnvelopeSchema,
2726
+ limits: { maxOutputCharacters: 2000, maxFinalReplyCharacters: 16 }, applicationEventBehavior: {
2727
+ lost: conversationRequestText({ text: "lost", origin: "application" }) } });
2728
+ try {
2729
+ await assert.rejects(f.conversation.wake({ messageId: "lost-marked-overflow", text: "lost" }), /not acknowledged/);
2730
+ await f.reopen();
2731
+ const receipt = await f.conversation.inspectDelivery({ messageId: "lost-marked-overflow" });
2732
+ assert.equal(receipt.status, "accepted");
2733
+ assert.equal(receipt.recovered, true);
2734
+ const saved = await f.storage.read("conversation", tx => tx.readTurn(receipt.turnId));
2735
+ assert.equal(saved.metadata.runtime.completedEnvelope, true);
2736
+ assert.equal(saved.metadata.runtime.status, "failed");
2737
+ assert.notEqual(saved.assistant?.text, JSON.stringify(value));
2738
+ assert.match((await f.conversation.read()).error, /final reply limit/);
2739
+ assert.equal((await f.trace()).filter(row => row.frame?.type === "user").length, 1);
2740
+ assert.equal(f.effects(), 0);
2741
+ } finally { await f.close(); }
2742
+ });