diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index b8922ba2..71228daa 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -20017,3 +20017,19 @@ - 相关记录:BUG-1466、BUG-1433、BUG-989(新对话首问才落库)、BUG-725 / BUG-1329(外壳拿稳定包装、调用最新回调);TASK-sidebar-unify-20260916 D1(只读侧栏的约定,本条推翻其中「别的页面不写」一项,产品 2026-10-27 选 A 授权)。 - 复发自:无 - 修复版本:分支 `codex/session-shell-116-20261027`。 + +## BUG-1468 | staging 门禁两次挂在「发送后 300 毫秒内出第一句」墙钟断言 + +- 状态:resolved(自动化) +- 首次发现:2026-10-28(`0f0fea325` 的 backend-quality-gate run id 5730,首跑与重跑都失败) +- 最近更新:2026-10-28 +- 影响面:只影响门禁;产品行为无变化。 +- 用户现象:无。门禁 5274 条只失败 1 条:`rectification-latency-20260926.test.tsx` 的 D3,报「first progress line within 300 ms of send」。部署因此没有发生,staging 停在 `36fd4b2c8`。 +- 触发条件:CI 机器较慢时。 +- 根因:断言用墙钟量「发送到第一句出现」不超过 300 ms。它要证的是第一句不等服务端,而墙钟在共享 CI 机上不可靠。本机基线和新版都约 74 ms;`CI=1` 本机全量通过;该测试只渲染校正对话组件,不渲染 `0f0fea325` 改过的任何文件。 +- 修复:去掉墙钟,改为断言此刻服务端回复还没交给页面(`controllableStream().answered === false`)。上一行「第一句已在屏上」的断言保留。三栏说明在测试里。 +- 验证:该文件 2 条通过;若页面改成等服务端才出第一句,上一行 `deepEqual` 即失败。 +- 防复发:组件测试不用墙钟预算证明「先于服务端」,用可控流的状态证明。 +- 相关记录:BUG-1042~1047(该测试来源)、BUG-1467。 +- 复发自:无 +- 修复版本:分支 `codex/session-shell-116-20261027`。 diff --git a/frontend/tests/rectification-latency-20260926.test.tsx b/frontend/tests/rectification-latency-20260926.test.tsx index 79b38e04..d46c7f82 100644 --- a/frontend/tests/rectification-latency-20260926.test.tsx +++ b/frontend/tests/rectification-latency-20260926.test.tsx @@ -229,10 +229,14 @@ function controllableStream() { let controller!: ReadableStreamDefaultController; const body = new ReadableStream({ start(c) { controller = c; } }); let release!: () => void; + let answered = false; const gate = new Promise((resolve) => { release = resolve; }); return { + /** True once the server reply has been handed to the page. */ + get answered() { return answered; }, respond: async () => { await gate; + answered = true; return new Response(body, { status: 200, headers: { "content-type": "application/x-ndjson; charset=utf-8" } }); }, release: () => release(), @@ -272,11 +276,14 @@ test("D3 · the first stage line shows on send (before any server byte), then fo }, }); try { - const sentAt = Date.now(); await chat.type("2023 年 3 月换了工作"); // The fetch has not resolved yet: this line is on screen with no server byte. assert.deepEqual(shown(chat), [LABELS.received], chat.text()); - assert.ok(Date.now() - sentAt <= 300, "first progress line within 300 ms of send"); + // 原值:assert.ok(Date.now() - sentAt <= 300, "first progress line within 300 ms of send") + // 新值:断言此刻服务端回复还没交给页面(stream.answered === false) + // 原因:要证的是「第一句不等服务端」,墙钟在共享 CI 机上不可靠:本机 74 ms, + // 0f0fea325 的门禁两次在这里超 300 ms,而该测试不渲染那次改动的任何代码(BUG-1468)。 + assert.equal(stream.answered, false, "first progress line shows before the server answers"); assert.equal(chat.text().includes("正在处理…"), false); stream.release();