# Tree-First Graph 内核实施清单 v2

> 更新时间：2026-04-16
>
> 基于以下实际状态重写：
> - 当前未提交代码
> - `/mnt/Data1T/mnote/design/tree-first-graph-kernel-v1.md`
> - `/mnt/Data1T/mnote/design/rust-web-long-term-checklist-v2.md`
> - `/mnt/Data1T/mnote/harness-tasks.json`

## 1. 这版为什么要重写

`v1` 已经把长期方向改到了 `tree-first graph kernel`，方向是对的，但完成口径仍然偏乐观。

当前真实代码已经证明：

- Kernel 文档、Rust 类型、query/command 协议、`mnote-web` kernel route 不是空想，已经存在
- 但 Sidebar、搜索、AI、Mindmap、阅读页、`BlockNote` 还没有真正切到 kernel projection 主路径
- `mnote-web` 的 kernel route 已接到真实 `sidebar.dataset.list` query plan，但仍保留 fixture/testing fallback，不能写成“主流量切换完成”

因此 `v2` 的目的不是推翻之前工作，而是把长期清单统一到：

> **既承认已落地的 Rust kernel 代码，也不再把骨架、样板和 host/runtime 拆分误写成长期阶段已完成。**

---

## 2. 状态口径

### `DONE`

- 已有真实代码进入主线
- 不只是文档或骨架
- 对应阶段的最小目标已经成立

### `PARTIAL`

- 已有真实代码和明确接缝
- 但主路径仍未完成切换
- 仍存在 fixture/testing fallback、旧对象模型或重前端壳残留

### `NOT_STARTED`

- 还停留在设计、口径或局部能力
- 尚未形成稳定主链

---

## 3. 当前总判断

当前基线应统一理解为：

- `Kernel Phase 0`：`DONE`
- `Kernel Phase 1`：`DONE`
- `Kernel Phase 2`：`DONE`
- `Kernel Phase 3`：`DONE`
- `Kernel Phase 4`：`DONE`
- `Kernel Phase 5`：`PARTIAL`
- `Kernel Phase 6`：`PARTIAL`
- `Kernel Phase 7`：`PARTIAL`
- `Kernel Phase 8`：`PARTIAL`
- `Kernel Phase 9`：`NOT_STARTED`

一句话总结：

> **Kernel 基础层与 Rust Web 承载层已经进入真实主线，树域 consumer 已统一到稳定 projection family；但旧前端壳仍然是主要执行面，下一步才是独立 Rust Web tree shell 重构。**

### 面向“全部用 Rust 重写”的附加口径

如果把长期总目标进一步固定为：

> **主执行面最终也迁到 Rust 家族，而不只是“Rust 拥有 kernel 语义”。**

那么当前状态应再补一层判断：

- `Kernel Phase 0-4` 解决的是“树域真相和协议先收口”
- 但距离“主要 UI 执行面改由 Rust 承接”还差一个关键中段：
  - `Sidebar / 页面树 / 文件树` 独立 Rust Web 子系统重构
- 这一步不是可选优化，而是旧前端壳退场前必须先完成的第一块主执行面切换

也就是说：

> **如果目标是“全部用 Rust 重写”，那么当前最优先的下一步，不是继续在旧 React 壳里打补丁，而是启动树域独立 Rust Web 重构。**

---

## 4. 新架构的真实验收定义

只有同时满足下面几条，才能说新架构真正成立。

