# seek PRD v3：可逆性、可扩展性、可定制性（umbrella）

> 目标版本：seek v0.4.x
> 依赖基础：v0（permission policy、tool 系统、hooks Registry）、v1（session JSONL、project_id）、v2（skill 包路径约定）
> 前置阅读：[PRD v0](v0.md) §4.7（Permission）、§4.8（Tool）；[`internal/hooks/hooks.go`](../../internal/hooks/hooks.go)（已有的 typed hook Registry）

**本文是 umbrella 文档**——只覆盖 v3 的总体动机、三柱划分、跨柱设计约束、总体实现计划。各柱的详细设计、数据模型、CLI/TUI 命令、验收标准在独立的 feature PRD 中维护：

| 柱 | 主题 | Feature PRD | 子里程碑 |
|---|---|---|---|
| **A** | 可恢复性（双层 checkpoint） | [`feature-checkpoint.md`](feature-checkpoint.md) | M9.0 + M9.1 |
| **B** | 可扩展性（用户可配置 shell hooks） | [`feature-shell-hooks.md`](feature-shell-hooks.md) | M9.2 + M9.3 |
| **C** | 可定制性（Tab 补全 + 自定义 keybindings） | [`feature-tui-ergonomics.md`](feature-tui-ergonomics.md) | M9.4 + M9.5 |

三个 feature **彼此完全独立**——可由不同开发者并行实施，各自有独立的发版节奏（v0.4.0 / v0.4.1 / v0.4.2）。

---

## 1. 动机

走完 v0–v2 之后，seek 在「能干什么」上对齐了 Claude Code 主流形态，但在三个**信任曲面**上仍有可见差距（参见 [`docs/comparison.md`](../comparison.md) P1 清单）：

- **可逆性（trust through recoverability）**——目前模型动手后，用户唯一的撤销手段是 git，且要先记得自己处于哪个干净基线。当 bash 工具执行 `rm -rf` 或 edit 工具改坏一个文件，没有一条命令能"把刚才那一步退掉"。这让 `--yolo` 模式心理成本很高，逐步降低了用户授权深度。
- **可扩展性（trust through escape hatch）**——seek 内部已有结构良好的 hooks Registry（`PrePromptHook` / `PreToolUseHook` / 五个 Observer），但它**只对 Go 代码开放**——v1 memory 子系统、v2 skill stats 都通过这个 Registry 接入，外部用户用不到。Claude Code 用户可以写一行 shell 命令在工具调用前/后跑 lint、记 audit log、阻拦 `kubectl delete` 之类的危险动作；seek 用户做不到，只能改源码重编译。
- **可定制性（trust through control）**——TUI 操作面板对所有人一样。重度用户（一天 3 小时以上 inline 交互）抱怨两件具体事：斜杠命令没 Tab 补全要全名手敲，常用快捷键（如 `/steer` 中断）记不住组合键又无法重绑。这两件事在「能不能干活」上是零分，在「干活舒不舒服」上是满分。

v3 把这三个曲面同时补齐——它们看似无关，但**共享同一个 design budget**（见 §2），所以打包到一个版本里更利于一致性把关。具体设计、命令、验收标准下沉到各自的 feature PRD。

## 2. 跨柱设计约束（每个 feature PRD 都要遵守）

这是 v3 最重要的部分——三个 feature 任意一个违反下列约束，都会引发跟现有 v0/v1/v2 子系统的不可见冲突。新功能 PRD 评审时**第一遍读**应该是检查这一节。

### 2.1 Prefix-cache 字节级确定性零妥协

DeepSeek 前缀缓存以**字节序列哈希**作为 key——命中率从 95.7%（实测）跌到个位数只需要一处"几乎相同但不完全相同"的字节扰动。v3 的三柱都不能在不知情用户面前修改 prompt 字节序列。

**具体派生规则**：

- **Shell hooks 的 stdout 永不进 prompt**（feature-shell-hooks §3.2 强制）——`pre_prompt` 事件接 `PreTurnObserver` 而非 `PrePromptHook`；`post_tool` 只是 observer。
- **Checkpoint 的 ref / blob / index 写入**全部在文件系统层，不进 prompt 历史（feature-checkpoint §5.1）。
- **Keybindings 改的是按键路由，不是用户输入文本**（feature-tui-ergonomics §6.1）——重绑 `submit = "ctrl+enter"` 不影响 prompt 字节。
- **唯一允许进 prompt 的副作用**：`pre_tool` shell hook 的 deny reason 作为 tool result 进历史——但这跟现有 `permission.ErrDenied` 流程一致，不引入**新**的 cache-volatility 来源。

