444 lines
13 KiB
Markdown
444 lines
13 KiB
Markdown
# 3-4 [done] mnote-web `3104` 边界收口与退役方案 v1
|
||
|
||
> 更新时间:2026-04-23
|
||
>
|
||
> 关联文档:
|
||
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
|
||
> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`
|
||
> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-rust-web-long-term-architecture-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/process/5-5-page-aggregate-single-truth-alignment-v1.md`
|
||
|
||
## 1. 文档目的
|
||
|
||
这份文档只回答一个已经进入架构层的问题:
|
||
|
||
> **当前 `127.0.0.1:3104` 还有没有存在意义,是否应从系统主链中移除。**
|
||
|
||
先给结论:
|
||
|
||
> **`3104` 不应该继续作为用户、浏览器、前端 runtime 可感知的端口存在。**
|
||
>
|
||
> **在当前代码基线上,它已经不再是默认开发链、前端主链或 AI 主链的必需端口;`mnote-web` 若仍启动,也应退回为显式 debug/internal runtime。**
|
||
|
||
因此当前正确目标不是:
|
||
|
||
- 继续接受多端口长期并存
|
||
- 或者为了“看起来只剩 3000”而直接硬删 `3104`
|
||
|
||
而是:
|
||
|
||
> **先把 `3104` 收口为 internal-only 边界,再按依赖拆解顺序逐步退役,最终让前端公开主链只剩 `3000`。**
|
||
|
||
## 1.1 完成结论
|
||
|
||
截至 2026-04-23,这份方案针对“`3104` 作为默认/公开边界”的收口已经完成,当前可固定为:
|
||
|
||
- `3000` 是唯一前端公开入口
|
||
- 正式主链已移除 `MNOTE_WEB_BASE_URL`、浏览器侧 `mnoteWebBaseUrl / mnoteWebTreeShellEnabled`
|
||
- `mnote-web` 默认监听地址已改为 `127.0.0.1:0`,不再默认绑定 `3104`
|
||
- `/tree`、`/document-debug` 等 debug 壳仅在显式环境变量下注册
|
||
- legacy smoke 只有在显式设置 `MNOTE_WEB_SMOKE_BASE_URL` 时才会命中 debug runtime
|
||
|
||
需要额外说明的是:
|
||
|
||
> **若本机仍看到 `127.0.0.1:3104` 监听,应视为旧 `mnote-web` 进程残留,不代表当前默认启动链。**
|
||
|
||
---
|
||
|
||
## 2. 当前真实状态
|
||
|
||
### 2.1 `3104` 当前是什么
|
||
|
||
`3104` 曾对应 Rust `mnote-web` 的默认监听地址,而不是首页入口端口。
|
||
|
||
当前 `mnote-web` crate 仍承载的能力包括:
|
||
|
||
- `/health`
|
||
- `/tree`
|
||
- `/document-debug`
|
||
- `/api/tree/commands`
|
||
- `/api/stream/events`
|
||
- `/api/hermes/bridge`
|
||
- `/api/compat/next/sidebar`
|
||
|
||
这说明它不是单纯“没人用的历史残留壳”,而是:
|
||
|
||
> **一个仍保留 debug / compat / internal transport 能力的 Rust Web 组件。**
|
||
|
||
### 2.2 当前真正的问题不在“它存在”,而在“它泄漏”
|
||
|
||
当前最不应该发生的事情,不是 `mnote-web` 作为内部服务存在,而是:
|
||
|
||
- 浏览器 runtime 直接知道 `mnoteWebBaseUrl`
|
||
- 前端页面逻辑直接拼 `3104`
|
||
- smoke / 调试脚本把 `3104` 当成正式主入口前提
|
||
- 新功能继续优先接到 `mnote-web compat` 路由
|
||
|
||
换句话说,问题的关键不是:
|
||
|
||
> “有没有本机内部回源端口”
|
||
|
||
而是:
|
||
|
||
> “这个内部回源边界是否继续污染前端主链与长期架构”。
|
||
|
||
### 2.3 当前已经完成的一次收口
|
||
|
||
当前已经确认完成的收口包括:
|
||
|
||
- 浏览器公开 runtime 不再暴露 `mnoteWebBaseUrl`
|
||
- Sidebar tree stream 浏览器侧统一走同源 `3000/api/mnote-web/stream`
|
||
- `public/mnote-env.json` 不再公开 `mnoteWebBaseUrl`
|
||
- AI orchestrator 主链已不再依赖 `MNOTE_WEB_BASE_URL`
|
||
- 默认开发链不再启动或要求 `mnote-web:3104`
|
||
- legacy smoke 不再默认指向 `3104`,必须显式传入 debug runtime 地址
|
||
- `mnote-web` 默认监听地址已不再固定为 `127.0.0.1:3104`
|
||
|
||
因此现在的架构判断应改写为:
|
||
|
||
> **`3000` 已经是前端唯一公开主入口,而 `3104` 已从默认边界退回到显式 debug/internal-only。**
|
||
|
||
---
|
||
|
||
## 3. 为什么现在还不能直接删除 `3104`
|
||
|
||
当前已经不再存在正式产品链必须依赖 `3104` 的情况,但仍保留三类遗留能力面需要继续降级:
|
||
|
||
### 3.1 Tree realtime contract 仍未完全对齐最终主链协议
|
||
|
||
当前 `3000/api/mnote-web/stream` 已不再回源 `mnote-web /api/stream/events`,但它仍是一个 Next route 级的过渡 transport,而不是最终的统一 realtime 主链。
|
||
|
||
因此当前现实不是:
|
||
|
||
- `3000` 已经原生持有 tree realtime transport
|
||
|
||
而是:
|
||
|
||
- `3000` 已完成对 `3104` 的切断
|
||
- 正式 realtime contract 仍需继续向 `snapshot / delta / resync` 单一主链收口
|
||
|
||
### 3.2 Hermes / AI tool registry 归属仍需继续收口
|
||
|
||
当前前端 AI route 与后端 `openai-agents-python` 编排层已经不再通过 `MNOTE_WEB_BASE_URL` 回源 `mnote-web /api/hermes/bridge` 获取 runtime tool 结果,而是走后端 orchestration + 本地 `bridge-runtime`。
|
||
|
||
这意味着:
|
||
|
||
- `3104` 已不再阻塞 AI 主链
|
||
- 但 AI tool registry / tool result contract 的正式归属还需继续明确
|
||
|
||
### 3.3 仍保留实验 / 调试 / compat 壳
|
||
|
||
以下链路仍带有明显过渡期性质:
|
||
|
||
- `/tree`
|
||
- `/document-debug`
|
||
- `compat/next/sidebar`
|
||
- 旧 smoke 脚本仍可在显式传入 runtime 地址后命中 debug runtime
|
||
- `/api/auth/mnote-web-token` 仍保留给 legacy debug/runtime smoke
|
||
|
||
这些路径已不在当前主路径上,但说明:
|
||
|
||
> **`mnote-web` 仍处于“内核能力 + compat + 调试壳”混杂状态。**
|
||
|
||
在这种状态下直接删掉全部 debug/runtime 入口,会丢失排障和对照手段;因此当前应做的是“默认退役 + 显式 debug 化”,而不是直接物理删除所有相关代码。
|
||
|
||
---
|
||
|
||
## 4. 当前必须立即固定的架构口径
|
||
|
||
### 4.1 对用户与浏览器的公开口径
|
||
|
||
当前必须固定为:
|
||
|
||
- 页面访问入口只有 `3000`
|
||
- 浏览器不得显式依赖 `3104`
|
||
- 前端公开 runtime / public config 不得再暴露 `mnoteWebBaseUrl`
|
||
|
||
### 4.2 对系统内部的口径
|
||
|
||
当前必须固定为:
|
||
|
||
- `3104` 只允许作为 loopback internal service 存在
|
||
- 它不是产品入口
|
||
- 它不是长期对外 contract
|
||
- 它只是 Rust Web transport 尚未并入最终主链前的内部边界
|
||
|
||
### 4.3 对未来收口方向的口径
|
||
|
||
当前必须固定为:
|
||
|
||
> **长期目标不是保留 `3000 + 3104` 双长期入口,而是把 `3104` 承担的正式能力迁走,最终退役 `3104`。**
|
||
|
||
---
|
||
|
||
## 5. 需要立即回退或禁止继续扩散的方向
|
||
|
||
下面这些方向应该立即视为错误方向:
|
||
|
||
### 5.1 禁止浏览器继续读取 `mnoteWebBaseUrl`
|
||
|
||
包括但不限于:
|
||
|
||
- 浏览器组件中直接构造 `http://127.0.0.1:3104`
|
||
- 通过 runtime config 让前端知道 `mnote-web` 基址
|
||
- 新页面逻辑绕过同源 `3000`,直接访问 `3104`
|
||
|
||
### 5.2 禁止把新长期业务继续堆进 `compat`
|
||
|
||
尤其不能继续把以下长期语义放进 `mnote-web compat`:
|
||
|
||
- 正式 sidebar 数据 contract
|
||
- 正式 page aggregate contract
|
||
- 正式 tree realtime contract
|
||
- 正式 AI tool orchestration contract
|
||
|
||
`compat` 只能继续承担:
|
||
|
||
- 过渡转接
|
||
- 旧链路对照
|
||
- fixture / smoke 支持
|
||
|
||
不能继续成为新增长期业务的落点。
|
||
|
||
### 5.3 禁止把 `/tree` 与 `/document-debug` 当成正式页面主链
|
||
|
||
它们可以保留为:
|
||
|
||
- 实验壳
|
||
- 调试入口
|
||
- 迁移对照入口
|
||
|
||
但不能继续被当成:
|
||
|
||
- 首页入口前置条件
|
||
- 正式文档页 transport
|
||
- 页面内主编辑区 runtime 壳
|
||
|
||
### 5.4 禁止新 smoke 把 `3104` 当产品主链前提
|
||
|
||
后续 smoke 要区分两类:
|
||
|
||
- `3000` 主站 smoke
|
||
- `mnote-web` 内部服务 smoke
|
||
|
||
不能再写成:
|
||
|
||
> “只要功能涉及 Rust,就默认直接打 `3104`”
|
||
|
||
---
|
||
|
||
## 6. `3104` 退役的阶段方案
|
||
|
||
## 6.1 Phase 0:公开边界收口
|
||
|
||
目标:
|
||
|
||
- 前端主链只公开 `3000`
|
||
- 浏览器不再感知 `3104`
|
||
- `3104` 收回 internal-only
|
||
|
||
当前状态:
|
||
|
||
- [x] 已完成
|
||
|
||
完成定义:
|
||
|
||
- [x] 浏览器公开 runtime 不再暴露 `mnoteWebBaseUrl`
|
||
- [x] Sidebar realtime 浏览器侧走同源 `3000/api/mnote-web/stream`
|
||
- [x] `public/mnote-env.json` 不再公开 `3104`
|
||
- [x] 浏览器主链已不再消费 `mnoteWebBaseUrl / mnoteWebTreeShellEnabled`
|
||
- [x] `public/mnote-env.json` 已去除 `mnoteWebTreeShellEnabled`
|
||
|
||
说明:
|
||
|
||
> 这一步解决的是“前端被多端口污染”的问题,不等于 `3104` 已退役。
|
||
|
||
## 6.2 Phase 1:把正式 sidebar/query 能力移出 `compat`
|
||
|
||
目标:
|
||
|
||
- `sidebar` 正式查询链不再依赖 `mnote-web /api/compat/next/sidebar`
|
||
- `3000` 直接消费 Rust bridge / kernel projection 正式 contract
|
||
|
||
当前状态:
|
||
|
||
- [x] 已完成
|
||
|
||
已完成:
|
||
|
||
- [x] `/api/sidebar` 已优先走 Rust bridge query,而不是继续扩 `compat sidebar`
|
||
- [x] 正式前端链路已不再调用 `fetchSidebarDatasetFromMnoteWeb`
|
||
|
||
已完成补充:
|
||
|
||
- [x] `compat/next/sidebar` 已明确降级为过渡 / 调试用途
|
||
- [x] 依赖 `compat sidebar` 的旧链路已收口为 legacy debug smoke,且必须显式传入 `MNOTE_WEB_SMOKE_BASE_URL`
|
||
|
||
## 6.3 Phase 2:tree realtime transport 正式并入主链
|
||
|
||
目标:
|
||
|
||
- `3000` 或其背后的正式服务直接承载 tree realtime contract
|
||
- 不再通过 Next route 反代 `3104 /api/stream/events`
|
||
|
||
当前状态:
|
||
|
||
- [x] 已完成
|
||
|
||
完成定义:
|
||
|
||
- [x] `3000` 的 tree stream 不再依赖 `MNOTE_WEB_BASE_URL`
|
||
- [ ] realtime stream contract 与 `3-3` 文档统一
|
||
- [ ] snapshot / delta / resync 成为正式主链,而不是代理式过渡链
|
||
- [x] `mnote-web /api/stream/events` 不再是前端主站 realtime 前置
|
||
|
||
备注:
|
||
|
||
> 这是 `3104` 能否退役的第一硬前提。只要 realtime stream 还在内部回源 `3104`,它就不能删除。
|
||
|
||
## 6.4 Phase 3:Hermes runtime bridge 从 `mnote-web` 迁出
|
||
|
||
目标:
|
||
|
||
- AI runtime tool bridge 不再强依赖 `MNOTE_WEB_BASE_URL`
|
||
- `openai-agents-python` 编排层与工具桥接边界收口到正式 AI 服务面
|
||
|
||
推荐方向:
|
||
|
||
- 由 `wolai-backend:8000` 持有 AI orchestration 正式入口
|
||
- Rust `bridge-runtime` 作为内核语义执行层
|
||
- `3000` 只负责页面与同源 API 边界,不再额外绕回 `3104`
|
||
|
||
当前状态:
|
||
|
||
- [x] 已完成
|
||
|
||
完成定义:
|
||
|
||
- [x] 前端 AI run route 不再通过 `mnote-web /api/hermes/bridge` 获取 tool 结果
|
||
- [x] 后端 `ai_document_agent.py` 不再把 `MNOTE_WEB_BASE_URL` 作为正式硬依赖
|
||
- [ ] AI tool registry / tool result contract 有独立正式归属
|
||
|
||
备注:
|
||
|
||
> 这是 `3104` 能否退役的第二硬前提。只要 AI tool bridge 还依赖它,它就不是可删除端口。
|
||
|
||
## 6.5 Phase 4:实验壳与调试入口降级
|
||
|
||
目标:
|
||
|
||
- `/tree`
|
||
- `/document-debug`
|
||
- 旧 `tree shell`
|
||
- 与 `3104` 直连的实验 host
|
||
|
||
全部明确降级为:
|
||
|
||
- debug only
|
||
- spike only
|
||
- legacy fallback only
|
||
|
||
当前状态:
|
||
|
||
- [~] 部分完成
|
||
|
||
完成定义:
|
||
|
||
- [x] 正式产品链不再依赖 `/tree`
|
||
- [x] 正式文档页不再依赖 `/document-debug`
|
||
- [x] 仍保留的实验组件不再混入默认主链
|
||
- [x] legacy smoke 已改为显式传入 `MNOTE_WEB_SMOKE_BASE_URL` 才会触发 debug runtime
|
||
- [x] `/tree` 与 `/document-debug` 已改成仅在显式 debug 开关下注册
|
||
|
||
已完成:
|
||
|
||
- [x] 浏览器侧 runtime config 不再兜底暴露 `mnoteWebBaseUrl`
|
||
- [x] `leptos_tiptap_iframe_debug` 不再通过 `mnoteWebBaseUrl` 推导调试 runtime 地址
|
||
- [x] `MnoteWebTreeShell` 已从前端正式代码路径移除
|
||
- [x] `mnote-web` 默认已不再注册 `/tree`、`/document`、`/document-debug`
|
||
|
||
## 6.6 Phase 5:正式退役 `3104`
|
||
|
||
当前状态:
|
||
|
||
- [x] 已完成
|
||
|
||
前提必须同时满足:
|
||
|
||
- [x] Sidebar / tree query 正式主链不再依赖 `compat sidebar`
|
||
- [x] tree realtime transport 已从 `3104` 迁出
|
||
- [x] Hermes runtime bridge 已从 `3104` 迁出
|
||
- [x] `/tree` 与 `/document-debug` 已降为非正式必需
|
||
- [x] 开发启动链不再要求单独拉起 `mnote-web:3104`
|
||
|
||
完成定义:
|
||
|
||
- [x] 默认开发工作流中不再需要 `3104`
|
||
- [x] `MNOTE_WEB_BASE_URL` 从正式主链配置中删除
|
||
- [x] `mnote-web` 若仍存在,则只作为显式 debug/internal app 运行,而不是长期内网网关
|
||
- [x] 运行态旧 `mnote-web:3104` 残留进程已清理;最新二进制默认启动不再监听 `3104`
|
||
|
||
说明:
|
||
|
||
> **`3-4` 的完成定义是退役 `3104` 作为默认/公开边界,不等于 `mnote-web`、tree realtime contract 或 AI tool registry 的所有后续演进已经结束。**
|
||
>
|
||
> **相关后续工作分别继续由 `3-3-rust-web-tree-realtime-event-stream-v1.md` 与 `07-ai` 主线承接,但它们不再构成 `3104` 退役阻塞。**
|
||
|
||
---
|
||
|
||
## 7. 推荐执行顺序
|
||
|
||
当前建议顺序固定为:
|
||
|
||
1. 完成 `Phase 2` tree realtime transport 收口
|
||
2. 完成 `Phase 3` Hermes runtime bridge 迁移
|
||
3. 完成 `Phase 4` 实验 / 调试壳降级
|
||
4. 最后执行 `Phase 5` 退役 `3104`
|
||
|
||
原因很简单:
|
||
|
||
- realtime 是前端主链的硬依赖
|
||
- AI bridge 是在线 AI 的硬依赖
|
||
- 调试入口最后再降级,避免迁移过程失去观测手段
|
||
|
||
---
|
||
|
||
## 8. 与 `8123` 的关系
|
||
|
||
`8123` 与 `3104` 不是同一类问题。
|
||
|
||
`8123` 当前更接近:
|
||
|
||
- spike runtime
|
||
- leptos-tiptap 独立开发端口
|
||
- 开发期资产构建 / 调试端口
|
||
|
||
而 `3104` 当前更接近:
|
||
|
||
- `mnote-web` 内部 transport 边界
|
||
- Rust Web 正式能力尚未完全并入主链前的内网服务
|
||
|
||
所以当前不应把两者混为一谈。
|
||
|
||
正确顺序是:
|
||
|
||
1. 先解决 `3104` 的正式能力迁移与边界退役
|
||
2. 再继续压缩 `8123` 这类 spike / dev runtime 端口
|
||
|
||
---
|
||
|
||
## 9. 一句话收口
|
||
|
||
当前关于 `3104` 的正确判断不是:
|
||
|
||
> “它已经没用了,可以直接删。”
|
||
|
||
也不是:
|
||
|
||
> “既然浏览器看不到,就可以长期保留。”
|
||
|
||
而是:
|
||
|
||
> **`3104` 现在仍有内部存在意义,但这种意义是过渡性的。当前必须把它严格收口为 internal-only,并以 tree realtime 与 AI runtime bridge 迁移为前提,最终退役。**
|