Files

1909 lines
84 KiB
TypeScript

import assert from "node:assert/strict";
import { mkdtemp, readFile, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { test } from "bun:test";
import { projectAgentRunKafkaEventToHwlabEvent, queryKafkaEventStream } from "../../internal/cloud/kafka-event-bridge.ts";
import { mapAgentRunRecordsToHwlabDebugEvents, projectHwlabRecordsThroughWorkbench, renderKafkaCliText, runKafkaCli } from "../src/hwlab-cli/kafka-regenerate.ts";
import { renderTraceRowsMarkdown, traceDisplayRows, traceToolSummary } from "../src/hwlab-cli/trace-renderer.ts";
const SESSION_ID = "ses_agentrun_5ec4e141_6abc_466d_9afe_049f7c0ac105";
const HWLAB_SESSION_ID = "ses_5ec4e141-6abc-466d-9afe-049f7c0ac105";
const TRACE_ID = "trc_mretx18t3jl4tg";
const RUN_ID = "run_a78cbcb05f2c4afaa748a3158db44998";
test("Kafka help shows canonical default input and explicit reconstruction debug input", async () => {
const result = await runKafkaCli(["help", "--json"], { env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(result.exitCode, 0);
assert.ok(result.payload.commands.some((command: string) => /regenerate hwlab.*--input-topic agentrun\.event\.v1/u.test(command)));
assert.ok(result.payload.commands.some((command: string) => /regenerate hwlab.*--input-topic agentrun\.event\.debug\.v1/u.test(command)));
assert.ok(result.payload.commands.some((command: string) => /render trace.*--input-topic hwlab\.event\.v1/u.test(command)));
assert.ok(result.payload.commands.some((command: string) => /inspect order.*--session-id ses_/u.test(command)));
});
test("Kafka session order inspection discovers a retained session and proves source through DOM order", async () => {
const firstTrace = "trc_order_first";
const secondTrace = "trc_order_second";
const agentrun = [
agentrunOrderRecord(1, firstTrace, "user_message", { userMessageId: "msg_order_first_user", text: "first input" }),
agentrunOrderRecord(2, firstTrace, "backend_status", { phase: "running", message: "first running" }),
agentrunOrderRecord(3, firstTrace, "assistant_message", { text: "first reply", replyAuthority: true, final: true }),
agentrunOrderRecord(4, firstTrace, "terminal_status", { terminalStatus: "completed", message: "completed" }),
agentrunOrderRecord(5, secondTrace, "user_message", { userMessageId: "msg_order_second_user", text: "second input" }),
agentrunOrderRecord(6, secondTrace, "backend_status", { phase: "running", message: "second running" })
];
const hwlab = agentrun.map((record, index) => hwlabOrderRecord(record, index));
const reads: any[] = [];
const result = await runKafkaCli([
"inspect", "order",
"--contains-text", "second input",
"--group-prefix", "hwlab-v03-workbench-isolated-debug-order-test",
"--json"
], {
env: {},
now: () => "2026-07-11T12:00:00.000Z",
async readKafka(input) {
reads.push(input);
return completeKafkaRead(input.stream === "agentrun" ? agentrun : hwlab);
}
});
assert.equal(result.exitCode, 0);
assert.equal(result.payload.scope.resolvedSessionId, HWLAB_SESSION_ID);
assert.equal(result.payload.scope.discovery.containsTextChars, 12);
assert.equal(result.payload.scope.discovery.matchedEventCount, 1);
assert.equal(result.payload.scope.discovery.candidates[0].offset, hwlab[4].offset);
assert.equal(reads.some((input) => input.stream === "agentrun" && input.sessionId === HWLAB_SESSION_ID), true);
assert.equal(result.payload.input.refreshHandoff.counts.replayed, 6);
assert.equal(result.payload.order.eventCount, 6);
assert.equal(result.payload.order.firstDivergence, null);
assert.deepEqual(result.payload.order.turnPairs.map((pair: any) => [pair.traceId, pair.dom.user, pair.dom.agent]), [
[firstTrace, 0, 1],
[secondTrace, 2, 3]
]);
assert.deepEqual(result.payload.projection.finalMessageOrder.map((row: any) => [row.role, row.traceId]), [
["user", firstTrace],
["agent", firstTrace],
["user", secondTrace],
["agent", secondTrace]
]);
assert.equal(result.payload.validation.mapperOneToOne, true);
assert.equal(result.payload.validation.sourceOrderPreserved, true);
assert.equal(result.payload.validation.sseOrderPreserved, true);
assert.equal(result.payload.validation.reducerOrderPreserved, true);
assert.equal(result.payload.validation.domTurnOrderPreserved, true);
assert.equal(result.payload.validation.noFirstDivergence, true);
});
test("Kafka session order inspection identifies AgentRun as the first layer when user_message is committed late", async () => {
const traceId = "trc_order_late_user";
const agentrun = [
agentrunOrderRecord(1, traceId, "backend_status", { phase: "running", message: "running before input" }),
agentrunOrderRecord(2, traceId, "user_message", { userMessageId: "msg_order_late_user", text: "late input" }),
agentrunOrderRecord(3, traceId, "assistant_message", { text: "reply", replyAuthority: true, final: true }),
agentrunOrderRecord(4, traceId, "terminal_status", { terminalStatus: "completed", message: "completed" })
];
const hwlab = agentrun.map((record, index) => hwlabOrderRecord(record, index));
const result = await runKafkaCli([
"inspect", "order",
"--session-id", HWLAB_SESSION_ID,
"--group-prefix", "hwlab-v03-workbench-isolated-debug-order-test",
"--json"
], {
env: {},
now: () => "2026-07-11T12:00:00.000Z",
async readKafka(input) {
return completeKafkaRead(input.stream === "agentrun" ? agentrun : hwlab);
}
});
assert.equal(result.exitCode, 0);
assert.equal(result.payload.order.firstDivergence.layer, "agentrun.event.v1");
assert.equal(result.payload.order.firstDivergence.code, "user-after-agent-source-event");
assert.deepEqual(result.payload.order.firstDivergence.evidence.agentrun, { user: 1, agent: 0 });
assert.deepEqual(result.payload.order.firstDivergence.evidence.dom, { user: 1, agent: 0 });
assert.equal(result.payload.validation.domTurnOrderPreserved, false);
assert.equal(result.payload.validation.noFirstDivergence, false);
});
test("offline HWLAB JSONL uses the shared Web pipeline and renders final response only outside Trace", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-render-"));
const inputFile = path.join(cwd, "hwlab-events.jsonl");
const outputFile = path.join(cwd, "trace.md");
const finalText = "Hi. What do you want to work on?";
const records = [
hwlabRecord(1, { type: "user", eventType: "user", status: "sent", label: "agentrun:user:message", userMessageId: "msg_render_trace_user", messageId: "msg_render_trace_user", targetTraceId: "trc_render_trace_target", text: "hi" }),
hwlabRecord(2, { type: "tool", eventType: "tool", status: "started", label: "agentrun:tool:commandExecution", toolName: "commandExecution", itemId: "tool_rg", command: "/bin/bash -lc 'cd /workspace && rg -n target src'" }),
hwlabRecord(3, { type: "tool", eventType: "tool", status: "completed", label: "agentrun:tool:commandExecution", toolName: "commandExecution", itemId: "tool_rg", command: "/bin/bash -lc 'cd /workspace && rg -n target src'", durationMs: 1234, exitCode: 0, stdoutSummary: "src/main.ts:42:target" }),
hwlabRecord(4, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_progress", message: "I am checking the workspace.", assistantText: "I am checking the workspace.", assistantSource: "agent-message" }),
hwlabRecord(5, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_final", message: finalText, assistantText: finalText, assistantSource: "completed-agent-message" }),
hwlabRecord(6, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_final", message: finalText, assistantText: finalText, assistantSource: "completed-agent-message-final", replyAuthority: true, final: true, finalResponse: { text: finalText } }),
hwlabRecord(7, { type: "result", eventType: "terminal", status: "completed", label: "agentrun:terminal:completed", terminal: true, message: "AgentRun completed" })
];
await writeFile(inputFile, records.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"render", "trace",
"--from", "jsonl",
"--trace-id", TRACE_ID,
"--session-id", HWLAB_SESSION_ID,
"--run-id", RUN_ID,
"--command-id", "cmd_render_trace",
"--jsonl-file", inputFile,
"--output-markdown", outputFile,
"--format", "markdown"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(result.exitCode, 0);
assert.equal(result.payload.input.scannedCount, 7);
assert.equal(result.payload.input.matchedCount, 7);
assert.equal(result.payload.projection.decodedCount, 7);
assert.equal(result.payload.projection.appliedCount, 7);
assert.equal(result.payload.projection.eventCount, 6, "formal user input must not create an agent trace event");
assert.equal(result.payload.projection.userMessageCount, 1);
assert.deepEqual(result.payload.projection.userMessageIds, ["msg_render_trace_user"]);
assert.deepEqual(result.payload.projection.userTargetTraceIds, ["trc_render_trace_target"]);
assert.equal(result.payload.projection.terminalObserved, true);
assert.equal(result.payload.projection.lastEventAt, "2026-07-10T12:00:00.006Z");
assert.deepEqual(result.payload.identity.observedRunIds, [RUN_ID]);
assert.deepEqual(result.payload.identity.observedCommandIds, ["cmd_render_trace"]);
assert.equal(result.payload.identity.sourceEventIdentityDuplicates, 0);
assert.equal(result.payload.render.toolRowCount, 1);
assert.equal(result.payload.render.assistantRowCount, 1);
assert.equal(result.payload.render.finalResponsePresent, true);
assert.equal(result.payload.render.finalResponseInTrace, false);
assert.deepEqual(result.payload.replayLineage.counts, { source: 7, applied: 7, assistant: 1, tool: 1, terminal: 1, final: 1 });
assert.deepEqual(result.payload.replayLineage.layers.source, {
total: 7,
user: 1,
assistant: 3,
tool: 2,
terminal: 1,
final: 1,
other: 1,
assistantDuplicate: { fingerprintCount: 0, occurrenceCount: 0, first: null, valuesPrinted: false }
});
assert.equal(result.payload.replayLineage.layers.final.duplicatedInRender, false);
assert.equal(result.payload.replayLineage.firstVisibleDuplicateLayer, null);
assert.equal(result.payload.render.rowsReturned, result.payload.render.rowCount);
assert.equal(result.payload.render.rowsOmitted, 0);
assert.equal(result.payload.validation.allMatchedEventsApplied, true);
assert.equal(result.payload.validation.finalResponseOutsideTrace, true);
const toolRow = result.payload.render.rows.find((row: any) => row.rowId.startsWith("tool:"));
assert.match(toolRow.header, /^\d{2}:\d{2}:\d{2}$/u);
assert.doesNotMatch(toolRow.header, /\b(?:ok|fail|run|running)\b|total=|duration=|exit=/u);
assert.equal(toolRow.toolState, "success");
assert.equal(toolRow.statusLabel, "工具调用成功");
assert.equal(toolRow.preview, "cd /workspace && rg -n target src");
const markdown = await readFile(outputFile, "utf8");
assert.equal((markdown.match(new RegExp(finalText.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"), "gu")) ?? []).length, 1);
assert.equal((markdown.match(/^hi$/gmu) ?? []).length, 1);
assert.match(markdown, /## 用户输入/u);
assert.match(markdown, /target trace: trc_render_trace_target/u);
assert.match(markdown, /## 运行记录/u);
assert.match(markdown, /## 最终回复/u);
assert.match(markdown, /<summary aria-label="工具调用成功:[^"]+" title="工具调用成功:[^"]+"><code>\d{2}:\d{2}:\d{2}<\/code> cd \/workspace &amp;&amp; rg -n target src<\/summary>/u);
assert.doesNotMatch(markdown.match(/<summary[^>]*>[\s\S]*?<\/summary>/u)?.[0] ?? "", /total=|duration=|exit=|src\/main\.ts:42:target|总耗时/u);
assert.equal(result.markdownOutput?.trim(), markdown.trim());
});
test("trace lineage reports the first non-final assistant content duplicate without printing message text", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-duplicate-lineage-"));
const duplicateText = "I am checking the workspace.";
const records = [
hwlabRecord(1, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_first", message: duplicateText, assistantText: duplicateText }),
hwlabRecord(2, { type: "tool", eventType: "tool", status: "completed", label: "agentrun:tool:commandExecution", toolName: "commandExecution", itemId: "tool_between", command: "rg target", exitCode: 0 }),
hwlabRecord(3, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_repeated", message: duplicateText, assistantText: duplicateText }),
hwlabRecord(4, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_final", message: "Done.", assistantText: "Done.", replyAuthority: true, final: true, finalResponse: { text: "Done." } }),
hwlabRecord(5, { type: "result", eventType: "terminal", status: "completed", label: "agentrun:terminal:completed", terminal: true })
];
const inputFile = path.join(cwd, "hwlab-events.jsonl");
await writeFile(inputFile, records.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"render", "trace",
"--from", "jsonl",
"--trace-id", TRACE_ID,
"--jsonl-file", inputFile,
"--format", "markdown"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(result.exitCode, 0);
assert.deepEqual(result.payload.replayLineage.counts, { source: 5, applied: 5, assistant: 2, tool: 1, terminal: 1, final: 1 });
assert.equal(result.payload.replayLineage.firstVisibleDuplicateLayer, "source");
assert.equal(result.payload.replayLineage.layers.source.assistantDuplicate.occurrenceCount, 1);
assert.equal(result.payload.replayLineage.layers.applied.assistantDuplicate.occurrenceCount, 1);
assert.equal(result.payload.replayLineage.layers.render.assistantDuplicate.occurrenceCount, 1);
assert.equal(result.payload.replayLineage.layers.source.assistantDuplicate.first.first.identity, "evt_render_1");
assert.equal(result.payload.replayLineage.layers.source.assistantDuplicate.first.duplicate.identity, "evt_render_3");
assert.doesNotMatch(JSON.stringify(result.payload.replayLineage), new RegExp(duplicateText.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"), "u"));
assert.match(renderKafkaCliText(result.payload), /assistant=2 tool=1 terminalRows=1 final=1 duplicateLayer=source/u);
});
test("shared row model removes late assistant progress after the same item completed", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-assistant-item-lifecycle-"));
const inputFile = path.join(cwd, "hwlab-events.jsonl");
const duplicateText = "The completed assistant item must stay visible once.";
const records = [
hwlabRecord(1, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_item", assistantSource: "completed-agent-message", message: duplicateText, assistantText: duplicateText }),
hwlabRecord(2, { type: "tool", eventType: "tool", status: "completed", label: "agentrun:tool:commandExecution", toolName: "commandExecution", itemId: "tool_between", command: "rg target", exitCode: 0 }),
hwlabRecord(3, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_item", assistantSource: "agent-message-delta-progress", message: duplicateText, assistantText: duplicateText }),
hwlabRecord(4, { type: "assistant", eventType: "assistant", status: "running", label: "agentrun:assistant:message", itemId: "assistant_final", assistantSource: "completed-agent-message-final", message: "Done.", assistantText: "Done.", replyAuthority: true, final: true, finalResponse: { text: "Done." } }),
hwlabRecord(5, { type: "result", eventType: "terminal", status: "completed", label: "agentrun:terminal:completed", terminal: true })
];
await writeFile(inputFile, records.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"render", "trace",
"--from", "jsonl",
"--trace-id", TRACE_ID,
"--jsonl-file", inputFile,
"--format", "markdown"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(result.exitCode, 0);
assert.deepEqual(result.payload.replayLineage.counts, { source: 5, applied: 5, assistant: 1, tool: 1, terminal: 1, final: 1 });
assert.equal(result.payload.replayLineage.layers.source.assistantDuplicate.occurrenceCount, 1);
assert.equal(result.payload.replayLineage.layers.applied.assistantDuplicate.occurrenceCount, 1);
assert.equal(result.payload.replayLineage.layers.render.assistantDuplicate.occurrenceCount, 0);
assert.equal(result.payload.replayLineage.firstVisibleDuplicateLayer, "source");
assert.equal((result.markdownOutput?.match(new RegExp(duplicateText.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"), "gu")) ?? []).length, 1);
});
test("fixed Kafka assistant lifecycle replays 500/1003 byte progress into one 1190 byte final", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-assistant-progress-contract-"));
const inputFile = path.join(cwd, "hwlab-events.jsonl");
const itemId = "msg_0d2ec_assistant_lifecycle";
const finalText = "x".repeat(1190);
const progress500 = finalText.slice(0, 500);
const progress1003 = finalText.slice(0, 1003);
assert.deepEqual([Buffer.byteLength(progress500), Buffer.byteLength(progress1003), Buffer.byteLength(finalText)], [500, 1003, 1190]);
const agentrunRecords = [
agentrunAssistantLifecycleRecord(136, 1, "assistant_progress", {
text: progress500,
itemId,
source: "agent-message-delta-progress",
progress: true,
progressFlush: false,
replyAuthority: false,
final: false,
textBytes: 500,
outputBytes: 500,
valuesPrinted: false
}),
agentrunAssistantLifecycleRecord(137, 2, "assistant_progress", {
text: progress1003,
itemId,
source: "agent-message-delta-progress",
progress: true,
progressFlush: false,
replyAuthority: false,
final: false,
textBytes: 1003,
outputBytes: 1003,
valuesPrinted: false
}),
agentrunAssistantLifecycleRecord(138, 3, "assistant_message", {
text: finalText,
itemId,
source: "completed-agent-message",
durableText: true,
replyAuthority: false,
final: false,
textBytes: 1190,
outputBytes: 1190,
valuesPrinted: false
}),
agentrunAssistantLifecycleRecord(142, 4, "backend_status", {
phase: "assistant-message-final-sealed",
itemId,
source: "assistant-message-final-seal",
finalSeal: true,
replyAuthority: true,
final: true,
replyRef: {
eventType: "assistant_message",
itemId,
source: "completed-agent-message",
textSha256: "a".repeat(64)
},
valuesPrinted: false
}),
agentrunAssistantLifecycleRecord(143, 5, "terminal_status", {
terminalStatus: "completed",
valuesPrinted: false
})
];
const hwlabRecords = agentrunRecords.map((record, index) => hwlabOrderRecord(record, index));
const hwlabEvents = hwlabRecords.map((record) => record.value.event);
assert.deepEqual(hwlabRecords.map((record) => record.value.context.agentRunEventType), [
"assistant_progress",
"assistant_progress",
"assistant_message",
"backend_status",
"terminal_status"
]);
assert.deepEqual(hwlabEvents.slice(0, 3).map((event) => [event.itemId, event.sourceSeq, event.progress, event.assistantText.length]), [
[itemId, 136, true, 500],
[itemId, 137, true, 1003],
[itemId, 138, false, 1190]
]);
assert.equal(hwlabEvents[3]?.finalSeal, true);
assert.equal(hwlabEvents[3]?.message, "assistant-message-final-sealed");
assert.equal(hwlabEvents[3]?.assistantText, undefined, "seal must not copy the completed body");
assert.equal(hwlabEvents[4]?.assistantText, undefined, "terminal must not copy the completed body");
const runningRows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, hwlabEvents.slice(0, 2));
assert.equal(runningRows.filter((row) => /助手/u.test(row.header)).length, 1);
assert.equal(runningRows.find((row) => /助手/u.test(row.header))?.seq, 137);
assert.equal(runningRows.find((row) => /助手/u.test(row.header))?.body, progress1003);
const completedRows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, hwlabEvents.slice(0, 3));
assert.equal(completedRows.filter((row) => /助手/u.test(row.header)).length, 1);
assert.equal(completedRows.find((row) => /助手/u.test(row.header))?.seq, 138);
assert.equal(completedRows.find((row) => /助手/u.test(row.header))?.body, finalText);
const projected = projectHwlabRecordsThroughWorkbench(hwlabRecords, {
traceId: TRACE_ID,
sessionId: HWLAB_SESSION_ID,
observedAt: "2026-07-12T10:01:00.000Z"
});
assert.equal(projected.appliedCount, 5);
assert.equal(projected.sourceEvents.length, 5);
assert.equal(projected.message?.runnerTrace?.events?.length, 5, "raw/applied observation must retain every unfiltered event");
assert.equal(projected.message?.text, finalText);
assert.equal(projected.message?.status, "completed");
assert.equal((projected.message?.finalResponse as { text?: string } | null)?.text, finalText);
await writeFile(inputFile, hwlabRecords.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"render", "trace",
"--from", "jsonl",
"--trace-id", TRACE_ID,
"--session-id", HWLAB_SESSION_ID,
"--jsonl-file", inputFile,
"--format", "markdown"
], { cwd, env: {}, now: () => "2026-07-12T10:02:00.000Z" });
assert.equal(result.exitCode, 0);
assert.equal(result.payload.projection.appliedCount, 5);
assert.equal(result.payload.projection.eventCount, 5);
assert.equal(result.payload.render.assistantRowCount, 0, "the authoritative outer final replaces the progress lifecycle");
assert.equal(result.payload.render.finalResponsePresent, true);
assert.equal(result.payload.render.finalResponseInTrace, false);
assert.deepEqual(result.payload.replayLineage.counts, { source: 5, applied: 5, assistant: 0, tool: 0, terminal: 1, final: 1 });
assert.equal(result.payload.replayLineage.layers.source.assistant, 3, "raw source lineage must keep both progress snapshots and the durable completion");
assert.equal(result.payload.replayLineage.layers.applied.assistant, 3);
assert.equal(result.payload.validation.allMatchedEventsApplied, true);
assert.equal(result.payload.validation.finalResponseOutsideTrace, true);
assert.equal(result.markdownOutput?.split(finalText).length, 2, "the final body must render exactly once");
const traceMarkdown = (result.markdownOutput ?? "").split("## 运行记录")[1]?.split("## 最终回复")[0] ?? "";
assert.doesNotMatch(traceMarkdown, /x{500}/u, "progress must not remain as a separate rendered row");
});
test("HWLAB compatibility window coalesces legacy assistant_message progress before AgentRun assistant_progress rollout", () => {
const itemId = "msg_legacy_progress_contract";
const finalText = "legacy durable body";
const agentrunRecords = [
agentrunAssistantLifecycleRecord(201, 1, "assistant_message", {
text: "legacy progress 1",
itemId,
source: "agent-message-delta-progress",
progress: true,
progressFlush: false,
replyAuthority: false,
final: false
}),
agentrunAssistantLifecycleRecord(202, 2, "assistant_message", {
text: "legacy progress 2",
itemId,
source: "agent-message-delta-progress",
progress: true,
progressFlush: true,
replyAuthority: false,
final: false
}),
agentrunAssistantLifecycleRecord(203, 3, "assistant_message", {
text: finalText,
itemId,
source: "completed-agent-message",
durableText: true,
replyAuthority: false,
final: false
}),
agentrunAssistantLifecycleRecord(204, 4, "terminal_status", { terminalStatus: "completed" })
];
const hwlabRecords = agentrunRecords.map((record, index) => hwlabOrderRecord(record, index));
const events = hwlabRecords.map((record) => record.value.event);
assert.deepEqual(events.slice(0, 2).map((event) => [event.agentRunEventType, event.eventType, event.progress]), [
["assistant_message", "assistant", true],
["assistant_message", "assistant", true]
]);
const rows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, events.slice(0, 3));
const assistantRows = rows.filter((row) => /助手/u.test(row.header));
assert.equal(assistantRows.length, 1);
assert.equal(assistantRows[0]?.seq, 203);
assert.equal(assistantRows[0]?.body, finalText);
const projected = projectHwlabRecordsThroughWorkbench(hwlabRecords, {
traceId: TRACE_ID,
sessionId: HWLAB_SESSION_ID,
observedAt: "2026-07-12T10:03:00.000Z"
});
assert.equal(projected.message?.text, finalText);
assert.equal(projected.message?.runnerTrace?.events?.length, 4);
assert.equal((projected.message?.finalResponse as { text?: string } | null)?.text, finalText);
const finalRows = traceDisplayRows(projected.message?.runnerTrace ?? {}, projected.message?.runnerTrace?.events ?? [], {
finalResponsePlacement: "outer",
outerFinalResponseText: finalText
});
assert.equal(finalRows.filter((row) => /助手/u.test(row.header)).length, 0);
});
test("shared tool summary model keeps status semantic and visible content status-free", () => {
const rows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, [
{
sourceSeq: 1,
sourceEventId: "evt_tool_running",
type: "tool_call",
status: "running",
label: "agentrun:tool:commandExecution:started",
toolName: "commandExecution",
itemId: "tool_running",
command: "bun test active-fixture",
createdAt: "2026-07-10T11:00:01.000Z"
},
{
sourceSeq: 2,
sourceEventId: "evt_tool_success",
type: "tool_call",
status: "completed",
label: "agentrun:tool:commandExecution:completed",
toolName: "commandExecution",
itemId: "tool_success",
command: "find . -maxdepth 3 -name package.json -o -name tsconfig.json -o -name vitest.config.ts",
durationMs: 1234,
exitCode: 0,
stdoutSummary: "src/main.ts:1:success",
createdAt: "2026-07-10T11:00:02.000Z"
},
{
sourceSeq: 3,
sourceEventId: "evt_tool_failure",
type: "tool_call",
status: "completed",
label: "agentrun:tool:commandExecution:completed",
toolName: "commandExecution",
itemId: "tool_failure",
command: "bun test failure-fixture",
durationMs: 2345,
exitCode: 1,
stderrSummary: "failure output",
createdAt: "2026-07-10T11:00:03.000Z"
},
{
sourceSeq: 4,
sourceEventId: "evt_tool_output_chunk",
type: "tool_call",
status: "output_chunk",
label: "item/commandExecution/outputDelta",
outputSummary: "streamed output",
createdAt: "2026-07-10T11:00:04.000Z"
}
]).filter((row) => row.rowId.startsWith("tool:"));
assert.deepEqual(rows.map((row) => row.toolState), ["running", "success", "failure", "running"]);
assert.deepEqual(rows.map((row) => row.tone), ["warn", "ok", "blocked", "warn"]);
assert.deepEqual(rows.map((row) => row.statusLabel), ["工具调用中", "工具调用成功", "工具调用失败", "工具调用中"]);
assert.ok(rows.every((row) => /^\d{2}:\d{2}:\d{2}$/u.test(row.header)));
assert.equal(rows[1]!.preview, "find . -maxdepth 3 -name package.json -o -name tsconfig.json -o -name vitest.config.ts");
assert.equal(rows[2]!.preview, "bun test failure-fixture");
assert.doesNotMatch(rows[3]!.header, /commandExecution|outputDelta/u);
const markdown = renderTraceRowsMarkdown(rows);
const visibleSummaries = [...markdown.matchAll(/<summary[^>]*>([\s\S]*?)<\/summary>/gu)].map((match) => match[1]);
assert.equal(visibleSummaries.length, 4);
for (const [index, summary] of visibleSummaries.entries()) {
assert.equal(summary, `<code>${rows[index]!.header}</code> ${traceToolSummary(rows[index]!)}`);
assert.doesNotMatch(summary, /\b(?:ok|fail|run|running)\b|total=|duration=|exit=/u);
}
assert.match(visibleSummaries[1]!, /^<code>\d{2}:\d{2}:\d{2}<\/code> find \. -maxdepth 3/u);
assert.match(markdown, /aria-label="工具调用中:/u);
assert.match(markdown, /aria-label="工具调用成功:/u);
assert.match(markdown, /aria-label="工具调用失败:/u);
});
test("fileChange and turn diff render real paths and unified diff as valid Markdown cards", () => {
const fileDiff = "@@ -1 +1 @@\n-export const value = 1;\n+export const value = 2;";
const aggregateDiff = `${fileDiff}\n@@ -0,0 +1 @@\n+# 文件编辑可见`;
const rows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, [
{
sourceSeq: 21,
sourceEventId: "evt_file_change_completed",
type: "tool_call",
eventType: "tool_call",
status: "completed",
label: "agentrun:tool:fileChange",
toolName: "fileChange",
toolType: "fileChange",
itemId: "item_file_change",
changes: [
{ path: "src/example.ts", kind: "update", diff: fileDiff },
{ path: "docs/说明.md", kind: "add", diff: "@@ -0,0 +1 @@\n+# 文件编辑可见" }
],
createdAt: "2026-07-12T15:00:01.000Z"
},
{
sourceSeq: 22,
sourceEventId: "evt_turn_diff_updated",
type: "diff",
eventType: "diff",
status: "updated",
label: "agentrun:diff",
diff: aggregateDiff,
message: aggregateDiff,
createdAt: "2026-07-12T15:00:02.000Z"
}
]);
const markdown = renderTraceRowsMarkdown(rows);
assert.equal(rows.length, 2);
assert.match(markdown, /2 个文件 · \+2 -1 · src\/example\.ts, docs\/说明\.md/u);
assert.match(markdown, /#### `src\/example\.ts`/u);
assert.match(markdown, /#### `docs\/说明\.md`/u);
assert.match(markdown, /\+export const value = 2;/u);
assert.match(markdown, /文件 diff 已更新/u);
assert.match(markdown, /\+# 文件编辑可见/u);
assert.equal((markdown.match(/<details>/gu) ?? []).length, 2);
assert.equal((markdown.match(/<\/details>/gu) ?? []).length, 2);
assert.ok(rows.every((row) => row.bodyFormat === "markdown"));
});
test("fileChange rendering uses preserved stats and ignores historical object coercion", () => {
const rows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, [
{
sourceSeq: 53,
type: "tool",
eventType: "tool",
status: "completed",
label: "agentrun:tool:fileChange",
toolName: "fileChange",
itemId: "item_large_file_change",
changes: [{ path: "/agentrun-workspace/src/large.ts", kind: "add", additions: 400, deletions: 0, diffTruncated: true }],
message: "bounded file change metadata",
createdAt: "2026-07-21T08:04:30.452Z"
},
{
sourceSeq: 54,
type: "tool",
eventType: "tool",
status: "completed",
label: "agentrun:tool:fileChange",
toolName: "fileChange",
itemId: "item_historical_file_change",
message: "[object Object]",
createdAt: "2026-07-21T08:04:31.452Z"
}
]);
assert.equal(rows[0]?.preview, "src/large.ts · +400 -0");
assert.match(rows[0]?.body ?? "", /新增 · \+400 -0/u);
assert.doesNotMatch(JSON.stringify(rows), /\[object Object\]/u);
assert.equal(rows[1]?.body, null);
assert.equal(rows[1]?.preview, "fileChange");
});
test("outer final response suppression follows formal assistant identity instead of equal text", () => {
const finalText = "Hi. What do you want to work on?";
const rows = traceDisplayRows({ eventSource: "hwlab-kafka-sse" }, [
{
sourceSeq: 1,
sourceEventId: "evt_same_text",
type: "assistant",
eventType: "assistant",
status: "running",
label: "agentrun:assistant:message",
itemId: "assistant_same_text",
message: finalText,
assistantText: finalText,
assistantSource: "completed-agent-message"
},
{
sourceSeq: 2,
sourceEventId: "evt_final",
type: "assistant",
eventType: "assistant",
status: "running",
label: "agentrun:assistant:message",
itemId: "assistant_final",
message: finalText,
assistantText: finalText,
assistantSource: "completed-agent-message-final",
finalResponse: { text: finalText },
final: true,
replyAuthority: true
}
], {
finalResponsePlacement: "outer",
outerFinalResponseText: finalText
});
assert.equal(rows.length, 1);
assert.equal(rows[0]?.rowId, "event:evt_same_text");
assert.equal(rows[0]?.body, finalText, "a distinct itemId with equal text must remain visible");
});
test("trace JSON defaults to a bounded tail while the Markdown artifact stays complete", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-window-"));
const inputFile = path.join(cwd, "hwlab-events.jsonl");
const records = Array.from({ length: 25 }, (_, index) => hwlabRecord(index + 1, {
type: "assistant",
eventType: "assistant",
status: "running",
label: "agentrun:assistant:message",
itemId: `assistant_${index + 1}`,
message: `progress ${index + 1}`,
assistantText: `progress ${index + 1}`
}));
records.push(hwlabRecord(26, { type: "result", eventType: "terminal", status: "completed", label: "agentrun:terminal:completed", terminal: true }));
await writeFile(inputFile, records.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"render", "trace",
"--from", "jsonl",
"--trace-id", TRACE_ID,
"--jsonl-file", inputFile,
"--row-limit", "5",
"--format", "markdown"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(result.exitCode, 0);
assert.equal(result.payload.render.rowCount, 25);
assert.equal(result.payload.render.rowsReturned, 5);
assert.equal(result.payload.render.rowsOmitted, 20);
assert.equal(result.payload.render.rowWindow, "tail");
assert.match(result.markdownOutput, /progress 1/u);
assert.match(result.markdownOutput, /progress 24/u);
});
test("command-scoped trace keeps attributable commandless final and terminal lifecycle events", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-command-scope-"));
const finalText = "Hi. What do you want to work on?";
const exactTool = hwlabRecord(1, {
type: "tool",
eventType: "tool",
status: "completed",
label: "agentrun:tool:commandExecution",
toolName: "commandExecution",
itemId: "tool_command_scope",
command: "rg -n target src",
exitCode: 0
});
const exactProgress = hwlabRecord(2, {
type: "assistant",
eventType: "assistant",
status: "running",
itemId: "assistant_progress",
assistantText: "Checking the workspace."
});
const unscopedFinal = withoutCommandId(hwlabRecord(3, {
type: "assistant",
eventType: "assistant",
status: "running",
itemId: "assistant_final",
assistantText: finalText,
finalResponse: { text: finalText },
final: true,
replyAuthority: true
}));
const unscopedTerminal = withoutCommandId(hwlabRecord(4, {
type: "result",
eventType: "terminal",
status: "completed",
terminal: true,
message: "AgentRun completed"
}));
const runnerShutdown = withCommandId(hwlabRecord(5, {
type: "backend",
eventType: "backend",
status: "running",
message: "runner shutdown"
}), "runner-shutdown");
const unscopedBackend = withoutCommandId(hwlabRecord(6, {
type: "backend",
eventType: "backend",
status: "running",
message: "unscoped heartbeat"
}));
let readerInput: any = null;
const result = await runKafkaCli([
"render", "trace",
"--from", "kafka",
"--trace-id", TRACE_ID,
"--session-id", HWLAB_SESSION_ID,
"--run-id", RUN_ID,
"--command-id", "cmd_render_trace",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--row-limit", "2",
"--format", "markdown"
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka(input) {
readerInput = input;
const events = [exactTool, exactProgress, unscopedFinal, unscopedTerminal, runnerShutdown, unscopedBackend];
return {
...completeKafkaRead(events),
scannedCount: 6,
parsedCount: 6,
matchedCount: 6,
filterRejectedCount: 0
};
}
});
assert.equal(result.exitCode, 0);
assert.equal(readerInput.commandId, undefined, "commandId must not be pushed down before lifecycle attribution");
assert.equal(readerInput.runId, RUN_ID);
assert.equal(result.payload.input.queryMatchedCount, 6);
assert.equal(result.payload.input.matchedCount, 4);
assert.equal(result.payload.input.refreshHandoff.status, "succeeded");
assert.equal(result.payload.input.refreshHandoff.liveSubscriptionInstalled, true);
assert.equal(result.payload.input.refreshHandoff.counts.replayed, 6);
assert.deepEqual(result.payload.input.refreshHandoff.barrier, [{ partition: 0, endOffset: "1907" }]);
assert.deepEqual(result.payload.input.commandScope.commandIdCounts, [
{ commandId: "cmd_render_trace", count: 2 },
{ commandId: "runner-shutdown", count: 1 }
]);
assert.equal(result.payload.input.commandScope.missingCommandIdCount, 3);
assert.equal(result.payload.input.commandScope.unscopedLifecycleCount, 2);
assert.equal(result.payload.input.commandScope.selectedUnscopedLifecycleCount, 2);
assert.equal(result.payload.input.commandScope.unscopedNonLifecycleCount, 1);
assert.equal(result.payload.input.commandScope.otherCommandRecordCount, 1);
assert.equal(result.payload.projection.eventCount, 4);
assert.equal(result.payload.projection.terminalObserved, true);
assert.equal(result.payload.projection.pipeline[0], "createWorkbenchKafkaRefreshHandoff");
assert.equal(result.payload.render.finalResponseInTrace, false);
assert.equal(result.payload.validation.commandLifecyclePreserved, true);
assert.equal((result.markdownOutput?.match(/Hi\. What do you want to work on\?/gu) ?? []).length, 1);
});
test("missing commandId cannot be satisfied by commandless lifecycle events from the same run", async () => {
const otherCommand = withCommandId(hwlabRecord(1, {
type: "tool",
eventType: "tool",
status: "completed",
label: "agentrun:tool:commandExecution",
itemId: "tool_other_command",
command: "rg -n target src",
exitCode: 0
}), "cmd_other");
const commandlessFinal = withoutCommandId(hwlabRecord(2, {
type: "assistant",
eventType: "assistant",
status: "running",
itemId: "assistant_final",
assistantText: "This belongs to the existing command.",
finalResponse: { text: "This belongs to the existing command." },
final: true,
replyAuthority: true
}));
const commandlessTerminal = withoutCommandId(hwlabRecord(3, {
type: "result",
eventType: "terminal",
status: "completed",
terminal: true
}));
const result = await runKafkaCli([
"render", "trace",
"--from", "kafka",
"--trace-id", TRACE_ID,
"--session-id", HWLAB_SESSION_ID,
"--run-id", RUN_ID,
"--command-id", "cmd_missing",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--format", "markdown"
], {
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() {
const events = [otherCommand, commandlessFinal, commandlessTerminal];
return {
...completeKafkaRead(events),
scannedCount: 3,
parsedCount: 3,
matchedCount: 3,
filterRejectedCount: 0
};
}
});
assert.equal(result.exitCode, 1);
assert.equal(result.payload.error.code, "source_command_missing");
assert.equal(result.payload.error.details.commandScope.exactCommandCount, 0);
assert.equal(result.payload.error.details.commandScope.selectedCount, 0);
assert.equal(result.payload.error.details.commandScope.selectedUnscopedLifecycleCount, 0);
});
test("Kafka Trace render returns a typed partial result when the captured end offsets were not reached", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-partial-"));
const record = hwlabRecord(1, {
type: "assistant",
eventType: "assistant",
status: "running",
itemId: "assistant_partial",
assistantText: "Partial trace row"
});
const result = await runKafkaCli([
"render", "trace",
"--from", "kafka",
"--trace-id", TRACE_ID,
"--session-id", HWLAB_SESSION_ID,
"--run-id", RUN_ID,
"--command-id", "cmd_render_trace",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--format", "markdown"
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() {
return {
events: [record],
scannedCount: 1,
parsedCount: 1,
matchedCount: 1,
filterRejectedCount: 0,
completionReason: "timeout",
reachedEndOffsets: false,
endOffsetsAvailable: false,
endOffsetsError: { code: "ENOTFOUND", message: "broker metadata hostname unresolved", valuesRedacted: true },
endOffsets: [],
completion: { reason: "timeout", complete: false, barrierReached: false, retentionStartVerified: true },
lastScannedOffsets: [{ partition: 0, offset: "0" }]
};
}
});
assert.equal(result.exitCode, 2);
assert.equal(result.payload.input.endOffsetsError.code, "ENOTFOUND");
assert.equal(result.payload.ok, false);
assert.equal(result.payload.status, "partial");
assert.equal(result.payload.error.code, "source_scan_incomplete");
assert.equal(result.payload.input.scanComplete, false);
assert.equal(result.payload.input.completionReason, "timeout");
assert.equal(result.payload.input.refreshHandoff.status, "failed");
assert.equal(result.payload.input.refreshHandoff.error.code, "workbench_kafka_refresh_timeout");
assert.equal(result.payload.validation.sourceScanComplete, false);
assert.equal(result.payload.validation.commandLifecyclePreserved, false);
assert.match(result.markdownOutput ?? "", /source scan: partial \(timeout\)/u);
assert.equal(typeof result.payload.output.artifact.path, "string");
assert.match(renderKafkaCliText(result.payload), /^partial action=kafka\.render\.trace code=source_scan_incomplete completion=timeout reachedEnd=false/u);
});
test("incomplete zero-match Kafka scan stays partial and never claims the trace is missing", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-trace-empty-partial-"));
const result = await runKafkaCli([
"render", "trace",
"--from", "kafka",
"--trace-id", TRACE_ID,
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--format", "markdown"
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() {
return {
events: [],
scannedCount: 0,
parsedCount: 0,
matchedCount: 0,
filterRejectedCount: 0,
completionReason: "timeout",
reachedEndOffsets: false,
endOffsetsAvailable: true,
endOffsets: [{ partition: 0, startOffset: "0", endOffset: "12" }],
completion: { reason: "timeout", complete: false, barrierReached: false, retentionStartVerified: true },
lastScannedOffsets: []
};
}
});
assert.equal(result.exitCode, 2);
assert.equal(result.payload.status, "partial");
assert.equal(result.payload.error.code, "source_scan_incomplete");
assert.notEqual(result.payload.error.code, "source_trace_missing");
assert.equal(result.payload.input.scannedCount, 0);
assert.equal(result.payload.input.matchedCount, 0);
assert.equal(result.payload.input.scanComplete, false);
assert.equal(result.payload.input.refreshHandoff.status, "failed");
assert.equal(result.payload.input.refreshHandoff.error.code, "workbench_kafka_refresh_timeout");
assert.equal(result.payload.validation.refreshHandoffComplete, false);
assert.match(result.markdownOutput ?? "", /source scan: partial \(timeout\)/u);
assert.equal(typeof result.payload.output.artifact.path, "string");
assert.match(renderKafkaCliText(result.payload), /^partial action=kafka\.render\.trace code=source_scan_incomplete completion=timeout reachedEnd=false scanned=0 matched=0 applied=0/u);
});
test("offline JSONL maps 35 stdio reconstructions to 35 ordered HWLAB debug events without runtime dependencies", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-jsonl-"));
const inputFile = path.join(cwd, "agentrun-events.jsonl");
const outputFile = path.join(cwd, "hwlab-events.jsonl");
const records = Array.from({ length: 35 }, (_, index) => reconstructionRecord(index + 1));
await writeFile(inputFile, records.map((record) => JSON.stringify(record)).join("\n") + "\n", "utf8");
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "jsonl",
"--session-id", SESSION_ID,
"--trace-id", TRACE_ID,
"--replay-id", "rpl_offline_35",
"--jsonl-file", inputFile,
"--output-jsonl", outputFile,
"--expect-count", "35",
"--no-publish",
"--json"
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async createProducer() { throw new Error("offline JSONL must not create a producer"); }
});
assert.equal(result.exitCode, 0);
assert.equal(result.payload.input.readCount, 35);
assert.equal(result.payload.output.count, 35);
assert.equal(result.payload.output.publishedCount, 0);
assert.deepEqual(result.payload.validation, {
expectedCount: 35,
sourceScanComplete: true,
oneToOne: true,
orderPreserved: true,
lineagePreserved: true,
firstSourceSeq: 1,
lastSourceSeq: 35,
inputKinds: ["stdio-derived partial reconstruction"]
});
assert.deepEqual(result.payload.runtimeDependencies, {
cloudApi: false,
database: false,
transactionalProjector: false,
kafka: false
});
const output = (await readFile(outputFile, "utf8")).trim().split("\n").map(JSON.parse);
assert.equal(output.length, 35);
assert.deepEqual(output.map((row) => row.value.debugLineage.sourceSeq), Array.from({ length: 35 }, (_, index) => index + 1));
assert.ok(output.every((row) => row.topic === "hwlab.event.debug.v1"));
assert.ok(output.every((row) => row.value.schema === "hwlab.event.debug.v1"));
assert.ok(output.every((row) => row.partition === 0));
assert.ok(output.every((row) => row.value.replayId === "rpl_offline_35"));
assert.deepEqual(output.map((row) => row.value.debugReplay.index), Array.from({ length: 35 }, (_, index) => index + 1));
assert.ok(output.every((row) => row.value.eventId === null && row.value.sourceEventId === null && row.value.outboxSeq === null));
assert.ok(output.every((row) => row.value.debugLineage.inputEventId === null && row.value.debugLineage.inputOutboxSeq === null));
assert.ok(output.every((row) => row.value.sourceEvent.partition === null && row.value.sourceEvent.offset === null));
assert.ok(output.every((row) => row.value.traceId === TRACE_ID && row.value.sessionId === HWLAB_SESSION_ID));
assert.ok(output.every((row) => row.value.debugLineage.inputSessionId === SESSION_ID));
assert.ok(output.every((row) => row.value.debugLineage.inputHwlabSessionId === HWLAB_SESSION_ID));
assert.ok(output.every((row) => row.value.reconstruction.kind === "stdio-derived partial reconstruction"));
assert.ok(output.every((row) => row.value.reconstruction.originalEventId === null && row.value.reconstruction.originalOutboxSeq === null));
assert.ok(output.every((row) => row.value.reconstruction.identityDerivation.kind === "agentrun-session-uuid-to-hwlab-session"));
assert.ok(output.every((row) => row.value.reconstruction.identityDerivation.reversible === true));
});
test("Kafka reader and producer are injected while canonical AgentRun events use strict decode and isolated output", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-canonical-"));
const records = Array.from({ length: 35 }, (_, index) => canonicalRecord(index + 1));
const readerCalls: any[] = [];
const producerCalls: any[] = [];
let connected = 0;
let disconnected = 0;
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "kafka",
"--session-id", SESSION_ID,
"--trace-id", TRACE_ID,
"--replay-id", "rpl_canonical_35",
"--input-topic", "agentrun.event.v1",
"--publish",
"--expect-count", "35",
"--output-jsonl", path.join(cwd, "canonical-output.jsonl"),
"--json"
], {
cwd,
env: {
HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092",
HWLAB_KAFKA_HWLAB_DEBUG_EVENT_TOPIC: "hwlab.event.debug.v1",
HWLAB_KAFKA_HWLAB_DEBUG_GROUP_PREFIX: "hwlab-v03-workbench-isolated-debug"
},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka(input) {
readerCalls.push(input);
return { ok: true, groupId: "hwlab-v03-agentrun-event-debug-regenerate-test", events: records, completionReason: "end-offset", reachedEndOffsets: true };
},
async createProducer() {
return {
async connect() { connected += 1; },
async send(input: any) { producerCalls.push(input); return [{ topicName: input.topic, partition: 0, baseOffset: "100" }]; },
async disconnect() { disconnected += 1; }
};
}
});
assert.equal(result.exitCode, 0);
assert.equal(readerCalls.length, 1);
assert.equal(readerCalls[0].groupIdPrefix, "hwlab-v03-workbench-isolated-debug");
assert.equal(readerCalls[0].sessionId, SESSION_ID);
assert.equal(readerCalls[0].limit, 36, "exact count verification must leave room to detect one extra event");
assert.equal(connected, 1);
assert.equal(disconnected, 1);
assert.equal(producerCalls.length, 1);
assert.equal(producerCalls[0].topic, "hwlab.event.debug.v1");
assert.equal(producerCalls[0].messages.length, 35);
assert.ok(producerCalls[0].messages.every((message: any) => message.partition === 0));
const envelopes = producerCalls[0].messages.map((message: any) => JSON.parse(message.value));
assert.ok(envelopes.every((event: any) => event.replayId === "rpl_canonical_35"));
assert.ok(producerCalls[0].messages.every((message: any) => message.headers["x-debug-replay-id"] === "rpl_canonical_35"));
assert.deepEqual(envelopes.map((event: any) => event.debugLineage.sourceSeq), Array.from({ length: 35 }, (_, index) => index + 1));
assert.deepEqual(envelopes.map((event: any) => event.eventId), Array.from({ length: 35 }, (_, index) => `hwlab:evt_${index + 1}`));
assert.deepEqual(envelopes.map((event: any) => event.debugLineage.inputOutboxSeq), Array.from({ length: 35 }, (_, index) => index + 1));
assert.ok(envelopes.every((event: any) => event.diagnostics.inputKind === "canonical-durable"));
assert.ok(envelopes.every((event: any) => event.schema === "hwlab.event.debug.v1"));
assert.equal(result.payload.output.publishedCount, 35);
assert.deepEqual(result.payload.config.outputTopic, { value: "hwlab.event.debug.v1", source: "env:HWLAB_KAFKA_HWLAB_DEBUG_EVENT_TOPIC" });
assert.deepEqual(result.payload.config.groupPrefix, { value: "hwlab-v03-workbench-isolated-debug", source: "env:HWLAB_KAFKA_HWLAB_DEBUG_GROUP_PREFIX" });
assert.equal(result.payload.validation.orderPreserved, true);
assert.equal(result.payload.validation.lineagePreserved, true);
assert.deepEqual(result.payload.output.offsetRanges, [{
topic: "hwlab.event.debug.v1",
partition: 0,
firstOffset: "100",
lastOffset: "134",
count: 35,
valuesPrinted: false
}]);
assert.equal(result.payload.replay.replayId, "rpl_canonical_35");
assert.equal(result.payload.replay.producerInvoked, true);
assert.equal(result.payload.replay.sourceMatched, true);
assert.deepEqual(result.payload.replay.outputBarrier, result.payload.output.offsetRanges[0]);
});
test("Kafka regeneration reports source trace missing before creating a producer", async () => {
let producerCreated = false;
let readerInput: any = null;
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "kafka",
"--session-id", SESSION_ID,
"--trace-id", "trc_missing_debug_source",
"--replay-id", "rpl_missing_debug_source",
"--group-prefix", "hwlab-v03-workbench-isolated-debug"
], {
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka(input) { readerInput = input; return { events: [canonicalRecord(1)] }; },
async createProducer() { producerCreated = true; throw new Error("must not create producer"); }
});
assert.equal(result.exitCode, 1);
assert.equal(result.payload.error.code, "source_trace_missing");
assert.equal(readerInput.topic, "agentrun.event.v1");
assert.equal(producerCreated, false);
});
test("canonical Kafka regeneration preflights without publishing and preserves replayId in the publish hint", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-preflight-"));
let producerCreated = false;
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "kafka",
"--session-id", SESSION_ID,
"--trace-id", TRACE_ID,
"--replay-id", "rpl_canonical_preflight",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--output-jsonl", path.join(cwd, "output.jsonl")
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() { return { events: [canonicalRecord(1)], completionReason: "end-offset", reachedEndOffsets: true }; },
async createProducer() { producerCreated = true; throw new Error("preflight must not create a producer"); }
});
assert.equal(result.exitCode, 0);
assert.equal(result.payload.config.inputTopic.value, "agentrun.event.v1");
assert.equal(result.payload.output.published, false);
assert.equal(result.payload.output.publishedCount, 0);
assert.equal(result.payload.replay.producerInvoked, false);
assert.equal(result.payload.replay.outputBarrier, null);
assert.match(result.payload.next.command, /--replay-id rpl_canonical_preflight/u);
assert.match(result.payload.next.command, /--group-prefix hwlab-v03-workbench-isolated-debug/u);
assert.match(result.payload.next.command, /--publish/u);
assert.equal(producerCreated, false);
});
test("partial AgentRun Kafka regeneration preserves the artifact and never invokes the producer", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-partial-"));
let producerCreated = false;
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "kafka",
"--session-id", SESSION_ID,
"--trace-id", TRACE_ID,
"--replay-id", "rpl_partial_no_publish",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--publish",
"--output-jsonl", path.join(cwd, "partial.jsonl")
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() {
return {
events: [canonicalRecord(1)],
scannedCount: 1,
parsedCount: 1,
matchedCount: 1,
completionReason: "limit",
reachedEndOffsets: false
};
},
async createProducer() { producerCreated = true; throw new Error("partial scan must not create producer"); }
});
assert.equal(result.exitCode, 2);
assert.equal(result.payload.status, "partial");
assert.equal(result.payload.error.code, "source_scan_incomplete");
assert.equal(result.payload.input.scanComplete, false);
assert.equal(result.payload.output.published, false);
assert.equal(result.payload.output.publishedCount, 0);
assert.equal(result.payload.replay.producerInvoked, false);
assert.equal(producerCreated, false);
assert.equal(typeof result.payload.output.artifact.path, "string");
assert.match(renderKafkaCliText(result.payload), /^partial action=kafka\.regenerate\.hwlab code=source_scan_incomplete completion=limit reachedEnd=false/u);
});
test("Kafka regeneration fails closed when publish metadata cannot form an offset barrier", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-barrier-"));
const result = await runKafkaCli([
"regenerate", "hwlab",
"--from", "kafka",
"--session-id", SESSION_ID,
"--trace-id", TRACE_ID,
"--replay-id", "rpl_missing_offset_barrier",
"--group-prefix", "hwlab-v03-workbench-isolated-debug",
"--publish",
"--output-jsonl", path.join(cwd, "output.jsonl")
], {
cwd,
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() { return { events: [canonicalRecord(1)], completionReason: "end-offset", reachedEndOffsets: true }; },
async createProducer() {
return {
async connect() {},
async send() { return []; },
async disconnect() {}
};
}
});
assert.equal(result.exitCode, 1);
assert.equal(result.payload.error.code, "debug_publish_barrier_missing");
});
test("reconstruction identity fabrication and product output topic fail closed", async () => {
const cwd = await mkdtemp(path.join(os.tmpdir(), "hwlab-kafka-debug-invalid-"));
const forged = reconstructionRecord(1);
forged.value.eventId = "evt_forged";
const inputFile = path.join(cwd, "forged.jsonl");
await writeFile(inputFile, `${JSON.stringify(forged)}\n`, "utf8");
const forgedResult = await runKafkaCli([
"regenerate", "hwlab", "--from", "jsonl", "--session-id", SESSION_ID,
"--jsonl-file", inputFile, "--no-publish"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(forgedResult.exitCode, 1);
assert.equal(forgedResult.payload.error.code, "hwlab_kafka_debug_identity_invalid");
const productResult = await runKafkaCli([
"regenerate", "hwlab", "--from", "jsonl", "--session-id", SESSION_ID,
"--jsonl-file", inputFile, "--output-topic", "hwlab.event.v1", "--no-publish"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(productResult.exitCode, 1);
assert.equal(productResult.payload.error.code, "product_topic_forbidden");
const productGroupResult = await runKafkaCli([
"regenerate", "hwlab", "--from", "jsonl", "--session-id", SESSION_ID,
"--jsonl-file", inputFile, "--group-prefix", "hwlab-v03-workbench-live-sse", "--no-publish"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(productGroupResult.exitCode, 1);
assert.equal(productGroupResult.payload.error.code, "debug_group_required");
const replayIdResult = await runKafkaCli([
"regenerate", "hwlab", "--from", "jsonl", "--session-id", SESSION_ID,
"--replay-id", "not-a-replay", "--jsonl-file", inputFile, "--no-publish"
], { cwd, env: {}, now: () => "2026-07-10T12:00:00.000Z" });
assert.equal(replayIdResult.exitCode, 1);
assert.equal(replayIdResult.payload.error.code, "invalid_replay_id");
});
test("Kafka mode requires a CLI or YAML-owned isolated group prefix", async () => {
let readCalled = false;
const result = await runKafkaCli([
"regenerate", "hwlab", "--from", "kafka", "--session-id", SESSION_ID, "--no-publish"
], {
env: {},
now: () => "2026-07-10T12:00:00.000Z",
async readKafka() { readCalled = true; return { events: [] }; }
});
assert.equal(result.exitCode, 1);
assert.equal(result.payload.error.code, "kafka_debug_group_missing");
assert.equal(readCalled, false);
});
test("Kafka query exposes the isolated generated group and original value hash", async () => {
const valueText = JSON.stringify(canonicalRecord(1).value);
const consumerConfigs: any[] = [];
const consumer = {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({
topic: "agentrun.event.v1",
partition: 0,
message: { offset: "1601", key: Buffer.from(SESSION_ID), value: Buffer.from(valueText), timestamp: "1783681200000" }
});
},
async stop() {},
async disconnect() {}
};
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 1,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return { consumer(config: any) { consumerConfigs.push(config); return consumer; } };
}
});
assert.match(queried.groupId, /^hwlab-v03-workbench-isolated-debug-\d+-[a-f0-9]{8}$/u);
assert.equal(consumerConfigs[0].groupId, queried.groupId);
assert.equal(queried.events[0].valueSha256, createSha256(valueText));
assert.equal(queried.scannedCount, 1);
assert.equal(queried.parsedCount, 1);
assert.equal(queried.matchedCount, 1);
assert.equal(queried.invalidJsonCount, 0);
assert.equal(queried.completionReason, "limit");
assert.equal(queried.endOffsetsAvailable, false);
});
test("Kafka query reports invalid JSON, filter rejection, and bounded end-offset completion", async () => {
const matching = canonicalRecord(1).value;
const mismatch = structuredClone(matching);
mismatch.sessionId = "ses_agentrun_other";
mismatch.run.sessionId = "ses_agentrun_other";
mismatch.event.payload.sessionId = "ses_agentrun_other";
const consumer = {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "0", value: Buffer.from("{invalid") } });
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "1", value: Buffer.from(JSON.stringify(mismatch)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "2", value: Buffer.from(JSON.stringify(matching)) } });
},
async stop() {},
async disconnect() {}
};
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 2,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "3" }]; }, async disconnect() {} }; },
consumer() { return consumer; }
};
}
});
assert.equal(queried.scannedCount, 3);
assert.equal(queried.parsedCount, 2);
assert.equal(queried.invalidJsonCount, 1);
assert.equal(queried.filterRejectedCount, 1);
assert.equal(queried.matchedCount, 1);
assert.equal(queried.completionReason, "end-offset");
assert.equal(queried.reachedEndOffsets, true);
assert.deepEqual(queried.endOffsets, [{ partition: 0, startOffset: "0", endOffset: "3" }]);
assert.deepEqual(queried.firstScannedOffsets, [{ partition: 0, offset: "0" }]);
assert.deepEqual(queried.lastScannedOffsets, [{ partition: 0, offset: "2" }]);
});
test("Kafka query fails closed when retention advances between barrier capture and consumer assignment", async () => {
const matching = canonicalRecord(1).value;
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "hwlab.event.v1",
sessionId: SESSION_ID,
limit: 10,
scanLimit: 10,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "3" }]; }, async disconnect() {} }; },
consumer() {
return {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({ topic: "hwlab.event.v1", partition: 0, message: { offset: "2", value: Buffer.from(JSON.stringify(matching)) } });
},
async stop() {},
async disconnect() {}
};
}
};
}
});
assert.equal(queried.completionReason, "retention-start-moved");
assert.equal(queried.completion.complete, false);
assert.equal(queried.completion.retentionStartVerified, false);
assert.equal(queried.completion.retentionStartMoved, true);
assert.equal(queried.reachedEndOffsets, false);
assert.equal(queried.scannedCount, 0);
assert.deepEqual(queried.firstScannedOffsets, [{ partition: 0, offset: "2" }]);
});
test("Kafka query prefers end-offset when the final record also reaches the event limit", async () => {
const matching = canonicalRecord(1).value;
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 1,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "1" }]; }, async disconnect() {} }; },
consumer() {
return {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "0", value: Buffer.from(JSON.stringify(matching)) } });
},
async stop() {},
async disconnect() {}
};
}
};
}
});
assert.equal(queried.matchedCount, 1);
assert.equal(queried.completionReason, "end-offset");
assert.equal(queried.reachedEndOffsets, true);
});
test("Kafka query session filter accepts canonical hwlabSessionId across AgentRun and HWLAB topics", async () => {
const matching = canonicalRecord(1).value;
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: HWLAB_SESSION_ID,
limit: 10,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "1" }]; }, async disconnect() {} }; },
consumer() {
return {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "0", value: Buffer.from(JSON.stringify(matching)) } });
},
async stop() {},
async disconnect() {}
};
}
};
}
});
assert.equal(queried.matchedCount, 1);
assert.equal(queried.filterRejectedCount, 0);
assert.equal(queried.completionReason, "end-offset");
});
test("Kafka query treats a retained empty partition as a completed bounded scan", async () => {
let runCalled = false;
let disconnected = false;
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "hwlab.event.v1",
traceId: TRACE_ID,
timeoutMs: 250,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "7", high: "7" }]; }, async disconnect() {} }; },
consumer() {
return {
async connect() {},
async subscribe() {},
async run() { runCalled = true; },
async stop() {},
async disconnect() { disconnected = true; }
};
}
};
}
});
assert.equal(queried.completionReason, "end-offset");
assert.equal(queried.reachedEndOffsets, true);
assert.equal(queried.scannedCount, 0);
assert.equal(runCalled, false);
assert.equal(disconnected, true);
assert.deepEqual(queried.endOffsets, [{ partition: 0, startOffset: "7", endOffset: "7" }]);
});
test("Kafka query stops every partition at the captured exclusive barrier and excludes later records", async () => {
const matching = canonicalRecord(1).value;
const mismatch = structuredClone(matching);
mismatch.sessionId = "ses_agentrun_other";
mismatch.run.sessionId = "ses_agentrun_other";
mismatch.event.payload.sessionId = "ses_agentrun_other";
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 10,
scanLimit: 10,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "2" }, { partition: 1, low: "0", high: "2" }]; }, async disconnect() {} }; },
consumer() {
return {
async connect() {},
async subscribe() {},
async run({ eachMessage }: any) {
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "0", value: Buffer.from(JSON.stringify(matching)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "1", value: Buffer.from(JSON.stringify(mismatch)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "2", value: Buffer.from(JSON.stringify(matching)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 1, message: { offset: "0", value: Buffer.from(JSON.stringify(mismatch)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 1, message: { offset: "1", value: Buffer.from(JSON.stringify(matching)) } });
await eachMessage({ topic: "agentrun.event.v1", partition: 1, message: { offset: "3", value: Buffer.from(JSON.stringify(matching)) } });
},
async stop() {},
async disconnect() {}
};
}
};
}
});
assert.equal(queried.completionReason, "end-offset");
assert.equal(queried.completion.complete, true);
assert.equal(queried.completion.barrierReached, true);
assert.equal(queried.scannedCount, 4);
assert.equal(queried.excludedPostBarrierCount, 1);
assert.deepEqual(queried.events.map((event: any) => [event.partition, event.offset]), [[0, "0"], [1, "1"]]);
assert.deepEqual(queried.lastScannedOffsets, [{ partition: 0, offset: "1" }, { partition: 1, offset: "1" }]);
});
test("Kafka query reports scan-limit and abort as typed incomplete completion", async () => {
const matching = canonicalRecord(1).value;
const limited = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 10,
scanLimit: 1,
timeoutMs: 500,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "5" }]; }, async disconnect() {} }; },
consumer() { return { async connect() {}, async subscribe() {}, async run({ eachMessage }: any) { await eachMessage({ topic: "agentrun.event.v1", partition: 0, message: { offset: "0", value: Buffer.from(JSON.stringify(matching)) } }); }, async stop() {}, async disconnect() {} }; }
};
}
});
assert.deepEqual(limited.completion, {
reason: "scan-limit",
complete: false,
barrierReached: false,
retentionStartVerified: true,
retentionStartMoved: false,
timeout: false,
matchedEventLimitReached: false,
scanLimitReached: true,
aborted: false,
valuesRedacted: true
});
const controller = new AbortController();
let disconnected = false;
const abortedPromise = queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "agentrun.event.v1",
sessionId: SESSION_ID,
limit: 10,
scanLimit: 10,
timeoutMs: 500,
signal: controller.signal,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return [{ partition: 0, low: "0", high: "5" }]; }, async disconnect() {} }; },
consumer() { return { async connect() {}, async subscribe() {}, async run() { await new Promise(() => undefined); }, async stop() {}, async disconnect() { disconnected = true; } }; }
};
}
});
setTimeout(() => controller.abort(), 5);
const aborted = await abortedPromise;
assert.equal(aborted.completionReason, "aborted");
assert.equal(aborted.completion.aborted, true);
assert.equal(aborted.completion.complete, false);
assert.equal(disconnected, true);
});
test("Kafka query does not report an empty offset response as a completed scan", async () => {
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "hwlab.event.v1",
traceId: TRACE_ID,
timeoutMs: 250,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() { return { async connect() {}, async fetchTopicOffsets() { return []; }, async disconnect() {} }; },
consumer() { return { async connect() {}, async subscribe() {}, async run() {}, async stop() {}, async disconnect() {} }; }
};
}
});
assert.equal(queried.completionReason, "timeout");
assert.equal(queried.reachedEndOffsets, false);
assert.equal(queried.endOffsetsAvailable, false);
assert.equal(queried.endOffsetsError?.code, "kafka_end_offsets_empty");
});
test("Kafka query disconnects a connected consumer when subscribe fails", async () => {
let disconnected = 0;
await assert.rejects(queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "hwlab.event.v1",
traceId: TRACE_ID,
timeoutMs: 250,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
consumer() {
return {
async connect() {},
async subscribe() { throw new Error("subscribe failed"); },
async run() {},
async stop() {},
async disconnect() { disconnected += 1; }
};
}
};
}
}), /subscribe failed/u);
assert.equal(disconnected, 1);
});
test("Kafka query setup and cleanup stay inside the command budget", async () => {
let consumerConnectCalled = false;
let consumerDisconnected = false;
const startedAt = Date.now();
const queried = await queryKafkaEventStream({
env: { HWLAB_KAFKA_BOOTSTRAP_SERVERS: "kafka.test:9092", HWLAB_KAFKA_CLIENT_ID: "hwlab-test" },
topic: "hwlab.event.v1",
traceId: TRACE_ID,
timeoutMs: 250,
groupIdPrefix: "hwlab-v03-workbench-isolated-debug",
kafkaFactory() {
return {
admin() {
return {
async connect() { await new Promise(() => undefined); },
async fetchTopicOffsets() { throw new Error("must not fetch after setup timeout"); },
async disconnect() {}
};
},
consumer() {
return {
async connect() { consumerConnectCalled = true; },
async subscribe() {},
async run() {},
async stop() {},
async disconnect() { consumerDisconnected = true; }
};
}
};
}
});
const elapsedMs = Date.now() - startedAt;
assert.equal(queried.completionReason, "timeout");
assert.equal(queried.endOffsetsAvailable, false);
assert.equal(queried.endOffsetsError?.code, "kafka_query_timeout");
assert.equal(consumerConnectCalled, false);
assert.equal(consumerDisconnected, true);
assert.ok(elapsedMs < 500, `query exceeded bounded setup budget: ${elapsedMs}ms`);
});
test("non-reversible AgentRun session identity stays only in debug lineage", () => {
const rawSessionId = "ses_agentrun_not_uuid";
const record = reconstructionRecord(1);
record.key = rawSessionId;
record.value.sessionId = rawSessionId;
record.value.hwlabSessionId = null;
record.value.run.sessionId = rawSessionId;
record.value.run.hwlabSessionId = null;
record.value.event.payload.sessionId = rawSessionId;
record.value.reconstruction.identityDerivation = {
kind: "none",
sourceField: "sessionId",
targetField: "hwlabSessionId",
reversible: false,
reason: "source sessionId is not ses_agentrun_<uuid-with-underscores>",
valuesPrinted: false
};
const mapped = mapAgentRunRecordsToHwlabDebugEvents([record], {
sessionId: rawSessionId,
traceId: TRACE_ID,
expectedCount: 1,
producedAt: "2026-07-10T12:00:00.000Z"
});
assert.equal(mapped.events[0].sessionId, null);
assert.equal(mapped.events[0].hwlabSessionId, null);
assert.equal(mapped.events[0].event.sessionId, null);
assert.equal(mapped.events[0].debugLineage.inputSessionId, rawSessionId);
assert.equal(mapped.events[0].reconstruction.identityDerivation.kind, "none");
});
function completeKafkaRead(events: any[]) {
const byPartition = new Map<number, bigint[]>();
for (const event of events) {
const partition = Number(event.partition);
const offset = BigInt(String(event.offset));
const offsets = byPartition.get(partition) ?? [];
offsets.push(offset);
byPartition.set(partition, offsets);
}
const endOffsets = [...byPartition.entries()].map(([partition, offsets]) => ({
partition,
startOffset: String(offsets.reduce((left, right) => left < right ? left : right)),
endOffset: String(offsets.reduce((left, right) => left > right ? left : right) + 1n)
})).sort((left, right) => left.partition - right.partition);
return {
topic: events[0]?.topic ?? "hwlab.event.v1",
events,
completionReason: "end-offset",
reachedEndOffsets: true,
endOffsetsAvailable: true,
endOffsets,
completion: { reason: "end-offset", complete: true, barrierReached: true, retentionStartVerified: true }
};
}
function reconstructionRecord(seq: number): any {
const value = {
schema: "agentrun.event.reconstruction.v1",
eventType: "agentrun.event.reconstructed",
source: "agentrun-cli-stdio-reconstruction",
eventId: null,
outboxSeq: null,
sourceSeq: seq,
observedAt: `2026-07-10T11:00:${String(seq).padStart(2, "0")}.000Z`,
traceId: TRACE_ID,
sessionId: SESSION_ID,
hwlabSessionId: HWLAB_SESSION_ID,
runId: RUN_ID,
commandId: "cmd_9fff03fc124b4203b065d04bbb7c4f1e",
run: { runId: RUN_ID, sessionId: SESSION_ID, hwlabSessionId: HWLAB_SESSION_ID, status: "running", valuesPrinted: false },
command: { commandId: "cmd_9fff03fc124b4203b065d04bbb7c4f1e", runId: RUN_ID, seq: 1, type: "run", state: "running", valuesPrinted: false },
event: {
id: null,
runId: RUN_ID,
seq,
type: "backend_status",
payload: {
traceId: TRACE_ID,
sessionId: SESSION_ID,
phase: `reconstructed-${seq}`,
reconstructed: true,
reconstructionKind: "stdio-derived partial reconstruction"
},
createdAt: `2026-07-10T11:00:${String(seq).padStart(2, "0")}.000Z`
},
reconstruction: {
kind: "stdio-derived partial reconstruction",
completeLifecycle: false,
originalEventId: null,
originalOutboxSeq: null,
sourceTopic: "codex-stdio.raw.v1",
sourcePartition: 0,
sourceOffset: String(3500 + seq),
sourceFrameSeq: seq,
sourceValueSha256: `sha256:${String(seq).padStart(64, "0")}`,
identityDerivation: {
kind: "agentrun-session-uuid-to-hwlab-session",
sourceField: "sessionId",
targetField: "hwlabSessionId",
reversible: true,
sourcePrefix: "ses_agentrun_",
targetPrefix: "ses_",
separatorTransform: "underscore-to-hyphen",
valuesPrinted: false
}
},
valuesPrinted: false
};
return { topic: "agentrun.event.debug.v1", partition: null, offset: null, key: SESSION_ID, value, headers: { "x-trace-id": TRACE_ID } };
}
function agentrunOrderRecord(seq: number, traceId: string, type: string, payload: Record<string, unknown>): any {
const record = canonicalRecord(seq);
const eventId = `evt_order_${seq}`;
record.offset = String(1600 + seq);
record.value.eventId = eventId;
record.value.sourceSeq = seq;
record.value.traceId = traceId;
record.value.hwlabSessionId = HWLAB_SESSION_ID;
record.value.run.hwlabSessionId = HWLAB_SESSION_ID;
record.value.event = {
id: eventId,
runId: RUN_ID,
seq,
type,
payload: {
traceId,
sessionId: SESSION_ID,
hwlabSessionId: HWLAB_SESSION_ID,
...payload
},
createdAt: `2026-07-11T11:00:${String(seq).padStart(2, "0")}.000Z`
};
return record;
}
function agentrunAssistantLifecycleRecord(seq: number, ordinal: number, type: string, payload: Record<string, unknown>): any {
const record = agentrunOrderRecord(seq, TRACE_ID, type, payload);
const createdAt = `2026-07-12T10:00:0${ordinal}.000Z`;
record.value.committedAt = createdAt;
record.value.event.createdAt = createdAt;
return record;
}
function hwlabOrderRecord(source: any, index: number): any {
const valueText = JSON.stringify(source.value);
const projected = projectAgentRunKafkaEventToHwlabEvent(source.value, {
producedAt: `2026-07-11T11:01:${String(index).padStart(2, "0")}.000Z`,
sourceTopic: source.topic,
sourcePartition: source.partition,
sourceOffset: source.offset,
sourceKey: source.key,
inputSha256: createSha256(valueText)
});
return {
topic: "hwlab.event.v1",
partition: 0,
offset: String(1901 + index),
key: HWLAB_SESSION_ID,
valueSha256: createSha256(JSON.stringify(projected)),
value: projected
};
}
function canonicalRecord(seq: number): any {
const eventId = `evt_${seq}`;
const value = {
schema: "agentrun.event.v1",
eventType: "agentrun.event.committed",
source: "agentrun-manager",
eventId,
outboxSeq: seq,
sourceSeq: seq,
committedAt: `2026-07-10T11:00:${String(seq).padStart(2, "0")}.000Z`,
traceId: TRACE_ID,
sessionId: SESSION_ID,
hwlabSessionId: HWLAB_SESSION_ID,
runId: RUN_ID,
commandId: "cmd_9fff03fc124b4203b065d04bbb7c4f1e",
run: {
runId: RUN_ID,
status: "running",
terminalStatus: null,
failureKind: null,
tenantId: "tenant-test",
projectId: "project-test",
providerId: "gpt.pika",
backendProfile: "gpt.pika",
sessionId: SESSION_ID,
hwlabSessionId: HWLAB_SESSION_ID,
conversationId: null,
threadId: null,
valuesPrinted: false
},
command: {
commandId: "cmd_9fff03fc124b4203b065d04bbb7c4f1e",
runId: RUN_ID,
seq: 1,
type: "run",
state: "running",
payloadHash: "hash",
valuesPrinted: false
},
event: {
id: eventId,
runId: RUN_ID,
seq,
type: "backend_status",
payload: { traceId: TRACE_ID, sessionId: SESSION_ID, phase: `canonical-${seq}` },
createdAt: `2026-07-10T11:00:${String(seq).padStart(2, "0")}.000Z`
},
valuesPrinted: false
};
return { topic: "agentrun.event.v1", partition: 0, offset: String(1600 + seq), key: SESSION_ID, value };
}
function hwlabRecord(sourceSeq: number, event: Record<string, unknown>): any {
return {
topic: "hwlab.event.v1",
partition: 0,
offset: String(1900 + sourceSeq),
key: HWLAB_SESSION_ID,
value: {
schema: "hwlab.event.v1",
eventType: "hwlab.trace.event.projected",
eventId: `hwlab:evt_render_${sourceSeq}`,
sourceEventId: `evt_render_${sourceSeq}`,
traceId: TRACE_ID,
hwlabSessionId: HWLAB_SESSION_ID,
sessionId: HWLAB_SESSION_ID,
runId: RUN_ID,
commandId: "cmd_render_trace",
serverSentAt: `2026-07-10T11:00:0${sourceSeq}.000Z`,
event: {
traceId: TRACE_ID,
sessionId: HWLAB_SESSION_ID,
source: "agentrun.kafka",
sourceSeq,
sourceEventId: `evt_render_${sourceSeq}`,
runId: RUN_ID,
commandId: "cmd_render_trace",
createdAt: `2026-07-10T11:00:0${sourceSeq}.000Z`,
...event
},
valuesPrinted: false
}
};
}
function withoutCommandId(record: any) {
delete record.value.commandId;
delete record.value.event.commandId;
return record;
}
function withCommandId(record: any, commandId: string) {
record.value.commandId = commandId;
record.value.event.commandId = commandId;
return record;
}
function createSha256(value: string) {
return new Bun.CryptoHasher("sha256").update(value).digest("hex");
}