### 2.2 复用 `internal/hooks` Registry，不开新拦截路径

`internal/hooks` 的 typed Registry（`PrePromptHook` + `PreToolUseHook` + 五个 Observer）已经被 v1 memory 子系统、v2 skill stats 使用——它是 seek 全局唯一的"agent 生命周期拦截点"。

**派生规则**：

- **Shell hooks 的实现** = 注册一个 `ShellRunner` 类型到 Registry，实现 `PreToolUseHook` + 五个 Observer 接口（feature-shell-hooks §5）。不在 `pkg/agent` 里加 middleware 钩子。
- **Checkpoint 的 session 清理** = 注册 `SessionEndObserver`（feature-checkpoint §5）——而不是在 main 退出路径加 cleanup。
- **将来添加新拦截点** = 扩 Registry 一处，所有依赖者自动获益。

理由：拦截路径并行存在会让"模型这次为什么被拒绝/被拦截"的根因追查指数级变难。v0 时 permission policy 是单点，v3 继续保持只有一个拦截 backbone。

### 2.3 "信任已配置"而非"信任每次执行"

- **Shell hooks 的执行不走 permission picker**（feature-shell-hooks §3.5）——hooks.toml 是用户/项目主动写入，等同 shell rc，事前一次性授信。trust 询问按 sha256 跟踪改动。
- **Checkpoint 的写入不弹 picker**（feature-checkpoint §2）——它是模型动手前的安全网，弹询问就失去意义。

理由：seek 已有 `ModeAsk` / `ModePlan` / `ModeYolo` 三种 permission gate，再叠一层"每次都问"会让用户立刻关掉新功能。v3 的扩展能力换取**信任前置 + 改动审计**（trust 询问 + audit log + sha256 跟踪）。

### 2.4 `pkg/` 层零变更

v3 全部落在 `internal/` 和 `cmd/` 下。`pkg/deepseek` 和 `pkg/agent` 是对外的稳定接口，跟 v0/v1/v2 的设计纪律一致——确保 `pkg/` 用户（如外部嵌入 seek 作为 library）不被 v3 改动波及。

### 2.5 失败降级而非阻断

- **非 git 仓库** → checkpoint 失活但文件 undo/redo 仍工作（feature-checkpoint §3.1）
- **hook 命令语法错** → 该 hook 跳过 + 启动横幅打印，其他 hook 继续（feature-shell-hooks §3.4）
- **keybindings.toml 解析错** → fallback 到默认，stderr 报错 + TUI 启动继续（feature-tui-ergonomics §4.4）

理由：v3 是"信任增强"，不是"准入条件"。任何子系统失败都不能阻塞用户当前的核心工作流。

## 3. 跨柱集成视图

### 3.1 Prefix cache 影响审计（合并三柱）

| 新机制 | 来源 | 是否进 prompt 字节序列 | 是否影响 cache |
|---|---|---|---|
| Git checkpoint 写 ref | 柱 A | 否 | 否 |
| 文件 checkpoint 写 blob | 柱 A | 否 | 否 |
| `/restore` 改 working tree | 柱 A | 否（不改历史 prompt） | 否 |
| Shell hook `pre_tool` deny | 柱 B | 是（deny reason 进 tool result，等同现有 `permission.ErrDenied` 流程） | 同 permission 拒绝 |
| Shell hook `post_tool` observe | 柱 B | 否 | 否 |
| Audit log 写入 | 柱 B | 否 | 否 |
| Tab 补全 | 柱 C | 否（纯 UI） | 否 |
| Keybindings | 柱 C | 否（路由改变，输入文本不变） | 否 |

**结论**：v3 所有新机制对 prefix cache 的影响等价于"用户主动决策的副作用"（拒绝、撤销文件），跟 v0 已经接受的现实成本同量级，不引入新的 cache-volatility 来源。

### 3.2 共享配置目录

三柱在 `~/.seek/` 和 `<project>/.seek/` 下新增的文件：

```
~/.seek/
├── hooks.toml                              # 柱 B：用户级 shell hooks
├── hooks-audit.jsonl                       # 柱 B：hook 执行 audit log
├── keybindings.toml                        # 柱 C：用户级 keybindings
├── trusted-projects.json                   # 柱 B：项目级 hooks trust 记录
└── projects/<id>/sessions/<sid>/
    ├── checkpoints/                        # 柱 A：文件 checkpoint blob + index
    │   ├── blobs/sha256/<aa>/<bb>/<rest>
    │   └── index.jsonl
    └── checkpoints.jsonl                   # 柱 A：git checkpoint 索引

<project>/.seek/
└── hooks.toml                              # 柱 B：项目级 shell hooks
```

