[Bug]: [重要提醒] 使用过程中整个 %USERPROFILE%\.codex 目录被永久删除(会话历史 100% 丢失,仅 1.1% 可恢复)
影响范围
其他
当前行为
⚠️ 这是一份风险预警,不是可稳定复现的 bug 报告。我无法指出具体是哪一行代码触发的, 但损失是真实的:整个
.codex被永久删除,454 MB 会话历史只剩约 1.1% 可恢复。 如果你的用户也把 Codex++ 和官方 Codex 桌面版/CLI 混着用,建议优先关注第 6 节的加固建议。
1. 环境
| 项 | 值 |
|---|---|
| Codex++ | 1.2.56(事件当天由 1.2.55 → 1.2.56 自更新) |
| Codex 桌面版 | MSIX OpenAI.Codex 26.903.8094.0(事件当天凌晨自动更新) |
| Codex CLI | codex-cli 0.153.4 |
| 启动模式 | launchMode: "patch" |
| 系统 | Windows 11 专业工作站版 24H2,26100.4351 |
| 磁盘 | NVMe SSD,C: 分区 251 GB |
.codex 规模 |
176 个文件 / 433.55 MB / 22 个技能 |
相关设置(settings.json):
{
"codexAppSessionDelete": true,
"launchMode": "patch",
"providerSyncEnabled": false,
"codexAppMarkdownExport": true,
"codexAppForceChineseLocale": true
}2. 事件时间线(证据来源已标注)
| 时间 | 事件 | 证据 |
|---|---|---|
| 2026-05-27 13:21:11 | .codex 创建 |
目录 CreationTime |
| 2026-09-08 16:35 | 最后一次正常使用 Codex | 抢救出的 rollout 时间戳 |
| 2026-09-09 00:20 | session_index.jsonl 最后写入 |
文件时间戳 |
| 2026-09-10 01:02 | Codex 桌面版 MSIX 自动更新 | WindowsApps 目录时间 |
| 2026-09-10 14:03:27 | 另一个程序的安装(DSH Desktop)删除它自己的 AppData(38 MB,与本次无关) | 回收站 $I 元数据 |
| 2026-09-10 14:39:48 | .codex 被永久删除 |
DiskGenius 目录项 + 逐文件内容校验 |
| 2026-09-10 14:59:09 | Codex 桌面版在空位置重建 .codex |
目录 CreationTime |
| 2026-09-10 14:59:33 | Codex++ 管理器进程启动,新建 ~/.codex-session-delete/ |
codex-plus.log 首条记录 timestamp_ms |
| 2026-09-10 15:07 | Codex++ 自更新 v1.2.56 |
日志 update.write.completed / update.launch.completed |
3. 实际损失
- 会话历史:
sessions\YYYY\MM\DD\rollout-*.jsonl共 184 个文件 / 454.1 MB(清单来自 Windows 搜索索引),全部丢失。 - 数据库:
state_5.sqlite(11 MB)、thread_history_1.sqlite(831 KB)、logs_2.sqlite(812 KB)、sqlite\codex-dev.db(217 KB) 全部不可用。 - 配置:
config.toml本体丢失(仅找到两份backups_state里的旧快照)。 - 自定义技能:
.codex\skills\下 22 个技能中 8 个不可用(正文被覆盖或全零)。
4. 为什么认定与 Codex++ 相关(请逐条评估)
4.1 它是唯一有能力、且被启用去"删除会话"的程序
反编译 codex-plus-plus.exe / codex-plus-plus-manager.exe 取出的前端逻辑:
function confirmDelete(title) { /* 弹出确认对话框 */ }
confirmDelete(ref.title).then(async (confirmed) => {
if (!confirmed) return;
const result = await postJson("/delete", ref);
if (result.status === "server_deleted" || result.status === "local_deleted") {
removeDeletedRow(row, button, ref);后端类型定义与 SQL:
enum DeleteStatus { server_deleted, local_deleted, partial, undone }
struct DeleteResult { session_id, message, undo_token, backup_path }
// 它会读取并据此定位本地会话文件
SELECT title, rollout_path FROM threads WHERE id = ?1
DELETE FROM messages WHERE session_id = ?1
DELETE FROM sessions WHERE id = ?14.2 它会直接改写用户的 rollout 文件
日志里存在这些字符串,说明它读写用户的 rollout 文件:
"rollout changed while provider metadata was being written"
"skippedLockedRolloutFiles"
"changedSessionFiles"4.3 它的 DeleteResult 声称有 backup_path 和 undo_token,但事件后没有任何可用的备份
这是我最担心的一点。我找遍了所有可能位置:
~/.codex-session-delete/下没有 backup / undo / trash 子目录(skill-backups也不存在)- 全盘搜索无
codex*backup/undo/.trash/deleted-session目录 - 事件后整个用户目录下没有任何 9/7 之后修改的
*.jsonl
即:它宣称有回滚能力,但这次没有留下任何可回滚的东西。
4.4 删除绕过了回收站(永久删除)
回收站内只有一个 114 字节的 $I 元数据记录(指向另一个目录),不存在对应的 $R 数据本体。433 MB 的目录被永久删除,用户没有任何恢复窗口。
5. 我不能证明的部分(请勿据此下结论)
- 我无法指出触发的那一步操作。 Codex++ 的日志从 14:59:33 才开始——而 14:39:48 那次删除所在的目录连同日志一起被删掉了,崩溃/报错信息不存在。
- 因此无法提供稳定复现步骤。
- 已排除的其它嫌疑(供你们参考):操作系统未升级(无
Windows.old、无$WINDOWS.~BT);PowerShell 历史 2207 行全文搜索,用户没有任何针对.codex的删除命令;Codex 桌面版 MSIX 更新发生在当天凌晨 01:02,与 14:39 无关。
共同的必要条件:Codex++ 以 patch 模式注入 Codex 进程,以用户身份运行,拥有 .codex 的完整读写删权限。
6. 建议的加固(希望项目考虑)
- 任何删除路径都先备份再删:
DeleteResult已有backup_path/undo_token字段,请确保它们真的落盘,并且备份独立于.codex(放在.codex-session-delete\backups\<timestamp>\之类不会被一起清掉的位置)。 - 删除走回收站而不是永久删除(Windows 上可用
SHFileOperation/IFileOperation带FOF_ALLOWUNDO),给用户一个后悔窗口。 - 限制"删除会话"的作用范围:只允许删除单个 rollout 文件与对应 DB 行,任何情况下不得对
.codex目录本身、sessions\父目录、skills\、config.toml做递归删除。建议在代码层面把.codex根目录加入"禁止递归删除"白名单。 - 对
.codex的写入操作(provider-sync、model suffix sanitize、patch 注入)增加审计日志,至少记录:操作名、受影响路径、文件数量、结果。目前codex-plus.log里没有"删除/迁移/重置"这类破坏性动作的记录,出事后完全无法追溯。 - 危险开关默认关闭:
codexAppSessionDelete涉及不可逆操作,建议默认false,并在开启时明确提示"此功能会修改/删除本地会话文件"。
7. 给其他用户的临时建议
在项目确认并修复之前,如果你同时使用 Codex++ 和官方 Codex:
- 关掉
codexAppSessionDelete(如果不需要该功能) - 给
%USERPROFILE%\.codex做定时备份(它不大,压缩后一般几百 MB 以内)——这次如果有备份,1 秒就能恢复,不必做一整晚的磁盘取证 - 考虑先切回非
patch启动模式,减少它对 Codex 本地数据的干预面
补充材料:如需取证脚本(原始扇区扫描、按 JSONL 签名抢救会话内容),我可以在评论里提供。抢救结果:从已删除扇区中恢复出 927 个 JSON 对象、468 条可读消息,覆盖 36 天的对话片段。
预期行为
Codex++ 应当同步当前供应商配置并启动 Codex,不修改、不删除用户的 %USERPROFILE%.codex 目录内容。
具体而言,在启用 codexAppSessionDelete(会话删除)与 launchMode: "patch" 的情况下, "删除会话" 这一操作的作用范围应仅限被选中的单个会话:
- 期望删除的只是目标 rollout 文件(sessions\YYYY\MM\DD\rollout-*.jsonl) 及数据库中对应该会话的行(sessions / messages / threads)
- 期望 .codex 根目录、sessions\ 父目录、skills\、config.toml、以及其它会话的文件 不被递归删除(无连带影响)
- 期望删除动作可回滚:后端 DeleteResult 已声明 backup_path 与 undo_token 字段, 期望这两个字段对应备份真实落盘,且备份位置不受该次删除影响
- 期望删除走回收站(可撤销),而非永久删除
实际行为:整个 .codex 目录(176 个文件 / 约 430 MB,含会话历史、全部配置与 22 个自定义技能) 被永久删除,未进回收站,未留下任何 backup_path 所指的备份。
复现步骤
【重要说明:本问题无法稳定复现,以下记录的是事发当天的实际操作序列, 供维护者判断哪一步可能触发;不是一份"照做必现"的复现步骤。 原因见末尾。】
环境中同时存在:Codex++ 1.2.56(launchMode: "patch", codexAppSessionDelete: true)、Codex 桌面版 MSIX 26.903.8094.0、 Codex CLI 0.153.4。%USERPROFILE%.codex 已使用数月, 含 184 个 rollout 会话文件(约 450 MB)、多个 sqlite、22 个自定义技能。
事发当天凌晨,Codex 桌面版通过 MSIX 自动更新到 26.903.8094.0。
当天白天(事发前约 36 分钟),安装/重装了一个无关程序, 该程序的安装过程删除了它自己的 AppData 目录(约 38 MB)——此事与 .codex 无关, 仅说明当时系统有安装类活动。
约 14:39,.codex 目录被永久删除(433 MB / 176 个文件全部消失, 未进入回收站)。
约 14:59,Codex 桌面版在空位置重新初始化了一个新的 .codex。
约 14:59:33,Codex++ 管理器进程启动,创建 ~/.codex-session-delete/ 并写入 codex-plus.log。
约 15:07,Codex++ 完成自更新到 v1.2.56。
观察到:会话全部消失;.codex 内 state_5.sqlite、thread_history_1.sqlite、 logs_2.sqlite、sqlite\codex-dev.db、config.toml 均丢失或不可用。
【为什么无法提供可靠的复现步骤】 删除发生在 Codex++ 的日志文件本身被一并删除的时刻: 现存 codex-plus.log 的首条记录晚于删除时刻约 20 分钟, 因此没有崩溃信息、没有操作记录、没有错误码可供定位。 我也未能在任何位置找到 backup_path / undo_token 对应的备份。
【已排除的可能性,供维护者缩小范围】
- 操作系统未做升级(无 C:\Windows.old、无 C:$WINDOWS.~BT)
- 用户在终端历史(2200+ 行)中没有任何针对 .codex 的删除命令
- Codex 桌面版 MSIX 更新发生在当天凌晨,与删除时刻相隔十余小时
【希望维护者协助确认的方向】 codexAppSessionDelete 的删除分支、provider-sync 流程、 以及 patch 模式下对 .codex 的写入路径,是否存在"作用范围超出预期"的可能。
日志 / 配置片段
Codex++ 版本
1.2.56
系统
Windows
提交前确认
- 我已经脱敏了 API Key、Token、账号等敏感信息。
- 我已经确认这是当前最新版仍然存在的问题。
Source: BigPizzaV3/CodexPlusPlus