会话归档、删除与持久化证明
处理活动与归档冲突、严格 flush 和不能自动修复的所有权异常。
This page has not been translated into English yet. The original Chinese version is shown below.
live session、活动 JSONL、归档 JSONL 和历史附件属于不同层。归档与删除会先协调运行时,再改变存储;HTTP 成功也要读取批量返回中的逐项结果。
归档与恢复到活动目录
POST /sessions/archive 将可归档 JSONL 从 chats/ 移入 chats/archive/。目标仍 live 时,先进入 session archive gate,严格关闭并要求 ACP child flush ChatRecordingService;关闭或 flush 失败时保留原 JSONL。
POST /sessions/unarchive 只是移回活动存储,之后仍需 load 或 resume 才成为 live session。直接 load/resume 归档会话返回 session_archived;与正在归档竞态的 mutation 可返回 session_archiving。
Active/archive 冲突
若两处同时存在同 ID,默认不移动、不删除、不覆盖任一持久副本,错误写在 batch errors 中。archive 在判断冲突前仍可能已严格关闭 live session并 flush 新记录,所以“冲突返回”不意味着运行时完全未变。
只有 session_storage_conflict_repair capability 存在时,才可显式传 resolveConflicts:true:archive 保留归档副本,unarchive 保留活动副本。工作区限定路由也使用 HTTP 200 batch envelope,不能继续只按旧的 409 session_conflict 判断。
硬删除
POST /sessions/delete 接受最多 100 个 sessionIds,以逐项结算返回 removed、notFound、errors。活动和归档 JSONL 同时存在时,硬删除移除两者。
该流程清理活动与归档 worktree sidecar,但保留 file-history snapshots、subagent transcripts 和部分 runtime sidecars;不能宣称它清除所有与会话有关的文件。附件与 checkout 的具体处理还应看对应接口,不从“delete”名称推断全盘递归清理。
损坏文件仍可能可处理
空、损坏或孤立的 regular transcript 不一定能 load,但仍可符合归档或删除条件。另一方面,所有权证明不足必须拒绝,而不是把“打不开会话”当作可以无条件删除。
| 情况 | 处理边界 |
|---|---|
| writer 已封存 handoff proof 后文件字节改变 | SessionTranscriptChangedError,需核对 sealed lock 与文件 |
| 第一条 JSON 形状物理记录超过有界身份读取窗口 | SessionTranscriptIdentityUnavailableError,需修复或缩小记录 |
| 能解析的恢复记录缺少字符串 sessionId/cwd | 无法证明归属,不继续自动处理 |
| active/archive 混合本地与外部所有权 | 保守拒绝,不自动选一份覆盖 |
超大但非对象前缀的损坏记录有不同兼容处理,不能只按文件尺寸判断所有权。维护操作应遵循会话恢复的证明流程。
Replay 与落盘不等价
load 返回的 compactedReplay/liveJournal 是内存窗口;history_truncated 表示较早内容不在该窗口,并通过 fullTranscriptAvailable 指明是否可分页读取磁盘历史。
运行完成、收到 terminal、可在 UI 中重放,都不单独证明最终 JSONL 已 flush。归档使用严格 close 正是为保留这一区别。