| 验收项 | 当前状态 | 说明 |
| --- | --- | --- |
| Rust 中存在统一的 kernel node / edge / projection / subtree 真相层 | `DONE` | `core-protocol` 已落地 |
| Rust 中存在统一的 kernel query / command 面 | `DONE` | `bridge-runtime` 已支持 kernel 查询与写协议 |
| Rust Web 能承接 kernel route | `DONE` | `mnote-web` 已具备通用 query transport、kernel/bridge/compat route、测试专用 fixture 边界，以及可切到真实 Sidebar 流量的兼容入口 |
| Sidebar / 页面树 / 文件树直接消费 kernel projection | `PARTIAL` | 前端主 Sidebar 已以 `kernelSidebarTree` 作为主树来源，但仍是重客户端壳，其他树域仍残留旧拼树 helper |
| 搜索直接消费 kernel-aware 检索结果 | `PARTIAL` | cron 已有 `kernel-aware refresh` 过渡链，搜索结果也已带 `nodeId` / `subtreeRootId` / `evidence`，但仍是 LightRAG 过渡口径，不是 kernel 真相层检索 |
| 阅读页直接消费 page subtree projection | `PARTIAL` | `DocumentReadView` 已直接消费 `pageSubtree`，但 projection 仍在前端读链内生成，不是 Rust/kernel 真相层输出 |
| AI 直接面向 node / subtree / edge 操作 | `PARTIAL` | AI runtime 与 Hermes bridge 已开始携带 `node` / `subtree` / `outline` / `evidence` 上下文，但还不是完整的 kernel-first tool 面 |
| Mindmap 正式退化为 projection / editor | `PARTIAL` | 理念已定，独立页已去 stub，但数据真相尚未下沉到 kernel |
| `BlockNote` 只负责内容节点编辑 | `PARTIAL` | 阅读态已先走 `pageSubtree`，编辑器也已按需挂载，但外围 panel / drawer 仍集中在 `DocumentContent` |
| 旧前端壳不再承担对象真相 | `NOT_STARTED` | 当前主入口仍是 Next/React |

---

## 5. Kernel Phase 0：边界冻结与术语统一

**当前状态：`DONE`**

### 已落地

- `tree-first-graph-kernel-v1.md` 已冻结：
  - `node`
  - `edge`
  - `projection`
  - `subtree`
  - `content node`
  - `reference edge`
  - `summary node`
  - `index node`
- 已明确四层边界：
  - 事实源
  - 投影
  - 编辑器
  - 外挂
- 已明确：
  - `Mindmap` 不是事实源
  - `BlockNote` 不是事实源
  - 页面树/文件树不是事实源

### 完成判定

- 后续长期任务不再把导图页、页面树、`BlockNote` 文档结构当作独立真相层

---

## 6. Kernel Phase 1：Node / Edge / Projection 基础模型落地

**当前状态：`DONE`**

### 已落地

- `rust/crates/core-protocol/src/kernel.rs` 已存在统一类型
- `rust/crates/core-protocol/src/lib.rs` 已导出 kernel 类型

### 已有能力

- `KernelNode`
- `KernelEdge`
- `KernelProjectionRequest`
- `KernelProjectionResult`
- `KernelSubtreeRef`
- `KernelSubtreeResult`
- `KernelAuditStamp`
- `KernelNodeType`
- `KernelEdgeType`
- `KernelProjectionKind`

### 当前结论

- 这一阶段不应再回退为“只有文档设计”
- 这里已经是实际代码事实

---

## 7. Kernel Phase 2：Kernel Query / Command / Subtree / Graph Traversal 协议落地

**当前状态：`DONE`**

### 已落地

- `rust/crates/bridge-runtime/src/lib.rs` 已支持：
  - `kernel.node.get`
  - `kernel.subtree.get`
  - `kernel.children.list`
  - `kernel.edges.list`
  - `kernel.graph.traverse`
  - `kernel.project_view`
  - `kernel.node.create`
  - `kernel.node.update`
  - `kernel.subtree.move`
  - `kernel.edge.attach`
  - `kernel.edge.detach`
- `rust/crates/storage-convex-bridge/src/mapping.rs` 已补 kernel query / command 映射

### 当前结论

- 这一阶段也不应再写成“待设计”
- 真实缺口不在协议是否存在，而在谁来真正消费这些协议

---

## 8. Kernel Phase 3：Rust Web 接入 kernel，成为主承载层

**当前状态：`DONE`**

### 已落地

- `rust/crates/mnote-web/` 已进入 workspace
- 已存在 `axum` app/router/context/middleware 骨架
- 已有 kernel route：
  - `/api/kernel/projections/sidebar`
  - `/api/kernel/subtree`
  - `/api/kernel/edges`
  - `/api/kernel/graph`
