# 7-2 [done] Phase 7 结构化 Artifact 写链最小落地方案 v1

> 更新时间：2026-04-23
>
> 上位依据：
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/process/5-5-page-aggregate-single-truth-alignment-v1.md`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-6-page-aggregate-alignment-checklist-v1.md`
> - `/mnt/Data1T/mnote/design/old/07-ai/process/7-phase7-ai-kernel-projection-plan-v4.md`
> - `/mnt/Data1T/mnote/design/07-ai/done/7-1-phase7-document-ai-minimum-loop-checklist-v1.md`
>
> 2026-05-05 追加说明：
> - 本稿的对象模型、artifact 写链与 kernel 边界仍然有效
> - 当时触发与执行口径曾被 `/mnt/Data1T/mnote/design/old/07-ai/process/7-phase7-ai-kernel-projection-plan-v4.md` 覆盖
> - 该 `mnote-cli` host 口径现已被 2026-05-13 的 Hermes 面板主线覆盖
>
> 2026-05-13 追加说明：
> - 本稿的对象模型、artifact 写链、projection-only `AI Artifacts` 分组与 kernel 边界继续有效
> - 触发与执行口径改由 `/mnt/Data1T/mnote/design/07-ai/done/7-3-page-ai-hermes-panel-and-mnote-plugin-v1.md` 覆盖
> - 当前凡是提到“页面 AI 面板触发”或“页面 AI host 固定动作”的位置，都应理解为：
>   页面 AI 面板作为 Hermes 页面内客户端发起意图，Hermes 通过 mnote skill/plugin 调用正式 artifact 工具，最终写入仍回到 Rust runtime / kernel

---

## 1. 文档目的

这份稿只回答一个问题：

> **在文档页 AI 最小闭环已经完成之后，`summary node / ai_note node / reference edge` 这三条结构化知识写链，第一版到底如何落地，才能既进入 kernel，又不重新污染页面树、文件树和页面主链。**

当前不写这份稿，后续最容易出现两类跑偏：

- 把 `summary / ai_note` 继续做成 AI 面板里的临时聊天产物，而不是 kernel node
- 为了让文件树看见它们，额外发明一个 `AI Artifacts` 真容器节点，重新污染树真相

因此本稿的目标不是“做完整 AI 平台”，而是：

> **只把 `summary node / ai_note node / reference edge` 这三条结构化写链，收口成第一版可执行、可验证、可继续扩展的最小实现。**

---

## 2. 当前结论

第一版固定采用下面这组边界，不再开放：

1. 只做三类结构对象：
   - `summary node`
   - `ai_note node`
   - `reference edge`
2. 只允许围绕**当前文档页**创建，不做跨页、跨工作区写链
3. 第一版允许页面 AI 面板提供固定快捷入口，但快捷入口本质是向 Hermes 发送意图；Hermes 通过 mnote skill/plugin 调用 artifact 工具，不再由页面 AI host 或 `mnote-cli` host 私有触发
4. 点击按钮后直接创建，不走“先预览再确认”的两阶段流
5. `summary node` 默认单例覆盖更新；`ai_note node` 每次新建
6. 两者都落成**可编辑的页面型节点**
7. 文件树可见，页面树默认不可见
8. 文件树中的 `AI Artifacts` 只是 projection-only 的虚拟分组，不是新的真实 kernel node
9. 每次创建 `summary node` 或 `ai_note node` 时，自动连一条指向当前页的 `reference edge`

一句话收口：

> **第一版不是让 AI 自由生长“知识图谱”，而是让当前页能够稳定产出两类正式 artifact node，并带上一条最小来源边。**

---

## 3. 为什么第一版只做这三条

### 3.1 这是从“正文写链”走向“结构写链”的最小跨越

当前 `7-1` 已经完成的是：

- AI 读取当前页 page aggregate 上下文
- AI 通过 `page.head.updateTitle / page.body.save` 回写标题和正文

但这仍然只是在“改当前页”。

如果要让 AI 真正进入 `tree-first graph kernel`，第一步不应该直接跳到：

- 跨页知识网
- PDF / Book 结构化摄取
- 完整 index node / retrieval 主线

而应先从三条最小结构写链开始：

- 为当前页生成一个 `summary node`
- 为当前页生成一个 `ai_note node`
- 把它们用 `reference edge` 连回当前页

### 3.2 这三条最适合当前主线边界

这三者同时满足：

