fix(rectification): keep adopt narration timeout on a clearable ref timer
Independent Staging Quality Gate / validate (push) Successful in 9m16s
Independent Staging Quality Gate / publish (push) Successful in 1m52s

AbortSignal.timeout() is unref'd, so a hanging generateText drained the test event loop and cancelled the rest of the file. Clear the timer after the model returns.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-04 15:23:13 +08:00
parent 5c9e98790b
commit 45bdb63eca
6 changed files with 226 additions and 14 deletions
+17 -1
View File
@@ -8062,6 +8062,22 @@
- 修复:提示词改为「不要出现『确认』『精确』这两个词」,与校验器同口径;校验器本身不放宽,「这不是确认的分钟」仍打回。`deliverAdoptNarration``adopt_narration=agent | template:<reason> | template:model_error | template:not_ready`(不含模型原文),并用 `AbortSignal.timeout(8000)` 超时走模板。意图分类器超时仍是既有缺口,本单不修。
- 验证:提示词源码断言含「不要出现」;`deliverAdoptNarration` 对 agent / template:unknown_minute / template:model_error / template:not_ready 各有断言;短 timeout 挂起 generateText 走模板且不抛。
- 防复发:采用旁白结果必须留下 `adopt_narration=` 日志。Agent.generate 必须带超时。不得把「确认」从校验器删掉却不改提示词。
- 相关记录:BUG-521
- 相关记录:BUG-521、BUG-523
- 复发自:无
- 修复版本:待发布
## BUG-523 | 采用旁白超时用 unref 计时器,测试挂死事件循环
- 状态:resolved
- 首次发现:2026-09-04
- 最近更新:2026-09-04
- 影响面:`frontend/src/lib/rectification-agentic/v9/adopt-narration-agent.ts` `composedAbortSignal`
- 用户现象:staging 门禁 `npm test` 退出码 1`13dded9f` 不能部署。生产请求有监听 socket 撑住事件循环,超时在真实流量里仍会触发;但每次调用都会留下一个无法 `clear` 的 8 秒计时器。
- 触发条件:`deliverAdoptNarration``AbortSignal.timeout()`;测试把 `generateText` 挂成永不 resolve 的 Promise。
- 根因:Node 的 `AbortSignal.timeout()` 内部计时器始终 unref,空事件循环会在 abort 前排空。测试运行器判 `cancelledByParent`,同文件后三条用例一并取消。验收只看了 `# fail`,没看 `# cancelled` 与退出码。
- 修复:改为 `setTimeout` + `AbortController`(计时器保持 ref),返回 `{ signal, dispose }`;模型返回、校验完成或外部 abort 后 `clearTimeout` 并移除监听。超时仍走 `template:model_error`
- 验证:`rectification-adopt-narration-20260904` 超时用例不再 cancelled;新增「调用完不留活跃计时器」用例;源码不含 `AbortSignal.timeout`。定向套件与该文件摘要须含完整六行且 `# cancelled 0`、退出码 0。
- 防复发:采用旁白超时不得再用 `AbortSignal.timeout`。验收必须贴 Node 摘要完整六行(tests / pass / fail / cancelled / skipped / todo)与进程退出码,不得只报 `# fail 0`
- 相关记录:BUG-522
- 复发自:BUG-522
- 修复版本:待发布