Repository navigation
fix(test): drain the process-level run registry between route checks - #133
Merged
Merged
Conversation
The guard suite shared the failure mode that made run-mirror look like a slow machine: beginRun/endRun keeps its tables in module scope, activeRunCount() reads them globally, and nothing drains them when a test abandons a turn. Inject one real failure and the following tests report 1 !== 0 and 3 !== 2 — counts that belong to the abandoned turn, not to them. Here the cascade is fast rather than slow, because the waitFor after the failing point is never reached. It is a fault-isolation defect, not a spontaneous flake: the file ran 10/10 clean before this and 10/10 clean under nice plus 14 CPU burners. One failure used to cost three. The drain helper imports nothing — no transport, no state-bus, no server paths. The call site lists what the file might leave behind by naming the callbacks, and a missing one is a visible omission rather than a silent leak. Cleanup unblocks, releases, awaits what it tracked, then asserts activeRunCount() === 0 so a leak fails by name. The coin-flip row count is left alone here on purpose: every chat assertion in this file goes through chatLines() with deepEqual, there is no bare length assertion to bypass, and the waitFor before each case means the row is always written — 8 out of 8 probes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
#132修的chat-run-mirrorflaky 留下一条姊妹隐患:本 PR 处理同一类问题的第二处,并把排空逻辑抽成共用 helper。诊断:两个问题只中一个
问题一存在且可复现 ✅
state-bus.js:717-718的runsByCid/runsBySid是模块级Map,activeRunCount()读全局,无重置钩子。注入 1 个真失败(把首条用例的 409 断言改 418)→ 3/3 红,后两条是
1 !== 0与3 !== 2——都是首条遗弃回合的残留 claim 被误算。与姊妹文件的差别只在:失败点之后的
waitFor(activeRunCount()===0)走不到,所以不烧 2 秒,级联表现为快速误报而非 14 秒。本质同一个坑。问题二不存在,未硬改 ❌
派单预判姊妹文件也有「抛硬币的行数断言」,实测证伪:
["› first","● ok","§§ processed_duration=3ms"])chatLines()(剥所有§§行)且用assert.deepEqual逐行比对,全文件无裸行数断言waitFor轮询,跨过毫秒边界,8/8 次都写了这一行——连抛硬币都不是所以没有加
durable()过滤器。这是故障隔离,不是自发性 flaky
nice -n 19+ 14 个 CPU burner 下 10 次文件本来就不自发性抖动。一次失败曾让三条一起红。
Helper 设计
新增
packages/webui/test/helpers/turn-drain.mjs:它不 import 任何东西——不碰传输层、不碰 state-bus、不解析 server 路径,只接注入的回调。
cleanup()顺序固定且承重:最后那步断言把静默泄漏变成指名道姓的失败。
两个调用点:guard 文件不传
unblock(无session/new闸门);run-mirror 传unblock: releaseNewSessionGate。闸门本身留在各自文件里。变异验证
releaseParkedPromptsawaitM2 单独说明:构造过存储污染探针(泄漏用例后接一条探针,等 200ms 读
sessions.loadSessions()),修复版与 M2 变体下存储都是[]。本文件两条用例之间没留出让 finalize 晚到越过rmSync的空档。所以await是排序加固,防的是没能确定性复现的时序竞争。门禁
pnpm webapp:typecheck/typecheckpnpm test:webapp×2pnpm test:webui×2pnpm check:sourcecheck-docs-alignment.mjstest-tmp-leak verify-registrytest-isolation-lint产品代码 0 行。
文档
不改
docs/,也不动AGENTS.md。曾建议在
AGENTS.md的 "Run the gates the way CI runs them" 追加一句,现决定不加,理由:那规则只对「真实handleSend+ 假 ACP 传输」的 route check 成立;send-run-guard.test.js直接调beginRun/endRun、不 park prompt。写成全仓库通用规则会让不适用它的文件以为要加钩子。因果链已完整写在 helper 的模块头注释里——下一个姊妹文件 import 时就会读到,比全仓库泛化的一行更精准,也不产生第二处会漂移的事实来源。若日后这类 check 变多,正确做法是扩
AGENTS.md里已有的 tmp-helper 那条,而不是新起平行规则。与 #132 的关系
两者都基于同一诊断。建议 #132 先合(它是本 PR 的前置事实来源),本 PR 可独立合入——它同时移植了 #132 的修复并改用同一 helper。
🤖 Generated with DeepSeek Harness