mindspace: close authority boundaries
This commit is contained in:
@@ -16,7 +16,8 @@
|
||||
| 位置 | 行为 |
|
||||
|------|------|
|
||||
| `mindspace-public-finish-sync.mjs` | `edit_file` 读取 baseline + `old_str`/`new_str` patch,再 `writeFileSync` 覆盖 |
|
||||
| `server.mjs` | Finish / SSE 流式事件调用 `materializePublicHtmlWritesFromSessionEvent` |
|
||||
| `mindspace-public-finish-service.mjs` | 在 MindSpace 内调用流式物化与最终 Finish sync,并生成 canonical URL |
|
||||
| `server/portal-session-routes.mjs` | Finish / SSE 流式事件只调用 `publicFinishService`,等待流式写入完成后再标记交付 ready |
|
||||
|
||||
### 守卫
|
||||
|
||||
@@ -25,6 +26,136 @@
|
||||
|
||||
---
|
||||
|
||||
## 1.1 Chat Save:HTML 修复与落盘权威必须在 MindSpace
|
||||
|
||||
### 必须保留
|
||||
|
||||
| 位置 | 行为 |
|
||||
|------|------|
|
||||
| `mindspace-chat-save-service.mjs` | 修复错误私有图片引用、物化私有图片并受限写回 `public/*.html`;预览缩略图生成与 sidecar 写入 |
|
||||
| `mindspace-chat-save-service.mjs` | quick share 的私有资源内联、`public/shared/*.html` 写入和 public URL 生成 |
|
||||
| `mindspace-server-adapter-contract.mjs` | `chatSaveService.materializeWorkspaceHtml`、`ensurePreviewThumbnail`、`renderPreviewThumbnailSvg`、`createSharedHtml`、`readWorkspaceHtml` 同时暴露给 local / remote adapter |
|
||||
| `server.mjs` | 只调用 `mindSpaceChatSave.materializeWorkspaceHtml`,禁止重新读取 `storageRoot` 或直接 `writeFile` |
|
||||
| `server/portal-mindspace-chat-save-routes.mjs` | 预览缩略图与分析/保存流程只调用 `getMindSpaceChatSave()`,禁止直接解析 `publishDir` 或调用 `ensureWorkspaceHtmlThumbnail` |
|
||||
| `server/portal-mindspace-chat-share-routes.mjs` | quick share 只调用 `createSharedHtml`;quick Plaza 的 workspace HTML 读取只调用 `readWorkspaceHtml`;禁止直接解析 publishDir、写文件、读取 storage root 或生成 public URL |
|
||||
|
||||
这条边界用于保证 `split-service` 下 Portal 不再成为 Chat Save
|
||||
的物理文件写权威。修复与图片物化继续保持幂等和 best-effort;
|
||||
真正的工作区写失败仍须明确返回错误,禁止静默回退到 Portal 本地写入。
|
||||
|
||||
### 守卫
|
||||
|
||||
- 单测:`mindspace-chat-save-service.test.mjs`
|
||||
- local / remote / RPC:`mindspace-local-runtime-services.test.mjs`、
|
||||
`mindspace-remote-server-adapter.test.mjs`、
|
||||
`mindspace-service/mindspace-rpc-server.test.mjs`
|
||||
- 源码门禁:`scripts/verify-mindspace-authority-boundary.mjs`
|
||||
- 综合验证:`npm run verify:mindspace-publish-guards`
|
||||
- runtime 双边一致性:构建 Portal 与 MindSpace service runtime 后执行
|
||||
`npm run verify:mindspace-publish-guards:full`
|
||||
|
||||
---
|
||||
|
||||
## 1.2 Conversation Artifact:登记与 manifest 写入权威必须在 MindSpace
|
||||
|
||||
### 必须保留
|
||||
|
||||
| 位置 | 行为 |
|
||||
|------|------|
|
||||
| `mindspace-conversation-package-artifact-service.mjs` | 从逻辑 user/session/artifact ref 解析工作区文件,登记 public HTML、聊天 DOCX、发布长图和通用 workspace 写入,并刷新 package manifest |
|
||||
| `mindspace-server-adapter-contract.mjs` | `conversationArtifactService` 的四类登记方法同时暴露给 local / remote adapter;`conversationPackageRegistry` 的远程契约只保留读取方法 |
|
||||
| `server/portal-session-routes.mjs` | Finish 只传 user/session/relativePath/messageId,禁止把 `publishDir` 传入 artifact 登记 |
|
||||
| `server/portal-mindspace-chat-save-routes.mjs` | DOCX 生成后调用 `registerChatDocxArtifact`,禁止直接取得 conversation package registry |
|
||||
| `server.mjs` | public HTML 与发布长图登记只调用 `mindSpaceConversationArtifacts`;禁止直接 `putObjectForSession`、`recordArtifact` 或 `writeManifestForSession` |
|
||||
|
||||
该边界保证 local 与 split-service 使用同一个产物登记入口。MindSpace
|
||||
负责 backing file 校验、确定性 artifact ID、对象写入和 manifest
|
||||
刷新;Portal 仍只负责鉴权、Finish 时序与生成结果转发。
|
||||
|
||||
Finish 中受第 1 节保护的 `edit_file` 落盘兼容逻辑已迁入
|
||||
`publicFinishService`,但仍复用同一纯实现和回归用例;禁止在 Portal
|
||||
增加本地写回 fallback,也不得破坏已验证的覆盖语义。
|
||||
|
||||
### 守卫
|
||||
|
||||
- 单测:`mindspace-conversation-package-artifact-service.test.mjs`
|
||||
- local / remote / RPC:`mindspace-local-runtime-services.test.mjs`、
|
||||
`mindspace-remote-server-adapter.test.mjs`、
|
||||
`mindspace-service/mindspace-rpc-server.test.mjs`
|
||||
- Portal 路由:`server/portal-session-routes.test.mjs`、
|
||||
`server/portal-mindspace-chat-save-routes.test.mjs`
|
||||
- 源码门禁:`scripts/verify-mindspace-authority-boundary.mjs`
|
||||
- 综合验证:`npm run verify:mindspace-publish-guards`
|
||||
|
||||
---
|
||||
|
||||
## 1.3 Workspace 读交付:物理路径与 canonical URL 必须在 MindSpace
|
||||
|
||||
### 必须保留
|
||||
|
||||
| 位置 | 行为 |
|
||||
|------|------|
|
||||
| `mindspace-workspace-publication-delivery-service.mjs` | 解析 `/MindSpace` 请求、校验 backing file 与 delivery contract、读取 HTML/二进制、补私有资源、生成缩略图/长图、扫描最近 HTML,并验证 Agent Run deliverables |
|
||||
| `mindspace-publications.mjs` | `resolvePublic` 返回 `workspacePublicUrl`;canonical workspace URL 不由 Portal 拼接 |
|
||||
| `mindspace-public-finish-service.mjs` | Finish 内完成 HTML 交付完整性检查、H5/微信 Page Data preparation、微信 HTML 链接交付与 fresh thumbnail 校验/修复;跨 RPC 返回的结果必须移除绝对路径与 HTML 原文 |
|
||||
| `mindspace-local-runtime-services.mjs` | 构造 `workspacePublicationDeliveryService` 与 `workspacePageDeliveryService`;local/remote 使用同一 adapter contract |
|
||||
| `server/portal-workspace-publication-delivery.mjs` | 只把逻辑 request path 交给 MindSpace,并代理 HTML/Base64 body;禁止读取、校验或返回本地绝对路径 |
|
||||
| `server/portal-publication-routes.mjs` | `/u/:slug/public` 调用 `readOwnerPublicAsset`;publication redirect 使用 `workspacePublicUrl` |
|
||||
| `server/portal-session-routes.mjs` | 先同步页面记录,再调用 `preparePageDataAfterFinish` 并消费逻辑结果;禁止解析 `publishDir`、`storageRoot` 或 `h5Root` |
|
||||
| `server/portal-integration-services-bootstrap.mjs` + `wechat-mp.mjs` | 微信只接收 `prepareWechatPageDataDelivery`、`prepareWechatHtmlDelivery`、`ensureWechatFreshPageThumbnails` 逻辑能力;禁止注入或读取 MindSpace 的 pool/storage path / publishDir / backing file path |
|
||||
| `server/portal-mindspace-asset-routes.mjs` | 下载和 from-asset 只消费 `readAssetContent` / `readPublicAssetContent` 的 Base64 body |
|
||||
|
||||
Portal 可以继续负责鉴权、viewer-specific HTML 注入、CSP/缓存响应头和
|
||||
repair turn 的触发,但不能获得 backing file 路径,也不能在 remote
|
||||
模式下回退读取 Portal 本机目录。
|
||||
|
||||
### 守卫
|
||||
|
||||
- 核心服务:`mindspace-workspace-publication-delivery-service.test.mjs`
|
||||
- Portal edge:`server/portal-workspace-publication-delivery.test.mjs`、
|
||||
`server/portal-publication-routes.test.mjs`
|
||||
- local / remote / RPC:`mindspace-local-runtime-services.test.mjs`、
|
||||
`mindspace-remote-server-adapter.test.mjs`、
|
||||
`mindspace-service/mindspace-rpc-server.test.mjs`
|
||||
- 源码门禁:`scripts/verify-mindspace-authority-boundary.mjs`
|
||||
- 综合验证:`npm run verify:mindspace-publish-guards`
|
||||
- runtime 双边一致性:构建两侧 runtime 后执行
|
||||
`npm run verify:mindspace-publish-guards:full`
|
||||
|
||||
---
|
||||
|
||||
## 1.4 Agent MCP:逻辑 workspace/package 与 scoped token 必须成套
|
||||
|
||||
### 必须保留
|
||||
|
||||
| 位置 | 行为 |
|
||||
|------|------|
|
||||
| `mindspace-workspace-tool-service.mjs` | 只接受逻辑 `workspaceRef`、当前 `sessionId/packageId` 和相对路径;阻止绝对路径、路径穿越、symlink escape 与浏览器持久存储 |
|
||||
| `mindspace-mcp-scoped-token.mjs` | token 同时绑定 user、session、package、workspace 与工具 allowlist,并校验签名和有效期 |
|
||||
| `mindspace-service/mindspace-rpc-server.mjs` | `/mindspace/v1/mcp/:tool` 从 token 注入作用域,拒绝请求体覆盖 user/session/package/workspace |
|
||||
| `mindspace-sandbox-mcp.mjs` | scoped 模式下通用 workspace 工具和 `generate_long_image` 只经 MindSpace Service;DOCX 仅在临时目录生成,再通过内部 `write_binary_file` 上传 |
|
||||
| `capabilities.mjs` + `user-auth.mjs` | 取得真实 session 后才生成 scoped token;签名 secret 不得进入 Goose extension env |
|
||||
| `mindspace-conversation-package-artifact-service.mjs` | 非公开 workspace 写入也必须直接登记 artifact 并刷新 manifest,不能把 asset sync 的结果当作唯一登记保证 |
|
||||
| `mindspace-workspace-tool-service.mjs` | 二进制写入和长图目标写入必须落盘、登记 artifact、刷新 manifest,并且响应不得暴露绝对路径 |
|
||||
|
||||
`publish_page` 在 scoped endpoint/token/workspace/session/package 任一项
|
||||
缺失时不得暴露。保留旧本地文件工具只是未配置 scoped split-service
|
||||
时的兼容路径,不得让它成为 remote 模式的静默 fallback。
|
||||
scoped 模式下 `generate_docx` / `generate_long_image` 也不得在 RPC
|
||||
失败时回退写 Goose 本地目标路径。
|
||||
|
||||
### 守卫
|
||||
|
||||
- 单测:`mindspace-workspace-tool-service.test.mjs`、
|
||||
`mindspace-mcp-scoped-token.test.mjs`、
|
||||
`mindspace-sandbox-mcp.test.mjs`、`capabilities.test.mjs`
|
||||
- RPC / policy:`mindspace-service/mindspace-rpc-server.test.mjs`、
|
||||
`user-auth.test.mjs`、`tkmind-proxy.test.mjs`
|
||||
- 源码门禁:`scripts/verify-mindspace-authority-boundary.mjs`
|
||||
- 综合验证:`npm run verify:mindspace-publish-guards`
|
||||
|
||||
---
|
||||
|
||||
## 2. 聊天 Finish:禁止清空对话 / 禁止暴露内部前缀
|
||||
|
||||
### 症状
|
||||
@@ -123,6 +254,7 @@ npm run verify:mindspace-publish-guards:full
|
||||
- [ ] 是否仍 merge 本地与服务器消息(Finish / UpdateConversation)?
|
||||
- [ ] 是否仍过滤/剥离用户消息中的 agent-only 前缀?
|
||||
- [ ] `edit_file` 是否仍会 materialize 到 `MindSpace/<userId>/public/`?
|
||||
- [ ] Chat Save HTML 修复与落盘是否仍只经 `chatSaveService`?
|
||||
- [ ] 是否已跑 `npm run verify:mindspace-publish-guards`?
|
||||
- [ ] 是否更新了本页或相关单测?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user