Files
memind/docs/regression-guards/page-data-delivery-contract.md
john 8bfb7959fc
Memind CI / Test, build, and release guards (push) Has been cancelled
fix: guard WeChat Page Data delivery with Aider review
2026-07-28 00:26:24 +08:00

75 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 contractAider 不能替代真实
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。