Files
pikasTech-HWLAB/internal/cloud/workbench-projection-writer.test.ts
T
2026-07-01 21:18:37 +08:00

1378 lines
54 KiB
TypeScript

// SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-19-p1-agentrun-incremental-cursor.
// Responsibility: Workbench projection writer/finalizer durable facts regression tests.
import assert from "node:assert/strict";
import { test } from "bun:test";
import { createCloudRuntimeStore } from "../db/runtime-store.ts";
import { writeWorkbenchProjectionEvent, writeWorkbenchProjectionSession } from "./workbench-projection-writer.ts";
test("workbench projection writer preserves Workbench launch context on Code Agent session facts", async () => {
const factWrites = [];
const accessWrites = [];
const launchContext = {
source: "project-management",
projectId: "project_constart_71freq",
taskRef: "mdtodo:constart-71freq-mdtodo:file_c5abae4e69c60370:R1",
sourceId: "constart-71freq-mdtodo",
sourceKind: "hwpod-workspace",
fileRef: "file_c5abae4e69c60370",
taskId: "R1",
hwpodId: "constart-71freq-c",
nodeId: "node-d601-f103-v2",
mdtodoRootRef: "docs/MDTODO",
workspaceRootHash: "workspace-hash",
hwpodWorkspaceArgs: "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'",
contextFingerprint: "ctx_projection_launch",
executionContext: {
sourceId: "constart-71freq-mdtodo",
sourceKind: "hwpod-workspace",
projectId: "project_constart_71freq",
taskRef: "mdtodo:constart-71freq-mdtodo:file_c5abae4e69c60370:R1",
fileRef: "file_c5abae4e69c60370",
taskId: "R1",
hwpodId: "constart-71freq-c",
nodeId: "node-d601-f103-v2",
mdtodoRootRef: "docs/MDTODO",
workspaceRootHash: "workspace-hash",
hwpodWorkspaceArgs: "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'",
contextFingerprint: "ctx_projection_launch",
valuesRedacted: true
},
valuesRedacted: true
};
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
accessWrites.push(input);
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-28T11:15:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_projection_launch_context",
ownerUserId: "usr_projection_launch",
ownerRole: "admin",
sessionId: "ses_projection_launch_context",
projectId: "project_constart_71freq",
conversationId: "cnv_projection_launch_context",
threadId: "thread-projection-launch-context",
status: "running",
payload: {
traceId: "trc_projection_launch_context",
status: "running",
updatedAt: "2026-06-28T11:15:00.000Z"
},
params: {
projectId: "project_constart_71freq",
taskRef: "mdtodo:constart-71freq-mdtodo:file_c5abae4e69c60370:R1",
message: "run this MDTODO task",
launchContext
},
session: {
sessionStatus: "running",
messages: [
{ messageId: "msg_projection_launch_user", role: "user", text: "run this MDTODO task", status: "sent", turnId: "trc_projection_launch_context", traceId: "trc_projection_launch_context" }
],
valuesRedacted: true,
secretMaterialStored: false
}
});
assert.equal(accessWrites.length, 1);
assert.equal(factWrites.length, 1);
const sessionJson = factWrites[0].params.facts.sessions[0].sessionJson;
assert.equal(sessionJson.launchContext.sourceId, "constart-71freq-mdtodo");
assert.equal(sessionJson.launchContext.hwpodId, "constart-71freq-c");
assert.equal(sessionJson.launchContext.contextFingerprint, "ctx_projection_launch");
assert.equal(sessionJson.launchContext.executionContext.hwpodWorkspaceArgs, "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'");
assert.equal(sessionJson.launchContext.valuesRedacted, true);
assert.equal(sessionJson.secretMaterialStored, false);
});
test("workbench projection writer commits terminal owner evidence as sealed durable facts", async () => {
const factWrites = [];
const accessWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
accessWrites.push(input);
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:00:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_terminal",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal",
threadId: "thread-writer-terminal",
status: "completed",
payload: {
traceId: "trc_writer_terminal",
status: "completed",
assistantText: "final answer",
runnerTrace: {
traceId: "trc_writer_terminal",
status: "completed",
startedAt: "2026-06-20T10:59:30.000Z",
lastEventAt: "2026-06-20T11:00:00.000Z",
finishedAt: "2026-06-20T11:00:00.000Z",
elapsedMs: 30000
},
agentRun: { runId: "run_writer_terminal", commandId: "cmd_writer_terminal", status: "completed", terminalStatus: "completed", lastSeq: 42 },
updatedAt: "2026-06-20T11:00:00.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_terminal", traceId: "trc_writer_terminal" },
{ messageId: "msg_writer_agent", role: "agent", text: "final answer", status: "completed", turnId: "trc_writer_terminal", traceId: "trc_writer_terminal" }
],
finalResponse: { text: "final answer", status: "completed", traceId: "trc_writer_terminal" }
}
});
assert.equal(accessWrites.length, 1);
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
assert.equal(facts.sessions[0].status, "completed");
assert.equal(facts.sessions[0].sealed, true);
assert.equal(facts.messages.length, 2);
assert.equal(facts.messages.find((message) => message.messageId === "msg_writer_agent").sealed, true);
assert.equal(facts.parts.some((part) => part.messageId === "msg_writer_agent" && part.text === "final answer" && part.sealed === true), true);
assert.equal(facts.parts.some((part) => part.messageId === "msg_writer_agent" && part.partType === "final_response" && part.text === "final answer" && part.sealed === true), true);
assert.equal(facts.turns[0].terminal, true);
assert.equal(facts.turns[0].sealed, true);
assert.equal(facts.turns[0].finalResponse.text, "final answer");
assert.equal(facts.messages.find((message) => message.messageId === "msg_writer_agent").lastEventAt, "2026-06-20T11:00:00.000Z");
assert.equal(facts.messages.find((message) => message.messageId === "msg_writer_agent").durationMs, 30000);
assert.equal(facts.turns[0].startedAt, "2026-06-20T10:59:30.000Z");
assert.equal(facts.turns[0].durationMs, 30000);
assert.equal(facts.checkpoints[0].projectionStatus, "caught_up");
assert.equal(facts.checkpoints[0].sealed, true);
assert.equal(facts.checkpoints[0].timing.finishedAt, "2026-06-20T11:00:00.000Z");
});
test("workbench projection writer keeps completed AgentRun without final response unsealed", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:02:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_terminal_missing_final",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_missing_final",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_missing_final",
threadId: "thread-writer-terminal-missing-final",
status: "completed",
payload: {
traceId: "trc_writer_terminal_missing_final",
status: "completed",
runnerTrace: {
traceId: "trc_writer_terminal_missing_final",
status: "completed",
startedAt: "2026-06-20T11:01:30.000Z",
lastEventAt: "2026-06-20T11:02:00.000Z",
finishedAt: "2026-06-20T11:02:00.000Z",
events: [
{ seq: 1, type: "assistant_message", status: "running", message: "progress only" },
{ seq: 2, type: "result", status: "completed", terminal: true, label: "agentrun:terminal:completed" }
],
eventCount: 2
},
agentRun: { runId: "run_writer_terminal_missing_final", commandId: "cmd_writer_terminal_missing_final", status: "completed", terminalStatus: "completed", lastSeq: 2 },
updatedAt: "2026-06-20T11:02:00.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_missing_final_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_terminal_missing_final", traceId: "trc_writer_terminal_missing_final" },
{ messageId: "msg_writer_missing_final_agent", role: "agent", text: "", status: "completed", turnId: "trc_writer_terminal_missing_final", traceId: "trc_writer_terminal_missing_final" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
const agentMessage = facts.messages.find((message) => message.messageId === "msg_writer_missing_final_agent");
assert.equal(facts.sessions[0].status, "running");
assert.equal(facts.sessions[0].terminal, false);
assert.equal(facts.sessions[0].sealed, false);
assert.equal(agentMessage.status, "running");
assert.equal(agentMessage.terminal, false);
assert.equal(agentMessage.sealed, false);
assert.equal(facts.parts.some((part) => part.partType === "final_response"), false);
assert.equal(facts.turns[0].status, "running");
assert.equal(facts.turns[0].terminal, false);
assert.equal(facts.turns[0].sealed, false);
assert.equal(facts.turns[0].finalResponse, null);
assert.equal(facts.turns[0].diagnostic.projectionStatus, "projecting");
assert.equal(facts.turns[0].diagnostic.waitingFor, "final_response");
assert.equal(facts.checkpoints[0].projectionStatus, "projecting");
assert.equal(facts.checkpoints[0].terminal, false);
assert.equal(facts.checkpoints[0].sealed, false);
});
test("workbench projection writer seals failed AgentRun turns with failure final response", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:03:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_terminal_failed",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_failed",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_failed",
threadId: "thread-writer-terminal-failed",
status: "failed",
payload: {
traceId: "trc_writer_terminal_failed",
status: "failed",
error: { code: "provider-stream-disconnected", message: "provider stream disconnected" },
runnerTrace: {
traceId: "trc_writer_terminal_failed",
status: "failed",
startedAt: "2026-06-20T11:02:30.000Z",
lastEventAt: "2026-06-20T11:03:00.000Z",
finishedAt: "2026-06-20T11:03:00.000Z",
events: [
{ seq: 1, type: "assistant_message", status: "running", message: "progress only" },
{ seq: 2, type: "result", status: "failed", terminal: true, label: "agentrun:terminal:failed", errorCode: "provider-stream-disconnected" }
],
eventCount: 2
},
agentRun: { runId: "run_writer_terminal_failed", commandId: "cmd_writer_terminal_failed", status: "failed", terminalStatus: "failed", failureKind: "provider-stream-disconnected", lastSeq: 2 },
updatedAt: "2026-06-20T11:03:00.000Z"
},
session: {
sessionStatus: "failed",
messages: [
{ messageId: "msg_writer_failed_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_terminal_failed", traceId: "trc_writer_terminal_failed" },
{ messageId: "msg_writer_failed_agent", role: "agent", text: "", status: "failed", turnId: "trc_writer_terminal_failed", traceId: "trc_writer_terminal_failed" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
const agentMessage = facts.messages.find((message) => message.messageId === "msg_writer_failed_agent");
const finalPart = facts.parts.find((part) => part.messageId === "msg_writer_failed_agent" && part.partType === "final_response");
assert.equal(facts.sessions[0].status, "failed");
assert.equal(facts.sessions[0].terminal, true);
assert.equal(facts.sessions[0].sealed, true);
assert.equal(agentMessage.status, "failed");
assert.equal(agentMessage.terminal, true);
assert.equal(agentMessage.sealed, true);
assert.match(agentMessage.text, /provider-stream-disconnected/u);
assert.equal(finalPart?.status, "failed");
assert.match(finalPart?.text ?? "", /provider-stream-disconnected/u);
assert.equal(facts.turns[0].status, "failed");
assert.equal(facts.turns[0].terminal, true);
assert.equal(facts.turns[0].sealed, true);
assert.match(facts.turns[0].finalResponse.text, /provider-stream-disconnected/u);
assert.equal(facts.turns[0].diagnostic.projectionStatus, "caught-up");
assert.equal(facts.turns[0].diagnostic.projectionHealth, "healthy");
assert.equal(facts.turns[0].diagnostic.blocker, null);
assert.equal(facts.checkpoints[0].projectionStatus, "caught_up");
assert.equal(facts.checkpoints[0].terminal, true);
assert.equal(facts.checkpoints[0].sealed, true);
assert.match(facts.checkpoints[0].finalResponse.text, /provider-stream-disconnected/u);
});
test("workbench projection writer does not synthesize terminal duration from updatedAt", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:05:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_terminal_no_finished_at",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_no_finished_at",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_no_finished_at",
threadId: "thread-writer-terminal-no-finished-at",
status: "canceled",
payload: {
traceId: "trc_writer_terminal_no_finished_at",
status: "canceled",
startedAt: "2026-06-20T11:00:00.000Z",
updatedAt: "2026-06-20T11:05:00.000Z",
agentRun: { runId: "run_writer_terminal_no_finished_at", commandId: "cmd_writer_terminal_no_finished_at", terminalStatus: "canceled" }
},
session: {
sessionStatus: "canceled",
messages: [
{ messageId: "msg_writer_terminal_no_finished_user", role: "user", text: "cancel me", status: "sent", turnId: "trc_writer_terminal_no_finished_at", traceId: "trc_writer_terminal_no_finished_at" },
{ messageId: "msg_writer_terminal_no_finished_agent", role: "agent", text: "hwlab-user-cancel", status: "canceled", turnId: "trc_writer_terminal_no_finished_at", traceId: "trc_writer_terminal_no_finished_at" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
const agentMessage = facts.messages.find((message) => message.messageId === "msg_writer_terminal_no_finished_agent");
assert.equal(facts.turns[0].status, "canceled");
assert.equal(facts.turns[0].finishedAt, null);
assert.equal(facts.turns[0].durationMs, null);
assert.equal(agentMessage.finishedAt, null);
assert.equal(agentMessage.durationMs, null);
assert.equal(facts.checkpoints[0].timing.finishedAt, null);
assert.equal(facts.checkpoints[0].timing.durationMs, null);
assert.equal(facts.checkpoints[0].diagnostic.blocker.code, "workbench_terminal_timing_authority_missing");
});
test("workbench projection writer keeps event writes durable when checkpoint reads are blocked", async () => {
const factWrites = [];
const baseStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:30:00.000Z" });
const blocked = new Error("Postgres durable runtime adapter is blocked for runtime evidence queries");
blocked.code = "runtime_evidence_queries_blocked";
const runtimeStore = {
allocateWorkbenchProjectedSeq(params, requestMeta) {
return baseStore.allocateWorkbenchProjectedSeq(params, requestMeta);
},
async queryWorkbenchFacts() {
throw blocked;
},
async writeWorkbenchFacts(params, requestMeta) {
const result = baseStore.writeWorkbenchFacts(params, requestMeta);
factWrites.push({ params, requestMeta });
return result;
}
};
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId: "trc_writer_blocked_checkpoint_event",
sessionId: "ses_writer_blocked_checkpoint_event",
sourceSeq: 1,
type: "backend",
eventType: "backend",
status: "running",
label: "agentrun:backend:running",
runId: "run_writer_blocked_checkpoint_event",
commandId: "cmd_writer_blocked_checkpoint_event",
startedAt: "2026-06-20T11:29:50.000Z",
createdAt: "2026-06-20T11:29:55.000Z"
}
});
assert.equal(factWrites.length, 1);
assert.equal(factWrites[0].params.facts.traceEvents[0].traceId, "trc_writer_blocked_checkpoint_event");
assert.equal(factWrites[0].params.facts.traceEvents[0].projectedSeq, 1);
assert.equal(factWrites[0].params.facts.checkpoints[0].projectionStatus, "projecting");
});
test("workbench projection writer keeps terminal session facts durable without trace backfill queries", async () => {
const factWrites = [];
let allocationSeq = 0;
let queryCount = 0;
const blocked = new Error("Postgres durable runtime adapter is blocked for runtime evidence queries");
blocked.code = "runtime_evidence_queries_blocked";
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
},
async queryWorkbenchFacts() {
queryCount += 1;
throw blocked;
},
async allocateWorkbenchProjectedSeq() {
allocationSeq += 1;
return { projectedSeq: allocationSeq };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:40:00.000Z"
};
}
};
const owner = await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_blocked_backfill",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_blocked_backfill",
projectId: "prj_writer",
conversationId: "cnv_writer_blocked_backfill",
threadId: "thread-writer-blocked-backfill",
status: "completed",
payload: {
traceId: "trc_writer_blocked_backfill",
status: "completed",
finalResponse: { text: "BLOCKED_BACKFILL_DONE", status: "completed", traceId: "trc_writer_blocked_backfill" },
agentRun: { runId: "run_writer_blocked_backfill", commandId: "cmd_writer_blocked_backfill", status: "completed", terminalStatus: "completed", lastSeq: 3 },
updatedAt: "2026-06-20T11:40:00.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_blocked_backfill_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_blocked_backfill", traceId: "trc_writer_blocked_backfill" },
{ messageId: "msg_writer_blocked_backfill_agent", role: "agent", text: "BLOCKED_BACKFILL_DONE", status: "completed", turnId: "trc_writer_blocked_backfill", traceId: "trc_writer_blocked_backfill" }
],
finalResponse: { text: "BLOCKED_BACKFILL_DONE", status: "completed", traceId: "trc_writer_blocked_backfill" }
}
});
assert.equal(owner.id, "ses_writer_blocked_backfill");
assert.equal(queryCount, 1);
assert.equal(factWrites.length, 1);
assert.equal(factWrites[0].params.facts.checkpoints[0].traceId, "trc_writer_blocked_backfill");
assert.equal(factWrites[0].params.facts.turns[0].finalResponse.text, "BLOCKED_BACKFILL_DONE");
assert.equal(factWrites[0].params.facts.traceEvents?.length ?? 0, 0);
assert.equal(allocationSeq, 0);
});
test("workbench projection writer does not synthesize terminal trace events from sealed facts", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:20:00.000Z" });
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:20:00.000Z"
};
}
};
for (const [sourceSeq, label] of [
[1, "agentrun:backend:admitted"],
[2, "agentrun:run:created"],
[3, "agentrun:runner-job:queued"]
]) {
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId: "trc_writer_terminal_backfill",
sessionId: "ses_writer_terminal_backfill",
source: "agentrun",
sourceSeq,
type: "backend",
eventType: "backend",
status: "running",
label,
runId: "run_writer_terminal_backfill",
commandId: "cmd_writer_terminal_backfill",
createdAt: `2026-06-20T11:19:0${sourceSeq}.000Z`
}
});
}
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_terminal_backfill",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_backfill",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_backfill",
threadId: "thread-writer-terminal-backfill",
status: "completed",
payload: {
traceId: "trc_writer_terminal_backfill",
status: "completed",
finalResponse: { text: "BACKFILL_DONE", status: "completed", traceId: "trc_writer_terminal_backfill" },
runnerTrace: {
traceId: "trc_writer_terminal_backfill",
status: "completed",
startedAt: "2026-06-20T11:19:01.000Z",
lastEventAt: "2026-06-20T11:19:13.000Z",
finishedAt: "2026-06-20T11:19:13.000Z",
eventCount: 3,
events: []
},
agentRun: { runId: "run_writer_terminal_backfill", commandId: "cmd_writer_terminal_backfill", status: "completed", terminalStatus: "completed", lastSeq: 3 },
updatedAt: "2026-06-20T11:19:13.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_backfill_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_terminal_backfill", traceId: "trc_writer_terminal_backfill" },
{ messageId: "msg_writer_backfill_agent", role: "agent", text: "BACKFILL_DONE", status: "completed", turnId: "trc_writer_terminal_backfill", traceId: "trc_writer_terminal_backfill" }
],
finalResponse: { text: "BACKFILL_DONE", status: "completed", traceId: "trc_writer_terminal_backfill" }
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId: "trc_writer_terminal_backfill", families: ["traceEvents", "turns", "messages"], limit: 20 });
const events = loaded.facts.traceEvents;
assert.deepEqual(events.map((event) => event.projectedSeq), [1, 2, 3]);
assert.deepEqual(events.map((event) => event.label), ["agentrun:backend:admitted", "agentrun:run:created", "agentrun:runner-job:queued"]);
assert.equal(events.some((event) => event.source === "workbench-terminal-projection"), false);
const terminalTurn = loaded.facts.turns.find((turn) => turn.terminal === true);
assert.equal(terminalTurn.finalResponse.text, "BACKFILL_DONE");
assert.equal(loaded.facts.messages.some((message) => message.role !== "user" && message.text === "BACKFILL_DONE"), true);
});
test("workbench projection terminal facts do not advance checkpoint past durable trace events", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:45:00.000Z" });
const traceId = "trc_writer_terminal_checkpoint_gap";
const sessionId = "ses_writer_terminal_checkpoint_gap";
const finalText = "CHECKPOINT_GAP_DONE";
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:45:00.000Z"
};
}
};
for (let sourceSeq = 1; sourceSeq <= 33; sourceSeq += 1) {
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId,
source: "agentrun",
sourceSeq,
type: sourceSeq === 33 ? "terminal" : "backend",
eventType: sourceSeq === 33 ? "terminal" : "backend",
status: sourceSeq === 33 ? "completed" : "running",
label: sourceSeq === 33 ? "agentrun:result:completed" : `agentrun:backend:${sourceSeq}`,
terminal: sourceSeq === 33,
runId: "run_writer_terminal_checkpoint_gap",
commandId: "cmd_writer_terminal_checkpoint_gap",
createdAt: `2026-06-20T11:44:${String(sourceSeq).padStart(2, "0")}.000Z`
}
});
}
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId,
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId,
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_checkpoint_gap",
threadId: "thread-writer-terminal-checkpoint-gap",
status: "completed",
payload: {
traceId,
status: "completed",
finalResponse: { text: finalText, status: "completed", traceId },
runnerTrace: {
traceId,
status: "completed",
eventCount: 34,
events: Array.from({ length: 34 }, (_, index) => ({ seq: index + 1, type: "backend", status: index === 33 ? "completed" : "running", terminal: index === 33 }))
},
agentRun: { runId: "run_writer_terminal_checkpoint_gap", commandId: "cmd_writer_terminal_checkpoint_gap", status: "completed", terminalStatus: "completed", lastSeq: 30 },
updatedAt: "2026-06-20T11:45:00.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_checkpoint_gap_user", role: "user", text: "question", status: "sent", turnId: traceId, traceId },
{ messageId: "msg_writer_checkpoint_gap_agent", role: "agent", text: finalText, status: "completed", turnId: traceId, traceId }
],
finalResponse: { text: finalText, status: "completed", traceId }
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId, families: ["traceEvents", "checkpoints", "turns"], limit: 80 });
assert.equal(loaded.facts.traceEvents.length, 33);
assert.equal(Math.max(...loaded.facts.traceEvents.map((event) => event.projectedSeq)), 33);
assert.equal(loaded.facts.checkpoints[0].projectedSeq, 33);
assert.equal(loaded.facts.checkpoints[0].sourceSeq, 30);
assert.equal(loaded.facts.turns[0].terminal, true);
});
test("workbench projection writer does not duplicate terminal trace events that already exist", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:25:00.000Z" });
const traceId = "trc_writer_terminal_backfill_existing";
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:25:00.000Z"
};
}
};
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId: "ses_writer_terminal_backfill_existing",
sourceSeq: 1,
type: "backend",
status: "running",
label: "agentrun:backend:admitted",
createdAt: "2026-06-20T11:24:01.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId: "ses_writer_terminal_backfill_existing",
sourceSeq: 2,
type: "assistant",
eventType: "assistant",
status: "completed",
label: "agentrun:assistant:message",
text: "ALREADY_DONE",
terminal: true,
createdAt: "2026-06-20T11:24:12.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId: "ses_writer_terminal_backfill_existing",
sourceSeq: 3,
type: "result",
eventType: "terminal",
status: "completed",
label: "agentrun:result:completed",
terminal: true,
createdAt: "2026-06-20T11:24:13.000Z"
}
});
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId,
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_backfill_existing",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_backfill_existing",
threadId: "thread-writer-terminal-backfill-existing",
status: "completed",
payload: {
traceId,
status: "completed",
finalResponse: { text: "ALREADY_DONE", status: "completed", traceId },
runnerTrace: {
traceId,
status: "completed",
startedAt: "2026-06-20T11:24:01.000Z",
lastEventAt: "2026-06-20T11:24:13.000Z",
finishedAt: "2026-06-20T11:24:13.000Z",
eventCount: 3,
events: []
},
agentRun: { runId: "run_writer_terminal_backfill_existing", commandId: "cmd_writer_terminal_backfill_existing", status: "completed", terminalStatus: "completed", lastSeq: 3 },
updatedAt: "2026-06-20T11:24:13.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_backfill_existing_user", role: "user", text: "question", status: "sent", turnId: traceId, traceId },
{ messageId: "msg_writer_backfill_existing_agent", role: "agent", text: "ALREADY_DONE", status: "completed", turnId: traceId, traceId }
],
finalResponse: { text: "ALREADY_DONE", status: "completed", traceId }
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId, families: ["traceEvents", "checkpoints"], limit: 20 });
assert.deepEqual(loaded.facts.traceEvents.map((event) => event.projectedSeq), [1, 2, 3]);
assert.deepEqual(loaded.facts.traceEvents.map((event) => event.label), ["agentrun:backend:admitted", "agentrun:assistant:message", "agentrun:result:completed"]);
assert.equal(loaded.facts.checkpoints[0].projectedSeq, 3);
});
test("workbench projection event writer aggregates assistant updates and skips late non-terminal rows after seal", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:32:00.000Z" });
const traceId = "trc_writer_assistant_aggregate";
const sessionId = "ses_writer_assistant_aggregate";
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId,
source: "agentrun",
sourceSeq: 1,
type: "backend",
eventType: "backend",
status: "running",
label: "agentrun:backend:running",
createdAt: "2026-06-20T11:31:00.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId,
source: "agentrun",
sourceSeq: 25,
type: "assistant",
eventType: "assistant",
status: "running",
label: "agentrun:assistant:message",
text: "AGGREGATED_FINAL",
createdAt: "2026-06-20T11:31:10.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId,
source: "agentrun",
sourceSeq: 26,
type: "assistant",
eventType: "assistant",
status: "completed",
label: "agentrun:assistant:message",
text: "AGGREGATED_FINAL",
finalResponse: { text: "AGGREGATED_FINAL", status: "completed", traceId },
terminal: true,
createdAt: "2026-06-20T11:31:12.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId,
source: "agentrun",
sourceSeq: 24,
type: "assistant",
eventType: "assistant",
status: "running",
label: "agentrun:assistant:message",
text: "AGGREGATED_FINAL",
createdAt: "2026-06-20T11:31:09.000Z"
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId, families: ["traceEvents", "messages", "checkpoints"], limit: 20 });
const events = loaded.facts.traceEvents;
assert.equal(events.length, 2);
assert.deepEqual(events.map((event) => event.projectedSeq), [1, 2]);
assert.equal(events[1].sourceEventId, `${traceId}:assistant-message:msg_writer_assistant_aggregate_agent`);
assert.equal(events[1].status, "completed");
assert.equal(events[1].text, "AGGREGATED_FINAL");
assert.equal(events.some((event) => event.sourceSeq === 24), false);
assert.equal(loaded.facts.messages.filter((message) => message.role !== "user").length, 1);
assert.equal(loaded.facts.checkpoints[0].terminal, true);
});
test("workbench projection writer does not rewrite prior-turn messages from merged owner session", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
updatedAt: "2026-06-20T11:10:00.000Z",
session: {
sessionStatus: "completed",
lastTraceId: input.traceId,
messages: [
{ messageId: "msg_writer_r1_user", role: "user", text: "round1 prompt", status: "sent", turnId: "trc_writer_r1", traceId: "trc_writer_r1" },
{ messageId: "msg_writer_r1_agent", role: "agent", text: "WRONG_ROUND2_TEXT", status: "completed", turnId: "trc_writer_r1", traceId: "trc_writer_r1" },
...input.session.messages
]
}
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_r2",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_multi_turn",
projectId: "prj_writer",
conversationId: "cnv_writer_multi_turn",
threadId: "thread-writer-multi-turn",
status: "completed",
payload: {
traceId: "trc_writer_r2",
status: "completed",
finalResponse: { text: "ROUND2_DONE", status: "completed", traceId: "trc_writer_r2" },
agentRun: { runId: "run_writer_r2", commandId: "cmd_writer_r2", status: "completed", terminalStatus: "completed", lastSeq: 9 },
updatedAt: "2026-06-20T11:10:00.000Z"
},
session: {
sessionStatus: "completed",
messages: [
{ messageId: "msg_writer_r2_user", role: "user", text: "round2 prompt", status: "sent", turnId: "trc_writer_r2", traceId: "trc_writer_r2" },
{ messageId: "msg_writer_r2_agent", role: "agent", text: "ROUND2_DONE", status: "completed", turnId: "trc_writer_r2", traceId: "trc_writer_r2" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
assert.deepEqual(facts.messages.map((message) => message.messageId), ["msg_writer_r2_user", "msg_writer_r2_agent"]);
assert.equal(facts.messages.some((message) => message.traceId === "trc_writer_r1"), false);
assert.equal(facts.messages.find((message) => message.messageId === "msg_writer_r2_agent").text, "ROUND2_DONE");
assert.equal(facts.turns[0].traceId, "trc_writer_r2");
assert.equal(facts.turns[0].finalResponse.text, "ROUND2_DONE");
});
test("workbench projection writer seals canceled AgentRun turns with canonical cancel final response", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:02:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_canceled",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_canceled",
projectId: "prj_writer",
conversationId: "cnv_writer_canceled",
threadId: "thread-writer-canceled",
status: "canceled",
payload: {
traceId: "trc_writer_canceled",
status: "canceled",
finalResponse: { text: "command cancelled before backend start", status: "canceled", traceId: "trc_writer_canceled" },
userMessage: "当前 AgentRun 请求已取消;traceId/runId/commandId 已保留,可重试上一条消息。",
runnerTrace: {
traceId: "trc_writer_canceled",
status: "canceled",
events: [{ type: "cancel", status: "canceled", terminal: true, createdAt: "2026-06-20T11:02:00.000Z" }],
updatedAt: "2026-06-20T11:02:00.000Z"
},
agentRun: { runId: "run_writer_canceled", commandId: "cmd_writer_canceled", status: "cancelled", commandState: "cancelled", terminalStatus: "cancelled", lastSeq: 12 },
updatedAt: "2026-06-20T11:02:00.000Z"
},
session: {
sessionStatus: "canceled",
messages: [
{ messageId: "msg_writer_canceled_user", role: "user", text: "cancel me", status: "sent", turnId: "trc_writer_canceled", traceId: "trc_writer_canceled" },
{ messageId: "msg_writer_canceled_agent", role: "agent", text: "", status: "canceled", turnId: "trc_writer_canceled", traceId: "trc_writer_canceled" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
const agentMessage = facts.messages.find((message) => message.messageId === "msg_writer_canceled_agent");
assert.equal(facts.sessions[0].status, "canceled");
assert.equal(facts.turns[0].terminal, true);
assert.equal(facts.turns[0].finalResponse.text, "hwlab-user-cancel");
assert.equal(facts.turns[0].assistantText, "hwlab-user-cancel");
assert.equal(agentMessage.text, "hwlab-user-cancel");
assert.equal(facts.parts.some((part) => part.messageId === "msg_writer_canceled_agent" && part.partType === "final_response" && part.text === "hwlab-user-cancel" && part.sealed === true), true);
});
test("workbench projection writer does not replace prior user prompt with cancel notice", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:04:00.000Z" });
const traceId = "trc_writer_canceled_prompt_preserved";
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: input.status === "canceled" ? "2026-06-20T11:04:30.000Z" : "2026-06-20T11:04:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId,
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_canceled_prompt_preserved",
projectId: "prj_writer",
conversationId: "cnv_writer_canceled_prompt_preserved",
threadId: "thread-writer-canceled-prompt-preserved",
status: "running",
payload: {
traceId,
status: "running",
prompt: "ORIGINAL CANCEL PROMPT",
updatedAt: "2026-06-20T11:04:00.000Z"
},
session: { sessionStatus: "running", lastTraceId: traceId }
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId: "ses_writer_canceled_prompt_preserved",
source: "agentrun",
sourceSeq: 1,
type: "backend",
eventType: "backend",
status: "running",
label: "agentrun:request:accepted",
createdAt: "2026-06-20T11:04:10.000Z"
}
});
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId,
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_canceled_prompt_preserved",
projectId: "prj_writer",
conversationId: "cnv_writer_canceled_prompt_preserved",
threadId: "thread-writer-canceled-prompt-preserved",
status: "canceled",
payload: {
traceId,
status: "canceled",
message: "当前 AgentRun 请求已取消;traceId/runId/commandId 已保留,可重试上一条消息。",
finalResponse: { text: "command cancelled before backend start", status: "canceled", traceId },
runnerTrace: {
traceId,
status: "canceled",
events: [{ type: "cancel", status: "canceled", terminal: true, createdAt: "2026-06-20T11:04:30.000Z" }],
updatedAt: "2026-06-20T11:04:30.000Z"
},
agentRun: { runId: "run_writer_canceled_prompt_preserved", commandId: "cmd_writer_canceled_prompt_preserved", status: "cancelled", commandState: "cancelled", terminalStatus: "cancelled", lastSeq: 12 },
updatedAt: "2026-06-20T11:04:30.000Z"
},
session: {
sessionStatus: "canceled",
lastTraceId: traceId,
messages: [
{ messageId: "msg_writer_canceled_prompt_preserved_user", role: "user", text: "当前 AgentRun 请求已取消;traceId/runId/commandId 已保留,可重试上一条消息。", status: "sent", turnId: traceId, traceId },
{ messageId: "msg_writer_canceled_prompt_preserved_agent", role: "agent", text: "", status: "canceled", turnId: traceId, traceId }
]
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId, families: ["messages", "parts", "turns"], limit: 20 });
const userMessages = loaded.facts.messages.filter((message) => message.role === "user");
const agentMessage = loaded.facts.messages.find((message) => message.role !== "user");
assert.deepEqual(userMessages.map((message) => message.text), ["ORIGINAL CANCEL PROMPT"]);
assert.equal(agentMessage.text, "hwlab-user-cancel");
assert.equal(loaded.facts.parts.some((part) => part.messageId === "msg_writer_canceled_prompt_preserved_user" && part.text.includes("请求已取消")), false);
});
test("workbench projection writer does not seal running assistant text as final response", async () => {
const factWrites = [];
const runtimeStore = {
async writeWorkbenchFacts(params, requestMeta) {
factWrites.push({ params, requestMeta });
return { written: true, facts: params.facts };
}
};
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:05:00.000Z"
};
}
};
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId: "trc_writer_running",
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_running",
projectId: "prj_writer",
conversationId: "cnv_writer_running",
threadId: "thread-writer-running",
status: "running",
payload: {
traceId: "trc_writer_running",
status: "running",
assistantText: "backend diagnostic text should not become final",
updatedAt: "2026-06-20T11:05:00.000Z"
},
session: {
sessionStatus: "running",
messages: [
{ messageId: "msg_writer_running_user", role: "user", text: "question", status: "sent", turnId: "trc_writer_running", traceId: "trc_writer_running" },
{ messageId: "msg_writer_running_agent", role: "agent", text: "", status: "running", turnId: "trc_writer_running", traceId: "trc_writer_running" }
]
}
});
assert.equal(factWrites.length, 1);
const facts = factWrites[0].params.facts;
const agentMessage = facts.messages.find((message) => message.messageId === "msg_writer_running_agent");
assert.equal(agentMessage.text, "");
assert.equal(facts.parts.some((part) => part.messageId === "msg_writer_running_agent"), false);
assert.equal(facts.turns[0].terminal, false);
assert.equal(facts.turns[0].finalResponse, null);
assert.equal(facts.turns[0].assistantText, null);
});
test("workbench projection event commit writes trace event and checkpoint facts", async () => {
const factWrites = [];
let now = "2026-06-20T11:01:05.000Z";
const baseStore = createCloudRuntimeStore({ now: () => now });
const runtimeStore = {
allocateWorkbenchProjectedSeq(params, requestMeta) {
return baseStore.allocateWorkbenchProjectedSeq(params, requestMeta);
},
queryWorkbenchFacts(params) {
return baseStore.queryWorkbenchFacts(params);
},
async writeWorkbenchFacts(params, requestMeta) {
const result = baseStore.writeWorkbenchFacts(params, requestMeta);
factWrites.push({ params, requestMeta });
return result;
}
};
now = "2026-06-20T11:03:30.000Z";
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId: "trc_writer_event",
sessionId: "ses_writer_event",
seq: 7,
sourceSeq: 70,
type: "backend",
status: "running",
label: "agentrun:backend:running",
runId: "run_writer_event",
commandId: "cmd_writer_event",
startedAt: "2026-06-20T11:00:30.000Z",
durationMs: 3000,
createdAt: "2026-06-20T11:01:00.000Z"
}
});
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId: "trc_writer_event",
sessionId: "ses_writer_event",
seq: 8,
sourceSeq: 71,
type: "result",
status: "completed",
label: "agentrun:result:completed",
terminal: true,
runId: "run_writer_event",
commandId: "cmd_writer_event",
createdAt: "2026-06-20T11:02:00.000Z"
}
});
assert.equal(factWrites.length, 2);
assert.equal(factWrites[0].params.facts.traceEvents[0].projectedSeq, 1);
assert.equal(factWrites[0].params.facts.checkpoints[0].projectionStatus, "projecting");
assert.equal(factWrites[0].params.facts.checkpoints[0].startedAt, "2026-06-20T11:00:30.000Z");
assert.equal(factWrites[0].params.facts.checkpoints[0].lastEventAt, "2026-06-20T11:01:00.000Z");
assert.equal(factWrites[0].params.facts.checkpoints[0].durationMs, null);
assert.equal(factWrites[0].params.facts.checkpoints[0].timing.durationMs, null);
assert.equal(factWrites[1].params.facts.sessions[0].status, "completed");
assert.equal(factWrites[1].params.facts.traceEvents[0].sealed, true);
assert.equal(factWrites[1].params.facts.traceEvents[0].projectedSeq, 2);
assert.equal(factWrites[1].params.facts.checkpoints[0].projectionStatus, "caught_up");
assert.equal(factWrites[1].params.facts.checkpoints[0].durationMs, 90000);
assert.equal(factWrites[1].params.facts.checkpoints[0].finishedAt, "2026-06-20T11:02:00.000Z");
assert.equal(factWrites[1].params.facts.checkpoints[0].lastEventAt, "2026-06-20T11:02:00.000Z");
});
test("workbench projection writer reuses lifecycle assistant message id for terminal session projection", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T11:10:00.000Z" });
const traceId = "trc_writer_terminal_same_message_id";
const expectedAssistantMessageId = "msg_writer_terminal_same_message_id_agent";
const accessController = {
async recordAgentSessionOwner(input) {
return {
id: input.sessionId,
projectId: input.projectId,
ownerUserId: input.ownerUserId,
ownerRole: input.ownerRole,
conversationId: input.conversationId,
threadId: input.threadId,
lastTraceId: input.traceId,
status: input.status,
session: input.session,
updatedAt: "2026-06-20T11:10:05.000Z"
};
}
};
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
traceId,
sessionId: "ses_writer_terminal_same_message_id",
sourceSeq: 10,
type: "backend",
status: "running",
label: "agentrun:backend:running",
startedAt: "2026-06-20T11:09:55.000Z",
createdAt: "2026-06-20T11:09:55.000Z"
}
});
await writeWorkbenchProjectionSession({
accessController,
runtimeStore,
traceId,
ownerUserId: "usr_writer",
ownerRole: "user",
sessionId: "ses_writer_terminal_same_message_id",
projectId: "prj_writer",
conversationId: "cnv_writer_terminal_same_message_id",
threadId: "thread-writer-terminal-same-message-id",
status: "completed",
payload: {
traceId,
status: "completed",
assistantText: "same lifecycle final",
finalResponse: { text: "same lifecycle final", status: "completed", traceId },
runnerTrace: {
traceId,
status: "completed",
startedAt: "2026-06-20T11:09:55.000Z",
lastEventAt: "2026-06-20T11:10:05.000Z",
finishedAt: "2026-06-20T11:10:05.000Z",
elapsedMs: 10000
},
agentRun: { runId: "run_writer_terminal_same_message_id", commandId: "cmd_writer_terminal_same_message_id", status: "completed", terminalStatus: "completed", lastSeq: 11 },
updatedAt: "2026-06-20T11:10:05.000Z"
},
session: {
sessionStatus: "completed",
lastTraceId: traceId,
messages: [
{ messageId: "msg_writer_terminal_same_message_id_user", role: "user", text: "same lifecycle", traceId, status: "sent" }
],
finalResponse: { text: "same lifecycle final", status: "completed", traceId }
}
});
const loaded = runtimeStore.queryWorkbenchFacts({ traceId, families: ["messages", "parts", "turns"], limit: 20 });
const assistantMessages = loaded.facts.messages.filter((message) => message.role !== "user");
const terminalTurn = loaded.facts.turns.find((turn) => turn.terminal === true);
assert.deepEqual(assistantMessages.map((message) => message.messageId), [expectedAssistantMessageId]);
assert.equal(terminalTurn.messageId, expectedAssistantMessageId);
assert.equal(loaded.facts.parts.some((part) => part.messageId === expectedAssistantMessageId && part.partType === "final_response" && part.text === "same lifecycle final"), true);
});
test("workbench projection event writer allocates projectedSeq idempotently by source event identity", async () => {
const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T12:00:00.000Z" });
const repeatedSourceEvent = {
traceId: "trc_writer_idempotent",
sessionId: "ses_writer_idempotent",
seq: 1,
source: "agentrun",
sourceSeq: 70,
type: "backend",
status: "running",
label: "agentrun:backend:running",
runId: "run_writer_idempotent",
commandId: "cmd_writer_idempotent",
startedAt: "2026-06-20T12:00:01.000Z",
createdAt: "2026-06-20T12:00:01.000Z"
};
await writeWorkbenchProjectionEvent({ runtimeStore, event: repeatedSourceEvent });
await writeWorkbenchProjectionEvent({
runtimeStore,
event: {
...repeatedSourceEvent,
seq: 1,
sourceSeq: 71,
label: "agentrun:backend:runner-ready",
startedAt: null,
durationMs: 999,
createdAt: "2026-06-20T12:00:02.000Z"
}
});
await writeWorkbenchProjectionEvent({ runtimeStore, event: repeatedSourceEvent });
const loaded = runtimeStore.queryWorkbenchFacts({ traceId: "trc_writer_idempotent", families: ["traceEvents", "checkpoints"], limit: 10 });
assert.deepEqual(loaded.facts.traceEvents.map((event) => event.projectedSeq), [1, 2]);
assert.deepEqual(loaded.facts.traceEvents.map((event) => event.sourceSeq), [70, 71]);
assert.equal(loaded.facts.checkpoints[0].projectedSeq, 2);
assert.equal(loaded.facts.checkpoints[0].startedAt, "2026-06-20T12:00:01.000Z");
assert.equal(loaded.facts.checkpoints[0].lastEventAt, "2026-06-20T12:00:02.000Z");
assert.equal(loaded.facts.checkpoints[0].durationMs, null);
});