fix(adapter): cursor/copilot/kimi 恢复缺 cliSessionId 时新起会话,杜绝 --continue 串用兄弟会话上下文 - #927
fix(adapter): cursor/copilot/kimi 恢复缺 cliSessionId 时新起会话,杜绝 --continue 串用兄弟会话上下文#927ITcathyh wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99598bed53
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // topic group's context leaking into a private chat. Losing this | ||
| // session's context is the lesser evil; matches reasonix/antigravity, | ||
| // which reject `--continue` for the same "most recent is racy" reason. | ||
| return base; |
There was a problem hiding this comment.
Propagate the fresh fallback to worker state
When a restored Cursor session lacks cliSessionId (and likewise for the changed Copilot/Kimi paths), this returns fresh-launch arguments while worker.ts leaves effectiveResume=true; because these adapters have no failing checkResumeTargetExists, the worker's fresh-demotion branch and its user-visible “历史会话无法恢复” warning never run. Copilot and Kimi normally lack ID capture, so routine crash, idle-recovery, or deployment restarts silently discard their conversation and deliver the next prompt to a blank context while the user is told nothing. Route this no-ID case through the worker's fresh fallback, or otherwise set the effective mode and emit the existing warning.
AGENTS.md reference: AGENTS.md:L64-L68
Useful? React with 👍 / 👎.
|
自动化初步评审发现一处建议在合入前补齐的用户态语义,最终以维护者审阅为准。 本 PR 在 Copilot/Kimi 缺少
因此用户可能在以为旧上下文仍在的情况下直接发送依赖历史的后续指令。建议让“缺精确 id → fresh”成为 worker/上层可观察的结果(例如复用现有 fresh-demotion 通知),并让关闭卡片/恢复回执明确区分“逻辑路由重新激活”与“CLI 历史上下文已恢复”;同时补 Copilot/Kimi 缺 id 的卡片与冷恢复通知测试。 其余复核结果:自动 spawn 统一走 |
…e 串用兄弟会话上下文 话题群会话 A 的上下文偶发串到私聊会话 B。根因:cursor / copilot / kimi 三个适配器在 resume=true 但 resumeSessionId 缺失(worker 重启时 cliSessionId 从未持久化,如崩溃早于捕获 / 观测失败)时回退到 `--continue`,而 `--continue` 恢复的是「全局最近会话」——同一 bot 的多个 botmux 会话共享 同一个 CLI 配置目录,于是 B 的 worker 可能把 A 的会话加载进自己的上下文, B 的回复里出现只属于 A 的句子。「偶现」正对应「worker 重启 + cliSessionId 缺失 + 兄弟会话最近活跃」三者同时成立的竞态窗口。 修法:移除 `--continue` 兜底,缺 id 时新起干净会话,宁可丢本轮上下文也不 串用兄弟会话。与 reasonix / antigravity 已确立的模式对齐(两者注释明确 拒绝 `--continue`:"most recent is racy when multiple botmux sessions run in parallel")。claude-code / codex / grok 等适配器本就按精确 id 恢复,不受影响。 影响面:仅 cursor / copilot / kimi 三个 CLI 适配器的「worker 重启且 cliSessionId 未持久化」恢复路径;话题群 / 群聊 / 私聊三种会话类型的 正常新建与精确恢复(有 cliSessionId)行为不变。 测试:cli-adapters 361/361、cursor-resume-policy 5/5、event-dispatcher 294/294、session-resume 39/39、write-input 136/136 均通过;新增 9 条 回归用例覆盖三适配器「缺 id 不 --continue / 有 id 精确 --resume / fresh 不受影响」。 Co-Authored-By: Claude <noreply@anthropic.com>
…t/kimi 恢复回退 交叉审核三项修复: 1. grok 漏网:grok.ts buildArgs resume 路径在 resumeSessionId 与 sessionId 均缺失时仍回退 --continue(恢复全局最近会话,跨 botmux 会话共享),与 cursor/copilot/kimi 同款漏洞。移除 --continue,缺 id 时新起。补回归测试。 2. cursor sticky 缺 id:cursor-resume-policy 旧策略为 --continue 时代设计, resume=true && !cliSessionId 时关闭观测。适配器移除 --continue 后该场景 实为新起会话,应恢复观测以捕获新 chat id,否则 id 永不捕获、下次重启仍 缺 id。更新策略与测试:缺 id 新起时观测+持久化。 3. copilot/kimi 恢复能力回退显式说明:两者无任何 cliSessionId 捕获机制 (无 bridge、无 observation、无 output capture),「缺 id」是常态。 移除 --continue 后每次 worker 重启都新起会话,丧失跨重启恢复能力。 在代码注释中写明该回退与后续 fast-follow(补 session id 捕获)。 测试:cli-adapters 362/362、cursor-resume-policy 5/5、cursor-transcript 22/22、event-dispatcher 294/294、session-resume 39/39、write-input 136/136 均通过;pnpm build 通过。 Co-Authored-By: Claude <noreply@anthropic.com>
评审指出:cursor/copilot/kimi 缺 cliSessionId 时 buildArgs 改为新起干净会话 是对的,但 worker 仍保留 effectiveResume=true,fresh-demotion 分支不触发 (这些适配器没有 failing checkResumeTargetExists),冷恢复/崩溃重启/空闲回收 静默丢上下文,而关闭卡片显示「点击恢复会话继续」、恢复回执说「会话已恢复」, 用户会在以为旧上下文仍在的情况下发依赖历史的指令。 - worker: 新增 Tier 0 回退——适配器声明 resumeRequiresCliSessionId 且无 cliSessionId 时走现有 fallBackToFresh 分支(effectiveResume=false + user_notify「历史会话无法恢复,已新起干净会话」),缺 id 新起成为可观察 结果;reattach 活 pane 不触发(无上下文丢失) - cursor/copilot/kimi 声明 resumeRequiresCliSessionId(buildArgs 缺 id 即 新起,无 --continue 回退);claude-code/grok(sessionId 即可恢复)与 gemini(完全忽略 resume)不声明,行为不变 - 关闭卡片:缺精确 id 时文案改为「重新激活话题路由 + 新起干净会话」,不再 暗示历史可恢复(card.body.resume_starts_fresh);有精确恢复命令时不变 - 恢复回执:区分「话题路由已重新激活」与「会话已恢复」 (card.action.resume_success_fresh) - 新增 services/resume-fresh-policy 统一判定,卡片/回执共用同一语义 - 测试:适配器能力位断言、卡片文案、恢复回执行为测试(copilot 缺 id/带 id、 claude-code 对照)、worker 降级与卡片文案 source-lock Co-Authored-By: Claude <noreply@anthropic.com>
99598be to
26a52d5
Compare
优先级:P1
根因
cursor、copilot、kimi 以及遗漏的 grok 在 worker 恢复但缺少精确
cliSessionId时回退到--continue。该参数恢复的是 CLI 全局最近会话;同一 bot 的多个 botmux 会话共享 CLI 配置目录,因此最近活跃的兄弟会话可能被错误加载,造成话题群、群聊或私聊之间的上下文泄漏。改动
--continue,而是新建干净会话;有 id 时继续精确恢复。--continue注释。影响面
仅影响四个 CLI 在 worker 重启且 cliSessionId 缺失的恢复路径;正常新建和有精确 id 的恢复不变。安全取舍是宁可丢失该轮跨重启上下文,也不加载其他 botmux 会话。
验证
--continue、有 id 精确恢复、fresh 启动不受影响,以及 cursor 缺 id 时恢复观测。pnpm build通过。