Files
mnote/design/old/08-legacy-rust-kernel/done/release-readiness-source-audit.md
T

9.8 KiB
Raw Blame History

[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() 统一生成 requestIdtraceIdworkspaceId
  • buildDocumentBridgeContextWithActor() 可为 ONLYOFFICE callback 这类无用户 cookie 的服务端回调显式注入 actor/source
  • buildDocumentCommandEnvelope() 统一挂载 commandIdtarget.pageId
  • documents.title/stats/options/save 均将 normalizedDocumentId 作为 target.pageId
  • onlyoffice/callback 会把 asset.document_id 作为 target.pageId,并透传 workspaceId

3.2 日志落账

  • recordBridgeCommandArtifacts() 使用同一 context.requestIdcontext.traceId
  • workspaceId 统一取 target.workspaceIdcontext.workspaceId
  • targetPageId 统一落到 command log
  • domain event payload 同时记录 request_idtrace_idcommand_idcommand_name

3.3 当前辅助验证

  • src/lib/documents/bridge.test.ts 已覆盖:
    • target.pageId = doc_1
    • executeSaveBridgeCommand 成功路径会调用 recordBridgeCommandArtifacts
    • 返回结果保留 req_1trace_1
  • src/app/api/onlyoffice/callback/route.test.ts 已覆盖:
    • callback 成功路径会调用 executeMediaAssetWritebackBridgeCommand
    • storageIdassetIddocumentIdworkspaceId 会进入 media.assets.replace_storage envelope

结论:

  • trace_idrequest_idworkspace_idpage_id 在 route、adapter、bridge log、回查入口之间已有统一口径。

4. 禁止事项复查

4.1 不双仓并行

  • 主仓脚本与文档已统一指向 /mnt/Data1T/mnote
  • wolai-frontend/srcwolai-frontend/convexrust/ 下未发现直接依赖 /mnt/Data1T/mnote-rust 的运行时代码路径

4.2 不跨仓链接

  • 排除 node_modules.next.venvrust/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.jsONLYOFFICE 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.tssrc/app/api/mindmap/[docId]/[mindmapId]/route.tsDELETE/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.tssrc/lib/documents/block-command-adapter.ts 应视为遗留兼容 helper,而非现网主执行面
  • src/app/api/ai-agent/run/route.ts 的核心工具主链现在已经统一走 Rust tool runtimedocs_searchdocs_readsearch_webimage_readslash_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 真实执行闭合。