Conversation
WSL 模式中 codex 写入 threads.rollout_path 的是 WSL 视角路径 (/mnt/<盘符>/...),Windows 侧 helper 按原路径读不到文件: rollout_file_backups 里 fs::read(path).ok()? 静默跳过,导致备份缺 __files、文件删除循环空转,最终返回「已从本地存储删除」的假成功, Codex 重启后从残留的 rollout 文件重建会话(删除后复活)。 - 新增 wsl_path_alternative:/mnt/<盘符>/... 与 <盘符>:/... 视角互转 - rollout_file_backups 先按原路径读取,失败再尝试互转视角;__files 条目的 path 用可读写视角并保留 source_path 原始写法 - 文件存在但两种视角均读取失败时并入 file_errors,不再静默成功 - undo 白名单同时放行两种视角,WSL 会话可完整撤销 - 兼容:两种视角下文件均不存在时维持旧行为(跳过并删除成功) 测试:wsl_path_alternative 单测 4 个;回归测试 3 个(真删除 + 备份/ 撤销完整、Windows 路径对照、文件缺失兼容);既有 27 个 storage 测试无退化;另在 Windows 真机通过 manager 二进制 + CDP 驱动真实 delete_local_session 命令做了端到端验证。
Owner
|
改动已合入 说明:合入时对分支做了 rebase,SHA 与 PR 原始提交不同,GitHub 无法自动识别为已合并。 这个修复很扎实 —— 根因链( 一处想请你确认:
也就是说核心的路径转换逻辑已被覆盖,但「WSL 视角下真的删掉文件并撤销还原」这条端到端行为只能在 Windows 上跑到。如果这条路径对 Windows CI 有依赖,请确认 CI 上是绿的。 |
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.
Fixes #162
问题现象
WSL 模式下在 Codex++ 里删除会话,界面提示删除成功(
local_deleted),但重启 Codex App 后会话重新出现在侧边栏。备份 json 里有tables.threads记录,却没有tables.__files段。根因
WSL 模式中 codex 写入
state_5.sqlite的threads.rollout_path是 WSL 视角路径(如/mnt/c/Users/.../rollout-xxx.jsonl),而 Codex++ 的 helper 是 Windows 侧进程,按该路径找不到文件。断链发生在crates/codex-plus-data/src/storage.rs的rollout_file_backups:连锁反应:
__files为空 → 文件删除循环遍历空列表(不删、零报错)→ 返回local_deleted假成功 → 数据库行已删、rollout 文件残留 → Codex 重启时从残留文件重建会话。我在 Windows 真机上用 A/B 对照实验复现过:同一个文件、同一张表,唯一变量是
rollout_path写 Windows 视角还是 WSL 视角——前者真删除,后者假成功、文件原样保留。修复方案
改动集中在
crates/codex-plus-data/src/storage.rs:wsl_path_alternative:/mnt/<盘符>/...与<盘符>:/...两种路径视角互转(纯字符串转换,双向可逆)。rollout_file_backups先按原路径读取,失败再尝试互转视角;备份条目的path使用可读写视角(供删除与撤销直接使用),两视角不同时附带source_path保留 DB 原始写法。file_errors:数据库删除后返回 Failed 并附 undo token,不再静默报成功——这是 WSL 模式下删除会话提示成功,但重启后会恢复 #162 明确要求的行为(「如果 rollout 文件读不到或删不掉,也不要返回删除成功」)。allowed_backup_file_paths)同时放行两种视角:保证 WSL 会话删除后可以完整撤销(数据库行 + rollout 文件都能还原)。放行集仍要求目标不存在、仍只能来自 DB 里真实存在的rollout_path,不扩大可写位置。兼容性:两种视角下文件均不存在时(如已被手动清理)维持旧行为——跳过文件、删除成功;Windows 视角路径的删除行为完全不变(有对照回归测试)。
测试
wsl_path_alternative单测 4 个:双向转换、往返稳定、非法形式拒绝。tests/wsl_rollout_path.rs):__files/source_path+ 撤销完整还原(#[cfg(windows)]);cargo test -p codex-plus-manager中delete_local_session相关测试通过;clippy 无新增警告。delete_local_session命令(与 GUI 删除按钮同一入口)——返回local_deleted、rollout 文件确实从磁盘消失、备份含__files、二次删除返回Thread not found in local storage。这个 bug 为什么被埋没了四个月
复盘下来不是没人看见,而是几层因素叠加,写出来供后续测试建设参考:
.ok()?把寻址失败吞掉,日志里只有一路成功(local_deleted)。没有报错就没有排查入口,用户侧只能观察到「重启后复活」这个间接症状。storage.rs最近一次改动(9 月初)就在这条流程上,只是 WSL 变体在他们的环境里不存在。其中第 3 点或许值得后续补一类「跨视角路径」的测试夹具;本 PR 的
wsl_rollout_path.rs已是这类夹具的第一个样例。贡献确认
cargo fmt(改动区域)、clippy 无新增警告、既有测试全绿。storage.rs语义改动 + 新测试文件,不含无关格式化噪音。