75 lines
4.5 KiB
Markdown
75 lines
4.5 KiB
Markdown
# Page Data 交付契约
|
||
|
||
Page Data 页面只有在下面所有条件满足后才可向用户交付链接:
|
||
|
||
1. HTML 实际调用的每个 dataset 已在工作区 `.mindspace/private-data.sqlite` 注册。
|
||
2. 每个注册 dataset 的真实 SQLite 表、声明字段和读写 action 都存在。
|
||
3. page record、online publication 与 policy 使用同一个真实 page UUID。
|
||
4. 公开页完成一次受权限约束的 insert smoke;后台页完成 password auth 后的 read smoke。
|
||
|
||
`private_data_bind_workspace_page` 是硬门:它在创建 page / publication / policy 前,必须从 SQLite registry 派生权限。Agent 传入的策略不能凭空创建 dataset 或字段权限。
|
||
|
||
运行时路径必须按语义区分:
|
||
|
||
- `workspaceRoot`:`MindSpace/<user>`,保存 HTML、policy 和 private-data.sqlite。
|
||
- `storageRoot`:MindSpace service 的持久页面/资产存储。
|
||
- `usersRoot`:登录用户目录。
|
||
|
||
不要通过 `MINDSPACE_STORAGE_ROOT` 推断 Page Data 的 workspaceRoot。Portal、MindSpace service 与 sandbox MCP 必须显式使用同一 workspace contract。
|
||
|
||
回归命令:
|
||
|
||
```bash
|
||
npm run verify:page-data
|
||
npm run verify:mindspace-publish-guards:full
|
||
npm run verify:mindspace-page-sync-guards
|
||
```
|
||
|
||
涉及 H5 交付时,还必须验证:未注册 dataset 时不产生可用 Page Data policy,且最终链接交付被拒绝或进入明确 repair 状态。
|
||
|
||
## 微信 Page Data 独立审核
|
||
|
||
微信服务号的 Page Data 生成与修复继续使用原微信消息任务和专属会话,不写入
|
||
`h5_agent_runs`。灰度开启 `H5_WECHAT_MP_PAGE_DATA_AIDER_REVIEW_ENABLED=1`
|
||
后,仅命中 `H5_WECHAT_MP_PAGE_DATA_AIDER_REVIEW_USERS` 的用户执行以下发送前门禁:
|
||
|
||
1. Goose 在原微信会话完成本轮 Page Data HTML、dataset、表和 bind。
|
||
2. 平台只把本轮 HTML 与本轮更新的 policy 交给 Tool Gateway 的 Aider 审核。
|
||
3. Aider 必须写入 `.memind/page-data-reviews/<requestId>.json` 审核收据。
|
||
4. 平台重新解析每段内联 JavaScript;语法错误、执行器不匹配或收据未通过均禁止发链接。
|
||
5. Aider 通过后仍须通过 MindSpace Page Data delivery contract,Aider 不能替代真实
|
||
dataset、policy、publication 和 insert/read smoke。
|
||
|
||
普通微信聊天、静态页面、H5 Agent Run 和其它服务不读取该灰度配置,也不进入此审核。
|
||
|
||
## Finish 异步收尾不得留下永久 preparing
|
||
|
||
Portal 的 session SSE 在收到 Finish 后会异步执行页面同步、HTML 守卫、Page Data
|
||
绑定检查和 delivery contract ready 标记。该收尾链路是幂等的;任一瞬时异常不得被
|
||
静默吞掉并把已完成页面永久留在 `preparing`。
|
||
|
||
- `server/portal-session-routes.mjs` 必须对整段 Finish delivery finalization
|
||
执行有限重试,并记录包含 session 与 attempt 的警告
|
||
- 已产生本轮 public HTML 时,HTML 或 Page Data 守卫返回非 ready 也必须进入
|
||
有限重试;不能把 `limit`、`triggered` 等中间状态当成成功收尾
|
||
- `tkmind-proxy.mjs` 收到 SSE Finish 后必须先独立启动页面收尾,再执行计费;
|
||
重复计费或计费服务异常不得跳过 delivery finalization
|
||
- workspace-backed 资产版本使用稳定的 `workspace://` storage key;工作区文件更新
|
||
必须锁定资产并原位更新当前版本记录,禁止为同一 storage key 并发插入新 version
|
||
- 每次尝试必须成对调用 `beginSessionPageDelivery` /
|
||
`endSessionPageDelivery`,失败后不得遗留内存 busy 状态
|
||
- 只有 HTML 与 Page Data 两道守卫都通过,才允许调用
|
||
`markPageDeliveryContractReady`
|
||
- 回归用例:`server/portal-session-routes.test.mjs` 中的 transient
|
||
post-Finish failure retry 场景
|
||
|
||
## PostgreSQL 用户空间角色守卫
|
||
|
||
生产用户空间 PostgreSQL(独立于 Goose session PostgreSQL)通过 `SET LOCAL ROLE ms_u_*_agent` 隔离每个用户。必须保留以下约束:
|
||
|
||
1. provisioning 必须显式授予运行连接用户 agent role 的 `SET` 权限。
|
||
2. agent role 保持 `INHERIT FALSE`;只允许显式 `SET ROLE` 后访问用户 schema,不能让连接用户默认继承全部用户权限。
|
||
3. 已存在的用户空间在首次访问时必须幂等检查并修复缺失的 `SET` 权限,不能只修复新注册用户。
|
||
4. 验收必须使用与生产等价的非超级用户连接完成 `SET LOCAL ROLE`、建表、dataset 注册和读写;超级用户会绕过角色切换限制,不能作为该问题的验收依据。
|
||
5. 修复角色授权时禁止修改用户 schema、表和数据;生产操作前保留用户空间 PG dump、角色授权快照和回滚 SQL。
|