- sidebar kernel route 已通过 `sidebar.dataset.list` runtime plan + 通用 Convex query transport 读取真实数据集
- 已新增真实 workspace / bridge 查询 route：
  - `/api/bridge/workspace`
  - `/api/bridge/request`
  - `/api/bridge/trace`
- 已新增 Next 兼容切流入口：
  - `/api/compat/next/sidebar`
- `MNOTE_WEB_QUERY_FIXTURES_JSON` + `allow_dev_fixtures` 已把 fixture 收紧到测试/开发边界
- `/api/sidebar` 与服务端 Sidebar 首包在配置 `MNOTE_WEB_BASE_URL` 后，默认经 `mnote-web` 的 Sidebar compat route 取数
- `mnote-web` transport 已优先转发真实 `Authorization`，否则才退回开发态 admin/dev identity
- 已有 kernel / bridge 路由测试，说明 route 不只是声明

### 已完成判定

- Sidebar 这条 kernel 查询主链已不依赖生产态 fixture fallback
- `mnote-web` 已不再只有 Sidebar 单点 transport，而是能承接更广的 query / bridge 主链
- Next -> Rust Web 的第一条真实切流边界已经明确并可启用

### 当前保留边界

- `kernel.subtree.get` / `kernel.project_view` 仍主要建立在 `sidebar.dataset.list` 这一份页面树数据集之上
- 更广义的 node pool、reference edge、summary/index node 真相层，仍属于后续阶段
- `mnote-web` 还不是整个产品的唯一 Web 入口，这属于更后的双栈收缩问题

### 完成判定

- 至少一条不依赖 fixture fallback 的 kernel 查询主链已在 `mnote-web` 上稳定运行
- 至少一条真实 workspace / bridge 查询主链已通过 `mnote-web` 对外提供
- 至少一条真实前端流量已具备默认切到 `mnote-web` 的兼容边界

---

## 9. Kernel Phase 4：Sidebar / 页面树 / 文件树切到 kernel projection

**当前状态：`DONE`**

### 本阶段边界

这个阶段只解决一件事：

> **把树域 consumer 全部统一到稳定的 kernel projection / tree protocol。**

这里刻意**不**包含：

- 独立 Rust Web tree shell
- `Leptos` / `Dioxus` / `Yew` 树域 UI 重写
- Sidebar 整体壳替换

这些属于 `Phase 4` 完成之后的独立大任务，即：

- [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/sidebar-pagetree-filetree-rust-web-rebuild-v1.md)

### 已落地

- [x] Sidebar 已有服务端首包
- [x] Rust runtime 已能把 `sidebar.dataset.list` 转为统一 kernel subtree / projection 结果
- [x] `sidebar-data.ts` 已生成 `kernel_sidebar_projection` 与 `kernelSidebarTree`
- [x] 前端主 Sidebar 已以 `sidebarData.kernelSidebarTree` 作为初始化与同步的主树来源
- [x] 已新增统一 `page_tree` projection protocol：
  - `rowId`
  - `nodeId`
  - `parentNodeId`
  - `projectionKind`
  - `depth`
  - `position`
  - `capabilities`
  - `resourceMeta`
- [x] `PrivateTree` 已改为直接消费 `page_tree` projection 可见行，而不是自行 flatten 嵌套树
- [x] 文件树已改为只消费 `page_tree projection + asset 映射`，`buildVisibleRows(...)` 收口为 projection -> visible rows
- [x] `move-embed picker` 空查询态已直接消费 `kernelSidebarTree -> page_tree projection`，不再调用 `buildDocumentTree(...)`
- [x] `SidebarInitialData` / `sidebar-data.ts` 已将 `kernelSidebarProjection` 与 `kernelSidebarTree` 收紧为主路径必备字段，不再在映射阶段对缺失 projection 做主路径 fallback

### 本阶段完成后仍保留的问题

