Skip to content

[Grok/dsh 62] 会话副本迁移与回退 #194

Description

@Blackman99

Parent

#132

Ticket: 62

Status: ready-for-agent

User Stories: 6, 62, 66(见父规格)

What to build

旧版用户选取会话迁移为新环境中的副本,检查完整性并继续工作,同时仍能回到原版原会话。

Acceptance criteria

  • 保留可支持消息、工具、附件和来源关系;不支持的事件或内容清晰报告,不假装完整导入。
  • 复制而非原地改写;旧进程/新进程不写同一会话,重复导入有明确身份与冲突处理。
  • 中途失败、缺附件、损坏日志或不支持版本不影响原始数据,回退不要求旧程序理解新格式。
  • 用隔离样本比较导入前后并实际恢复继续,验证旧版仍可读其原记录。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    已集成到 rewrite/grok-dsh-20260920:

    • 3f072be (单独的清理提交:删除误提交的 scripts/__pycache__/*.pyc,.gitignore 增加 __pycache__/)
    • 287ee62 (本任务)

    实现:新增 codsh --rust import sessions [ID]... [--all] [--preview|--apply] [--again] [--allow-partial] [--json](rust/src/session_migrate.rs + packages/cli/bin/rust-session-migrate.mjs)。

    • 无参数时列出旧会话及副本会保留/丢失的内容;指定 ID 或 --all 默认只预览,--apply 才写入。
    • 旧 dsh Home 只用固定版本 dsh 持久层 open(id, 'read') 读取,不写入、不加锁、不迁移;每个副本在 ~/.codsh-rust/dsh 中使用新会话 id,新旧程序不会写同一个会话,也没有双写同步。
    • 保留消息、工具调用与结果、标题、图片/文件附件(按内容地址复制并校验 sha256)、子代理会话(子会话 id 与父引用一起改写);旧 agent preset 去掉并注明。
    • 不支持的内容会明确报告:本版本不读的可跳过事件、不显示的内容块、未完成回合、缺失附件或子代理日志(缺失数据默认阻止 --apply,--allow-partial 才复制其余部分);损坏日志、更高版本格式、未知必需事件、dsh 无法恢复的日志一律拒绝,不做复制。
    • 每个副本写完后重读并比对摘要才算完成;中途失败会删除本次创建的会话、附件和记录;进程崩溃留下的 pending 记录在下次 --apply 时清理;同一 Home 同时只允许一个导入进程。
    • 来源记录 session-migrations/<副本 id>.json(旧 Home、会话 id、日志路径、字节摘要、报告),/session-info 显示 "Imported from: legacy dsh session …"。再次导入未变化的会话报告已有副本;旧会话之后有变化报告冲突,--again 才生成新副本,旧副本保留。
    • 回退:旧程序的数据从未改动,直接用旧 codsh 即可,不需要理解新格式。

    实际运行的检查(Linux,仅 mock 模型,隔离临时 Home):

    • scripts/rust-session-migrate.spec.mjs:6/6 通过(附件+子代理复制与来源记录、重复导入/冲突/--again、缺失附件拒绝与 --allow-partial、可跳过事件报告、未知必需事件/损坏帧/v9 格式/不存在的会话被拒、两个故障注入点清理、残留 pending 记录清理、用法错误退出码;每项都校验旧 Home 字节与 mtime 不变)。
    • scripts/rust-session-migrate-pty-test.py:PASS。真实旧客户端(dsh --profile code + mock)创建写文件会话和带 2 个子代理的会话,另加一个带真实附件存储图片/文件的会话;list/preview 不写入;--all --apply 全部复制,旧 Home 不变;副本无界面恢复并继续一轮(含附件会话);子代理副本在 PTY TUI 中恢复、继续一轮,/session-info 显示来源;旧客户端 --resume 原会话仍可继续;之后再导入报告冲突,--again 生成含新回合的第二个副本,第一个副本不变。
    • pnpm run typecheck 通过;pnpm test:2566 通过、15 跳过、1 失败(rust-plan.spec.mjs 满载下等待超时,单独重跑 13/13 通过)。
    • cargo test --locked -p codsh-rust:664 通过,4 个已知失败(filesystem_sandbox×2、privacy、voice,与基线相同);cargo test --locked --workspace --exclude codsh-rust:1043 通过;cargo fmt --check 通过;clippy 0 警告。
    • scripts/rust-plain-json-test.py、scripts/rust-usage-pty-test.py 通过。

    未验证:macOS / Windows;真实付费提供商(只用 mock);v3 之前的旧日志格式(只会经 dsh 自带的内存迁移读取,没有真实 v2 样本);真实长期使用的用户 Home;附件副本在 TUI 中的渲染(只验证了无界面恢复与继续)。

    main、npm 发布、默认版本均未改动。

    后续:#211(完整对齐审计)少了一个前提,但仍有其他未完成的前提,暂未解除阻塞。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions