# R2 | 会话衔接协议（Session Handoff Protocol，预计 0.5-1 天）

- 前置：R1 完成（特别是 R1.5 安装链路，否则新增的 CONVENTIONS 引用又会装后空指）。
- 需求来源（真实事故）：2026-06-11 用户在 Fable 审计对话中上下文耗尽，对话彻底无法继续，靠人肉重述才接上。Light 现有的是**被动断点恢复**（orchestrator §0 六探针，事后救火）；缺的是**主动交接**——上下文将尽或任务完成时，主动给用户一段"新对话启动提示词"，让下一个对话零成本无缝接上，且能衔接到任意上级对话。
- 本轮产出：CONVENTIONS 新节 + a02 新正文节 + orchestrator §5 升级 + 衔接卡模板 + 启动提示词模板 + 路由触发词 + README FAQ + 演练记录。

## R2.1 设计总览（先读懂再动手）

**两件套产出**：触发时，agent 必须同时交付——
1. **衔接卡（handoff card）落盘**：自包含的状态快照文件，给下一个 agent 读；
2. **启动提示词打印**：直接打印在聊天里的一段中文提示词，用户复制→新开对话→粘贴即续。

**四类触发条件**（宁早勿晚，阶段边界默认触发）：
| 触发 | 判据（行为性信号，agent 无法精确读 token 量） |
|---|---|
| T1 上下文水位 | 对话已很长/已读大量文件/感知到压缩摘要出现/用户说"快不行了" |
| T2 任务完成 | 本段任务收尾时，主动给"下一步"的启动提示词（哪怕用户没要） |
| T3 阶段切换 | orchestrator 检查点通过、进入新阶段前 |
| T4 用户索要 | "给我衔接提示词 / 开新对话继续" |

**与既有机制的关系**（写进文档，避免概念打架）：
- 主动交接（本协议）= 事前留种，恢复成本趋零；
- 被动恢复（orchestrator §0 六探针）= 没有衔接卡时的兜底，保留不动；
- 衔接卡 ≠ 当前事实：下一个 agent 仍须按 orchestrator §5 既有纪律刷新 git/passport 证据。

## R2.2 衔接卡规格（templates 落地）

- 落盘路径：项目内 `.light/handoff/S<NN>-<slug>.md`（与 passport.yaml 同级；`<NN>` 两位序号递增）；无项目目录的轻对话则只打印提示词不落盘（在协议文档里如实声明这一局限）。
- 新建 `skills/light-memory-pm/templates/handoff_card.md`，字段：

```markdown
---
session_no: S03                 # 本会话序号
suggested_title: "[goat] S04 图表绘制"   # 给下一个对话的建议名称
parent_session: S02             # 上级会话号（衔接链；可追到任意上级）
project: dairygoat-detect-track # db09 项目 slug；无项目写 none
date: 2026-06-12
---
## 当前阶段
<pipeline 阶段 / 当前 skill / 本段在做什么>
## 已完成（产物路径 + 验证摘要）
- <path> — <怎么验证的>
## 工作区状态
<clean / 未提交清单 / 已提交未推送 / 等 CI（run id）>
## 下一步（≤3 条，最小动作）
1. ...
## 阻塞/风险
<需用户决策 / 数据缺口 / 无>
## 必读文件（按序）
1. 本卡 → 2. .light/passport.yaml → 3. db09 项目卡 → 4. <本段关键产物>
## 禁止
- 别重做"已完成"清单里的事；别凭记忆补写未验证结论。
```

- **自包含原则**：每张卡必须独立可读——下一个 agent 只读最新一张卡就能续上，不需要翻任何历史对话；要衔接更上级的对话，沿 `parent_session` 链读对应旧卡即可。这就是"无缝衔接到上级任何一个对话"的实现方式。

## R2.3 启动提示词模板（templates 落地）

新建 `skills/light-memory-pm/templates/handoff_prompt.md`，agent 按此模板**填好具体值**后打印（不是把模板原样丢给用户）：

