Files

154 lines
13 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.
# 04.runtime_workspace 设计评审(三)
**评审编号:** 03
**日期:** 2026-08-06
**评审对象:** [04.runtime_workspace.md](04.runtime_workspace.md)(实施权威)、[01.design_review.md](01.design_review.md)、[02.design_review.md](02.design_review.md)、[00.base.md](../00.base/00.base.md)、[01.kernel.md](../01.kernel/01.kernel.md)、[03.sdk_and_coreapp.md](../03.sdk_and_coreapp/03.sdk_and_coreapp.md)、[plan.md](../plan.md)、[app_final_design.md](../../设计/02.正式方案/app_final_design.md)、[lineup-runtime-sdk-architecture.md](../../设计/02.正式方案/lineup-runtime-sdk-architecture.md)、[lineup-app-layer-architecture.md](../../设计/02.正式方案/lineup-app-layer-architecture.md)。
**评审方法:** 独立以第 04 次主定义作为唯一实施依据,对照前置迭代冻结的 Manifest / Tool Descriptor / 生命周期契约和正式 Runtime 方案。只记录会使本轮实现或验收无法得到唯一结论的问题;不把 Rust 演进、系统通知、真实语音、Whiteboard 工作区或其他范围外设想重新升级为当前问题。
**总体结论:** 已确认的核心方向保持一致:MiniApp 是 Agent 的业务工具;`pomodoro.start` / `pomodoro.interrupt` 由 Agent 调用;deadline、Agent 中断和生命周期中断由 Runtime 原子裁决;完成后立即关闭并由 Interact 呈现;快照采用 `retain_readonly`;子会话和 pending Interact 的归属规则正确;Whiteboard 和 Rust Core 均未误入本轮范围。D04-10~D04-12 已按收敛决议回填:两个 Tool 已有最小可发布 Descriptor,同一会话只允许一轮 `focusing` 专注,当前验收入口限定为 IM、未来 Voice 只复用语义。所有 P0~P3 设计问题已清零,本迭代设计就绪,待实施。
## 问题清单(Outline
状态标记:🔴 未解决,必须处理;🟡 已提出修复方向,尚未确认或未回填实施权威;✅ 已解决;⚪ 可延期但必须保留记录。P0~P3 必须在当前迭代处理;P4~P5 可以延期,但必须记录延期原因和重新评估条件。
| 状态 | 优先级 | 编号 | 问题 | 当前结论 / 下一步 |
|---|---:|---|---|---|
| ✅ | P1 | D04-10 | 已命名 `pomodoro.start` / `pomodoro.interrupt`,但尚未给出能进入 Agent Inventory 的完整 Tool Descriptor,也未明确短 Tool 的 Runtime 与 Pomodoro 各自承担的处理步骤。 | 已冻结两个 Tool 的 v1 Descriptor:输入 / 输出 schema、调用模型、启动/前台策略、超时/幂等和 Runtime 优先的原子裁决顺序。 |
| ✅ | P1 | D04-11 | `interrupt` 假定每个会话只有一个 `focusing` operation,但再次收到同一会话的 `pomodoro.start` 时的规则没有定义。 | 已确定同一 `conversation_id` 只允许一轮 `focusing` operation;不同 call 的第二次 start 稳定拒绝为 `active_focusing_operation`,不创建任何新资源。 |
| ✅ | P2 | D04-12 | 主定义和验收把“IM 或 Voice”写为当前可验收入口,但本迭代明确不实现真实 Audio Mode。 | 已限定第 04 次仅以 IM 验收完整闭环;未来 Voice 复用同一意图和 Tool 语义,不要求本轮实现或验收。 |
| ✅ | — | D04-C7 | Agent 驱动、唯一终态与 outbox | `pomodoro.interrupt` 已不再被误作用户直接 SDK commandAgent Tool、deadline 和 lifecycle 共同进入 Runtime 的原子终态裁决,第一结果唯一。D04-10 仅补 Tool Descriptor 层,未推翻此决议。 |
| ✅ | — | D04-C8 | 完成后的工作区和会话收口 | 已确定 `completed` 后 Runtime 写唯一结果 / outbox,立即关闭 Pomodoro、结束子会话、恢复 Interact;不保留 Pomodoro 完成页。 |
| ✅ | — | D04-C9 | 业务快照、子会话与 Interact | snapshot 只作 UI / 历史展示,`retain_readonly` 旧实例不可写、不可复活;已结束子会话只读,pending 标准交互留在主 IM。 |
| ✅ | — | D04-C10 | 当前范围 | Whiteboard 仅保持第 03 次 SDK / 隔离回归;系统通知、来电检测、免打扰和真实 Audio Mode 均不在第 04 次范围。 |
| ⚪ | P5 | D04-C11 | Runtime Core 是否下沉 Rust | 已在 `plan.md` 留作后续方向;没有 profiling 证明状态、deadline、Tool/outbox 或 lifecycle 是热点之前,不进入第 04 次实施。重新评估触发条件不变。 |
## 已确认的一致性
### Agent 是业务入口,Pomodoro 不是用户直接操作的独立 App
主定义第 2、3 节已清楚表达:用户用当前 IM(未来可用 Voice)向 Agent 说明开始或停止的意图;Agent 调用
Pomodoro Manifest 声明的 ToolPomodoro 本身只显示和接收 Runtime 投影,不设置暂停、继续或结束专注的业务按钮。
这与前置迭代“Agent Tool 经 Runtime Tool Router 和动态 Inventory 调用、bundled App 不直连 Agent”的边界一致。
### 三种结束来源已有共同的可靠收口点
到达 `ends_at`、Agent 调用 `pomodoro.interrupt({})`、用户返回 Interact / 切换 App / 关闭工作区,已明确竞争同一
Runtime 原子终态。先成功者把长期 `pomodoro.start` 收口为 `completed``interrupted`,并只产生一次结果和
outbox;迟到事件获得稳定回执。自动暗屏、锁屏与 Surface 重载不是退出,刷新或重启按绝对 `ends_at` 恢复或结算。
这符合 Runtime 对 operation、outbox、焦点与生命周期拥有最终权力的正式架构。
### 完成、历史和 Interact 归属已经无冲突
完成路径已选择“立即收口”:Runtime 原子完成后立即关闭 Pomodoro、结束子会话并恢复 Interact,由 Interact /
Agent 呈现结果。`app.instance-state.v1` 的 snapshot 与 deadline operation 分属不同事实来源;Pomodoro 使用严格
schema v1、4 KiB、`retain_readonly`,关闭后只能作为只读历史。已结束子会话同样只读;仍 pending 的标准交互
由 Interact / 主 IM 继续承接,不能追加到旧子会话。
## D04-10:两个 Agent Tool 缺少可执行的 Manifest / 路由契约
**已解决(2026-08-06,收敛决议)。** 主定义已冻结 `pomodoro.start` / `pomodoro.interrupt` 的 v1 Descriptor
Runtime 先校验、定位和原子裁决;Pomodoro Surface 只接收已裁决投影,既不决定终态也不影响短 Tool 的回执。
以下为决议前的风险分析。
### 为什么这是 P1
第 04 次主定义已经确定两个名称和高层语义:
```text
pomodoro.start({ duration_seconds, activity? }) 长期 operation
pomodoro.interrupt({}) 短 Tool
```
但第 03 次迭代冻结的 Tool Descriptor 要求每项 Agent Tool 至少具备稳定 ID、版本、输入 / 输出 JSON Schema、
`handling`、目标 App、前台要求和超时等信息;正式 Runtime 方案还要求声明面向 Agent 的说明、幂等规则、风险和
启动策略。这些字段决定 Runtime 是否创建 instance、何时前台化、如何验证输入、以及何时可向 Agent 发送结果。
当前 Pomodoro Manifest 片段只声明了 `app.instance-state.v1`,未给出这两项 Tool 的等价契约。
这在 `pomodoro.interrupt` 上尤其不能由实现自行猜测:当前主定义同时说“Runtime 将调用路由给该 Pomodoro
instance”与“Runtime 在同一原子裁决中将 `pomodoro.start` 收口”。若没有清晰的 Descriptor 和处理顺序,Web /
Tauri 实现可能分别选择“Surface 收到短 Tool 后自己 complete”或“Runtime 直接给 Agent 回执”。前一种会使
Surface 的存活状况影响中断可靠性,违反已确认的终态所有权;后一种是合理选择,但必须作为契约写明。
### 最小收敛内容
不需要新增用户能力或扩大 SDK。建议在实施权威中为两个 Tool 加一个最小 Manifest 表 / JSON 片段,至少固定:
1. `pomodoro.start``operation` 调用模型、输入 schema`duration_seconds` 为正整数,`activity` 为可选受限字符串)、最终输出 schema(`completed` / `interrupted` 及约定的结果字段)、启动 / 前台策略、超时或由 `ends_at` 约束的规则、幂等键与重复调用结果;
2. `pomodoro.interrupt` 的短调用模型、空对象输入 schema、三种既定稳定回执的输出 schema,以及它不接受目标 ID 的规则;
3. Runtime 在验证、按 `conversation_id` 定位并原子收口后写入短 Tool 自身回执和长期 `start` 的唯一结果 / outboxPomodoro Surface 只接收已裁决状态投影,不能以 `sdk.tools.complete` 决定或补写任何终态;
4. 两项 Tool 在当前 app 未运行、Surface 已卸载、instance 正在 closing、Inventory revision 过期和 schema 非法时的受控拒绝 / 恢复路径。
字段名称不必照搬本记录;关键是由 Runtime 发布到 Agent 的契约能让 Web 与 Tauri 得到同一行为。完成回填后,本项可关闭。
## D04-11:同一会话的第二次 `pomodoro.start` 没有唯一规则
**已解决(2026-08-06,收敛决议)。** 同一 `conversation_id` 只允许一个 `focusing` Pomodoro operation。
不同 `source_tool_call_id` 的第二次 `pomodoro.start` 稳定返回 `active_focusing_operation`,不创建 instance、
子会话、deadline operation、焦点变更或 outbox;Agent 必须先停止旧轮,或等待其已经终态。
以下为决议前的风险分析。
### 为什么这是 P1
主定义让 `pomodoro.interrupt({})` 从调用的 `conversation_id` 绑定“当前唯一的 `focusing` Pomodoro operation”。
`pomodoro.start` 在已有 `focusing` operation 时是否可以再创建一个 instance / 子会话 / deadline operation 尚未
定义。若两个 Host 自行选择不同处理,至少会产生以下不兼容情况:
```text
实现 A:允许第二个 start
→ 同一 conversation 同时存在两个 focusing operation
→ interrupt({}) 无法再唯一定位目标。
实现 B:静默覆盖第一个 start
→ 第一个长期 Tool 没有可靠的 interrupted 结果 / outbox。
实现 C:拒绝第二个 start
→ 需要向 Agent 返回什么稳定结果尚未定义。
```
这不是未来“多个计时器”功能的讨论,而是当前单次专注约束必须明确拒绝或替换的边界。否则无法完成
`pomodoro.interrupt` 的唯一目标验收,也无法实现本轮的唯一 outbox 要求。
### 最小收敛内容
推荐第一版采用最保守规则:同一 `conversation_id` 已有 `focusing` Pomodoro operation 时,新的
`pomodoro.start` 被 Runtime 稳定拒绝(例如 `active_focusing_operation`),不创建任何 instance、子会话、deadline
或 outboxAgent 必须先调用 `pomodoro.interrupt({})`,或在旧 operation 已 `completed` / `interrupted` 后再开始。
若产品希望“新的开始替换旧的开始”,也可采用先原子中断旧 operation、再创建新 operation 的规则,但必须定义两个
Tool 结果 / outbox 的先后和任一事务失败时的恢复,复杂度更高。
无论选择哪种,都应在验收加入:重复 start、并发 start、start 与 interrupt 并发、start 与 deadline 并发,且确认
每个 operation 只有一次终态和一次长期 Tool outbox。
## D04-12:当前 IM 验收与未来 Voice 语义混在一起
**已解决(2026-08-06,收敛决议)。** 第 04 次仅通过 IM 验证完整闭环;未来 Voice 只能复用相同的自然语言
意图、Agent Tool 和 Runtime 语义,本轮不实现或验收 Audio Mode、语音采集、识别或媒体能力。
以下为决议前的风险分析。
### 为什么这是 P2
用户已经确认:当前用户主要以 IM 消息与 Agent 交互,未来 Voice 必须复用同一“自然语言意图 → Agent Tool →
Runtime”模型。这个语义是正确的。可是主定义的目标和验收第 1、4 条目前写成“IM 或 Voice”,同时本迭代范围又
明确排除 Audio Mode 的真实媒体能力。按字面,验收人员无法判断是否必须交付语音采集、识别、语音对话入口或
Voice 端到端测试。
这不要求本轮实现 Voice,也不要求改变 Agent Tool。需要的只是把时间边界写清:第 04 次实际验证当前 IM;未来
Voice 接入后必须把识别出的同类意图映射到相同的两个 Tool,并遵守相同的会话绑定、终态和 outbox 语义。
### 最小收敛内容
将主定义、总体计划和验收中的“IM 或 Voice”改为类似表述:
```text
第 04 次通过 IM 验证用户向 Agent 表达开始 / 停止意图的完整闭环。
未来 Voice 复用相同的 Agent Tool 和 Runtime 语义;本轮不实现或验收真实 Audio Mode、语音采集、识别或媒体能力。
```
然后保留 Web Reference Host 和 Tauri Desktop Host 的 IM 代表性流程验收。回填后,本项可关闭。
## 评审关闭条件
1. D04-10D04-12 已回填 [04.runtime_workspace.md](04.runtime_workspace.md)、[plan.md](../plan.md) 和验收条目;
2. 实施时依据冻结后的 Tool Descriptor 增加合法、非法输入、Inventory 过期、重复 / 并发和 Surface 缺席的 fixture 与自动化验收;
3. D04-C11 继续作为 P5 carryover 留在计划中;没有 profiling 证据前,不启动 Rust 迁移;
4. 本评审只记录发现,未修改主定义、计划、正式方案或实现。