fix: validate Kafka refresh delivery in web probe
This commit is contained in:
@@ -25,12 +25,21 @@ test("realtime fanout keeps the YAML terminal timeout when durationMs is absent"
|
||||
terminalTimeoutMs: 480_000,
|
||||
terminalQuietMs: 2_000,
|
||||
reconnectQuietMs: 3_000,
|
||||
expectedProductSse: {
|
||||
deliverySemantics: "kafka-retention-then-live",
|
||||
liveOnly: false,
|
||||
replay: true,
|
||||
replaySupported: true,
|
||||
lossPossible: false,
|
||||
refreshHandoff: true,
|
||||
replayPriorTraceOnReconnect: true,
|
||||
},
|
||||
forbiddenRequestPaths: [],
|
||||
requiredEventTypes: { agentrun: ["terminal_status"], hwlab: ["terminal"] },
|
||||
expectedKafka: {
|
||||
topics: { stdio: "codex-stdio.raw.v1", agentrun: "agentrun.event.v1", hwlab: "hwlab.event.v1" },
|
||||
groups: { directPublish: "direct", transactionalProjector: "projector", liveSse: "live" },
|
||||
capabilities: { directPublish: true, liveKafkaSse: true },
|
||||
capabilities: { directPublish: true, liveKafkaSse: true, kafkaRefreshReplay: true },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -83,3 +92,150 @@ test("realtime fanout validates stdio against the scoped AgentRun session lineag
|
||||
assert.equal(expectedStreamSessionId("agentrun", hwlabSessionId), hwlabSessionId);
|
||||
assert.equal(expectedStreamSessionId("hwlab", hwlabSessionId), hwlabSessionId);
|
||||
});
|
||||
|
||||
test("realtime fanout validates YAML-owned refresh and legacy live-only connected contracts", () => {
|
||||
const source = nodeWebObserveRunnerRealtimeSource();
|
||||
const build = new Function(`${source}\nreturn realtimeAssertConnectedContract;`) as () => (
|
||||
connected: Record<string, unknown>,
|
||||
sessionId: string,
|
||||
label: string,
|
||||
profile: Record<string, unknown>,
|
||||
options?: Record<string, unknown>,
|
||||
) => void;
|
||||
const assertConnected = build();
|
||||
const sessionId = "ses_refresh_contract";
|
||||
const expectedKafka = {
|
||||
topics: { hwlab: "hwlab.event.v1" },
|
||||
capabilities: { directPublish: true, liveKafkaSse: true, kafkaRefreshReplay: true },
|
||||
};
|
||||
const refreshProfile = {
|
||||
expectedKafka,
|
||||
expectedProductSse: {
|
||||
deliverySemantics: "kafka-retention-then-live",
|
||||
liveOnly: false,
|
||||
replay: true,
|
||||
replaySupported: true,
|
||||
lossPossible: false,
|
||||
refreshHandoff: true,
|
||||
replayPriorTraceOnReconnect: true,
|
||||
},
|
||||
};
|
||||
const refreshConnected = {
|
||||
realtimeSource: "hwlab.event.v1",
|
||||
deliverySemantics: "kafka-retention-then-live",
|
||||
liveOnly: false,
|
||||
replay: true,
|
||||
replaySupported: true,
|
||||
lossPossible: false,
|
||||
filters: { sessionId, traceId: null },
|
||||
capabilities: expectedKafka.capabilities,
|
||||
refreshReplay: {
|
||||
phase: "live",
|
||||
topic: "hwlab.event.v1",
|
||||
topicPartitions: [0],
|
||||
barrier: [{ partition: 0, endOffset: "18" }],
|
||||
counts: { matched: 8, replayed: 8, buffered: 1, bufferedDelivered: 1, liveDelivered: 0, deduplicated: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
assert.doesNotThrow(() => assertConnected(refreshConnected, sessionId, "refresh", refreshProfile, { requireRetainedEvents: true }));
|
||||
assert.throws(
|
||||
() => assertConnected({ ...refreshConnected, deliverySemantics: "live-only" }, sessionId, "refresh", refreshProfile),
|
||||
/differs from the owning YAML/u,
|
||||
);
|
||||
assert.throws(
|
||||
() => assertConnected({ ...refreshConnected, refreshReplay: { ...refreshConnected.refreshReplay, counts: { ...refreshConnected.refreshReplay.counts, replayed: 9 } } }, sessionId, "refresh", refreshProfile),
|
||||
/replayed count exceeds matched count/u,
|
||||
);
|
||||
|
||||
const liveProfile = {
|
||||
expectedKafka: { topics: { hwlab: "hwlab.event.v1" }, capabilities: { directPublish: true, liveKafkaSse: true, kafkaRefreshReplay: false } },
|
||||
expectedProductSse: {
|
||||
deliverySemantics: "live-only",
|
||||
liveOnly: true,
|
||||
replay: false,
|
||||
replaySupported: false,
|
||||
lossPossible: true,
|
||||
refreshHandoff: false,
|
||||
replayPriorTraceOnReconnect: false,
|
||||
},
|
||||
};
|
||||
assert.doesNotThrow(() => assertConnected({
|
||||
realtimeSource: "hwlab.event.v1",
|
||||
deliverySemantics: "live-only",
|
||||
liveOnly: true,
|
||||
replay: false,
|
||||
replaySupported: false,
|
||||
lossPossible: true,
|
||||
filters: { sessionId, traceId: null },
|
||||
capabilities: liveProfile.expectedKafka.capabilities,
|
||||
}, sessionId, "live", liveProfile));
|
||||
});
|
||||
|
||||
test("realtime fanout proves one formal user event through AgentRun, HWLAB Kafka, and product SSE", () => {
|
||||
const source = nodeWebObserveRunnerRealtimeSource();
|
||||
const build = new Function(`${source}\nreturn realtimeValidateTurnEvidence;`) as () => (input: Record<string, unknown>) => void;
|
||||
const validate = build();
|
||||
const traceId = "trc_user_passthrough";
|
||||
const sessionId = "ses_user_passthrough";
|
||||
const runId = "run_user_passthrough";
|
||||
const commandId = "cmd_user_passthrough";
|
||||
const userMessageId = "msg_user_passthrough";
|
||||
const base = { traceId, runId, commandId, terminal: false };
|
||||
const userHwlab = {
|
||||
...base,
|
||||
partition: 0,
|
||||
offset: "0",
|
||||
hwlabSessionId: sessionId,
|
||||
eventId: "hwlab:evt_user",
|
||||
sourceEventId: "evt_user",
|
||||
sourceSeq: 1,
|
||||
eventType: "user",
|
||||
userMessageId,
|
||||
envelopeFingerprint: "fingerprint:user",
|
||||
};
|
||||
const terminalHwlab = {
|
||||
...base,
|
||||
partition: 0,
|
||||
offset: "1",
|
||||
hwlabSessionId: sessionId,
|
||||
eventId: "hwlab:evt_terminal",
|
||||
sourceEventId: "evt_terminal",
|
||||
sourceSeq: 2,
|
||||
eventType: "terminal",
|
||||
userMessageId: null,
|
||||
terminal: true,
|
||||
envelopeFingerprint: "fingerprint:terminal",
|
||||
};
|
||||
const debug = {
|
||||
connected: {
|
||||
stdio: { consumerReady: true, topic: "codex-stdio.raw.v1" },
|
||||
agentrun: { consumerReady: true, topic: "agentrun.event.v1" },
|
||||
hwlab: { consumerReady: true, topic: "hwlab.event.v1" },
|
||||
},
|
||||
openCount: { stdio: 1, agentrun: 1, hwlab: 1 },
|
||||
connectedEventCount: { stdio: 1, agentrun: 1, hwlab: 1 },
|
||||
errors: { stdio: [], agentrun: [], hwlab: [] },
|
||||
records: {
|
||||
stdio: [{ ...base, partition: 0, offset: "0", frameSeq: 1, hwlabSessionId: "ses_agentrun_user_passthrough" }],
|
||||
agentrun: [
|
||||
{ ...base, partition: 0, offset: "0", hwlabSessionId: sessionId, eventId: "evt_user", eventType: "user_message", userMessageId },
|
||||
{ ...base, partition: 0, offset: "1", hwlabSessionId: sessionId, eventId: "evt_terminal", eventType: "terminal_status", terminal: true },
|
||||
],
|
||||
hwlab: [userHwlab, terminalHwlab],
|
||||
},
|
||||
};
|
||||
const product = { openCount: 1, connectedEventCount: 1, errors: [], records: [{ ...userHwlab }, { ...terminalHwlab }] };
|
||||
const profile = {
|
||||
debugStreams: ["stdio", "agentrun", "hwlab"],
|
||||
requiredEventTypes: { agentrun: ["user_message", "terminal_status"], hwlab: ["user", "terminal"] },
|
||||
expectedKafka: { topics: { stdio: "codex-stdio.raw.v1", agentrun: "agentrun.event.v1", hwlab: "hwlab.event.v1" } },
|
||||
};
|
||||
|
||||
assert.doesNotThrow(() => validate({ turn: 1, traceId, sessionId, runId, commandId, debug, terminalSnapshots: [product], preTerminalSnapshots: [], profile }));
|
||||
const missingUserProduct = { ...product, records: [terminalHwlab] };
|
||||
assert.throws(
|
||||
() => validate({ turn: 1, traceId, sessionId, runId, commandId, debug, terminalSnapshots: [missingUserProduct], preTerminalSnapshots: [], profile }),
|
||||
/product subscriber lacks pre-terminal or terminal event|product SSE lacks the formal user event/u,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user