# [recycle] 发布前源代码审计 > 更新时间:2026-04-16 > > 审计范围:`/mnt/Data1T/mnote` ## 1. Bridge 入口与日志回查 ### 1.1 最小查询与写入入口 当前已确认的 bridge 主线入口: - 查询: - `src/app/api/documents/content/route.ts` - `src/app/api/documents/meta/route.ts` - `src/app/api/sidebar/route.ts` - 写入: - `src/app/api/documents/title/route.ts` - `src/app/api/documents/stats/route.ts` - `src/app/api/documents/options/route.ts` - `src/app/api/documents/save/route.ts` - `src/app/api/blocks/patch/route.ts` - `src/app/api/onlyoffice/callback/route.ts` ### 1.2 日志与事件落账 当前已确认: - `src/lib/documents/metadata-command-adapter.ts` 成功路径会调用 `recordBridgeCommandArtifacts` - `src/lib/documents/save-command-adapter.ts` 成功路径会调用 `recordBridgeCommandArtifacts` - `src/app/api/blocks/patch/route.ts` 成功路径会调用 `recordBridgeCommandArtifacts` - `src/lib/documents/media-asset-command-adapter.ts` 会在 ONLYOFFICE callback 成功写回后尝试复用同一 bridge log 落账 - `src/lib/documents/bridge-log.ts` 会同时写入: - `bridgeLogs.recordCommandLog` - `bridgeLogs.recordDomainEvent` - 回查入口: - `src/app/api/bridge/request/route.ts -> bridgeLogs.listByRequest` - `src/app/api/bridge/trace/route.ts -> bridgeLogs.listByTrace` 结论: - bridge 的最小查询、最小写入、日志生成、事件生成和错误返回已经形成源码闭环。 ## 2. 保存口径审计 当前正文与页面元信息主写链如下: - `documents.save -> api.documents.updateContent` - `documents.title.update -> api.documents.updateTitle` - `documents.stats.update -> api.documents.updateStats` - `documents.options.update -> api.documents.updateOptions` - `blocks.patch -> 读取文档内容后回写 api.documents.updateContent` OnlyOffice 写回: - `src/app/api/onlyoffice/callback/route.ts -> media.assets.replace_storage -> api.mediaAssets.replaceStorageFromUpload` 结论: - 页面正文、页面元信息、块补丁与 OnlyOffice 附件写回最终都以 Convex mutation 为主事实写入点。 - 当前未发现把页面/块主真相改写到 `mnote-rust`、本地缓存目录或其他派生目录的主写链。 ## 3. `trace_id` / `request_id` / `workspace_id` / `page_id` 一致性 ### 3.1 前端与 route - `buildDocumentBridgeContext()` 统一生成 `requestId`、`traceId`、`workspaceId` - `buildDocumentBridgeContextWithActor()` 可为 ONLYOFFICE callback 这类无用户 cookie 的服务端回调显式注入 `actor/source` - `buildDocumentCommandEnvelope()` 统一挂载 `commandId`、`target.pageId` - `documents.title/stats/options/save` 均将 `normalizedDocumentId` 作为 `target.pageId` - `onlyoffice/callback` 会把 `asset.document_id` 作为 `target.pageId`,并透传 `workspaceId` ### 3.2 日志落账 - `recordBridgeCommandArtifacts()` 使用同一 `context.requestId`、`context.traceId` - `workspaceId` 统一取 `target.workspaceId` 或 `context.workspaceId` - `targetPageId` 统一落到 command log - domain event payload 同时记录 `request_id`、`trace_id`、`command_id`、`command_name` ### 3.3 当前辅助验证 - `src/lib/documents/bridge.test.ts` 已覆盖: - `target.pageId = doc_1` - `executeSaveBridgeCommand` 成功路径会调用 `recordBridgeCommandArtifacts` - 返回结果保留 `req_1`、`trace_1` - `src/app/api/onlyoffice/callback/route.test.ts` 已覆盖: - callback 成功路径会调用 `executeMediaAssetWritebackBridgeCommand` - `storageId`、`assetId`、`documentId`、`workspaceId` 会进入 `media.assets.replace_storage` envelope 结论: - `trace_id`、`request_id`、`workspace_id`、`page_id` 在 route、adapter、bridge log、回查入口之间已有统一口径。 ## 4. 禁止事项复查 ### 4.1 不双仓并行 - 主仓脚本与文档已统一指向 `/mnt/Data1T/mnote` - `wolai-frontend/src`、`wolai-frontend/convex`、`rust/` 下未发现直接依赖 `/mnt/Data1T/mnote-rust` 的运行时代码路径 ### 4.2 不跨仓链接 - 排除 `node_modules`、`.next`、`.venv`、`rust/target` 等构建产物后,主仓源码范围内未发现跨仓符号链接 ### 4.3 不复制第二套产品前端壳 - 主仓保留的是既有 `wolai-frontend` 主壳 - 历史仓对象页壳与第二套 sidebar 仅在文档中被标记为禁止误复制范围 ### 4.4 不把对象页壳 / diagnostics / smoke 页带入主线 - 当前主仓 `wolai-frontend/src/app` 下未发现新增的 `diagnostic` / `smoke` 页面目录 - 历史仓相关页面已在边界文档中明确列入禁止误复制清单 ### 4.5 不散落多个 Rust 源码根 - 主仓顶层 `Cargo.toml` 仅存在 `rust/Cargo.toml` - 其余 crate `Cargo.toml` 均位于 `rust/crates/*` ## 5. 运行态复核结果与最终结论 本审计只能关闭源码可验证项,但截至 2026-04-16,发布前运行态复核已经补齐五条直接证据: - 已复跑 `scripts/task019-document-ui-regression.js`,文档页标题、正文、保存、刷新、回查链通过。 - 已复跑 `scripts/task021-mindmap-ui-regression.js`,Mindmap 全屏页的新增子节点、删除子节点、保存链、刷新回查与 `requestId/traceId` 元信息同步通过。 - 已复跑 `scripts/task022-onlyoffice-ui-regression.js`,ONLYOFFICE `9.3.1` 基线下的打开、插件桥、callback 写回、forcesave 与 `storage_id` 变化通过。 - 已通过 `pnpm exec vitest run src/lib/ai-agent/runtime/runAgent.test.ts`,补齐 `docs_search -> docs_read` 的 AI runtime 调用证据。 - 已通过 `bash /mnt/Data1T/mnote/rust/scripts/task049-cli-smoke.sh`,补齐 CLI 主链的最小真实执行验收。 当前已不再存在阻塞发布的 CLI / AI 运行态尾项。 补充核验结果: - `cargo test --manifest-path /mnt/Data1T/mnote/rust/Cargo.toml -p mnote-cli -p bridge-runtime` 已通过。 - `wolai-frontend` 相关定向 `eslint` 当前无 error,仅剩仓库既有 warnings,不构成本轮发布阻塞。 仍然要求环境满足的前置条件: - 浏览器回归环境可访问 `http://127.0.0.1:3000` - `MNOTE_ONLYOFFICE_PROBE_DOCX=/tmp/mnote-onlyoffice-probe/probe.docx` 可用 - 已登录态可通过 `/auth` 或测试账号快速登录建立 ## 6. 旧 TS 执行面割接清单 当前源码审计之外,还需要看“哪些 TS route 还能留,哪些只是历史兼容”。 本轮已新增: - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md` 该文档已把主仓当前执行面明确分成四类: - `RUST_OWNER` - `TS_TRANSPORT_KEEP` - `TS_COMPAT_PENDING` - `TS_LEGACY_DELETE` 其中当前仍需要长期观察但不再构成主链阻塞的旧面主要包括: - `src/app/api/documents/embed/route.ts` - `src/app/api/mindmap-ai/**` 其中页面旧面在 2026-04-16 的最终口径如下: - `src/app/api/documents/create-child/route.ts` 已改走 `documents.create` - `src/app/api/documents/empty-trash/route.ts` 已改走 `documents.emptyTrashByWorkspace` - `src/app/api/documents/purge/route.ts` 已改走 `documents.purge` - `src/app/api/documents/template/route.ts` 已改走 `documents.template` - `src/app/api/documents/embed/route.ts` 已改走 `documents.save`,但目标页面插入位与 `pageReference` block 组装仍在 TS,因此继续按 `TS_COMPAT_PENDING` / 产品编排壳维护 - `src/app/api/mindmap/[docId]/route.ts` 与 `src/app/api/mindmap/[docId]/[mindmapId]/route.ts` 的 `DELETE/PATCH` 已改走 `mindmaps.delete/restore/purge` - `src/app/api/mindmap-trash/empty/route.ts` 已改走 `mindmaps.emptyTrashByWorkspace` - `src/app/api/blocks/*` 现网主链实际统一走 `src/lib/blocks/block-command-adapter.ts`;`src/lib/documents/block-command-adapter.ts` 应视为遗留兼容 helper,而非现网主执行面 - `src/app/api/ai-agent/run/route.ts` 的核心工具主链现在已经统一走 Rust tool runtime:`docs_search`、`docs_read`、`search_web`、`image_read`、`slash_run` 不再保留 TS 真执行兜底 结论: - 当前可以说“Rust 已成为 mnote 的主业务执行平面”。 - 仍保留的 TS 路径只剩 `TS_TRANSPORT_KEEP`、少量 `TS_COMPAT_PENDING` 产品编排壳与冻结的 `TS_LEGACY_DELETE` 清单。 - 第一批 `TS_LEGACY_DELETE` 已不再阻塞这轮 release readiness;它们现在的要求是“保持纯壳 / 冻结 helper,不允许反向长出新的业务规则”。 最终 release readiness 口径: - 若按源码审计口径:可以说明“Rust 已成为 mnote 的唯一业务执行平面”,同时明确仍保留 `TS_TRANSPORT_KEEP` 与少量产品编排壳。 - 若按完整发布口径:文档页、Mindmap、OnlyOffice、AI runtime、CLI smoke 的 Phase 8 scoped gate 已闭合,可以给出最终完成结论。 - 后续维护口径:剩余 `TS_TRANSPORT_KEEP` / `TS_LEGACY_DELETE` 只属于长期清理与边界维护,不再构成第二套业务执行平面。 补记: - 2026-04-15 已复跑 `scripts/task019-document-ui-regression.js`,确认文档页标题、正文、保存与刷新回查通过。 - 2026-04-15 已复跑 `scripts/task021-mindmap-ui-regression.js`,确认新增/删除节点、保存链、刷新回查与 `requestId` / `traceId` 元信息同步通过。 - 2026-04-15 已复跑 `scripts/task022-onlyoffice-ui-regression.js`,在升级后的 ONLYOFFICE `9.3.1` 基线上确认 `oo_insert_text` 插件桥、`同步保存`、callback 写回与 `storage_id` 变化仍然通过;本次 callback 最终写回已不再由 route 直接调用 `api.mediaAssets.replaceStorageFromUpload`,而是先经 `media.assets.replace_storage` bridge 命令再落到 Convex。 - 2026-04-16 已通过 `src/lib/ai-agent/runtime/runAgent.test.ts`,确认 `docs_search -> docs_read` 的运行态工具链顺序、事件流与结果归一化闭合。 - 2026-04-16 已通过 `rust/scripts/task049-cli-smoke.sh`,确认 `sidebar/page/block/search/tool/mindmap` 主链 CLI 真实执行闭合。