你的命令跑到别人的服务器上了吗?Hermes 修复了跨 Profile 的 SSH 环境泄漏


如果你的 Hermes 同时开着两个 Profile——一个连公司的服务器,一个连家里的 NAS——请先看这个:8 月 22 日合入 main 的 #92156 修复了一个可能让你把命令跑在错误主机上的泄漏。它听起来很技术,但后果很直接:切换 Profile 后,你的终端命令有可能静默地继续用上一个 Profile 缓存的 SSH 环境,也就是你以为在 A 服务器上执行的命令,实际跑到了 B 服务器上。

泄漏是怎么发生的

Hermes 的终端工具会缓存每个会话的远程环境(SSHEnvironment 这类),避免每次执行命令都重新建立连接。这个缓存存在一个叫 _active_environments 的字典里,用 _resolve_container_task_id() 算出来的键做索引。

问题出在这个键上:WebUI / 网关的会话都被映射到同一个 "default"。于是同一进程里,Profile A(ssh_host=10.0.0.1)和 Profile B(ssh_host=10.0.0.2)共用同一个缓存槽位——切换 Profile 后,B 的终端可能直接捡起 A 缓存的 SSH 环境,命令静默地跑在 10.0.0.1 上,而不是你以为的 10.0.0.2。

在 SSH 场景下这尤其危险:rmgit push、改配置这类命令,跑错主机意味着在错误的目标上执行破坏性操作,而你自己毫无察觉——因为输出看起来“一切正常”。

修复:按 session 隔离缓存

#92156 的修复思路很直接:缓存键从 "default" 改为 session:<key>

  • WebUI 的流式传输层会为每个会话设置独立的 session key;
  • 网关侧通过 contextvars 按消息注入 session key;
  • 切换 Profile(切换会话)后,新会话的缓存键不同,不再能复用上一个 Profile 的 SSHEnvironment,自然也就不会把命令发到错误的主机。

顺带说明:修复没有破坏子代理共享父容器、或 RL/benchmark 环境(TerminalBench2 等)的按任务隔离——那些路径有各自的键规则,delegate_task 子代理仍然共享父会话的长连接容器。

你应该做什么

  1. 多 Profile + SSH 的用户:更新到包含该修复的版本(hermes update --branch main 或等下一个 release,当前最新正式版仍是 v0.20.5);
  2. 验证方法:两个 Profile 分别配不同的远程主机,各执行一次 hostnameecho $SSH_CONNECTION,确认输出与各自配置一致;
  3. 通用建议:多 Profile 的玩法见《Hermes Profiles:一台机器跑多个独立实例》;终端环境相关的细节也可以翻《4 个隐藏技巧》里的配置键用法。

发布状态

该修复(#92156)已合入 main(8/22),尚未随正式版本发布。想尝鲜用 hermes update --branch main。它与昨天聊到的《循环看门狗调优》同属 8 月下旬 main 上的一批 gateway/终端加固。

总结

跨 Profile 的 SSH 环境泄漏是个“看不见的坑”:不是报错,而是静默地跑在错误的主机上。好消息是修复已经合入 main,按会话隔离缓存后,切换 Profile 再也不会捡到上一个 Profile 的远程环境。如果你是多 Profile 重度用户,值得第一时间更新并验证。