Files
pikasTech-HWLAB/internal/cloud/workbench-projection-writer.test.ts
T

289 lines
9.6 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "bun:test";
import {
buildWorkbenchProjectionEventFacts,
recordWorkbenchSessionOwner,
writeWorkbenchSessionAdmissionFact
} from "./workbench-projection-writer.ts";
import { projectionOutboxRealtimeEvents } from "./server-workbench-realtime-http.ts";
test("HTTP lifecycle records ownership without writing projection facts", async () => {
const calls = [];
const accessController = {
async recordAgentSessionOwner(input) {
calls.push(input);
return { id: input.sessionId, ownerUserId: input.ownerUserId, status: input.status };
}
};
let projectionWrites = 0;
const owner = await recordWorkbenchSessionOwner({
accessController,
runtimeStore: { writeWorkbenchFacts() { projectionWrites += 1; } },
traceId: "trc_owner_only",
ownerUserId: "usr_owner",
ownerRole: "user",
sessionId: "ses_owner_only",
projectId: "prj_owner",
status: "completed",
session: { source: "http-result" }
});
assert.equal(owner.id, "ses_owner_only");
assert.equal(calls.length, 1);
assert.equal(calls[0].traceId, "trc_owner_only");
assert.equal(projectionWrites, 0);
});
test("admission persists only the dedicated session scope fact", async () => {
const calls = [];
const runtimeStore = {
async writeWorkbenchSessionAdmissionFact(params, meta) {
calls.push({ params, meta });
return { written: true, admissionOnly: true };
},
writeWorkbenchFacts() {
throw new Error("generic projection writer must not be used by admission");
}
};
const result = await writeWorkbenchSessionAdmissionFact({
runtimeStore,
session: {
id: "ses_admission_only",
ownerUserId: "usr_owner",
ownerRole: "user",
projectId: "prj_owner",
conversationId: "cnv_owner",
lastTraceId: "trc_admission_only",
status: "running",
session: { source: "manual-session-create", launchContext: { source: "workbench" } },
createdAt: "2026-07-10T10:00:00.000Z",
updatedAt: "2026-07-10T10:00:01.000Z"
}
});
assert.equal(result.admissionOnly, true);
assert.equal(calls.length, 1);
const fact = calls[0].params.fact;
assert.equal(fact.sessionId, "ses_admission_only");
assert.equal(fact.ownerUserId, "usr_owner");
assert.equal(fact.lastTraceId, "trc_admission_only");
assert.equal(fact.projectedSeq, 0);
assert.equal(fact.sourceEventId, "ses_admission_only:session-admission");
assert.deepEqual(fact.sessionJson.launchContext, { source: "workbench", valuesRedacted: true });
});
test("admission fails closed when the dedicated durable entry is absent", async () => {
await assert.rejects(
writeWorkbenchSessionAdmissionFact({ runtimeStore: { writeWorkbenchFacts() {} }, session: { id: "ses_missing_entry" } }),
(error) => error?.code === "workbench_admission_store_unconfigured"
);
});
test("Kafka projector builds running facts from one canonical source event", () => {
const built = buildWorkbenchProjectionEventFacts({
projectedSeq: 4,
projectedAt: "2026-07-10T10:00:02.000Z",
event: {
traceId: "trc_running",
sessionId: "ses_running",
runId: "run_running",
commandId: "cmd_running",
sourceEventId: "evt_running",
sourceSeq: 7,
type: "assistant",
eventType: "assistant",
status: "running",
text: "committed delta",
createdAt: "2026-07-10T10:00:01.000Z"
}
});
assert.equal(built.written, true);
assert.equal(built.facts.sessions[0].lastTraceId, "trc_running");
assert.equal(built.facts.messages[0].text, "committed delta");
assert.equal(built.facts.turns[0].terminal, false);
assert.equal(built.facts.checkpoints[0].projectedSeq, 4);
assert.equal(built.facts.traceEvents[0].sourceEventId, "evt_running");
});
test("authoritative assistant final seals terminal with a final response", () => {
const built = buildWorkbenchProjectionEventFacts({
projectedSeq: 5,
projectedAt: "2026-07-10T10:00:04.000Z",
previousCheckpoint: {
traceId: "trc_terminal",
sessionId: "ses_terminal",
projectedSeq: 4,
sourceSeq: 4,
startedAt: "2026-07-10T10:00:00.000Z",
lastEventAt: "2026-07-10T10:00:03.000Z",
timing: { startedAt: "2026-07-10T10:00:00.000Z", lastEventAt: "2026-07-10T10:00:03.000Z", finishedAt: null, durationMs: null }
},
event: {
traceId: "trc_terminal",
sessionId: "ses_terminal",
sourceEventId: "evt_terminal",
sourceSeq: 5,
type: "assistant",
eventType: "assistant",
status: "completed",
terminal: true,
replyAuthority: true,
text: "durable final answer",
createdAt: "2026-07-10T10:00:04.000Z"
}
});
const turn = built.facts.turns[0];
assert.equal(turn.terminal, true);
assert.equal(turn.sealed, true);
assert.equal(turn.finalResponse.text, "durable final answer");
assert.equal(built.facts.messages[0].terminal, true);
assert.equal(built.facts.parts[0].partType, "final_response");
assert.equal(built.facts.checkpoints[0].projectionStatus, "caught_up");
});
test("completed terminal without final response remains visibly unsealed", () => {
const built = buildWorkbenchProjectionEventFacts({
projectedSeq: 1,
event: {
traceId: "trc_missing_final",
sessionId: "ses_missing_final",
sourceEventId: "evt_missing_final",
sourceSeq: 1,
type: "result",
eventType: "terminal",
status: "completed",
terminal: true,
createdAt: "2026-07-10T10:00:00.000Z"
}
});
const session = built.facts.sessions[0];
const message = built.facts.messages[0];
const turn = built.facts.turns[0];
const traceEvent = built.facts.traceEvents[0];
const checkpoint = built.facts.checkpoints[0];
for (const fact of [session, message, turn, traceEvent, checkpoint]) {
assert.equal(fact.status ?? "running", "running");
assert.equal(fact.terminal, false);
assert.equal(fact.sealed, false);
}
assert.equal(built.terminal, false);
assert.equal(built.sourceTerminal, true);
assert.equal(turn.finalResponse, null);
assert.equal(turn.diagnostic.terminalSealBlocked, true);
assert.equal(traceEvent.diagnostic.sourceStatus, "completed");
assert.equal(traceEvent.finishedAt, null);
assert.equal(traceEvent.durationMs, null);
assert.equal(checkpoint.projectionStatus, "projecting");
assert.equal(checkpoint.projectionHealth, "degraded");
const [sse] = projectionOutboxRealtimeEvents({
events: [{
outboxSeq: 1,
entityFamily: "traceEvents",
entityId: traceEvent.id,
projectedSeq: 1,
projectionRevision: 1,
traceId: traceEvent.traceId,
sessionId: traceEvent.sessionId,
commitType: "event",
terminal: traceEvent.terminal,
sealed: traceEvent.sealed,
payload: { family: "traceEvents", fact: traceEvent }
}]
});
assert.equal(sse.name, "workbench.trace.event");
assert.equal(sse.payload.terminal, false);
assert.equal(sse.payload.sealed, false);
assert.equal(sse.payload.snapshot.status, "running");
assert.equal(sse.payload.event.terminal, false);
});
test("late running event cannot overwrite a sealed terminal", () => {
const built = buildWorkbenchProjectionEventFacts({
projectedSeq: 10,
previousCheckpoint: {
traceId: "trc_sealed",
sessionId: "ses_sealed",
projectedSeq: 9,
sourceSeq: 9,
terminal: true,
sealed: true,
finalResponse: { text: "sealed answer", status: "completed" }
},
event: {
traceId: "trc_sealed",
sessionId: "ses_sealed",
sourceEventId: "evt_late",
sourceSeq: 8,
type: "backend",
status: "running"
}
});
assert.equal(built.written, false);
assert.equal(built.suppressedAfterSeal, true);
assert.equal(built.projectedSeq, 9);
assert.equal(built.sourceEventId, "evt_late");
assert.equal("facts" in built, false);
});
test("late terminal event cannot overwrite a different sealed terminal", () => {
const built = buildWorkbenchProjectionEventFacts({
projectedSeq: 11,
previousCheckpoint: {
traceId: "trc_sealed_terminal",
sessionId: "ses_sealed_terminal",
projectedSeq: 10,
sourceSeq: 10,
status: "completed",
terminal: true,
sealed: true,
finalResponse: { text: "immutable completed answer", status: "completed" }
},
event: {
traceId: "trc_sealed_terminal",
sessionId: "ses_sealed_terminal",
sourceEventId: "evt_late_failed_terminal",
sourceSeq: 11,
type: "terminal_status",
status: "failed",
terminal: true,
errorCode: "late-failure"
}
});
assert.equal(built.written, false);
assert.equal(built.suppressedAfterSeal, true);
assert.equal(built.projectedSeq, 10);
assert.equal(built.sourceEventId, "evt_late_failed_terminal");
assert.equal("facts" in built, false);
});
test("same canonical source event derives deterministic fact identities", () => {
const input = {
projectedSeq: 3,
projectedAt: "2026-07-10T10:00:03.000Z",
event: {
traceId: "trc_deterministic",
sessionId: "ses_deterministic",
sourceEventId: "evt_deterministic",
sourceSeq: 3,
type: "assistant",
eventType: "assistant",
status: "running",
text: "same",
createdAt: "2026-07-10T10:00:02.000Z"
}
};
const first = buildWorkbenchProjectionEventFacts(input);
const second = buildWorkbenchProjectionEventFacts(input);
assert.equal(first.facts.traceEvents[0].id, second.facts.traceEvents[0].id);
assert.equal(first.facts.messages[0].messageId, second.facts.messages[0].messageId);
assert.equal(first.facts.parts[0].partId, second.facts.parts[0].partId);
});