- 前端主 Sidebar 仍是超大客户端组件
- 页面树 / 文件树 / picker 虽已统一协议，但 Rust Web tree shell 仍未开始
- 文件树中的 `asset-folder` / `asset` / `index` 仍由前端 adapter 基于现有数据集补齐，不是 Rust 直接输出的 `file_tree projection`
- `buildDocumentTree(...)` 仍保留在兼容 helper 与旧单测中，但已退出树域主路径
- 现在可以进入树域 Rust Web 壳重写，但不能把这一步与本阶段混写成同一任务

### 下一阶段任务

- 独立推进 [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
- 把当前 `page_tree` / `file_tree` protocol 下沉成 Rust Web 独立 route / shell
- 继续缩小 Sidebar 超大客户端壳，只保留局部交互岛
- 让文件树中的更宽对象投影逐步由 Rust projection 直接输出

### 面向“全部用 Rust 重写”的优先级解释

如果长期目标只是“Rust 持有语义”，这里可以被理解为下一批独立大任务。

但如果长期目标已经固定为“全部用 Rust 重写”，那么这里应升级为：

- **最近主线 P0**
- **旧前端壳的第一块正式替换带**
- **后续阅读页 / 搜索 / AI / Mindmap Rust 化之前的必经步骤**

原因是：

- 树域是工作区主导航与对象结构入口，替换价值最高
- `page_tree / file_tree` 协议已经冻结，返工风险最低
- 当前 Sidebar 仍是旧前端壳里最重、最容易继续扩散语义的一块
- 如果不先把树域执行面剥离出来，后续文档页、搜索页、导图页 Rust 化会继续被旧壳牵制

### 完成判定

- [x] 主 Sidebar 以及相关树域已直接消费 kernel projection
- [x] 页面树 / 文件树 / 嵌入移动器等不再通过旧对象数组拼树
- [x] tree row / projection protocol 已冻结，足以支撑下一步独立 Rust Web tree shell 重构
- [x] 当前 React/Next 树域可以继续作为 consumer 壳存在，但不再定义树结构真相

---

## 10. Kernel Phase 5：结构知识刷新与 kernel-aware 检索

**当前状态：`PARTIAL`**

### 新口径

这阶段不再按“单独搭一个 RAG 系统”来定义。

长期正确方向是：

- 用 cron 定时刷新知识
- 直接把结构知识写回 kernel
- 用 kernel-aware 检索命中 node / subtree / evidence

这与传统 `LightRAG-first` 不同，更接近：

- Karpathy 的知识刷新思路：https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
- `llmwiki-cli` 这类结构化知识索引方案：https://github.com/doum1004/llmwiki-cli；https://github.com/stellarlinkco/llm-wiki/blob/main/README.zh-CN.md
- `Mindmap` / `BookMindmap` / 章节树 / 书籍子树作为结构索引投影

当前已经有直接代码证据，但只能算过渡态：

- `convex/crons.ts` 已新增 `kernel_aware_refresh_daily_transition`
- `convex/jobs.ts` 已新增 `enqueueKernelAwareRefresh`、`enqueueKernelAwareRefreshSweep` 与 `refresh.kernel_aware_transition`
- 刷新结果已带 `nodeIds`、`subtreeRootIds`、`evidenceAssetIds`
- 搜索结果类型与 adapter 已返回 `nodeId` / `subtreeRootId` / `evidence`

但这条链目前仍通过 `LightRAG` 过渡入库，还不能写成“kernel 真相层知识刷新已完成”。

### 已落地

- 已有 cron 驱动的 `kernel-aware refresh` 过渡入口
- 已有工作空间成员校验与刷新目标选择：
  - workspace
  - document
  - mindmap
  - asset
- 已有搜索结果结构化返回：
  - `nodeId`
  - `subtreeRootId`
  - `evidence`
- recent / 常规搜索在缺失 Rust evidence 时，也会补齐最小 evidence fallback

### 当前真实问题

- 结构知识仍未直接写回 kernel node / edge
- `summary node`、`ai_note node`、`index node`、`reference edge` 还没有形成真实 kernel 写链
- `BookMindmap` / 章节树还没有形成统一 kernel index 主链
- 当前刷新任务仍是 `kernel_aware_transition`，不是最终的 kernel truth pipeline
- 搜索虽已消费 kernel-aware 结果形状，但还没有 server-first 搜索页或 Rust Web 检索壳

### 下一阶段必须完成

- 把 `kernel_aware_transition` 从 LightRAG 过渡链继续收口到真实 kernel 节点/边写链
- 明确 `summary node`、`ai_note node`、`index node`、`reference edge` 的真实写入协议
- 把增量刷新输入继续稳定到：
  - workspace
  - page
  - subtree
  - book
  - pdf
- 把刷新输出真正落到：
  - `summary node`
  - `ai_note node`
  - `index node`
  - `reference edge`
  - `book subtree`
  - `chapter subtree`
- 把检索面继续推进到：
  - 按 node type 过滤
  - 按 subtree 过滤
  - 按 edge 过滤
  - 返回正文/附件/页码/证据回查
- 定义残留 `LightRAG` 的过渡边界与移除计划

### 完成判定

- 至少一条 cron 驱动的知识刷新链能稳定更新 kernel 节点/边
- 至少一条搜索链能直接返回 kernel node / subtree / evidence

---

## 11. Kernel Phase 6：Mindmap 降级为 projection / editor

**当前状态：`PARTIAL`**

### 已落地

- 理念上已经确认 `Mindmap` 不是中心
- Rust 侧已有 Mindmap 对象协议
- 独立导图页已先在服务端获取 initial projection，再进入客户端页面壳
- 独立导图页已直接使用 `StandaloneMindmapView`，不再以 `editorStub` 作为入口
- `MindmapBlock.tsx` 已出现 `standalone` / `documentBridge` 边界
- 文档内嵌导图已默认走 preview-first 入口

### 当前真实问题

- 独立导图页仍是客户端重壳，并且仍复用同一个重型 `MindmapBlock` 族组件
- 文档内嵌导图虽然已经 preview-first，但进入编辑/沉浸态后仍复用同一个重型 `MindmapSurfaceView`
- 导图操作尚未直接回写统一 kernel subtree

### 下一阶段必须完成

- 继续把独立导图页壳从文档编辑上下文与共享重组件中拆开
- 内嵌导图改为轻预览/轻编辑入口
- 把导图编辑动作收口为 kernel command

### 完成判定

- 独立导图页与文档内嵌导图都只作为 kernel projection / editor 入口，而不是独立事实源

---

## 12. Kernel Phase 7：文档阅读页与 AI 面板切到 kernel projection

**当前状态：`PARTIAL`**

### 已落地

- 阅读态/编辑态已经分离
- `DocumentContent` 已生成 `pageSubtree`
- `DocumentReadView` 已直接消费 `pageSubtree`
- 阅读态结构面板已直接消费 `outline` / `evidence`
- `BlockNote` 默认不再首屏强挂
- AI 已做 host/runtime 拆分
- `DocumentAiAgentPanel.runtime.tsx` 已向 AI route 发送 `node` / `subtree` / `outline` / `evidence`
- `/api/ai-agent/run` 已把这些上下文序列化进 Hermes 指令

### 当前真实问题

- 阅读页已经是 page subtree projection 驱动，但 projection 仍在前端读链内生成，不是 Rust/kernel 真相层直接输出
- `DocumentContent` 仍集中挂载 `DocumentAiAgentPanel`、`DocumentHistoryDrawer`、`DocumentCommentsDrawer`、`PageBacklinksPanel`、`PageOptionsSidebar`
- AI runtime 仍是页面级重壳，不是 kernel-first tool bridge
- 搜索/AI/阅读页之间虽然开始共享 `node` / `subtree` / `outline` / `evidence` 口径，但还没有统一到稳定的 node / subtree / edge 真相协议面

### 下一阶段必须完成

- 把 page subtree projection 从前端读链继续下沉到更稳定的 Rust/kernel 输出边界
- 阅读页大纲、回链、结构信息改读 kernel edge / subtree
- AI tool 直接面向 node / subtree / edge
- AI 可以创建：
  - `summary node`
  - `ai_note node`
  - `reference edge`
- 搜索与 AI 共用 kernel-aware 检索上下文

### 完成判定

- 阅读页与 AI 至少各有一条主路径直接消费 kernel projection

---

## 13. Kernel Phase 8：BlockNote 退化为内容编辑挂件

**当前状态：`PARTIAL`**

### 已落地

- `src/lib/documents/page-subtree.ts` 已显式定义 `pageSubtree`
- `DocumentContent` 已把阅读态与编辑态拆开
- `DocumentContent` 已通过 `isEditing` / `keepEditorMounted` 让 `BlockNote` 按需挂载
- 阅读态已不再默认依赖 `BlockNote` 才能渲染正文

### 当前真实问题

- 页面结构仍未与 `BlockNote` 内容结构彻底解耦
- `DocumentContent` 仍挂着大量外围 panel / drawer
- page subtree 与 content node 的边界还没有正式回写到 kernel / editor 分层

### 下一阶段必须完成

- 把 page subtree 与 content node 的边界继续固化到更稳定的 kernel / editor 分层
- 明确哪些节点继续由 `BlockNote` 编辑
- 明确哪些结构节点改由 kernel-aware editor 处理
- 把外围 panel 从编辑宿主中继续拆走

### 完成判定

- 页面结构不再由 `BlockNote` 数据结构定义
- `BlockNote` 只承担内容节点编辑

---

## 14. Kernel Phase 9：旧前端壳与旧对象模型下线

**当前状态：`NOT_STARTED`**

### 当前真实问题

- 当前主应用入口仍是 Next App Router
- 当前主文档页、主 Sidebar、主搜索、主导图页都仍运行在旧前端壳内

### 下一阶段必须完成

- 盘点旧对象真相残留
- 盘点旧 helper / adapter 残留
- 删除已被 kernel projection 替代的旧 route
- 删除已被 kernel command/query 替代的旧 adapter
- 明确最终双栈收缩与切流计划

### 完成判定

- 旧前端壳与旧对象模型都不再承担主事实来源

---

## 15. 推荐执行顺序

如果按当前真实代码继续推进，建议顺序是：

1. 维持 `Kernel Phase 4` 已完成口径，不再回头重做 consumer 统一
2. 立即启动 `Phase 4` 后继任务：
   - [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
3. 在树域 Rust Web 子系统形成稳定主链后，再继续把文档阅读页的 `page subtree / read_view` 下沉到 Rust 输出边界
4. 再推进 `Kernel Phase 5`
5. 再推进 `Kernel Phase 6`
6. 再推进 `Kernel Phase 7`
7. 最后进入 `Kernel Phase 8` 和 `Kernel Phase 9`

原因很简单：

- 旧 `Phase 4` 的目标已经完成，真正未完成的是“树域执行面 Rust 化”
- 树域是所有主页面里最先具备 Rust 化条件的一块，因为 projection / command protocol 已经先被冻结
- 文档阅读页、搜索、AI、Mindmap 后续都会依赖这条更稳定的树域与 projection 分发主链
- 如果继续把精力分散到旧 React 壳上的局部修补，会拖慢真正的执行面切换
- 知识刷新与 kernel-aware 检索仍然重要，但它们更适合在树域主承载面开始切换后并行推进，而不是抢在前面替代主导航改造

---

## 16. 最终结论

当前最准确的表述不是“长期阶段已经做完”，而是：

> **Kernel 基础层已经做出来了，真正难的部分才刚开始，也就是让所有主视图与主工具链逐步切到 kernel projection。**

所以后续主线必须固定为：

> **先完成树域的 kernel projection 统一，再基于稳定协议做 Sidebar / 页面树 / 文件树的独立 Rust Web 重构；之后再并行推进结构知识刷新、Mindmap、阅读页、AI、`BlockNote` 与旧壳退场。**

如果把总目标进一步固定为“全部用 Rust 重写”，则这里还应再明确一句：

> **下一步应该继续的，不是旧定义里的 `Kernel Phase 4` 本身，而是它的后继任务，也就是 `Sidebar / 页面树 / 文件树 Rust Web 重构`；这是旧前端壳退场前最值得优先拿下的第一块执行面。**
