Skip to content
FunCoding

Search

Search docs, Skills and MCP

Daemon worktree 恢复与所有权转移

理解 marker 证明、superseded 会话和 task reset 的失败边界。

This page has not been translated into English yet. The original Chinese version is shown below.

恢复带 worktree 的持久 session,不只是重新把 cwd 指到旧目录。daemon 需要同时验证 workspace、checkout、sidecar 和 marker 的归属,防止把已转移的 checkout 再交给旧会话。

持久 worktree 的证明

当前 Part 4A sidecar 明确标识请求的 workspace root。checkout 必须 canonical contained 于对应 .qwen/worktrees/ 之下;marker 必须是单链接 regular file,内容精确等于恢复的 session ID。

验证后可把 idle child 移到该 checkout;active child 只有报告 cwd 已经等于目标时才可接受,缺失或不同 cwd 时不能在 active prompt 下强行移动。

成功确认的响应带 canonical worktree metadata 与 worktreeState:"persisted-v1"。旧的特殊冷恢复路径若不能延后 restore question,可能保留 session并返回 worktree metadata,但没有 worktreeState、也未完成 relocation;不能把有 worktree 字段等同于已证明当前执行位置。

Legacy 与 Channel-owned 状态

不带 workspaceCwd 的结构化 legacy sidecar 保留尽力恢复兼容路径,需标识请求 workspace 或 Git 顶层并通过 containment 检查,但没有新 marker attestation,也可能没有 worktreeState。

当前来源为 Channel-owned 时,Part 4A 或无法分类的 sidecar 会抑制 agent 的尽力 cleanup,保留未确定的 checkout 证据。持久来源元数据优先,缺失时才用 load/resume 请求中的有效来源。

需要采取不同动作的错误

错误解释与恢复方向
worktree_session_superseded旧 sidecar 已指向 replacement;先成功 load replacement,再更新客户端引用
worktree_reset_interrupted双向关系一致但 marker 尚未转移或缺失;针对被替代的旧 session 重试 reset
worktree_marker_missing缺 marker 且不满足上项关系;需要 reset task,反复 restore 不会重建 marker

superseded 的判断先看关系链接,再读 marker。提前中断的转移可能指向尚无 marker 所有权、无法恢复的 replacement,因此不能见到 replacement ID 就直接宣布迁移成功。

Worktree reset 的事务顺序

session_worktree_reset_v1 支持 POST /session/:id/worktree-reset,用于 Channel task reset:先在根 workspace 建立新的 thread session,移入已验证 checkout,再按旧 sidecar 的 supersededBy、新 sidecar 的 supersedes、marker 的顺序转移归属。

转移期间使用 checkout lock 和 admission barrier,封锁 prompt,以及 rewind、cwd change、branch、fork、shell、goal control、workflow-task action 等开始工作或移动 cwd 的路径。cancel、detach、kill 等停止与释放路径保留可用。

遇到 worktree_reset_active 表示该 writer 被转移门禁拒绝,不是普通可立即重放的模型错误。各崩溃窗口的完整修复契约仍应按官方协议逐项判断。

Replacement 成功不等于旧 child 已消失

最后一步断开旧 session 的客户端登记与内存 worktree 关联;如果旧 child 仍持有后台工作,响应会带 supersededSessionLive:true,并保留 admission barrier 和日志记录。

客户端应据此保留未完成清理状态,不把 HTTP 200 当作旧执行者彻底退出。也不能自行删除 checkout 或 marker 来“修好”不一致;先遵循明确的 reset/restore 错误分类。