Handoff Resume
概述
加载先前由 handoff-save 写入 <worktree-root>/.handoff/ 的 handoff 文件,让新会话进入之前的上下文——在取得方向授权之前不得执行任何修改操作。方向授权有且只有两个来源:用户当场批准,或「持久授权」双源核验通过(见确认门规则)。
文件选择
根据是否带参数决定行为。
不带参数
- 找到当前 worktree 根:
git rev-parse --show-toplevel(没用git worktree的话就是仓库根目录,无需额外配置);不在 git 仓库时回退到当前工作目录 - 找到当前 branch:
git branch --show-current - 列出
.handoff/<branch-slug>--*.md(按当前 branch 过滤) - 按文件名中的时间戳倒序排列
- 根据匹配数量分支:
- 0 个 → 告知用户找不到,停止。提示用户可改用
/handoff-resume <关键词>或/handoff-resume <绝对路径>扩大范围 - 1 个 → 向用户显示文件名,询问
是这个吗?,等待回复。不要自动加载。 - 多个 → 展示前 5 条
主题 — 时间戳 — 大小,请用户选择
- 0 个 → 告知用户找不到,停止。提示用户可改用
展示文件路径时:必须使用 Markdown 链接格式 [<文件名>](<绝对路径>),让 Claude Code UI 渲染成可点击链接。链接文本用文件名(不含目录),URL 用完整绝对路径。同样适用于"是这个吗?"的文件展示和多文件列表。
带参数
- 参数是绝对路径 → 直接加载,不要再问"是这个吗?"。用户传了路径就是答复了"选哪个"
- 参数是
.handoff/内的文件名(或相对路径如.handoff/xxx.md)→ 直接加载,同上 - 参数是关键词 → 在当前 worktree 的
.handoff/*.md全集(不限 branch)中模糊匹配:- 恰好 1 个文件匹配 → 直接加载
- 多个匹配 → 列出匹配项请用户选择
- 0 个匹配 → 告知用户并停止
关键:本 skill 有两道独立的门——文件选择门(确认要加载哪个文件)和确认门规则(读完文件后 3-5 句复述 + 选项列表 + 等待方向)。带参数场景下文件选择已被参数回答,跳过文件选择门,但仍走确认门规则。两道门仅在"无参数 + 单匹配"流程里合并显示。
跨 worktree:不要主动搜索其他 worktree。如果用户需要从别的 worktree 恢复,必须自己传绝对路径。
确认门规则(核心纪律)
这是本 skill 最重要的部分。取得方向授权之前,禁止执行任何修改动作。 方向授权有且只有两个来源:用户当场批准(下面第 1-4 步的默认路径),或持久授权双源核验通过(见下小节)。
确定要加载的文件后(用户确认 / 显式参数 / 唯一匹配 都算确定),读取文件,然后在调用任何 Edit / Write / NotebookEdit / 写入型 Bash 命令之前:
- 用 3-5 句话向用户复述你的理解,覆盖:
- 当时在做什么(任务目标)
- 工作中断在哪里(handoff 第 6 节)
- 最关键的决策或约束
- 把 handoff 第 7 节"候选下一步"原样列出。如果你认为有新的选项值得提出,加在后面并明确标注
新增选项 - 明确询问:
请问要按哪个方向继续,还是有其他想法? - 等待用户回复。不得继续执行。
取得方向授权之后:
- 确认门已关闭,回归正常的 Agent 行为
- 不要在后续每次写操作前额外加确认。本规则只在恢复入口生效一次,不是会话级的常态约束
持久授权(双源核验)
handoff 第 9 节的「持久授权」字段记载了进行中流程的落盘授权凭证时,对该流程核验以下两源,同时成立即视为方向授权已取得:
- 声明源:handoff 记载了凭证(文件路径 + 授权字段 + 期望值 + 身份字段 + 重入方式 + 授权范围)
- 磁盘源:你此刻实际读取该凭证文件,授权字段与身份字段全部与记载相符
实例绑定(核验的一部分,不是可选项):身份字段是凭证文件里标识流程实例的字段(如 pr、worktree、flow id),作用是把凭证钉死在「流程」与「重入方式」指向的同一个实例上。记载缺身份字段,或「流程 / 凭证身份 / 重入目标」三者有任何一处对不上——都按核验不过处理。授权字段值相符但身份是别的实例(别的 PR、别的 worktree)=借用他流程的凭证,不放行。
范围即免问上限(核验的一部分,不是注释):「授权范围」记载这份授权免问的动作边界,缺失即声明源不完整、核验不过。它只会比凭证契约更窄、不会更宽——记载收窄了的(如「到合并闸为止,合并另行确认」),凭证契约授得再全也以记载为准。
两源缺一不可:handoff 没记载或记载不全(缺身份字段 / 缺授权范围)→ 你不得自己翻出某个 state 文件宣称有授权、也不得拿凭证契约补齐缺项;盘上不符(值已变 / 身份不符 / 文件不存在)→ 记载写得再明白也不放行。
核验通过后:照常完成第 1、2 步的复述,然后把第 3、4 步替换为一行告知——检测到 <流程> 的持久授权(<凭证路径> 值与身份均与记载相符),按记载的重入方式在授权范围内续跑——随即按记载的重入方式把控制权交还该流程自己的 skill(其安全闸与模式判定照常生效)。续跑的免问边界就是记载的「授权范围」:范围内的动作直接做;走到范围外的第一个动作即失去方向授权,停下按原确认门问。handoff 里的其他开放问题、新方向,照常等用户。
核验不过:按无授权处理,走第 3、4 步,并在复述里如实标注核验结果。
Red Flags —— 立即停止
读完 handoff 文件、方向授权尚未取得之前,如果出现以下任一情况,说明你已经违反本 skill:
- 调用了
Edit/Write/NotebookEdit或写入型Bash命令 - 看到 handoff 提到的问题就"开始动手修"
- 觉得"选项 A 很明显"就直接照做
- 说"我先按 X 进行"却没等用户回复
- 觉得"handoff 写得很清楚"而跳过了复述步骤
- handoff 没有「持久授权」记载,却拿自己翻到的 state 文件或会话记忆当授权续跑
- 「持久授权」有记载,但没实际读盘核验就续跑
- 凭证的授权字段值对上了就放行,没核对身份字段、或没核对「流程 / 凭证身份 / 重入目标」是否同一实例
- 核验通过就当全流程放行——把记载「授权范围」之外的动作(如写明另行确认的合并、清理)也无人值守做掉
反向同样违规:双源核验通过了还停下问方向——确认门拦的是「没有授权」,不是授权本身;把用户落盘的明确授权当空气,等于废掉它承诺的无人值守。
任何一条命中:停下,回到确认门规则的对应步骤重新走。
常见错误
| 错误 | 修正 |
|---|---|
| 不带参数、只匹配到 1 个文件就自动加载 | 即使只有 1 个,也要先把文件名给用户看并询问 |
| 用户已显式传路径还做二次"是这个吗"确认 | 显式参数就是答复"选哪个",直接加载并进入确认门 |
| 跳过 3-5 句的复述 | 复述是用户在你动手前发现误解的最后一道防线 |
| 把第 7 节当成执行队列 | 那是讨论用的选项清单,不是 to-do |
| 后续每次写操作都加确认 | 确认门只在恢复入口生效,之后按用户平时的设置走 |
| 没问就跨 worktree 搜 | 当前 worktree 内搜索,跨 worktree 必须用户传路径 |
| 「持久授权」只信 handoff 记载、不读盘 | 双源核验的第二源是磁盘:必须实际读凭证文件比对 |
| 凭证值相符就放行,不管它是谁的 state | 身份字段 + 实例一致性是核验的一部分:借来的凭证(别的 PR / 别的 worktree)值再对也不放行 |
| 核验通过 = 全流程放行 | 免问上限是记载的「授权范围」:范围外走到即停、回确认门问;范围缺失则整份记载核验不过 |
| 双源核验通过仍停下等用户 | 一行告知代替提问,随即续跑该流程 |
边界情况
.handoff/不存在 → 告知用户,停止。不要创建(创建是 save skill 的职责)- handoff 文件陈旧(如时间戳超过 7 天、branch 已大幅推进)→ 仍然加载,但在复述里明确指出陈旧度,让用户决定是否跳过部分章节
- handoff 引用的文件已不存在 → 在复述里标记,不要默默忽略
- 「持久授权」凭证核验不过(文件不存在 / 值不符 / 身份不符 / 记载缺身份字段或授权范围)→ 按无授权走原确认门,复述里如实标注核验结果
- 不在 git 仓库 → 仍可工作;把当前工作目录视为 worktree 根,跳过 branch 过滤,列出
.handoff/内全部文件