**git 内部新增的引用空间**（柱 A）：

```
refs/seek/checkpoints/<session-id>/<turn-index>     # 不在 default refspec
```

### 3.3 跨柱 slash 命令清单（最终态）

v3 全部交付后，`/help` 浮层中按字母序新增的命令：

| 命令 | 来源 |
|---|---|
| `/checkpoints` | 柱 A |
| `/hooks` | 柱 B |
| `/keys` | 柱 C |
| `/redo` | 柱 A |
| `/restore` | 柱 A |
| `/undo` | 柱 A |

新增的 CLI 子命令：

| 命令 | 来源 |
|---|---|
| `seek checkpoint {list,restore,prune}` | 柱 A |
| `seek undo` / `seek redo` | 柱 A |
| `seek hooks {list,check,trust,audit}` | 柱 B |
| `seek keys {list,check,actions}` | 柱 C |

## 4. 总体实现计划

| 子 ms | 内容 | 估时 | 所属 feature | 发版 | 状态 |
|---|---|---|---|---|---|---|
| **M9.0** | git checkpoint 写入 + 索引 + `/restore` + `seek checkpoint` CLI | ~3 天 | feature-checkpoint | v0.4.0 | ✅ 已交付 |
| **M9.1** | 文件 checkpoint blob + `/undo` `/redo` + session 清理 | ~2.5 天 | feature-checkpoint | v0.4.0 | ✅ 已交付 |
| **M9.2** | shell hooks 核心：toml 解析 + ShellRunner + pre/post_tool + CLI | ~3 天 | feature-shell-hooks | v0.4.1 | ✅ 已交付 |
| **M9.3** | hooks 剩余事件 + trust 询问 + audit log | ~1.5 天 | feature-shell-hooks | v0.4.1 | ✅ 已交付 |
| **M9.4** | `internal/keymap` + `update_key.go` 重构 + `/help` 渲染 + CLI | ~2 天 | feature-tui-ergonomics | v0.4.2 | 📐 规划中 |
| **M9.5** | Tab 补全（cmdMeta + picker） | ~1 天 | feature-tui-ergonomics | v0.4.2 | 📐 规划中 |
| **M9.6** | 集成测试 + pitfall 记录 + 文档（README + book chapter） | ~1.5 天 | umbrella（本文） | v0.4.2 收尾 | 📐 规划中 |
| **合计** | | **~14.5 天** | | | |

**并行实施建议**：

- 三个 feature 之间**零代码冲突**（验证：见每个 feature 的 §5 集成表）
- 共享的 `internal/paths` 改动是 append-only，并行加 helper 不会冲突
- `internal/tui/commands.go` 的 `cmdMeta` 注册是 append-only 数组，三柱独立加自己的条目
- 唯一需要协调的：M9.4 的 `update_key.go` 机械替换 + M9.5 的 parseInput Tab 拦截——同一个文件，建议同一人完成或先 M9.4 后 M9.5

**发版三段**：

- **v0.4.0**：M9.0 + M9.1（双层 checkpoint）—— 用户体感最大，单独 ship 给 `--yolo` 用户立刻降心理负担
- **v0.4.1**：M9.2 + M9.3（shell hooks）—— 团队场景的招牌功能
- **v0.4.2**：M9.4 + M9.5 + M9.6（工效 + 收尾）

如果时间紧，可优先砍 M9.5（Tab 补全）：体感正向但非阻塞，且已有 fuzzy 命令解析在用。

## 5. 后续版本

v3 的可逆性 + 可扩展性是 v4/v5 更激进自动化能力的**前置条件**——没有可信的撤销和审计，没人敢真把 agent 调度跑在生产分支上。

- **v4**：
  - Tab 补全推到子命令级（`/skill <verb>` / `/memory <verb>` 的候选）
  - Chord keybinding（如果 v3 的"单键不够用"反馈强烈）
  - Checkpoint 跨 session 浏览（`/checkpoints --all-sessions`）+ 跨 session 文件 undo
  - Shell hooks 加 `tool_args_match`（参数 glob 匹配，不仅 tool name）
  - Devcontainer / Docker 沙箱（v3 不做的容器化执行）—— 跟 hooks 在 deny / observe 语义上同源
- **v5**（候选）：
  - 多 agent / 子代理（对应对比文档的 P2）
  - Routines / scheduled agent（P2）
  - 远程触发 / push notification（P2）

各 feature PRD 的 §10（"后续版本"）维护各柱的细化路线图。
