docs(iteration): freeze sdk v1 contract fixtures
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# `03.sdk_and_coreapp` 第 2 次设计评审记录
|
||||
|
||||
> 评审编号:02
|
||||
> 评审日期:2026-08-05
|
||||
> 评审对象:[03.sdk_and_coreapp.md](03.sdk_and_coreapp.md)、[01.design_review.md](01.design_review.md)
|
||||
> 评审方式:独立子 agent 只读复核
|
||||
> 结论:核心方向已收敛;没有 P0 阻塞问题。以下 P1 项需在开始编码前逐项确认并回填主定义文档。
|
||||
|
||||
## 问题清单(Outline)
|
||||
|
||||
> **状态标记:** ✅ 已确认并回填设计; 🟡 待产品/架构决策; 🔵 待在契约中细化; ⚪ 文档或实施编排建议; — 不适用或无此问题。
|
||||
>
|
||||
> 本清单是本次评审的当前有效视图。后文保留每个问题的背景和建议;在问题被确认前,建议不是实施依据。
|
||||
> 确认后应先更新本清单,再回填 [03.sdk_and_coreapp.md](03.sdk_and_coreapp.md) 的契约、实施步骤和验收项。
|
||||
|
||||
| 状态 | 编号 | 问题 | 当前结论 / 下一步 |
|
||||
|---|---|---|---|
|
||||
| — | P0 | 阻塞级架构冲突 | 本次未发现需要推倒既有模型的 P0 问题。 |
|
||||
| ✅ | P1-1 | Task Dashboard 示例中 Tool 完成后关闭 App | 已回填:Tool 完成只回传 Agent;App 保留、后台或关闭由用户动作、`requestClose` 或 Lifecycle Policy 决定,只有真正 `AppLifecycleManager.close` 才结束 App 与子会话。 |
|
||||
| ✅ | P1-2 | `interactive` Tool 的专用路由 | 已回填:`interactive` 是 Runtime 自己处理的 Agent 交互分支,不创建/复用业务 MiniApp instance,不调整业务 App 焦点,也不进入任何 MiniApp SDK Tool Inbox;Runtime 私有契约交给 Interact / Shell 呈现。 |
|
||||
| — | P1-3 | 展示位置切换后的提交资格 | 不再适用:展示位置不是交互 owner 或提交权限。切换 App 前后台、关闭 App 或改在 IM 显示不改变同一 `interaction_id` 的归属;Runtime 只接受首次有效回答,之后才拒绝重复/重放。 |
|
||||
| ✅ | P1-4 | Tool 与交互的取消、超时和并发提交 | 已回填:用户回答、Agent dismiss、到期和 Runtime 失败竞争同一唯一终态;Runtime 第一个原子状态写入获胜,Tool 跟随同一结果,且只写一条 outbox。interactive Tool 仅使用交互 `expires_at`,不维护独立超时。 |
|
||||
| ✅ | P1-5 | `notice` 的 Tool 完成时点与结果 | 已回填:notice 必须保留为 Interact / IM 的只读卡片,可选同时 Toast 数秒;Runtime 持久化卡片并安排呈现后,立即以 `{ outcome: "accepted" }` 完成并回传,不表示用户已阅读。 |
|
||||
| — | P2-1 | 将普通标准交互统一当作敏感秘密输入 | 不再适用:`notice / choice / confirm / input` 按普通 IM 会话内容与日志基线处理;本迭代不为它们另设秘密输入契约或专门负向扫描。未提交草稿仍只在运行期存在,重启清空。 |
|
||||
| ⚪ | P4-1 | 首次评审中的历史提案可读性 | **遗留问题:** 不阻塞本迭代;建议在下一次文档整理或新评审时,进一步突出其中 `sdk.ui`、owner、`parent_call_id` 等旧提案仅供追溯、不可实施。 |
|
||||
| ⚪ | P4-2 | `password-input` 秘密输入原语 | **遗留问题:** 当前不阻塞 `03`;真正出现密码、卡密、私钥或临时 token 的 Agent 交互需求时,单独定义该原语及其不显示明文、不进入普通 IM 正文/日志/Telemetry/审计、可靠传递与清理等安全契约。 |
|
||||
|
||||
## 通过项
|
||||
|
||||
- 标准交互已经清楚限定为 Interact 中的人与 Agent 会话交互,而非 MiniApp SDK;公开 SDK 不包含 `sdk.ui`。
|
||||
- Task Dashboard、Whiteboard 已收敛为 `kind = bundled`,必须走受限 Surface / Bridge,不能取得可信 Host DOM、Tauri、Transport、Store、Agent 或其他 MiniApp 数据。
|
||||
- 用户答案经 Interact 交给 Runtime;Runtime 保存交互归属、校验、持久化并可靠回传当前唯一 Agent,bundled MiniApp 不参与。
|
||||
- App 子会话正确区分了人与 Agent 的记录和 MiniApp 内部业务操作;前后台、关闭、历史只读和“继续处理”的总体规则一致。
|
||||
- MVP 单 Agent 边界明确,没有提前引入多 Agent 连接、切换或路由。
|
||||
|
||||
## P0:阻塞问题
|
||||
|
||||
无。
|
||||
|
||||
## P1:开始编码前需要确认的事项
|
||||
|
||||
### P1-1:Tool 完成不应自动关闭 Task Dashboard
|
||||
|
||||
**已解决(2026-08-05):** 主定义文档已经确认“Agent Tool 完成不自动关闭 App,也不结束 App
|
||||
子会话”。Task Dashboard 示例与验收现已统一为该规则。
|
||||
|
||||
当前规则:
|
||||
|
||||
```text
|
||||
Tool 完成
|
||||
→ Runtime 持久化并回传 Agent
|
||||
→ App 是否保持前台、进入后台或关闭,取决于用户动作、MiniApp requestClose 或 Lifecycle Policy
|
||||
→ 只有真正执行 AppLifecycleManager.close,才结束 App 与 App 子会话
|
||||
```
|
||||
|
||||
验收已要求:Tool 成功回传后 Dashboard 可继续使用;只有真正关闭才结束子会话。
|
||||
|
||||
### P1-2:interactive Tool 必须不进入 MiniApp SDK Tool Inbox
|
||||
|
||||
**已解决(2026-08-05):** 通用 Tool 路由、实施步骤和验收已明确拆开 `interactive` 与一般 Tool。
|
||||
`notice / choice / confirm / input` 不会投递到 App Orchestrator、业务 MiniApp instance、SDK Tool Inbox
|
||||
或 `sdk.tools.subscribe`。
|
||||
|
||||
当前规则:
|
||||
|
||||
```text
|
||||
handling = interactive
|
||||
→ 不投递任何 MiniApp SDK Tool Inbox
|
||||
→ Runtime Agent interaction service 创建 StandardInteractionRecord
|
||||
→ Runtime 私有契约交给 Interact / Shell 呈现
|
||||
→ Interact 提交 interaction_id + 用户动作/答案
|
||||
→ Runtime 校验、持久化、outbox 回传 Agent
|
||||
|
||||
handling = direct / launch / foreground / operation
|
||||
→ 才进入 App Orchestrator、SDK Tool Inbox、MiniApp tools.* 路径
|
||||
```
|
||||
|
||||
验收已要求:Agent 发起的四类标准交互不得出现在任何 MiniApp Inbox 或 `sdk.tools.subscribe`。
|
||||
|
||||
### P1-3:切换展示位置后,旧页面必须失去提交资格
|
||||
|
||||
**不再适用(2026-08-05):** 该问题错误地把 App 上方覆盖层或 IM 卡片当成了交互的 owner。标准交互
|
||||
始终属于 Interact / 主 IM;`app_session_id` 只保留与哪段 App 工作相关的上下文,不形成 UI 父子关系。
|
||||
|
||||
切换 App 前后台、关闭 App 或改变展示位置不改变同一个 `interaction_id` 的归属,也不需要用
|
||||
`presentation_id` / `presentation_revision` 废止旧页面的回答资格。只要用户仍处于有效 LineUp /
|
||||
Interact 会话且交互尚未终态,Runtime 可接受该交互的首次有效回答;以后到达的重复、重放或迟到提交
|
||||
因交互已经终态而被拒绝。Shell 可以避免用户看到重复视觉卡片,但这是体验策略,不是结果正确性的依据。
|
||||
|
||||
验收应覆盖:交互从 Whiteboard 覆盖层改在 IM 中显示、Whiteboard 关闭后交互仍 pending 时,任一有效
|
||||
Interact 页面提交的第一份答案只产生一次持久化结果和一次 Agent 回传;后续提交不改变结果。
|
||||
|
||||
### P1-4:Tool 与交互的取消、超时和并发提交需要收敛规则
|
||||
|
||||
**已解决(2026-08-05):** Runtime 是标准交互的唯一终态裁决者。用户回答、Agent dismiss、到期和
|
||||
Runtime 失败都竞争同一条交互的唯一结果。
|
||||
|
||||
当前规则:
|
||||
|
||||
```text
|
||||
Runtime 对仍为 pending / presented 的 interaction 执行原子状态写入
|
||||
→ 第一个成功写入的动作获胜
|
||||
→ 用户回答:持久化答案,Tool 得到 answered
|
||||
→ Agent dismiss:交互与 Tool 得到 cancelled
|
||||
→ expires_at 到期:交互与 Tool 得到 expired
|
||||
→ Runtime 失败:交互与 Tool 得到 failed
|
||||
→ 同一事务或等价原子动作中只创建一条 Tool 结果 outbox
|
||||
|
||||
任何后到的回答、dismiss、取消或超时处理
|
||||
→ interaction_already_final
|
||||
→ 不覆盖结果,不创建第二条 outbox
|
||||
```
|
||||
|
||||
MVP 中 interactive Tool 没有另一套独立 timeout;其期限就是交互 `expires_at`。Agent 主动停止等待必须走
|
||||
`dismiss`,不走独立的通用 Tool 取消路径。
|
||||
|
||||
### P1-5:`notice` 的完成时点和 Tool 结果需要固定
|
||||
|
||||
**已解决(2026-08-05):** `notice` 是 Interact / IM 中持久保留的只读卡片;Toast 只是同一条 notice
|
||||
记录的可选短暂提醒,不是没有历史的独立消息。
|
||||
|
||||
```text
|
||||
Runtime 校验并持久化 notice 卡片
|
||||
→ 交给 Interact 呈现
|
||||
→ 当前前台界面可同时 Toast 数秒
|
||||
→ Runtime 立即以 { outcome: "accepted" } 完成并回传一次 Tool 结果
|
||||
```
|
||||
|
||||
`accepted` 只表示 Runtime 已接受、保存并安排呈现,不表示用户已看见或阅读。Toast 自动消失、用户忽略
|
||||
Toast 或收起 notice 卡片,均不产生新的 Agent 结果;持久化或安排呈现前 Runtime 失败时,结果为 `failed`。
|
||||
|
||||
## P2:本迭代验收前必须处理(本次无未决项)
|
||||
|
||||
### P2-1:将普通标准交互统一当作敏感秘密输入
|
||||
|
||||
**不再适用(2026-08-05):** 此问题把所有标准交互一概当成秘密输入,边界过重且不符合产品语义。
|
||||
`notice`、`choice`、`confirm` 与普通 `input` 是人与 Agent 的正常 IM 会话内容:已提交的内容按普通 IM
|
||||
会话历史、保留与日志基线处理,不在 SDK v1 中额外定义为密码或秘密。全局日志基线仍然有效,不能因此
|
||||
随意打印会话正文、Tool 参数或 token。
|
||||
|
||||
未提交的 `input` 草稿仍只能存在于当前运行期;重启后清空,不自动提交、发送或进入 outbox。这是恢复
|
||||
和正确性要求,不代表普通 `input` 已升级为秘密输入能力。
|
||||
|
||||
## P4:遗留问题(不阻塞当前迭代)
|
||||
|
||||
### P4-1:首次评审中的历史提案可读性
|
||||
|
||||
**延期原因:** 顶部 Outline 和总体结论已经说明早期 `sdk.ui`、owner、`parent_call_id` 等提案不再是
|
||||
实施依据;这不影响当前 SDK、Runtime 或验收实现。
|
||||
|
||||
建议在下一次文档整理或新的设计评审时,将原始评审正文加上“仅供追溯,禁止作为实现、测试或验收依据”
|
||||
的更醒目标识,或移至附录。当前有效结论始终以主定义文档和评审记录顶部的 Outline 为准。
|
||||
|
||||
### P4-2:`password-input` 秘密输入原语
|
||||
|
||||
**延期原因:** 当前 `03` 要完成的是 `notice / choice / confirm / input` 的 SDK v1 与会话交互闭环;
|
||||
目前没有真实的密码、卡密、私钥或临时 token 输入场景。把秘密输入仅做成普通 `input` 的掩码样式,不能
|
||||
解决内容怎样保留、传递、重试和清理的问题,因此不在本迭代仓促实现。
|
||||
|
||||
**重新评估条件:** Agent 确实需要向用户收集密码、卡密、私钥、临时 token 或同类秘密时,启动单独设计。
|
||||
届时 `password-input` 应作为与 `input` 并列的 Agent 交互原语,由 Runtime 按 `kind` 强制执行安全契约,
|
||||
而不是允许 Agent 用普通 `input` 自行约定保护方式。至少要明确:界面不显示明文;主 IM 只保留“已提交
|
||||
敏感信息”等替代记录;内容不进入普通日志、Telemetry 或审计;可靠 outbox 的暂存、加密(如需要)、
|
||||
Agent 接收后的清理、重启、失败、重试与一次性传递规则。
|
||||
Reference in New Issue
Block a user