fix(tmux): 会话级 env 不再泄漏进 tmux server 全局环境(误路由 AskUserQuestion 卡片)#364
Open
deepcoldy wants to merge 1 commit into
Open
fix(tmux): 会话级 env 不再泄漏进 tmux server 全局环境(误路由 AskUserQuestion 卡片)#364deepcoldy wants to merge 1 commit into
deepcoldy wants to merge 1 commit into
Conversation
## 问题 botmux 的 TmuxBackend/TmuxPipeBackend 用**默认 tmux socket**(/tmp/tmux-*/default)跑 会话,和用户自己的交互 tmux 共用同一个 server。tmuxEnv() 之前只剥 TMUX/TMUX_PANE,会把 本会话的 BOTMUX_SESSION_ID / BOTMUX_CHAT_ID / BOTMUX_LARK_APP_ID / SESSION_DATA_DIR 等 带进 tmux **client env**——当 botmux 首个 `new-session` 引导起 server 时,tmux 把 client env 固化成 server 的**全局环境**,此后同 server 上新建的每个会话(包括用户 `ssh devbox` 起的 `tmux new-session -A -s cc`)的 pane 都继承这份全局 env。 后果:用户终端里一个普通 Claude Code 会话继承了 botmux 的 BOTMUX_SESSION_ID/CHAT_ID, 其 AskUserQuestion 的 PreToolUse hook(botmux hook claude-code)误以为自己是 botmux 会话, 把选择题卡片 POST 给 daemon、发到那个飞书话题群里。 ## 修法(对正在运行的会话零影响) 1. tmuxEnv() 增加剥离 botmux 托管的会话/机器人级 env key(isBotmuxManagedTmuxEnvKey: BOTMUX* 前缀一律剥 + __OWNER_OPEN_ID/SESSION_DATA_DIR/IS_SANDBOX/CLAUDE_CONFIG_DIR/ CLAUDE_CODE_RESUME_TOKEN_THRESHOLD/CJADK_INTERACTIVE + 裸 IM 凭据)。pane 本身靠 `/usr/bin/env KEY=VAL` 注入拿正确的 per-session 值(不走 client/global env),所以对 botmux 自己的会话完全无感。新引导的 server 全局环境从此干净。 2. 新增 TmuxBackend.scrubServerGlobalEnvOnce():daemon 每进程跑一次,把已被旧版 botmux 污染的 server 全局环境里的 botmux key `set-environment -g -u` 掉(自愈老 server)。 只改全局环境表、**不触碰已运行 pane 的进程环境**——活会话字节不变,只有之后新建的 pane 才拿到干净环境。在 TmuxBackend.spawn() 与 TmuxPipeBackend.spawn() 顶部触发 (运行时真正实例化的是 TmuxPipeBackend)。 ## 影响面 - 会话后端:TmuxBackend / TmuxPipeBackend(PtyBackend 不受影响,其 CLI child 仍正常拿 BOTMUX_*)。 - 三个非注入的 BOTMUX_*(BOTMUX_BOT_INDEX/QUIET_RESTART/MEMORY_DIAG_INTERVAL_MS)经确认只在 daemon/CLI 启动层读取、pane 内从不读,剥离安全;顺带修掉了它们对其它 bot 面板的过期泄漏。 ## 测试 - pnpm build 绿。 - 单测:tmux-env-isolation / tmux-backend-env / tmux-pipe-backend / child-env / per-bot-env / tmux-probe / tmux-reattach / startup-tmux-gate / backend-gate / selector-shape = 126 passed。 - e2e:tmux-backend.e2e = 4 passed。 - 隔离 socket 端到端复现+验证脚本(12/12 PASS): · tmuxEnv 剥掉 BOTMUX_SESSION_ID/TMUX,保留 HOME/PATH; · 经新 tmuxEnv 引导的 server 全局环境无 BOTMUX_*/SESSION_DATA_DIR/LARK_APP_ID,co-tenant pane 不继承; · scrub 清掉预污染 server 的 BOTMUX_*,且运行中 pane 存活、其 env 前后字节一致。
6e6b16b to
d2bcfe9
Compare
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.
问题
botmux 的 tmux 后端用默认 tmux socket(
/tmp/tmux-*/default)跑会话,和用户自己的交互 tmux 共用同一个 server。tmuxEnv()此前只剥TMUX/TMUX_PANE,会把本会话的BOTMUX_SESSION_ID/BOTMUX_CHAT_ID/BOTMUX_LARK_APP_ID/SESSION_DATA_DIR等带进 tmux client env。当 botmux 首个new-session引导起 server 时,tmux 把 client env 固化成 server 的全局环境,此后同 server 上新建的每个会话(包括用户ssh devbox起的tmux new-session -A -s cc)的 pane 都继承这份全局 env。后果:用户终端里一个普通 Claude Code 会话继承了 botmux 的
BOTMUX_SESSION_ID/CHAT_ID,其 AskUserQuestion 的 PreToolUse hook(botmux hook claude-code)误以为自己是 botmux 会话,把选择题卡片 POST 给 daemon、发进那个飞书话题群。修法(对正在运行的会话零影响)
闸口:
tmuxEnv()增加剥离 botmux 托管的会话/机器人级 env key(isBotmuxManagedTmuxEnvKey:BOTMUX*前缀一律剥 +__OWNER_OPEN_ID/SESSION_DATA_DIR/IS_SANDBOX/CLAUDE_CONFIG_DIR/CLAUDE_CODE_RESUME_TOKEN_THRESHOLD/CJADK_INTERACTIVE+ 裸 IM 凭据)。pane 本身靠/usr/bin/env KEY=VAL注入(读opts.env而非tmuxEnv(opts.env))拿正确的 per-session 值,不走 client/global env,对 botmux 自己的会话完全无感。新引导的 server 全局环境从此干净。自愈老 server:新增
TmuxBackend.scrubServerGlobalEnvOnce(),daemon 每进程跑一次,把已被旧版 botmux 污染的 server 全局环境里的 botmux keyset-environment -g -u掉。只改全局环境表、不触碰已运行 pane 的进程环境——活会话字节不变,只有之后新建的 pane 才拿到干净环境。在TmuxBackend.spawn()与TmuxPipeBackend.spawn()顶部触发(运行时真正实例化的是TmuxPipeBackend)。影响面
TmuxBackend/TmuxPipeBackend。PtyBackend不受影响(其 CLI child 仍正常直接拿BOTMUX_*)。BOTMUX_*(BOTMUX_BOT_INDEX/QUIET_RESTART/MEMORY_DIAG_INTERVAL_MS)经确认只在 daemon/CLI 启动层读取、pane 内从不读,剥离安全。测试
pnpm build绿。待 live 验证
需
pnpm switch:here && botmux restart部署后在飞书里确认:botmux 会话仍能正常触发 ask 卡片,且用户终端新开的 tmux pane 不再带BOTMUX_*。