# 4-6 [done] Tree Command Protocol Cutover Stage 2 v1

> 更新时间：2026-05-16
>
> 目的：冻结树域 command protocol 的长期命名面，并明确 `documents.*` 到 `tree.*` 的兼容迁移口径。

## 1. 结论

长期命名面不再继续扩大 `documents.*`。

固定迁移方向为：

- 兼容层继续保留 `documents.*`
- 长期正式协议统一切到 `tree.*`

## 2. 长期正式命名

冻结如下：

- `tree.node.create`
- `tree.node.rename`
- `tree.node.archive`
- `tree.node.restore`
- `tree.node.purge`
- `tree.subtree.move`
- `tree.subtree.copy`
- `tree.asset.attach`
- `tree.asset.detach`
- `tree.node.embed`

## 3. 当前兼容映射

| 兼容命名 | 长期命名 | 说明 |
| --- | --- | --- |
| `documents.create` | `tree.node.create` | 新建页面 |
| `documents.title.update` | `tree.node.rename` | 重命名页面 |
| `documents.move` | `tree.subtree.move` | 移动子树 |
| `documents.delete` | `tree.node.archive` | 软删除进入回收站 |
| `documents.restore` | `tree.node.restore` | 从回收站恢复 |
| `documents.purge` | `tree.node.purge` | 永久删除 |
| `documents.embed` | `tree.node.embed` | 嵌入页面 |
| `documents.copy_tree` | `tree.subtree.copy` | 复制树 |

## 4. Cutover 顺序

### Stage 2A

- 先在 Rust route / bridge 上接受 `tree.*`
- 同时保留 `documents.*` alias
- 前端 command client 开始显式知道两套名字的对应关系

### Stage 2B

- 主调用路径默认发 `tree.*`
- 兼容入口只用于旧 route / 旧测试 / 旧调试脚本

### Stage 2C

- 删除主路径对 `documents.*` 的依赖
- 仅保留极薄 alias，或在最终阶段删除 alias

## 5. 命名边界

### 5.1 `tree.node.*`

用于单节点生命周期命令：

- `tree.node.create`
- `tree.node.rename`
- `tree.node.archive`
- `tree.node.restore`
- `tree.node.purge`
- `tree.node.embed`

### 5.2 `tree.subtree.*`

用于结构级命令：

- `tree.subtree.move`
- `tree.subtree.copy`

### 5.3 `tree.asset.*`

用于资源挂接：

- `tree.asset.attach`
- `tree.asset.detach`

## 6. 当前约束

- 前端组件不再自己扩散树语义
- tree command client 是唯一稳定入口
- route / bridge / kernel command 的映射必须集中管理

## 7. 完成判定

当以下条件同时成立时，视为 Stage 2 完成：

- 文档明确记录 `documents.*` 到 `tree.*` 的映射
- Rust / 前端都接受 `tree.*`
- 主调用路径默认走 `tree.*`
- `documents.create` 等兼容命名不再是新增主语义入口

## 8. 2026-05-16 复核记录

本轮复核结论：

- `3000` 前端主交互链已经默认走 `/api/tree/commands` action，由 route / Rust runtime 构造正式 `tree.*` command envelope。
- `documents.*` 仍作为兼容 alias 和 Convex legacy mutation 函数名存在，但不再作为页面生命周期主链新增语义入口。
- `bridge-runtime` 已给 `documents.create/title.update/move/delete/restore/purge/copy_tree` 兼容 alias 的 execution plan 增加 `commandProtocol` 元数据：
  - `owner=rust-runtime-kernel`
  - `preferredCommandName=tree.*`
  - `compatCommandName=documents.*`
  - `deprecatedAlias=true/false`
- `mnote-web` transport 在调用 Convex legacy mutation 前剥离 `commandProtocol`，该字段只作为 Rust plan / artifact 审计边界，不进入旧 validator。

已验证命令：

```bash
cargo test --manifest-path rust/Cargo.toml -p bridge-runtime tree_ -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web tree_command -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web convex_command_args_strips_tree_archive_artifacts_for_legacy_mutation -- --nocapture
```

后续仍需单独收口：

- `/api/documents/create-child` 仍是 compat-only 子页面创建入口，后续应迁到 `/api/tree/commands` 或明确退役。
- `mnote-cli` 中页面生命周期命令仍构造旧 `documents.*`，后续若 CLI 继续保留为正式入口，应迁到 `tree.*`。
