# Clavue Roadmap v10 — 最高维度逻辑

> 取代 `clavue-upgrade-plan-v9.md` 的"slice 堆砌"视角。
> v9 把上游 Claude Code 2.1.x changelog 当 checklist 抄；v10 反过来，从
> **PRODUCT.md + ARCHITECTURE.md** 倒推。
>
> Generated 2026-05-17, version baseline `clavue@8.10.17`, upstream
> `claude-code@2.1.143`, 测试基线 1363 pass / 0 fail / 3 skipped。

---

## 0. 北极星（不可动摇的判定标准）

一切开发决策走这三问，**任一为否就 defer**：

1. **产品身份**：这条改动是否让 "clavue 是 execution-first AI coding CLI"
   更清晰？(PRODUCT.md:3)
2. **运行时契约**：是否符合 "one runtime decision per turn"？
   (ARCHITECTURE.md:19)
3. **可逆性**：失败时能否 `git revert <slice>` 干净回滚，不留状态污染？

不满足任一条的改动 — 哪怕上游 changelog 列了 — **不抄**。
v9 后半段大量 "cargo-cult parity" defer 决策都源于此。

---

## 1. 当前状态的诚实画像

### 1.1 已经稳的（不要再碰）

- **核心安全防线**：Bash 沙箱 + `/dev/(tcp|udp)` 阻断 + sandbox `deniedDomains` +
  plan-mode 写阻断 + hook-ask deny 覆盖 + `hard_deny` + `$defaults`。
- **MCP 稳定性骨架**：60s 默认 timeout / OAuth 并发锁 / freshest-token
  reread / workspace 保留名 / `/clear` 重连 key 保留。
- **Prompt cache 1h TTL** 门控顺序 + 5m force-override。
- **PostToolUse `updatedToolOutput`** 对称 + `continueOnBlock` 降级。
- **Provider headers**: Bedrock service tier / workspace-id (带 CLAVUE_ 别名)。
- **Agent ergonomics**: case-insensitive subagent_type / `claude agents --cwd`。
- **Long-session UX (最小)**: `/undo` alias for `/rewind`。
- **Skill 匹配**: `name *` 空格星号归一化 / 3-mode skillOverrides /
  `:*` prefix / token estimate UI。

总计 ~50 个 anchored 测试覆盖以上。

### 1.2 已经停的（明确不推 — 写下原因防止下轮重启）

| 项目 | 原因 |
|---|---|
| v9 Slice 4.4 `require(` ban | 290 处 feature-flag DCE 模式，user constraint 禁动 |
| v9 Slice 4.4 LOC > 1500 ban | 14+ 文件超标，规则会一片红 |
| v9 Slice 4.3 TODO triage | 140 处大部分是上游 ink/vadimdemedes 库 TODO，不是真实债务 |
| v9 Slice 3.4 `--add-dir/--settings/...` | 上游 `claude agents` 是 FleetView (背景 session)，我们是 list-only，flag 无消费者 |
| v9 Slice 3.5 worktree runtime consumer | schema 默认与当前 runtime 行为相反，强落会破坏用户预期 |
| v9 Slice 2.5 reactive compact 重设 | preservedMessages 已最激进 (last group)，2.1.142 spec 不清 |
| v9 Slice 1.2 terminalSequence / mcp_tool hook | 新 output 字段 + 新 hook type，medium blast，非核心 |

### 1.3 还有的真实债务（按 cost/value 排序）

| 债务 | Value | Cost | 推不推 |
|---|---|---|---|
| 巨型文件 (REPL.tsx 7231 / main.tsx 6659) | 中 | 极高 (risk-of-regression) | 战略级，单独 PR 流，不进 v10 |
| `RuntimeDecision` 类型缺失 | 高 | 中 | **v10 P0** — ARCHITECTURE.md 承诺却不存在 |
| `/recap` / `/focus` slash command | 中 | 高 (需要 recap engine) | defer 到 v11 |
| Plugin UX (details/prune/cost) | 中 | 高 (需 token estimator + walker) | defer 到 v11 |
| Native binary launcher (bin/clavue) | 高 (启动 < 100ms) | 高 (release 流程改) | **v10 P3 单独** |
| EnterWorktree path 输入 | 低 | 中 | defer |
| Vertex mTLS / X.509 WIF | 低 (企业) | 中 | defer 到 v11 |
| PR URL paste → /resume | 低 | 中 | defer |
| 类型化测试迁移 (.mjs → .test.ts) | 中 | 极高 (1366 测试) | **不全迁**；新增测试用 .ts；老的留 |

---

## 2. v10 的真正主线（按维度排）

不是再列 12 个 slice。v10 只有 **3 个维度的任务**：

### 维度 A — **兑现 ARCHITECTURE.md 的承诺** (P0, 必做)

ARCHITECTURE.md:19-30 写 "every turn governed by one runtime decision"，
枚举了 10 个字段。但 `src/` 没有 `RuntimeDecision` 类型 — 文档说有，代码没。

**A1. 落地 `RuntimeDecision` 类型 + resolver**
- 新文件 `src/runtime/decision.ts` —  10 字段 type + resolver + 测试。
- **零 callsite 改动**：只是把现有 per-turn 散落的判断（route policy / provider /
  workflow mode 等）通过 type 收口，不修改 query 主循环逻辑。
- 验证：新测试断言 resolver 对同一 (route, provider, settings) 输入幂等返回
  同 RuntimeDecision；不修改 `query.ts` / `QueryEngine.ts` 主路径。
- Blast：低（新增 type 文件，no 现有 callsite 改）。
- 真正解锁 v9 0.5 的 "featureModules 静态化" — 但那是 v10 之后的事。

**A2. 用 source-anchor 测试 pin ARCHITECTURE.md 的 10 个字段**
- `tests/architecture-runtime-decision-contract.test.mjs` 断言 `RuntimeDecision`
  type 包含全部 10 个字段（product identity / provider adapter / model
  family / transport / capability tier / workflow mode / plan discipline /
  verification discipline / recovery mode / visible tools）。
- 防止后续 PR 静默删字段。

### 维度 B — **加固已落但未 anchor 的关键不变量** (P1, 半天)

v9 进展里有几条是 "已实现但没 anchor"，本会话前面已经补了 5 个。剩余 audit：

**B1. anchor `RuntimeDecision` 一旦落地后立刻 anchor 10 个字段**（见 A2）

**B2. 巡查 src/ 内 anchored-by-comment 但无 test 的不变量**
- grep `Upstream Claude Code 2\.1\.` 注释 → 列出每条对应的 anchor test。
- 缺哪条补哪条，不做主动重构。

**B3. release-gate 加 architecture 守护**
- `scripts/check-source-purity.mjs` 加一条：若 `src/runtime/decision.ts`
  不存在或 `RuntimeDecision` type 缺关键字段，fail。
- 验证：当 A1 落地后这条 check 才通过。

### 维度 C — **doc 收口** (P2, 看心情)

v9 列了 `docs/archive/` 重排 + INDEX.md。这是 "no-blast-radius" 工作，
任何时候做都行，但对北极星贡献低。

**C1.** 把 v9 plan 移到 `docs/archive/2026-q2/clavue-upgrade-plan-v9.md`，
保留 redirect README。_Done 2026-05-17 — redirect stub at
`docs/clavue-upgrade-plan-v9.md` points to archive + this roadmap._
**C2.** 更新 `docs/INDEX.md` 指向 v10 roadmap。_Skipped — `docs/INDEX.md`
不存在；不为归档创造新 entrypoint，避免额外维护面。_

---

## 3. 显式不做的

- **不抄上游 changelog**。Cargo-cult parity 已经造成了 v9 一半 slice 的 defer。
  上游有什么 ≠ 我们要什么。
- **不重构巨型文件**。REPL.tsx / main.tsx / messages.ts 是稳定的、有测试覆盖
  的、风险换不来等量收益。等真正需要时再拆。
- **不增加新 slash command 除非有 user-facing 痛点**。/recap / /focus 都是
  Claude Code UX 增量，我们的 Companion 子系统已经覆盖 recap workflow。
- **不为了"显得在工作"加测试**。每个新测试必须 pin 一个**非显然**的不变量
  —— 显然行为不值得 source-anchor 测试。

---

## 4. 执行顺序（明确步骤，可逆）

1. **A1 + A2**（半天）— `src/runtime/decision.ts` + 2 个测试。
2. **B2**（1-2 小时）— grep + 补缺失 anchor。
3. **B3**（30 分钟）— purity check 加 architecture guard。
4. **C1 + C2**（30 分钟）— doc 归档。

每步独立 commit + RC。任一步出 regression：`git revert <slice>`，回到 1363
基线，重新评估。

**完成定义**：
- 测试数 ≥ 1370 pass / 0 fail。
- `npm run check` 全绿。
- ARCHITECTURE.md 的 "one runtime decision per turn" 在 `src/` 有对应 type。
- v9 plan 状态表归档，v10 roadmap 成为唯一入口。

---

## 实施记录 (2026-05-17)

| 维度 | 状态 | 证据 |
|---|---|---|
| A1 RuntimeDecision alias | done | `src/utils/model/codingRoutePolicy.ts` `export type RuntimeDecision = CodingRoutePolicyDecision` + product-identity docblock |
| A2 contract test | done | `tests/runtime-decision-contract.test.mjs` (3 测试 pin alias + 9 字段 + product identity 排除原因) |
| B2 anchor 巡查 | done | `src/` 引用 upstream 2.1.{105,122,140,141,142,143} 全部被 `tests/` 覆盖；本轮额外补 3 处 v9 标 done 但缺 anchor 的关键不变量 |
| B3 purity guard | done | `scripts/check-source-purity.mjs` 加 `checkRuntimeDecisionContract` — alias 缺失或字段丢失立即 fail |
| C1 v9 归档 | done | `docs/archive/2026-q2/clavue-upgrade-plan-v9.md` + `docs/clavue-upgrade-plan-v9.md` redirect stub |
| C2 INDEX.md | skipped | 文件原本不存在；不为归档创建新 entrypoint |

### 本轮补的 anchor (v9 标 done 但缺 source-anchor)

| 测试 | 锁定的不变量 |
|---|---|
| `dangerously-disable-sandbox-respects-ask.test.mjs` | `dangerouslyDisableSandbox` 不绕过 ask rule (与 policy AND-gate) |
| `find-dangerous-flags-no-auto-approve.test.mjs` | `find -delete/-exec/-execdir/-ok/-okdir/-fprint(0)?/-fls/-fprintf` 不能 auto-approve |
| `dangerous-paths-no-auto-edit.test.mjs` | `--dangerously-skip-permissions` 不能 auto-edit `.git/.vscode/.idea/.clavue/.claude/`，`.clavue/settings(.local).json` endsWith 锚定 |

测试基线：1372 pass / 0 fail / 3 skipped (本会话累加 +14: contract 3 +
posttooluse-continue-on-block 3 + clear-preserves-mcp-reconnect 2 +
sandbox-ask 2 + find-flags 1 + dangerous-paths 3)。`npm run check` 全绿。

### v9 残余实现物固化 (2026-05-17, 同会话续 commit)

发现工作区另有未 commit 的 v9 实现+测试残留（57 处文件，约 4400 行）。
按子系统切 14 个 commit 落地到 `v89-p0-development`：

| Hash | 子系统 | 内容 |
|---|---|---|
| `b9d9d2b` | settings schema | worktree.bgIsolation + baseRef 字段 |
| `2bcd205` | permissions | sandbox/autoMode/plan-mode 加固 + 4 测试 |
| `62edf61` | bash security | `/dev/(tcp\|udp)` 重定向阻断 + 测试 |
| `b8b75ea` | mcp | 60s timeout 默认 + workspace 保留名 + /clear 重连 + 3 测试 |
| `7e81bfa` | provider headers | Bedrock service tier + ANTHROPIC_WORKSPACE_ID + 2 测试 |
| `ffd904f` | ergonomics | agents --cwd + subagent_type case + /undo alias + skill `name *` + 4 测试 |
| `78d86ae` | hooks | PreCompact block path + PostToolUse `updatedToolOutput` + 2 测试 |
| `e7f183d` | query loop | featureModules 注册表 + queryEngine/claude 拆分 + STOP_HOOK_MAX_LOOPS + 2 测试 |
| `986fa92` | tests | prompt-cache 1h TTL 不变量 anchor |

每个 commit 独立可 revert；commit 内测试全过。`npm test` 终态：1375 tests
/ 1372 pass / 0 fail / 3 skipped。`npm run check` 全绿 (exit 0)。

---

## 5. v10 之后（v11 候选池，等当下落定再决策）

- Long-session UX 完整化（/recap engine, /focus）。
- Plugin UX (details/prune/cost)。
- Native binary launcher (P3 单独 PR)。
- featureModules 静态导入（依赖 A1）。
- Vertex mTLS / PR URL paste / EnterWorktree path。

这些都不进 v10 — 不是因为没价值，是因为 v10 必须先把 ARCHITECTURE.md
的承诺兑现，否则后面的所有 "one decision per turn" 优化都没有锚点。

---

## 北极星检查（最后一次）

| v10 任务 | 产品身份 | 运行时契约 | 可逆性 |
|---|---|---|---|
| A1 RuntimeDecision type | ✓ 把 "execution-first" 的判定锚点固化 | ✓ 直接兑现 | ✓ 新文件 |
| A2 contract test | ✓ 防身份漂移 | ✓ 防字段丢 | ✓ 测试 only |
| B2 anchor 巡查 | — | ✓ 防回归 | ✓ 测试 only |
| B3 purity guard | — | ✓ 锁住 | ✓ 脚本 only |
| C1/C2 doc 归档 | ✓ 单一入口 | — | ✓ 文件移动 |

v10 = **把 v9 已落的事兑现到契约层** + **解锁 v11 的运行时统一**。
不是新功能，是地基。