- 与当前页 AI 主链直接相邻
- 不要求跨页权限扩展
- 不要求额外引入新的树真相层
- 能直接复用当前的 page aggregate 上下文
- 能验证 `typed node / typed edge` 进入产品主线，而不是继续只停在文档里

### 3.3 `PDF / Book -> kernel index` 当前必须继续后置

`kernel index` 第一版不并入本稿，原因很明确：

- 它依赖更稳定的摄取边界
- 它会引入更重的异步任务与检索协议
- 它不是当前页 AI host 面板的最小邻接能力

所以本稿故意不把阶段 5 全写成一个“大包”，而是只切出：

> **当前页 -> artifact node / reference edge**

---

## 4. 对象模型

第一版真正进入 kernel 的对象只有三类。

### 4.1 `summary node`

`summary node` 是一个真实的 `KernelNode`，`node_type = summary`。

它的产品语义固定为：

- 它代表“当前页的最新摘要页”
- 它不是聊天消息
- 它不是页面内一段临时 block
- 它是可编辑页面型节点，但语义上属于 artifact

它的最小数据要求：

- `node_type = summary`
- `workspace_id = 当前页 workspace`
- `metadata.title = 当前页标题 + Summary`
- `content = 可被页面主编辑区消费的正文载荷`
- `refs.reference_node_ids` 至少包含当前页 `pageId`
- `refs.source_node_ids` 至少包含当前页 `pageId`
- `audit` 带最小 request / trace / actor 信息

### 4.2 `ai_note node`

`ai_note node` 也是一个真实的 `KernelNode`，`node_type = ai_note`。

它的产品语义固定为：

- 它代表“围绕当前页生成的一份 AI 工作笔记页”
- 它不是摘要快照
- 它允许后续继续人工编辑
- 它是页面型节点，但语义上属于 artifact

它的最小数据要求：

- `node_type = ai_note`
- `workspace_id = 当前页 workspace`
- `metadata.title = 当前页标题 + AI Note + 时间戳/序号`
- `content = 可被页面主编辑区消费的正文载荷`
- `refs.reference_node_ids` 至少包含当前页 `pageId`
- `refs.source_node_ids` 至少包含当前页 `pageId`
- `audit` 带最小 request / trace / actor 信息

### 4.3 `reference edge`

`reference edge` 在第一版里不新增新的 edge type 名字，先收口到现有 `KernelEdgeType::References`。

它的产品语义固定为：

- 表示 artifact node 引用了当前页
- 它不是父子边
- 它不进入页面树 / 文件树
- 它只进入关系层 / 引用层 /后续 graph traversal

第一版边方向固定为：

- `from_node_id = artifact node`
- `to_node_id = 当前页 node`
- `edge_type = references`

这样可以稳定表达：

> **这个 summary / ai_note 是围绕当前页生成的。**

### 4.4 `AI Artifacts` 不是对象，只是投影分组

第一版明确禁止把 `AI Artifacts` 做成真实 node。

它只允许存在于：

- 文件树 projection
- 可能的 Inspector / artifact 列表 projection

它不允许存在于：

- kernel node truth
- tree command truth
- page aggregate truth

理由很简单：

- 它只是展示分组
- 它不是用户真正的知识对象
- 它不应反向塑造树真相

---

## 5. 写入语义

### 5.1 统一动作面

第一版只开放两个显式动作：

- `create_summary_artifact_for_current_page`
- `create_ai_note_artifact_for_current_page`

这里先用产品动作名描述，不在本稿中强行冻结底层最终 route/path 名。

长期原则固定为：

- 它们必须进入 Rust runtime / bridge-runtime 主写链
- 不允许绕过 kernel 直接只写前端本地状态
- 不允许只停留在 AI 面板会话日志里

### 5.2 `summary node` 的写入策略

`summary node` 第一版采用**单例覆盖更新**。

固定规则：

1. 先按“当前页 -> artifact node_type = summary”查询是否已有 summary node
2. 若已存在：
   - 复用该节点 `node_id`
   - 覆盖其 `content`
   - 更新其 `metadata.updated_at`
   - 保留其页面型身份
3. 若不存在：
   - 新建一个 `summary node`
   - 自动附加到当前页的 artifact projection 分组下
   - 自动创建一条 `reference edge`

为什么 `summary` 采用单例：

- 它更像“当前页最新摘要”
- 否则文件树下会快速积累多份摘要页
- 第一版要先控制 artifact 数量，而不是先保留完整历史

### 5.3 `ai_note node` 的写入策略

