Skip to content

[Feature] 安全卸载空闲 External Harness runtime,并在下一条真实消息时恢复 #294

Description

@4sj9wrhgbp

Summary

希望为 CodexHost 自有的 External Harness 执行连接增加可选的空闲卸载与同 Thread 恢复:释放已经确认安全空闲的 Harness Session、Transport 和受管子进程,但保留逻辑 Thread、历史与恢复信息;只有下一条真实用户消息到来时才恢复同一会话。

这是功能申请,不是内存泄漏结论。逻辑 Thread 数、已加载 Session 数和进程数不是同一个指标;当前公开 CLI 也不能直接给出精确的已加载连接数。

取证环境:CodexHost v0.8.0,Windows x64 Installer。本申请不包含本机路径、会话内容、账号信息或凭据。

与现有工作的关系

v0.8.0 已通过 #267 改进 Claude 后台 Subagent 完成后的 Turn 结算;#238 也处理过后台 Subagent 结束后 Thread 长期保持 active 的问题。#247 仍在处理子 Thread 运行状态发布。

这些工作为“正确判断 busy / idle”提供了必要基础,但尚未实现执行连接的空闲卸载、关闭失败隔离和按真实新消息恢复。因此本申请与上述问题相关,但不重复。

作为另一套运行时的参考,openai/codex#32154 的源码级调查报告指出 Native Codex 存在约 30 分钟的空闲卸载路径;CodexHost 的 External Harness 有独立的审批、Tool、后台 Subagent、Transport 和恢复语义,不能直接照搬。

建议行为

  1. 仅处理当前 CodexHost 实例创建并持有的 External Harness Session 和受管子进程;不按进程名批量终止,也不处理其他 Host 或系统进程。
  2. 卸载不删除、归档或关闭逻辑 Thread,不修改业务完成状态;保留 Host Thread ID、Native Session ID、cwd、必要历史、模型、Thinking、权限和非敏感请求环境身份。
  3. 空闲超时与空闲连接数量超限分别触发;数量超限时按最后一次真实活动时间,从最久未使用且安全的连接开始。
  4. 空闲检查至少覆盖:运行 Turn、待发送请求、审批/提问、Tool、后台任务、Subagent/continuation、未保存结果、历史读取、启动/配置切换及 Host 账户或全局请求环境切换。任一状态无法确认时只跳过该连接。
  5. 进入卸载状态后阻止并发恢复和第二写者,同时保留旧 Session 引用;只有 Transport 关闭、受管进程退出、输出消费结束及持久化屏障全部确认成功后,才清除引用并进入可恢复状态。
  6. 关闭超时或结果不确定时保留旧引用与诊断,阻止自动重建;不得把空闲卸载记录为 Turn cancel,也不得静默新建 Thread 从头执行。
  7. 新消息与卸载并发时,请求只登记和提交一次。旧 generation 的迟到回调不得污染恢复后的新 Session。
  8. thread/read、列表、侧栏、健康检查和 Transport keepalive 不恢复 Session,也不重置“真实活动”时间;只有包含真实用户输入的下一次 turn/start 才恢复。
  9. 恢复前重新核对 Native Session、cwd、requested/accepted model、Thinking、权限和请求环境;不一致时保留原记录并明确报错。
  10. Adapter 必须显式实现只读空闲安全探针和可证明的安全关闭回执。未实现时返回 unknown 并跳过。建议首版使用 allowlist,仅支持通过测试的 Claude Adapter;v0.8.0 Hermes 在具备等价关闭契约前先排除。

建议配置

建议默认完全关闭,并提供三个阶段:

{
  "executionConnections": {
    "idleUnload": {
      "mode": "off",
      "idleTimeoutMs": 600000,
      "maxIdleConnections": 5,
      "adapterAllowlist": ["claude-code"]
    }
  }
}
  • mode: off | observe | enforce;缺失或无效时退回 off
  • 10 分钟和 5 个只是首版可调初值,不要求固定为最终默认值。
  • observe 只报告候选、blocker 和受管资源统计,不关闭连接。
  • 计时可复用 Host Runtime 事件循环,不新增后台服务,也不调用模型判断空闲。

配置文件位置和字段命名可以遵循项目现有配置约定;关键是提供明确的作用范围、严格校验和总关闭开关。

最低验收条件

  • 使用 Fake Timers 覆盖超时和数量阈值,不让测试真实等待 10 分钟。
  • 覆盖 busy、审批、Tool、后台任务、Subagent、未保存结果、配置/账户切换保护。
  • 覆盖消息与卸载并发、关闭超时、关闭失败、老回调迟到和幂等提交。
  • 覆盖同 Thread 恢复,以及模型、Thinking、权限和 cwd 保持。
  • 反复卸载/恢复不会累积 Session、Transport、回调或受管进程。
  • 用一个真实小会话证明:旧受管进程已退出;只读历史不恢复;下一条真实消息只执行一次并延续原会话。

非目标

  • 不扩展为全局内存压力管理或系统进程清理器。
  • 不接入 Pipeline、Stop Hook 或模型调用。
  • 不承诺固定 Token 或内存节省比例。
  • 本 Issue 先讨论生命周期和安全边界,不附带修改正式安装包的私人补丁。

如果维护者认可这个方向,我可以继续补充更细的状态机、竞态测试矩阵和 v0.8.0 对应源码位置;当前先避免在方向未确认前维护容易被后续版本覆盖的本地分支。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions