Subagent teardown tests inherit their execution lane budgets
子代理清理测试继承执行通道的时间预算
The Windows coverage run (run 34085536250, job 101628739668) reports two teardown failures despite granting tests and hooks 90 seconds. The ACP ignored-EOF test races disposal against its own five-second timer. The real Codex test overrides the hook budget with 30 seconds. Neither deadline tests a product latency guarantee. The Codex body has already observed process-tree exit before its hook fails; the log does not
English
Problem
The Windows coverage run (run 34085536250, job 101628739668) reports two teardown failures despite granting tests and hooks 90 seconds. The ACP ignored-EOF test races disposal against its own five-second timer. The real Codex test overrides the hook budget with 30 seconds. Neither deadline tests a product latency guarantee. The Codex body has already observed process-tree exit before its hook fails; the log does not identify whether context disposal, HTTP closure, or temporary-directory removal exceeded the hook budget.
Decision
The ACP test awaits disposal under the execution lane’s test budget, then checks the actual child outcome. Failure cleanup awaits disposal and child completion before removing the private directory. A deferred exit observation proves that disposal cannot finish merely because termination was requested. The production EOF and termination grace periods remain unchanged.
The Codex test inherits the execution lane’s hook budget, which vitest.config.ts applies to every inline project from DSH_COVERAGE_TEST_TIMEOUT_MS (coverageTestTimeoutOptions owns why a CLI flag cannot carry it). Cleanup captures its contexts, HTTP fixtures, and temporary roots before its first asynchronous wait, so an overdue hook cannot drain resources registered by another test. It preserves context-disposal, server-closure, and directory-removal ordering, waits for every captured disposer, and attempts the remaining cleanup stages after a rejection. Collected errors identify each failing stage or path and retain their causes; cleanup reports them only after all captured resources have been attempted.
The native Windows CI decision continues to own lane scheduling and budgets. This change only removes conflicting local deadlines and strengthens resource-lifetime assertions; it does not establish a Windows process-kill or filesystem defect.
Alternatives considered
- Increase production grace periods or filesystem retries: the failures do not demonstrate incorrect product timing or exhausted removal retries.
- Replace local deadlines with larger constants: that would still override future lane budgets.
- Return from cleanup immediately after requesting termination: that would permit children or sockets to outlive the fixture.
- Serialize coverage: unrelated tests need not lose concurrency to accommodate two local deadline overrides.
Consequences
The lane timeout remains a bound on hangs. Focused tests verify observed child completion and cleanup ownership instead of host termination speed. Native Windows runs remain necessary for taskkill, process-exit delivery, and NTFS removal evidence; passing macOS tests cannot prove those mechanisms. No model-visible output, Session fixture, production timeout, or CI routing changes.
中文
问题
Windows 覆盖率运行 (run 34085536250, job 101628739668) 为测试和钩子提供 90 秒预算,却报告了两个清理失败。ACP 忽略 EOF 测试让清理与自设的五秒定时器竞争。真实 Codex 测试将钩子预算覆盖为 30 秒。这两个期限都不用于验证产品延迟保证。Codex 测试正文在钩子失败前已经观察到进程树退出;日志未指出究竟是上下文释放、HTTP 关闭还是临时目录删除超出了钩子预算。
决策
ACP 测试 在执行通道的测试预算内等待清理完成,然后检查真实子进程的结果。失败清理先等待释放和子进程完成,再删除私有目录。延迟的退出观察证明,清理不能仅因已请求终止而完成。生产环境的 EOF 与终止宽限期保持不变。
Codex 测试 继承执行通道的钩子预算;vitest.config.ts 从 DSH_COVERAGE_TEST_TIMEOUT_MS 把该预算施加到每个内联 project(coverageTestTimeoutOptions 负责说明 CLI 标志为何无法承载它)。清理在第一次异步等待前取得其上下文、HTTP 夹具和临时根目录,因此超时钩子不能取走其他测试注册的资源。清理保留上下文释放、服务器关闭、目录删除的顺序,等待所有已取得的释放操作,并在拒绝后继续尝试其余清理阶段。收集的错误指出各自失败的阶段或路径并保留原始原因;只有全部已取得资源都尝试清理后才报告错误。
原生 Windows CI 决策 继续负责通道调度和预算。本次改动仅移除冲突的局部期限并加强资源生命周期断言;它并不证明 Windows 进程终止或文件系统存在缺陷。
曾考虑的替代方案
- 增加生产环境宽限期或文件系统重试次数:这些失败不能证明产品时序错误或删除重试耗尽。
- 用更大的常量替换局部期限:这样仍会覆盖未来的通道预算。
- 请求终止后立即结束清理:这样会允许子进程或套接字存活超过夹具的生命周期。
- 将覆盖率测试串行化:无关测试不应为两个局部期限覆盖而失去并发能力。
后果
通道超时仍为挂起提供时间上限。定向测试验证观察到的子进程完成和清理所有权,而不是宿主机终止速度。taskkill、进程退出通知和 NTFS 删除仍需原生 Windows 运行提供证据;macOS 测试通过不能证明这些机制。模型可见输出、Session 夹具、生产环境超时与 CI 路由均不变。