`ai_note node` 第一版采用**每次新建**。

固定规则：

1. 每次点击 `创建 AI Note` 都新建一个 `ai_note node`
2. 标题默认带时间戳或递增序号
3. 创建后自动创建一条 `reference edge`
4. 不尝试合并、覆盖旧 `ai_note`

为什么 `ai_note` 采用多实例：

- 它更像工作产物
- 一次次 AI 分析、本轮整理、本轮方案，本来就可能并存
- 如果也做成单例，会过早丢失工作过程

### 5.4 来源边写入策略

创建 `summary node` 或 `ai_note node` 时，自动写一条 `reference edge`。

第一版不要求用户再单独确认，也不要求额外按钮。

这条边的作用不是“展示炫酷图谱”，而是保证两个基本能力：

1. 后续能追溯这个 artifact 来源于哪一页
2. 后续文件树/关系面板/graph traversal 不需要重新猜测来源

### 5.5 第一版不做的写入动作

第一版明确不做：

- artifact -> 多来源页面的复合引用
- artifact -> 块级 evidence 的精细挂接
- 跨页创建 summary / ai_note
- 人工拖拽 artifact 重新挂到别的页面
- artifact 自动进页面树

这些都属于第二版以后再做的能力。

---

## 6. 触发方式与产品入口

### 6.1 允许固定按钮触发，但必须经过 Hermes

第一版允许页面 AI 面板提供两个固定快捷按钮：

- `创建 Summary`
- `创建 AI Note`

但按钮不得绕过 Hermes 或 mnote plugin 直接写入。正确链路是：

```text
Leptos 页面 AI 面板
  -> Hermes session/run
  -> mnote Hermes skill/plugin
  -> Rust runtime / kernel
  -> artifact node / reference edge
```

自然语言触发可以作为后续能力加入，但第一版验收仍以固定按钮或固定 tool intent 为准，避免 artifact 写链质量和权限边界同时失控。

### 6.2 点击后直接创建

第一版点击按钮后，直接创建，不走预览确认。

这是一个非常明确的产品取舍：

- 优点：动作和结果一一对应，最容易验证主写链
- 缺点：产物质量控制不如“先预览再落库”

当前优先级里，第一版更重视：

- 正式写链成立
- kernel node / edge 成立
- 文件树 projection 成立
- Hermes tool call -> mnote plugin -> Rust kernel 的边界成立

而不是先做复杂的人机审核流。

### 6.3 内容来源固定为当前页全文

第一版两个按钮的内容来源都固定为：

- 当前页全文

不做：

- 仅选区生成
- 仅当前可见块生成
- 混入会话消息做额外上下文真相

这能确保第一版边界足够清楚：

> **artifact 是围绕当前页全文生成，而不是围绕聊天面板局部状态生成。**

---

## 7. 文件树 projection 与页面树隐藏规则

### 7.1 页面树默认不可见

`summary node` 与 `ai_note node` 第一版默认不进入页面树 projection。

原因：

- 页面树是日常导航主链
- artifact 进入页面树会明显污染日常使用
- 它们虽然是页面型节点，但不是“用户正常页面层级”的一部分

### 7.2 文件树可见

`summary node` 与 `ai_note node` 第一版可以在文件树 projection 中可见。

这样做的目的不是把文件树变成第二个知识图谱，而是保留一个“必要时可管理”的管理入口。

### 7.3 `AI Artifacts` 虚拟分组规则

在文件树 projection 中，为每个当前页生成一个 projection-only 分组：

- `AI Artifacts`

固定规则如下：

1. 它不是真实 node
2. 它不持久化到 kernel
3. 它只存在于 `file_tree` projection 结果中
4. 它的 children 由“当前页关联的 artifact nodes”动态投影得出

### 7.4 文件树中的相对位置

第一版推荐把 `AI Artifacts` 放在当前页下面，但与普通子页面分区显示。

不是：

- artifact 混在普通子页面列表里

而是：

- 当前页
  - 普通文件/子页
  - `AI Artifacts`
    - `Summary`
    - `AI Note 2026-04-23 10:31`
    - `AI Note 2026-04-23 10:46`

这样既满足“文件树可管理”，又最大限度避免污染普通导航。

### 7.5 `reference edge` 不进树

`reference edge` 永远不是树项。

它应只进入：

- 关系面板
- 引用面板
- graph traversal
- 后续结构阅读态

它不允许伪装成页面树 / 文件树节点。

