Repository navigation
[Bug] workspace.json 的 sessionIds 被静默截断,重启后历史会话从侧边栏消失 #10513
问题描述DeepSeek Harness 桌面端重启后,侧边栏中所有历史会话消失,仅显示当前会话。磁盘上的会话数据文件完好无损,但 环境信息
复现步骤
根因分析
// 预期状态(正常)
"sessionIds": [
"session-666417ac-...",
"session-7f8586dd-...",
"session-a0eac71f-...",
"session-743bd856-...",
"session-011ec8c0-..."
]
// 实际状态(异常)
"sessionIds": [
"session-666417ac-..." // 仅剩最新会话
] |
Replies: 1 comment
|
磁盘上 5 个会话目录都在、只有
我们在另一个 agent 记忆存储里踩过完全同类的问题(单次写入不报错,但条目被一点点或一次性"写丢"),最后落地的是两层: ① 写入侧:净减少守卫 + 原子替换 // 写回前对比:只增不减是正常路径;净减少 ≥2 条必须显式声明意图
const before = new Set(onDisk.sessionIds);
const after = new Set(next.sessionIds);
const dropped = [...before].filter(id => !after.has(id));
if (dropped.length >= 2 && !opts.allowDrastic) {
log.warn('ESUSPECT_EROSION', { dropped }); // 完整 delta 记日志
return; // 拒绝写入,而不是覆盖
}
// 写 tmp → fsync → rename,避免半写文件成为下次启动的"空读"来源关键点:守卫要拿写入瞬间磁盘上的版本做对比,而不是进程内存里那份(内存那份可能正是从空读得来的)。 ② 读取侧:索引只当缓存,以磁盘目录为准做对账 一个可以帮定位的信息:如果能在截断发生的那次启动日志里看到 Same index-erosion failure mode hit our own agent memory store; the net-loss guard above is what we run in production — SwarmAI. Discussion: Memory is the Moat |
磁盘上 5 个会话目录都在、只有
sessionIds从 5 条变成 1 条 —— 这个形状基本可以排除"数据损坏",更像是索引文件的 read-modify-write 被一次"空读"覆盖:workspace.json失败或读到空/半写状态(Windows 上常见原因:上次退出时写到一半被杀、杀毒软件/索引服务短暂锁文件、或非 ASCII 路径在某条代码路径上解析失败后走了 fallback 默认值)[]起步push(currentId)然后整份写回 → 历史 4 条被静默抹掉我们在另一个 agent 记忆存储里踩过完全同类的问题(单次写入不报错,但条目被一点点或一次性"写丢"),最后落地的是两层:
① 写入侧:净减少守卫 + 原子替换