# seek PRD v4：闭环工效（umbrella）

> 目标版本：seek v0.5.x
> 依赖基础：v0–v3 全部子系统（permission、tool、session JSONL、hooks Registry、checkpoint、keymap）
> 前置阅读：[PRD v3 umbrella](v3.md) §2（跨柱设计约束——v4 继承）、[`docs/comparison.md`](../comparison.md)

**本文是 umbrella 文档**——v4 用以承接 v3 完成后浮现出的新工效空白。第一个落地柱（D）是 [`feature-suggested-reply.md`](feature-suggested-reply.md)；后续柱待 dogfood 数据沉淀后再划。

| 柱 | 主题 | Feature PRD | 子里程碑 |
|---|---|---|---|
| **D** | 闭环工效（next-turn 预测 + mispredict 自校准） | [`feature-suggested-reply.md`](feature-suggested-reply.md) | M10.0 |
| E | （待规划） | — | — |
| F | （待规划） | — | — |

---

## 1. 动机

v0–v3 让 seek 在"能干什么"上对齐主流，且在「可逆 / 可扩展 / 可定制」三柱补齐了一线工效。但 dogfood 期间反复出现一个**新空白**：

- 模型回完话后，用户的下一步**经常是高度可预测的**——模型给了 A/B/C 三选项推荐 A，用户大概率回 "用 A"；模型说"建议跑测试"，用户大概率回 "yes" 或 "跑"。**这部分意图表达没必要让用户每次完整敲一遍**。
- 同时，模型对自己"猜下一步"的准确度是一个**未利用的自校准信号**——猜错说明模型对用户当前的关注点理解偏差，下一轮应当显式重新对齐。

v4 柱 D 用同一套机制同时拿下两个收益：

1. **工效**：高频意图一键 Tab 接受，减少键盘磨损
2. **自校准**：mispredict 触发反向注入，让模型在下一轮**主动**修正对用户的理解

这两件事单独看都不够格做独立 feature，但**绑在一起做才是真正的闭环**——这是把 v4 命名为"闭环工效"而非"工效优化"的原因。

## 2. 跨柱设计约束（继承 v3，新增三条 v4 特有）

v3.md §2 的全部约束在 v4 继续生效（**prefix-cache 字节确定性**、**复用 Registry**、**信任前置**、**`pkg/` 层零变更**、**失败降级而非阻断**）。v4 不引入新例外。

v4 特有的新约束：

### 2.1 旁路调用不污染主 transcript

v4 柱 D 引入第一个"旁路 LLM 调用"（next-turn 预测，走 Flash 模型）。该调用的请求、响应都**绝不**写入 session JSONL 的 `messages[]`。session 是单一真相，旁路结果只作为 UI hint 或 calibration 的瞬时输入存在。后续若再加旁路调用（如 v5 设想的 embedding-based semantic match），同样适用。

理由：transcript 是 prefix-cache key 的来源，也是 `--resume` 的重放素材。旁路调用的可变性若进 transcript，会同时污染两者。

### 2.2 闭环数据存最小集

`predicted_next` 字段（feature-suggested-reply §4.5）存原始预测文本，但 **match 判定不持久化**——每次构造 ChatRequest 时即时计算。原因：match 算法（normalizedMatch / embedding / LLM-judge）会随版本演进，持久化 match 字段会让历史 session 在新算法下行为不一致。单一真相是 `predicted_next` + 当前用户消息。

这条约束推到一般原则：**派生数据不存，原始信号存**。后续柱若有类似的"实时计算 vs 持久化"权衡，默认走"实时计算"。

### 2.3 单一开关贯穿全链路

v3 柱 C 的 keybindings 引入了细粒度的 action → key 配置（合理，因为粒度本来就细）；v4 柱 D 走另一个方向——**一个 `suggest_reply: bool` 开关同时控制预测 / UI / 注入**。理由：闭环的三个环节互相依赖，给用户拆开三个开关只会让"我开了 UI 关了注入，为啥还在调 API"这种困惑出现。

新加柱时若也是"闭环型"，应遵循单一开关原则；若是"独立工效叠加型"（如 v3 柱 C），才考虑多开关。

## 3. 跨柱集成视图（v4 增量）

### 3.1 Prefix cache 影响审计

| 新机制 | 来源 | 是否进主 transcript | 是否影响主流 cache |
|---|---|---|---|
| Next-turn 预测调用 | 柱 D | 否（走旁路 Flash 模型，独立 cache 曲线） | 否 |
| `predicted_next` 字段持久化 | 柱 D | 是（assistant message 新增可选字段） | 是——但**session 解析层在送 API 前剥离**，发到 LLM 的 messages[] 不含 |
| Calibration system note 注入 | 柱 D | 否（瞬时构造，不持久化） | 仅 mismatch 那一回合的最末两条 message 重算（≤ 320 token）；其他 token 仍可缓存 |
| Tab 接受建议填入输入框 | 柱 D | 用户按 Enter 后才进 transcript，与正常输入等同 | 同正常输入 |

**净结论**：v4 柱 D 对主流 cache 的扰动**仅出现在 mismatch 那一回合**（calibration 注入触发），且 ≤ 320 token 重算量；非 mismatch 回合零扰动。

### 3.2 共享配置目录

v4 不新增配置文件——`suggest_reply` 字段挂在已有的 `~/.seek/config.json`（v0 已有），`--no-suggest` 是 CLI flag。session schema 升到 v3，沿用现有 `~/.seek/sessions/<sid>.jsonl` 文件路径。

## 4. 总体实现计划

| 子 ms | 内容 | 估时 | 所属 feature | 发版 | 状态 |
|---|---|---|---|---|---|
| **M10.0** | 柱 D 完整闭环：预测尾调用 + Tab 接受 + UI + calibration 注入 + 单开关 | ~3 天 | feature-suggested-reply | v0.5.0 | 🚀 已交付 |

更多柱待 dogfood v0.5.0 的 prediction match rate 数据后再划。

## 5. 与 v3 的关系

- v3 收尾后**才**进 v4——v3 三柱（checkpoint / shell hooks / TUI ergonomics）是 v4 的基础设施依赖（柱 D 的 Tab 接受逻辑要在 M9.5 的 commandMenu Tab 分支**之后**判定 input 空 + 有 suggestion，才让出 Tab 给 suggestion accept）
- v4 不重构 v3——所有 v3 机制原样保留；柱 D 是叠加层

## 6. 后续柱候选（仅 brainstorm，不承诺）

下面是 v3 完结时浮现但还没上 v4 的候选，等 dogfood 数据来决定哪个最痛：

- **跨 session 用户偏好提取**——把 `predicted_next_match` 长时数据反哺到 soul.md / index.md，让冷启动 session 也有上下文
- **MCP 客户端嵌入**——feature-mcp-client.md 已存在的设计稿，等 v3 收尾才有人力推进
- **TUI 多面板**——长任务时把 agent 进度跟用户输入分开（独立浮层），不挤同一个屏幕
- **Token budget 实时 surface**——告诉用户当前 turn 接近 prefix cache 失效点，可主动 `/compact`
- **WebFetch v2 with `--llm-summary`**——网页抓取后让 LLM 摘要再喂给 agent，省主 transcript token

这些是 backlog 不是 commitment。先把柱 D ship 出去，看用户反馈。
