feat(runtime): isolate bundled miniapps behind bridge
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# `03.sdk_and_coreapp` 第 4 次验收评审记录
|
||||
|
||||
> 评审编号:04
|
||||
> 评审日期:2026-08-05
|
||||
> 评审对象:[03.sdk_and_coreapp.md](03.sdk_and_coreapp.md)
|
||||
> 架构基线:[APP架构设计.md](../../APP架构设计.md)
|
||||
> 参考评审:[01.design_review.md](01.design_review.md)、[02.design_review.md](02.design_review.md)、[03.design_review.md](03.design_review.md)
|
||||
> 评审方式:主 agent 交叉检查 + 独立子 agent 只读验收;检查构建、自动化测试、Runtime/MiniApp/Host 代码、SDK 契约、Manifest 和真实浏览器路径。
|
||||
> 总体结论:功能回归通过,但架构与 SDK 验收不通过。发现的 P1 问题必须在本迭代修复后,才能把迭代标记为真正完成。
|
||||
|
||||
## 问题清单(Outline)
|
||||
|
||||
> **状态标记:** 🔴 未解决,必须处理;🟡 已提出修复方向,尚未实现;✅ 已解决;⚪ 可延期但必须保留记录。
|
||||
>
|
||||
> P0~P3 必须在当前迭代处理;P4~P5 可以延期,但要写清延期原因和重新评估条件。
|
||||
|
||||
| 状态 | 优先级 | 编号 | 问题 | 证据 | 当前结论 / 下一步 |
|
||||
|---|---:|---|---|---|---|
|
||||
| 🔴 | P1 | A1 | MiniApp 的 Capability 请求绕过 Runtime 的 Manifest、Policy 和审计边界 | `tauri/src/runtime/coordination/lineup-runtime.ts:379-381` | 必须由 Runtime 校验 Manifest 声明、Capability Registry/Policy、输入 schema、前台要求和用户确认;不能直接拼接 `app.call` 发出。 |
|
||||
| ✅ | P1 | A2 | `bundled` MiniApp 的业务逻辑仍在可信 Host JS 中运行,没有真正的受限执行边界 | `tauri/src/main.ts`、`isolated-surface-host.ts` | 已移除 Host 直接实例化;Task Dashboard/Whiteboard 业务逻辑改在 opaque sandbox iframe 内运行,只能通过 Runtime Bridge 请求能力。待浏览器复验。 |
|
||||
| ✅ | P1 | A3 | SDK 暴露完整 workspace,MiniApp 可看到其他 App 实例和全局焦点栈 | `lineup-runtime.ts`、`miniapp-sdk.ts` | 已从 `LineUpMiniAppSDK` 删除 `workspace()`,不再把全局实例和焦点栈交给 bundled MiniApp。 |
|
||||
| ✅ | P1 | A4 | 同一个 App 的多个 instance 之间 Inbox 订阅没有隔离 | `lineup-runtime.ts` | 已按 `app_scope + conversation_id + instance_id` 过滤实时订阅,并补充双实例回归测试。 |
|
||||
| 🔴 | P1 | A5 | Interact 使用专用 `ChatRuntimeSDK` 旁路,没有和其他 MiniApp 共用 SDK v1 语义 | `tauri/src/core-apps/chat/chat-app-host.ts:67-75`、`main.ts:103-125` | 需要明确并实现统一 SDK 适配:Interact 可有可信 DOM,但交互、Tool、生命周期仍必须通过统一 Runtime 契约;不能让专用接口成为另一套协议。 |
|
||||
| 🔴 | P1 | A6 | 标准交互的超时、dismiss、提交和答案 schema 没有由 Runtime 统一裁决 | `lineup-runtime.ts:507-558, 798-815`、`agent-interaction-service.ts:93-101` | 必须让 Interaction 与 Kernel Tool 共用一个终态迁移;超时/dismiss 要写唯一 Agent outbox;提交前按 `notice/choice/confirm/input` 校验答案,拒绝重复和竞态。 |
|
||||
| 🔴 | P2 | A7 | 迭代文档中的 Tool 名称和代码 Manifest 不一致 | 主文档 §5.2/§5.3;`reference-miniapps.ts` | 统一契约、Manifest、fixture、Agent Inventory 和验收脚本中的名称。 |
|
||||
| 🔴 | P2 | A8 | 当前 Task Dashboard/Whiteboard Surface 主要是 Host 硬编码的静态页面,无法证明真实业务 UI 在各自受限 Surface 内运行 | `main.ts:180-198`、`isolated-surface-host.ts` | 至少提供能代表业务边界的受限 Surface fixture,并验证 MiniApp 业务逻辑不能取得 Host DOM 或 Runtime 内部。 |
|
||||
| 🔴 | P2 | A9 | MiniApp progress 没有进入可恢复的 Tool 状态记录 | `miniapp-tool-state.ts` | 如果契约要求进度可恢复,需持久化最后进度并覆盖 Runtime 重启;否则修改文档,明确 progress 只是一种可丢失事件。 |
|
||||
| ⚪ | P3 | A10 | App session 记录和 opened/closed 事件没有显式保存 `agent_id` / `conversation_id` 字段 | `app-instance-manager.ts`、`lineup-runtime.ts:203-209,1052-1058` | Envelope 有部分上下文,但应与文档最低字段要求统一,避免未来多 Agent 或跨会话时产生歧义。 |
|
||||
| ⚪ | P3 | A11 | 旧的 `openExtensionApp` 公开入口仍提供较宽的旁路能力 | `lineup-runtime.ts:286-300` | 清理旧兼容入口,或明确它只为历史测试保留并加上 instance/call 状态约束。 |
|
||||
|
||||
## 1. 已验证通过的部分
|
||||
|
||||
- `npm run build` 通过。
|
||||
- `npm test -- --run` 通过:29 个测试文件、126 个测试。
|
||||
- `git diff --check` 通过。
|
||||
- 使用独立 `agent-browser` 会话登录本地测试账号成功。
|
||||
- 主 IM 页面、同步状态、应用子会话区域和“启用任务面板”入口可见。
|
||||
- 用户消息可以发送并显示“已发送”。
|
||||
- AppServer 频道中的其他用户消息已能被 Runtime 安全忽略;真实页面不再出现此前大量的 `scope_mismatch`。
|
||||
|
||||
这些证据只能说明基础功能路径可运行,不能证明 MiniApp 隔离、统一 SDK 和所有状态机契约已经满足架构要求。
|
||||
|
||||
## 2. P1 问题说明
|
||||
|
||||
### A1:Capability 请求没有经过 Runtime 的完整裁决
|
||||
|
||||
现在 bundled MiniApp 可以调用 `sdk.capabilities.request(name, reason, input)`,实现直接把参数包装成
|
||||
`lineup.v1.app.call`。这意味着 MiniApp 可以请求一个没有写入自己 Manifest、没有经过当前 Capability Policy
|
||||
检查、也没有经过 Host 支持检查的能力。即使后续 Agent 还要确认,这条入口也已经让 MiniApp 伪造了系统能力请求。
|
||||
|
||||
正确的边界应该是:MiniApp 提出请求 → Runtime 检查 Manifest 和 Policy → 校验参数 → 检查前台/生命周期 →
|
||||
进入统一的 Capability 状态机和用户确认流程 → 再由 Host 执行。
|
||||
|
||||
### A2:bundled MiniApp 实际仍是可信代码(已修复,待浏览器复验)
|
||||
|
||||
已删除 `main.ts` 中对 `TaskDashboardMiniApp` 和 `WhiteboardMiniApp` 的直接实例化。开发版 Surface 现在把
|
||||
Task Dashboard/Whiteboard 的业务脚本放进 opaque sandbox iframe,iframe 只能发送经过校验的
|
||||
`lineup.miniapp.v1.request`,由 Runtime 执行 Inbox、Tool、生命周期和 Surface 操作;Host 不再把 Runtime 对象、
|
||||
Store 或 Transport 注入 MiniApp。
|
||||
|
||||
这和架构文档要求的“bundled 也不是 system,必须使用受限 Surface/Bridge”不一致。若继续保留这种实现,必须把
|
||||
它们改成明确的 Host 内建 System 代码并修改信任模型;不能继续同时声称它们是普通 bundled MiniApp。
|
||||
|
||||
### A3/A4:SDK 数据边界没有做到 instance 级别(已修复)
|
||||
|
||||
`LineUpMiniAppSDK` 已不再提供 `workspace()`,因此 MiniApp 不能查看其他 instance 或 Runtime 焦点栈。
|
||||
|
||||
`inbox.list()`、ACK 和 `inbox.subscribe()` 现在都按 `app_scope + conversation_id + instance_id` 过滤;新增回归
|
||||
测试验证同一 App 的两个 instance 不会互收消息。
|
||||
|
||||
### A5:Interact 的 SDK 语义没有统一
|
||||
|
||||
Interact 使用 `ChatRuntimeSDK` 和 Host 注入的 `toolInteractions`,而 Task Dashboard/Whiteboard 使用
|
||||
`LineUpMiniAppSDK`。可信 DOM 可以是 Interact 与 bundled 的不同实现方式,但交互归属、Tool 状态、Runtime
|
||||
动作和错误/恢复语义不能因此分成两套没有共同契约的接口。当前代码无法用一套 SDK golden fixture 证明三类 App
|
||||
遵守相同的 Runtime 边界。
|
||||
|
||||
### A6:标准交互有两套状态,可能互相打架
|
||||
|
||||
- `expireToolCall()` 只修改 Kernel Tool 状态,没有调用 `AgentInteractionService.expire()`,也没有发送 expired outbox。
|
||||
- Agent dismiss 修改了 Interaction,但没有同步修改 Kernel Tool 状态。
|
||||
- submit 先改 Kernel,再改 Interaction;如果第二步失败,会留下两套状态不一致。
|
||||
- 提交结果是任意对象,没有按四种交互类型校验;例如 choice 的 UI 可以提交多选数组,而冻结契约要求的是单选结果。
|
||||
|
||||
这会导致 UI、持久化记录和 Agent 看到的最终结果不一致,属于当前迭代必须修复的正确性问题。
|
||||
|
||||
## 3. 验收结论
|
||||
|
||||
当前结论为(完成本轮 P1-1 后):
|
||||
|
||||
```text
|
||||
功能回归:通过
|
||||
基础构建与自动化测试:通过
|
||||
真实登录和消息发送:通过
|
||||
App 架构边界:部分通过(A2 已实现,待浏览器复验;A1/A5/A6 仍不通过)
|
||||
MiniApp 隔离与 SDK 规范:A2/A3/A4 已通过,Capability/Interact/状态机仍不通过
|
||||
标准交互终态契约:不通过
|
||||
迭代整体验收:不通过,先继续处理 A1,再处理 A5/A6;A2~A4 需在最终浏览器复验中确认
|
||||
```
|
||||
|
||||
本次验收没有修改实现代码。下一步应先处理 P1,再重新运行自动化测试和真实浏览器验收;P2/P3 不能被静默
|
||||
删除,至少要在本迭代结束前有明确的修复或延期决定。
|
||||
Reference in New Issue
Block a user