```text
【请把本对话命名为：[<项目短名>] S<NN+1> <下一段目标>】
你在 <仓库/项目根绝对路径> 工作，接续上一个会话（S<NN>）。
先按顺序读：
1. .light/handoff/S<NN>-<slug>.md（衔接卡，含已完成/下一步/禁止事项）
2. .light/passport.yaml 与 databases/db09-projects/projects/<slug>/project_card.md
读完先用 git status / git log -3 刷新现实，再开始执行衔接卡"下一步"第 1 条。
本段目标：<一句话>。完成判据：<可检验的标准>。
收尾要求：更新衔接卡（新建 S<NN+1> 卡）并打印下一段启动提示词——本协议自传播，不许断链。
```

要点（写进协议文档）：
- 第一行就是**对话命名建议**——客户端没有改名 API，只能请用户手动设置；编号让对话列表天然有序（用户原始诉求）。
- 末行"自传播"条款：每个接手会话收尾时必须再生成下一张卡+提示词，协议才不会用一次就断。

## R2.4 挂接点改造（六处，全部本轮完成）

1. **CONVENTIONS.md 新增 §9 会话衔接**（放 §8 之后）：约 8-10 行，写明四类触发、两件套产出、自包含原则、与断点恢复的关系；衔接卡/提示词模板指向 a02。这是全局纪律——**所有**技能的长任务都适用，不只 orchestrator。
2. **a02 memory-pm SKILL.md 新增正文节"会话衔接（主动交接）"**：协议执行者；含 2.2/2.3 模板指针、触发判据表、落盘规则。注意 a02 是常驻技能，正文从严控行数，细则下沉 `references/`（与 R7 瘦身方向一致，别先写胖再减）。
3. **orchestrator SKILL.md §5 升级**：现有"断点交接输出"已有摘要格式（SKILL.md:101-116），升级为：摘要落衔接卡（指向 a02 模板，删除自带格式避免口径分裂——R1 刚修过这类病）+ **必须同时打印启动提示词**；§3 检查点流程加一句"阶段切换默认触发 T3"。
4. **a06 project-structure**：scaffold 的目录模板与 .gitignore 模板纳入 `.light/`（passport + handoff/ 子目录；审计 E-5 提前到本轮，R7 不再重复做）。
5. **ROUTER.md + ROUTER_EXAMPLES.md**：增触发行"给我衔接提示词 / 开新对话继续 / 这个对话快满了 → a02 + light-orchestrator（主动交接）"；样例集加 2-3 个正例 + 1 个反例（"继续写这段话"仍走单技能，不触发交接）。注意与既有"继续/刚断了"（被动恢复）的边界在样例里写清。
6. **README FAQ**：加一条"对话太长上下文不够了怎么办？"——介绍本协议（这也是 R10 门面卖点之一，先把内容备好）。

## R2.5 验收

- [ ] 演练：在 `projects/` 示例项目（或 dairygoat）真实走一遍——A 会话造卡并打印提示词 → 新开 B 会话只凭提示词恢复 → B 比对状态无损并能继续"下一步"第 1 条；演练记录落 `_verification_log/`（含两段会话的关键输出摘要）。
- [ ] 衔接链演练：B 会话再造 S 卡，验证从 B 能沿 parent_session 读回 A 的卡。
- [ ] `grep -rn "handoff" skills/light-orchestrator/` 无两套格式并存（口径唯一）。
- [ ] ROUTER_EXAMPLES 新样例进入；check_skills/check_entry_docs/check_skill_links 全绿。
- [ ] 安装视角：新增模板随 a02 技能目录走，无仓库级引用断链。

## 提交切分建议

- `记忆管理技能:新增会话衔接协议与衔接卡、启动提示词模板`
- `编排器:阶段交接升级为衔接卡加启动提示词两件套`
- `通用规范与路由:登记会话衔接纪律与触发样例`
- `项目结构技能:scaffold纳入.light目录与忽略规则`

## 收尾

总纲 §5 八步；PROGRESS 更新；打印 R3 启动提示词。
