Files
memind/docs/mindspace-boundary-audit-20260702.md
T
2026-07-02 21:03:14 +08:00

7.3 KiB

MindSpace 解耦 P0 边界审计

日期: 2026-07-02

分支: codex/mindspace-decouple-20260702

目标:

  • 找出当前代码中直接依赖 MindSpace 物理路径、公开 URL、agent sandbox policy、MindSpace DB 表的边界点。
  • 为后续 P1 MindSpaceService、P2 conversation package、P3 独立进程拆分提供改造顺序。
  • 本文只做审计和分层,不改变运行行为。

1. 审计结论

当前 MindSpace 已经具备资产、页面、发布、agent job 的基础模型,但边界仍混在 Portal 单体里:

  • 物理 workspace 路径由 user-publish.mjsuser-space.mjsserver.mjscapabilities.mjs 共同参与。
  • 公开 URL 由 user-publish.mjsmindspace-assets.mjsmindspace-publications.mjsserver.mjs 等处生成或修正。
  • Agent sandbox policy 仍以 sandboxRoot / SANDBOX_ROOT 为核心契约。
  • DB 层已有 h5_page_records.source_session_idh5_page_records.source_message_idh5_agent_jobs.session_id,但 h5_assets 还缺 conversation provenance。
  • 现有回归守卫重点保护 public/*.html materialize、Finish merge、用户消息内部前缀隐藏,这些路径后续改造时不能绕过。

架构判断:

  • P1 先抽 MindSpaceService 和 storage adapter 边界,不拆进程。
  • P2 先落 conversation package 元数据和 manifest,不立即替换所有文件路径。
  • P3 以后再把 MindSpace Service 独立进程化。
  • 103/105 只作为生产部署说明,不作为开发或架构依赖。

2. 物理路径边界

核心文件:

文件 当前职责 风险 P1 处理方式
user-publish.mjs PUBLISH_ROOT_DIR = MindSpace、用户发布目录、公开 URL helper、skill 约束文本 URL 和路径耦合在同一层 保留兼容 helper,但新代码走 MindSpaceService URL/storage 接口
user-space.mjs MINDSPACE_STORAGE_ROOT、workspace 分区、上传镜像、agent hints workspace 和 asset storage 同时出现 把 storage root、workspace root 分离为 adapter 能力
server.mjs watcher、static route、shared upload、public serving Portal 直接掌握所有路径 P1 先集中成 MindSpace route/service facade
mindspace-sandbox-mcp.mjs OS 层 SANDBOX_ROOT 文件操作 Goose 以 raw fs path 作为契约 P4 改成 workspaceRef / packageId,短期保留兼容
capabilities.mjs 注入 sandbox MCP env 和 args policy 直接依赖 sandboxRoot 新增 policy adapter,避免业务层自己拼 path

主要路径形态:

MindSpace/<userId>/public/*.html
MindSpace/<userId>/oa/*
data/mindspace/users/<userId>/*
SANDBOX_ROOT=<absolute workspace path>
MINDSPACE_STORAGE_ROOT=<absolute storage path>

3. URL 权威边界

核心文件:

文件 当前职责 风险 P1 处理方式
user-publish.mjs buildPublicUrl()buildPublicZonePageUrl() 调用方可能把 helper 当长期权威 标记为 legacy compatibility,新增 canonical URL service
mindspace-assets.mjs public temp image URL asset public URL 与 storage key 绑定 改成 MindSpaceService.createPublicAssetUrl()
mindspace-publications.mjs publication response、public URL、标准图片替换 发布 URL 权威分散 publication canonical URL 统一收口
server.mjs /MindSpace/* route、redirect、shared upload public URL Express route 同时做 URL 修复和文件服务 route 仅调用 MindSpace service facade
mindspace-chat-save.mjs 修正聊天中的 MindSpace 链接 后续仍需兼容旧 URL 保留兼容,新增 canonicalize API

短期规则:

  • 不删除旧 URL helper。
  • 新增代码不得直接拼 /MindSpace/<userId>/...
  • 所有新 public URL 生成必须经过 MindSpace service facade。

4. Agent Policy 边界

核心文件:

文件 当前职责 风险 P1/P4 处理方式
capabilities.mjs 将 sandbox MCP 注入 Goose extension policy 里暴露 raw path 先增加 policy builder 边界,后续改 workspaceRef
mindspace-agent-runner.mjs agent job claim 后创建 goosed 运行上下文 job 与 workspace/path/publish layout 混合 job runner 改为请求 MindSpace workspace capability
user-space.mjs hints 中告诉 agent 目录和公开链接格式 agent 直接学习物理路径 hints 改为逻辑 workspace + 兼容说明
mindspace-sandbox-mcp.mjs read/write/edit/create_dir 只能处理 filesystem backend 后续新增 MindSpace MCP bridge

长期 policy 目标:

{
  "mindspace": {
    "workspaceRef": "mindspace://users/<userId>/conversations/<sessionId>",
    "packageId": "cp_xxx",
    "apiBaseUrl": "https://mindspace.example.com",
    "accessToken": "scoped-short-lived-token"
  }
}

5. DB 和 Provenance 边界

已有基础:

  • h5_assets: asset 基础元数据,当前没有 source_session_idsource_message_idsource_run_id
  • h5_asset_versions: storage_key 是当前 asset 到物理存储的主要桥。
  • h5_page_records: 已有 source_session_idsource_message_idsource_asset_id
  • h5_page_versions: 已有 source_snapshot_json,可承载页面生成时的上下文。
  • h5_publish_records: 保存 public_url,是公开 URL 现有权威记录。
  • h5_publication_asset_refs: publication 与 asset 引用关系。
  • h5_agent_jobs: 已有 session_idresult_page_idresult_asset_id
  • h5_agent_runs: 已有 agent_session_idrequest_id

缺口:

  • 没有 conversation package 表。
  • 没有 package 与 asset/page/publication/job/message 的统一 artifact 关系表。
  • Asset 层没有完整对话来源,导致“这次对话生成了哪些文件”只能间接推断。

建议新增:

  • h5_conversation_packages
  • h5_conversation_artifacts

过渡策略:

  • 先通过 h5_page_records.source_session_idh5_agent_jobs.session_id 回填页面/任务。
  • 新增 asset 时尽量携带 session_idmessage_idrun_id 到 artifact 表。
  • 不急着修改旧 asset schema,优先用 junction table 降低迁移风险。

6. 回归守卫

后续改这些区域前必须跑:

npm run verify:mindspace-publish-guards
npm run verify:mindspace-publish-guards:full

重点保护:

  • mindspace-public-finish-sync.mjs: edit_file 必须 materialize 到 public/*.html
  • chat-finish-sync.mjs: Finish / UpdateConversation 必须 merge,禁止盲覆盖。
  • conversation-display.mjssrc/utils/message.ts: 用户消息不得展示 routing/skill 内部前缀。
  • src/hooks/useTKMindChat.ts: syncSessionMessages merge + retry。
  • server.mjs: session snapshot 缓存必须保守。

7. 第一阶段落点

P1 最小代码目标:

  • 新增 MindSpaceStorageAdapter 契约和 local fs adapter 包装层。
  • 新增 canonical public URL facade。
  • 新增 conversation package manifest 纯函数。
  • 先不替换现有 route,不改生产行为。

P2 最小产品目标:

  • 为每个 chat session 懒创建 package。
  • 新上传文件、生成文件、页面、发布记录写入 artifact 归属。
  • H5 增加 package view。
  • 历史数据 best-effort 回填。

本轮已经开始的安全基线:

  • 当前工作必须在 codex/mindspace-decouple-20260702
  • main 本地 pre-commit 已阻止直接提交。
  • 不允许把 103 作为本地开发依赖。