---

## 8. 与当前主链的关系

### 8.1 不改变当前页主编辑区真相

第一版 artifact 写链不会改变：

- 当前页正文依然走 `page.body.save`
- 当前页标题依然走 `page.head.updateTitle`
- 当前页页面设置依然走 `page.layout.updateOptions`

artifact 写链是新增的结构写链，不是对当前页主链的替代。

### 8.2 与 page aggregate 的关系

第一版 artifact 生成必须依赖当前 page aggregate 上下文，但不把 artifact 自身并入当前页的 page aggregate truth。

也就是说：

- page aggregate 提供生成材料
- artifact 是新的 kernel node
- artifact 不是当前页 `page_body` 的附属字段

这是必须守住的边界，否则又会回到“把结构对象塞进页面壳状态”的旧路。

### 8.3 与 tree command 的关系

artifact node 虽然默认不进页面树，但它们仍然是 tree-first graph kernel 的真实 node。

因此长期上仍应可复用：

- `kernel.node.get`
- `kernel.subtree.get`
- `kernel.edges.list`
- `kernel.edge.attach`

但第一版不要求把 artifact 的全部树命令交互一次做完。

---

## 9. 最小实现分层

### 9.1 Kernel / Rust runtime 层

需要补的最小能力：

1. 创建 `summary node`
2. 更新现有 `summary node`
3. 创建 `ai_note node`
4. 创建 `references` edge
5. 按当前页查找其关联 artifact nodes

第一版不要求完整 artifact 生命周期，只要求：

- create
- update summary
- list by current page relation

### 9.2 Projection 层

需要补的最小能力：

1. `file_tree` projection 能识别“当前页关联的 artifact nodes”
2. 在 projection 里注入一个虚拟 `AI Artifacts` 分组
3. 页面树 projection 不注入该分组

### 9.3 前端文档页层

需要补的最小能力：

1. 页面 AI 面板显示两个固定按钮
2. 点击按钮后触发相应写入动作
3. 创建完成后，文件树对应 projection 刷新
4. 若新建了 `ai_note node`，允许点击进入该页面
5. 若更新了 `summary node`，允许点击进入摘要页

---

## 10. 验证口径

第一版完成，至少要满足以下验证。

### 10.1 Summary 链

- 当前页点击 `创建 Summary`
- 若不存在 summary node，则新建
- 若已存在，则覆盖更新
- 文件树中当前页下出现或保留 `AI Artifacts / Summary`
- 页面树中不出现该节点
- 可打开该 `summary node`
- kernel 中存在从 `summary node -> 当前页` 的 `references` edge

### 10.2 AI Note 链

- 当前页点击 `创建 AI Note`
- 每次都新建一个新的 `ai_note node`
- 文件树中当前页下 `AI Artifacts` 分组内累积出现新节点
- 页面树中不出现这些节点
- 可打开新建的 `ai_note node`
- kernel 中存在从 `ai_note node -> 当前页` 的 `references` edge

### 10.3 真相边界

- `AI Artifacts` 不出现在真实 kernel node 列表中
- `AI Artifacts` 只存在于文件树 projection 结果中
- 当前页 page aggregate 不被额外塞入 artifact truth
- artifact 不混入普通页面树导航主链

---

## 11. 明确不做什么

第一版明确不做：

- 自然语言隐式触发 artifact 创建
- 跨页 summary / ai_note 写链
- artifact 多来源引用
- block 级 evidence 精细挂接
- `AI Artifacts` 真实容器节点化
- artifact 进入页面树默认主链
- artifact 复杂权限模型
- artifact 预览确认流
- artifact 版本历史产品壳

---

## 12. 最终冻结口径

当前冻结如下：

> **阶段 5 的第一版，只把 `summary node / ai_note node / reference edge` 作为最小结构化知识写链落到 kernel。**

> **`summary node / ai_note node` 都是真实页面型 kernel node，`reference edge` 使用现有 `references` typed edge；`AI Artifacts` 只是文件树 projection 下的虚拟分组，不是真实对象。**

> **第一版只允许围绕当前页，通过页面 AI 面板固定按钮直接触发；`summary node` 单例覆盖更新，`ai_note node` 每次新建；创建节点时自动连一条指向当前页的 `reference edge`。**

一句话收口：

> **第一版的目标不是做“大而全 AI 知识层”，而是让当前页第一次稳定地产出正式 artifact node，并且能在不污染页面树真相的前提下进入文件树管理视图。**
