# LineUp App 架构设计 **状态:** 当前权威设计基线 **更新日期:** 2026-08-04 **适用实现:** Tauri 2 Desktop Host 与同代码 Web Reference Host **本文取代:** `DESIGN.md`、`M4_COMPATIBILITY_AND_RELEASE.md`、`TECHNOLOGY_SELECTION.md` ## 1. 设计结论 **LineUp 是用户安装和使用的主应用;LineUp Runtime 是 LineUp App 内部提供给小程序的核心 运行环境。** Runtime 不是与小程序平级的产品 App,也不是一个独立客户端。 ```text LineUp App │ ├── App Shell / Host │ ├── 当前前台小程序的挂载与切换 │ ├── 连接状态、通知和安全恢复入口 │ └── Tauri / Web Host Provider │ ├── LineUp Runtime │ ├── AppServer / Remote Agent 通信 │ ├── Conversation、Store、sync loop、outbox │ ├── MiniApp Registry、Instance、Focus、Lifecycle │ ├── Tool Router、Inbox、Inventory │ ├── Surface、Capability、Artifact、Audit │ └── LineUp MiniApp SDK │ └── MiniApps ├── Interact(系统内建:IM / Audio / Video) ├── Task Dashboard(参考 / 已安装小程序) ├── Whiteboard(参考 / 已安装小程序) ├── Draw-and-Guess(参考 / 已安装小程序) └── 未来第三方小程序 ``` 任何 MiniApp 都必须通过 Runtime SDK 使用通信、Tool、生命周期、Surface 和系统能力;不得 建立独立 Agent 通信链路,或直接访问 Host 特权、Store、认证信息及其他 MiniApp 数据。 ## 2. 产品边界与术语 | 术语 | 含义 | 不能做什么 | |---|---|---| | **LineUp App** | 用户实际使用的主应用、产品容器和交付单位。 | 不能把业务规则重新堆进 Shell。 | | **App Shell / Host** | Tauri 或 Web 中的挂载、切换、通知、恢复和受限 Host Provider。 | 不解释 Agent 协议,不决定 Tool/App 路由。 | | **LineUp Runtime** | App 内部的长期协调环境;唯一拥有通信、可靠性、MiniApp 调度与安全决策。 | 不负责任意 MiniApp 的具体 DOM 或业务 UX。 | | **MiniApp** | 运行在 Runtime 上的功能单元。 | 不直连 Agent/AppServer,不直写 Runtime 状态。 | | **System MiniApp** | 随 LineUp 发布、代码可信的内建 MiniApp,如 Interact。 | 仍不能绕过 Runtime 调度或 Capability Policy。 | | **Installed MiniApp** | 经验证后在受限 Surface 中运行的小程序。 | 不访问 Host DOM、Tauri invoke、token、任意网络或其他 MiniApp。 | | **MiniApp SDK** | Runtime 向 MiniApp 开放的受控能力集合。 | 不是通用 Web、Tauri 或 Agent SDK。 | | **Tool** | Agent 通过 Runtime 调用的、Manifest 已声明的 MiniApp 功能。 | 不是 App 内部任意函数。 | | **Capability** | Runtime/Host 保管的录音、文件、通知等系统能力。 | 不是 MiniApp 自动拥有的权限。 | | **Surface** | 复杂交互使用的受限 UI 容器。 | 不承载未验证远端脚本或 Host 特权。 | ### 2.1 Interact MiniApp `Interact` 是第一个系统级 MiniApp,也是用户与 Agent 的默认交互入口: ```text Interact MiniApp ├── IM Mode:文字、图片、短消息、任务和结果投影 ├── Audio Mode:实时语音(后续) ├── Video Mode:实时视频(后续) └── IM 标准交互的默认 Renderer Provider:notice / choice / confirm / input ``` 当前实现仍保留兼容名称: ```text 产品概念:Interact MiniApp 当前 app_scope:chat 当前目录:tauri/src/core-apps/chat/ ``` 目录和作用域改名属于独立迁移任务,不能和 Runtime/MiniApp SDK 重构混在一起。 Interact 是可信内建代码,因此可以使用 LineUp 的可信 DOM 组件;但它和所有 MiniApp 一样, 必须经 SDK 请求 Runtime 行为,不能直接访问 Transport、Conversation Store、焦点栈、App Registry、原始 Agent Envelope 或系统能力。 Interact 的 SDK 采用“通用 Runtime 操作 + 可信 UI 投影”的适配方式:Runtime 操作负责消息发送、 标准交互提交/取消/过期、草稿和任务操作;UI 投影只负责 IM 视图、Agent 消息订阅和子会话展示。 UI 投影不是另一套通信或存储协议,Interact 的可信 DOM 也不因此取得 Transport、Store、原始 Agent Envelope、Host DOM 根节点或系统能力。当前 `chat` 兼容接口保留扁平方法,但新代码应按 `sdk.runtime.*` 和 `sdk.ui.*` 使用。 ## 3. 当前技术与 Host 基线 唯一客户端实现与验收基线是: ```text Tauri 2 Desktop Host + Web Reference Host ``` 它们运行同一份 TypeScript Runtime 与 MiniApp 代码,并不是两个客户端: - **Web Reference Host**:浏览器开发、Tailscale 联调和自动化验证入口;只能提供可安全降级 的浏览器能力。 - **Tauri Desktop Host**:正式桌面交付;只在 Runtime 授权后提供文件、通知、媒体等 Host Provider 能力。 不规划独立 Android/Kotlin 客户端,也不规划 Wails Host。已退役的 Android/Wails Spike 只保留 在 Git 历史中,不能作为架构、协议、目录或验收依据。 开发命令: ```bash cd lineup-app/tauri npm run web:dev # Web / Tailscale Reference Host npm run desktop:dev # Tauri Desktop Host npm test -- --run # Runtime、MiniApp 与 Host 回归 npm run build # TypeScript 检查与 Web production build ``` Web Host 与 AppServer 的地址必须按访问位置匹配:同机浏览器使用 `127.0.0.1`,Tailscale 浏览器 使用受信任的 Tailscale 地址。`0.0.0.0` 仅是服务器监听地址,不能作为浏览器 API 目标。 ## 4. Runtime 的唯一所有权 Runtime 是以下对象的唯一所有者: ```text Transport Conversation Store sync loop outbox 协议兼容与原始 Envelope 校验 作用域筛选与 message_id 去重 MiniApp Inbox 与 ACK MiniApp Registry、Instance、Focus、Lifecycle Tool Router、Inventory、Capability、Surface、审计与恢复 ``` 当前消息路径必须保持单向: ```text AppServer / Remote Agent → LineUp Runtime → 协议、scope、权限、去重和持久化 → MiniApp SDK Inbox / Tool Call → MiniApp UX → SDK Result / Progress / Lifecycle Request → Runtime 校验、审计、outbox → AppServer / Remote Agent ``` 禁止项: ```text MiniApp 直接 fetch AppServer 或 Agent MiniApp 直接读写 Conversation Store、sync cursor 或 outbox MiniApp 构造或发送原始 Agent Envelope MiniApp 直接切换其他 MiniApp、改写 focus stack 或 Registry MiniApp 直接调用 Tauri invoke、Host DOM 根节点或系统能力 Surface 从消息 payload 直接加载 URL、HTML、CSS、JS、Bundle 或 source ``` ## 5. MiniApp 信任模型与 SDK 权限视图 所有 MiniApp 共享 Runtime 的协议语义,但按来源获得不同的 SDK 视图。 | 能力 | Interact / System MiniApp | Installed MiniApp | |---|---:|---:| | 接收自身 Inbox、ACK | 可以 | 可以 | | 接收 Runtime Tool Call | 可以 | 可以 | | 上报 progress / result / error | 可以 | 可以 | | 请求前台、后台、关闭 | 可以,由 Runtime 决定 | 可以,由 Runtime 决定 | | 请求 Surface | 可以,经 Runtime Policy | 可以,经 Runtime Policy | | 请求 Capability | 可以,经 Runtime Policy | 可以,经 Runtime Policy | | 可信内建 DOM 组件 | 可以 | 不可以 | | 隔离 iframe / Surface Bridge | 可选 | 必须 | | 直连 Transport、Store、Agent | 不可以 | 不可以 | | 直接 Host / Tauri / OS 调用 | 不可以 | 不可以 | | 读取其他 MiniApp 数据 | 不可以 | 不可以 | 系统内建不等于绕过 Runtime:可信来源只决定代码的发布与 UI 执行方式,不改变 Runtime 的 通信、焦点、Tool、权限和审计边界。 ## 6. MiniApp 实例、焦点与恢复 MiniApp Registry 管理“有哪些小程序”,Instance Manager 管理“哪些实例正在运行”。二者不能 混为一个状态。 ```ts type MiniAppInstanceRecord = { instance_id: string; app_scope: string; conversation_id?: string; state: | "starting" | "foreground" | "background" | "suspended" | "stopping" | "stopped" | "failed"; parent_instance_id?: string; started_at: string; stopped_at?: string; error?: string; }; ``` Runtime 保存焦点栈,不以单个 MiniApp 自己的布尔状态作为事实来源: ```text focus stack: chat:audio-001 draw-and-guess:game-001 foreground: draw-and-guess:game-001 background: chat:audio-001 ``` 当扩展 MiniApp 关闭或失败时,Runtime 必须恢复焦点栈中的前一有效实例。重启后,Runtime 恢复有界的实例与焦点状态;`starting` 或 `stopping` 中断的实例必须安全降级为 `suspended`, 不得伪装为已完成的 Host 操作。 ## 7. MiniApp SDK v1 下一阶段的核心交付是 **LineUp MiniApp SDK v1**。SDK 不是万能 API,而是 Runtime 根据 Manifest、实例状态、权限和 Policy 开放的最小请求集合。 ```ts interface LineUpMiniAppSDK { readonly context: MiniAppContext; inbox: MiniAppInboxAPI; tools: MiniAppToolAPI; lifecycle: MiniAppLifecycleAPI; surfaces: MiniAppSurfaceAPI; capabilities: MiniAppCapabilityRequestAPI; } type MiniAppContext = { app_scope: string; instance_id: string; conversation_id: string; app_version: string; state: "starting" | "foreground" | "background" | "suspended"; }; ``` ### 7.1 Inbox ```ts interface MiniAppInboxAPI { list(after_message_id?: string): readonly MiniAppMessage[]; subscribe(listener: (message: MiniAppMessage) => void): Unsubscribe; acknowledge(message_id: string): boolean; } ``` Runtime 在投递前校验 Envelope、scope、目标 MiniApp、实例状态和去重;消息先持久化,再由 MiniApp ACK。后台化、刷新、Surface 重载或 Runtime 重启不能丢失未处理消息。 ### 7.2 Tool ```ts interface MiniAppToolAPI { subscribe(listener: (call: MiniAppToolCall) => void): Unsubscribe; get(call_id: string): MiniAppToolCall | undefined; reportProgress(call_id: string, progress: MiniAppToolProgress): Promise; complete(call_id: string, result: JsonObject): Promise; fail(call_id: string, failure: MiniAppToolFailure): Promise; cancel(call_id: string, reason?: string): Promise; } ``` `complete`、`fail`、`cancel` 都是对 Runtime 的请求,不是直接网络发送。Runtime 必须验证 `call_id` 的实例归属、合法状态迁移、输入/输出 schema、幂等性和权限,然后持久化、审计并 写入 outbox。 一旦 Runtime 接受某个 App instance 的关闭,关闭表示释放该 instance,不是把它留在后台:Runtime 停止 向它投递新普通 Tool,将仍为 `received / routing / waiting_for_app / running` 的绑定 Tool 原子收敛为 `cancelled(app_closed)`,每条 Tool 只写一条 cancelled outbox;已 `submitted` 的结果不可改写,继续可靠发出。 然后才关闭 Surface、停止 instance、结束 App 子会话并恢复焦点。普通 Tool 的完成或失败本身不关闭 App。 标准交互是例外:App 关闭只通知 Agent,不自动取消仍 pending 的人与 Agent 交互。 ### 7.3 人与 Agent 标准交互、Lifecycle、Surface 与 Capability `notice`、`choice`、`confirm`、`input` 是 Interact 的人与 Agent 交互组件,与 IM 消息同属于 当前会话;它们不是 MiniApp SDK,也不用于 MiniApp 自己的业务表单、确认或输入。Agent 通过 标准 Tool 交互请求发起它们,Runtime 校验、持久化、恢复、审计并可靠回传结果,Interact 负责呈现。 这四种是普通的人与 Agent 会话交互,不在 SDK v1 中统一定义为密码或秘密输入。已提交内容遵循普通 IM 的会话历史、保留和日志基线;尤其不能因为它们是普通输入,就突破全局“日志不记录会话正文、Tool 参数、 token 等内容”的约束。未提交 `input` 草稿仅保留在当前运行期,重启清空。密码、卡密、私钥、临时 token 等真正秘密输入留待未来作为独立的 `password-input` 原语设计;届时 Runtime 必须按类型强制其展示、记录、 传递和清理规则,Agent 不能用普通 `input` 绕过这些保护。 每条人与 Agent 的标准交互都必须在 Interact / IM 中留下相应的卡片、气泡或结果记录。`notice` 是只读 IM 卡片;当前界面可同时短暂 Toast 提醒,但 Toast 只是同一条记录的辅助呈现,不能作为唯一消息或用户 已阅读的证明。Runtime 成功持久化 notice 卡片并交给 Interact 呈现后,即可向 Agent 返回 `accepted`。 MVP 中,一个 LineUp Runtime 只连接一个 Agent,当前登录会话的 `agent_uid` 作为每条交互和 App 子会话的 `agent_id`。此处保存 Agent 身份是为了让答案按创建时的上下文回到正确对象;本阶段 不实现多 Agent 连接、切换、会话列表、outbox 或跨 Agent 路由。 Agent 发 interactive Tool 时,未带经过 Runtime 验证的 `app_session_context.app_session_id`,一律归入主 IM; Runtime 绝不能按当前前台 App 猜测归属。若带有该上下文,Runtime 只接受同一 Agent、同一父会话的真实 App 子会话;已经关闭的子会话可保留为历史上下文,但不复活旧 App。Runtime 创建子会话时会可靠告知 Agent 其稳定 ID,非法或跨会话的引用直接拒绝且不创建交互。 当 Interact 位于前台时,标准交互显示在 IM 时间线/卡片中;当 bundled MiniApp 位于前台时, Interact / Shell 可以在当前 App 之上显示同一会话的交互层。视觉位置不改变归属:请求和结果始终 属于当前 conversation、Agent call 与 Interact instance,结果经 Runtime 回传 Agent,而不交给 前台 MiniApp。 用户作答时,Interact 只把“交互 ID + 用户动作/答案”交给 Runtime,不直接把答案发送给 Agent。Runtime 从创建时保存的记录取得 Agent、主会话、App 子会话和 Tool 的归属,并核对当前 LineUp / Interact 会话、 有效期、答案格式和是否已结束。只有第一次有效回答可以写入会话历史和可靠 outbox;后续重复或重放提交 不得改变结果,也不得再次通知 Agent。展示位置不是交互的 owner 或提交权限:App 前后台切换、关闭或从 覆盖层改在 IM 显示,都不改变交互归属。客户端不能提交或改写 Agent、会话、Tool 或 App 子会话的归属字段。 用户回答、Agent remote dismiss、到期和 Runtime 失败都只能竞争同一条交互的唯一终态。Runtime 以第一个 成功完成的原子状态写入为准,并同时持久化唯一 Tool 结果/outbox;后来到达的动作不得覆盖结果或再次通知 Agent。MVP 中 interactive Tool 的等待期限与交互的 `expires_at` 相同,Agent 主动停止等待必须走 Runtime 私有的 `interaction.dismiss(control_id, call_id)`:Runtime 从受认证 Envelope 推导 Agent 和会话,以 `call_id` 定位交互。重放或目标已终态只返回稳定幂等回执,绝不再写 outbox;该控制契约不属于 MiniApp SDK。 启动一个 App instance 会在主 IM 会话中创建或恢复与之关联的 App 子会话,并可靠向当前 Agent 发送 `app_session.opened`,提供 `agent_id`、`conversation_id`、`app_session_id`、`app_scope` 与 `instance_id`。 主 IM 将其显示为可展开的 折叠组,记录 Agent 的提问、用户回答和 Agent 的简洁结果;它不记录 App 内部业务操作,例如用户在 Task Dashboard 点击按钮或填写 App 自己的表单、在 Whiteboard 绘制和编辑内容。App 进入后台时, 子会话仍继续;Agent Tool 完成也不自动结束子会话。只有 Runtime 的 `AppLifecycleManager.close` 使 instance 进入 stopped 或 failed、并从 focus stack 移除时,子会话才结束但保留为主 IM 的历史。新的 App instance 必须创建新的子会话,不接续旧实例记录。 已结束子会话可在主 IM 中只读展开,但不会重新启动 App、重新执行操作或复活未回答的问题。用户选择 “继续处理”旧工作时,Runtime 启动新的 App instance 和新的子会话;新子会话可以引用旧会话、artifact 或已保存的 App 状态作为上下文,但不能向旧子会话追加记录。 若 App 子会话关联等待回答的 Agent 问题,App 位于前台时 Interact 可在其上方显示提问层;用户切换到 其他 App 或普通 IM 时,该层收起但问题继续等待,主 IM 的对应折叠组标记“等待你的回答”。用户既可 展开该组直接回答,也可回到原 App 后回答。Shell 可避免用户看到重复的视觉卡片,但展示位置不改变交互 归属或提交资格;Runtime 通过首次有效回答和终态检查防止重复结果。真正关闭 App 会按普通 Tool 的 `app_closed` 规则先收敛未终态 Tool,随后移除该 App 上方的展示层并结束 App 子会话。Runtime 将关闭事件 (含仍 pending 的 interaction call_id)可靠通知 Agent;问题本身仍属于 Interact / 主 IM,直到 Agent 远程 dismiss、用户回答、到期或 Runtime 失败才结束。 因此 bundled MiniApp 不能发起、读取、提交或取消这类 Agent 交互,也不因其显示在自身上方而获得 Host DOM 或会话数据。复杂、高频或私有业务 UI(例如 Task Dashboard 的“新建任务”表单、Whiteboard 画布文字编辑、画笔、颜色选择、拖放和工具栏)必须留在 MiniApp 自己的 Surface 内。系统权限确认 (文件、麦克风、通知等)则属于 Runtime/Host Capability Gateway,而不是普通 `confirm`。 ```ts interface MiniAppLifecycleAPI { requestForeground(): Promise; requestBackground(): Promise; requestClose(reason?: string): Promise; } ``` MiniApp 只能请求生命周期变化;Runtime 决定是否允许。若接受关闭,则按上面的 `app_closed` 收敛普通 Tool、 处理 Surface 并恢复焦点;若用户只想暂时离开,应请求后台化。 Surface 与 Capability 也只能请求: ```text MiniApp requestOpenSurface / requestCapability → Runtime 校验 Manifest、Policy、实例状态和用户确认要求 → Host Provider 执行受限操作 → Runtime 记录审计并返回受控结果 ``` 不应在 SDK v1 提供 `fetch`、任意网络、任意文件系统、剪贴板、麦克风、摄像头或 Tauri 直接调用。高风险能力以后通过 Capability Request 按需开放。 ## 8. Tool Contract 与 Inventory MiniApp 只能在 Manifest 中声明 Tool;Agent 只能调用当前 Runtime 已公布 Inventory 中的 Tool。 ```ts type ToolDescriptorBase = { id: string; // 例如 task-dashboard.open version: 1; input_schema: JsonSchema; output_schema: JsonSchema; permissions?: readonly string[]; }; type ToolDescriptor = ToolDescriptorBase & ( | { handling: "interactive"; target?: never } | { handling: "direct" | "launch" | "foreground" | "operation"; target: { app_scope: string; requires_foreground: boolean; restore_previous_focus: boolean; }; timeout_ms?: number; } ); ``` 统一调度路径: ```text Agent Tool Invoke → Runtime 校验 Envelope、Inventory revision、Tool Descriptor、参数、scope、App 状态和权限 → 创建可持久化 Tool Call / 审计记录 → Tool Router 判定 direct / interactive / launch / foreground / operation ├── interactive:不使用 target、不创建业务 instance,只由 Runtime 建立 Interact 会话交互 └── 其他 handling:投递到目标 MiniApp instance → MiniApp SDK 报告 progress / result / error → Runtime 校验输出 schema、持久化、更新焦点、写 outbox → Agent 收到可靠结果 ``` `notice`、`choice`、`confirm`、`input` 是 Agent 调起的 Runtime 统一 `interactive` Tool/交互记录 能力。Interact 提供会话语义和呈现,Runtime 持有记录与可靠结果路径;其他 MiniApp 只能作为当前 前台界面被 Interact 交互层覆盖,不能调用、实现或取得该交互的内容与结果。 可回答交互的请求以相对 `expires_in_ms` 指定期限;Runtime 计算和持久化 `expires_at`,缺省 15 分钟, 仅接受 1 分钟至 24 小时。notice 不等待回答,也不接受期限。 建议稳定拒绝码至少包括: ```text inventory_revision_mismatch tool_not_advertised tool_input_invalid tool_output_invalid app_disabled app_instance_not_found app_scope_mismatch lifecycle_denied capability_denied call_already_final ``` ## 9. Surface、Bundle、Capability 与发布安全 复杂 UI 只能运行在受限 Surface 中。Installed MiniApp 的生产 Bundle 必须满足: ```text 签名 Manifest → 精确 byte size 校验 → SHA-256 校验 → 原子写入已验证 cache → app_id + exact version 解析 → sandbox="allow-scripts" 的隔离 Surface ``` ### 9.1 Host 兼容矩阵 | 情况 | Host 必须行为 | 禁止行为 | 观测信号 | |---|---|---|---| | 旧 Client 收到未知 `lineup.v1.*` | 安全 fallback,不执行 | 将 payload 当 HTML/能力执行 | `unsupported_type` / `unsupported_version` | | 新 Client 收到旧 plain text | 仅作为 Markdown 显示 | 赋予交互或能力 | legacy markdown renderer | | 不支持目标 Surface version | 不挂载,显示安全提示 | 自动前移到相邻版本 | `surface_unavailable` | | 收到生产 Surface | 仅在签名、长度、SHA-256 成功后挂载已验证 bytes | 接收 URL、HTML、JS、Bundle/source | install disposition | | 候选 Bundle 验证失败 | 保留当前 active 已验证版本 | 覆盖 active bytes 或执行候选 | `signature_invalid` 等 | | active Bundle 被撤销 | 原子回滚到已验证 predecessor;没有则不可用 | 回退到未验证缓存/远端 URL | `rolled_back` / `unavailable` | | Bridge 收到非当前 iframe 消息 | 丢弃 | 仅相信 origin 字符串或调用 Host API | bridge rejection counter | | Capability Catalog 变化 | 发布最小新 Inventory | 用过期 Inventory 自动执行 | catalog revision | ### 9.2 生产发布序列 1. 发布方创建不可变 artifact 与生产 Manifest:`app_id`、精确版本、artifact ID、长度、 SHA-256、最小 Host 版本、权限、可信 `key_id`、Ed25519 签名。 2. Manifest 与 Bundle 部署在 Host 配置的 HTTPS artifact 服务;Manifest 不携带 URL、HTML、 CSS、JS 或 source。 3. Host 在临时内存中验证签名、精确长度与 SHA-256;失败不写 cache。 4. 验证成功后原子安装,并只解析精确 `app_id + version`;不得自动前移版本。 5. 仅向满足最小 Host 版本且已启用目标版本的 Client 灰度发布。 6. 监控签名、摘要、下载、Bridge 与 Capability 状态;安全事件发生时只回滚到已验证的 predecessor。 7. 回滚后保留审计元数据,但不记录 artifact 内容、URL、token、文件路径或 Capability 参数; 新 artifact 必须使用新版本号。 正式 HTTPS Host 才可被标记为 production-capable。HTTP LAN 开发 Host 在浏览器 WebCrypto 受限时必须安全拒绝验签,不能为了联调放宽该规则。 ## 10. 当前实现状态 ### 10.1 已完成:历史安全基础 历史 M0~M4 已完成并沉淀在当前代码中;它们不是新的平行排期: | 历史阶段 | 保留能力 | |---|---| | M0 | HTTP Transport、Conversation Store、协议解码、Markdown、安全 fallback、基础回归 | | M1 | Tool Call、Task、可靠交互结果、执行摘要、可信 choice/confirm/input | | M2 | Surface Registry、实例生命周期、隔离 iframe 与恢复 | | M3 | Capability Registry、用户确认、审计与受限 Host 执行 | | M4 | 签名 Manifest、Bundle 校验/缓存/回滚、golden fixture | ### 10.2 已完成:第二次升级 ```text 00.base → Runtime 托管 Interact IM(当前兼容名 chat)的稳定基线 01.kernel → MiniApp Instance / Focus / Lifecycle、Tool Router、App Orchestrator、 Extension SDK 雏形、Workspace 持久化和恢复 ``` 当前实现已验证登录、同步、本地回显、Markdown、安全渲染、Tool Call、Task、Surface、 Capability、App Inbox、outbox、实例焦点恢复和生产构建。自动化回归当前为 23 个测试文件、 99 个测试;`npm run build` 通过。 Runtime 的关键结构位于: ```text tauri/src/runtime/app-management/ tauri/src/runtime/coordination/ tauri/src/runtime/persistence/ tauri/src/runtime/protocol/ tauri/src/runtime/surfaces/ tauri/src/runtime/capabilities/ tauri/src/core-apps/chat/ ``` ### 10.3 下一阶段:03.sdk_and_coreapp 下一阶段不是应用市场,也不是立即建设服务端下载目录。目标见 [03.sdk_and_coreapp.md](../迭代/03.sdk_and_coreapp/03.sdk_and_coreapp.md):定义并验证 MiniApp SDK v1: ```text 冻结 AppManifest、ToolDescriptor、Tool Call、App Context、Result/Progress/Error 和错误码 → Runtime 实现通用 SDK 请求路由、schema 校验、审计、恢复和 revisioned Inventory → Interact 适配为第一个 System MiniApp SDK 样本 → Task Dashboard 作为第一个参考 MiniApp 验证 Tool、progress、result、focus 与恢复 → Whiteboard 验证受限 Surface、状态 patch、Artifact 与 Capability 请求 ``` 参考 MiniApp 在此阶段使用 `kind = bundled`:随开发 Host 内置、有 Manifest 和 Runtime 注册记录, 但不依赖服务端 Catalog、远程下载或第三方发布。`bundled` 不是系统级信任;参考只描述这些 MiniApp 在当前阶段用于验证 SDK 的工作目的,不是 Manifest 类型名称。 ### 10.4 后续阶段 MiniApp SDK 与参考实现稳定后,再按顺序推进: ```text 04.app-delivery-registry → Catalog Entry、Manifest/Bundle 下载、验签、安装、启用、禁用、更新、回滚、移除 05.catalog-and-market(按产品需要) → 搜索、分类、发布者、安装 UX、组织分发与可能的商业能力 ``` `03.sdk_and_coreapp` 已经包含 Task Dashboard 和 Whiteboard 的端到端参考实现;不再另设 `03.reference-miniapps`,以免把同一批工作拆成两个编号。 “市场”属于最后的产品分发层,不能反向决定 Runtime、SDK、Tool 或安全模型。 ## 11. 验收与发布门槛 每次 Runtime、MiniApp SDK 或 Host 改动至少满足: ```text npm test -- --run npm run build ``` 对于 SDK/参考 MiniApp,还必须有以下证据: 1. 合法与非法 Manifest、Inventory revision、Tool 输入/输出 schema 的自动化测试; 2. Tool 启动 MiniApp、前后台切换、结果回传、失败回焦和重启恢复的场景测试;接受关闭后,未终态普通 Tool 仅产生一次 `app_closed` 取消、已 submitted 结果继续 outbox,随后才关闭 Surface / instance 并恢复焦点; 3. Interact 的 `notice / choice / confirm / input` 会话呈现不退化,覆盖 IM 内联与前台 bundled MiniApp 上交互层的显示、conversation/call 绑定、结果可靠回传 Agent、默认/越界交互期限、非法 `app_session_context` 拒绝、`interaction.dismiss` 幂等重放,以及 bundled MiniApp 无法访问或提交交互的测试; 4. MVP 的单 Agent 身份随交互和 App 子会话持久化;不新增多 Agent 连接、切换、会话列表或路由; 5. App instance 的子会话创建、后台/暂停保留、`AppLifecycleManager.close` 后结束折叠、重启恢复和新 instance 隔离可验证;创建时会可靠向 Agent 提供 `app_session_id`,关闭时会发出包含仍 pending interaction call_id 的可靠 App 已关闭事件,但不会自动 取消 Interact 交互;子会话只包含人与 Agent 的交互,不包含 MiniApp 的内部业务操作; 6. 已结束子会话可只读查看;“继续处理”旧工作会创建新 instance / 新子会话,可引用旧上下文但不复活旧问题; 7. App 切换时未回答问题从前台 App 上方收起并在对应子会话标记;用户可在 IM 或回到原 App 后回答,且同一问题不可重复提交; 8. Installed MiniApp 无法取得 Host DOM、Tauri invoke、token、任意网络或其他 MiniApp 数据; 9. 有头浏览器验证登录、同步、本地回显和代表性 MiniApp 路径; 10. 对生产 Bundle,验证签名 `open → patch → close → rollback`、隔离 Bridge 和 Capability 拒绝路径; 11. `git diff --check` 无格式错误,日志不得包含身份、会话、消息正文、Tool 参数、token 或 artifact 内容。 ## 12. 相关文档与源码导航 - [迭代/00.base/00.base.md](../迭代/00.base/00.base.md):Runtime 托管 Interact IM 的稳定基线。 - [迭代/01.kernel/01.kernel.md](../迭代/01.kernel/01.kernel.md):Runtime Kernel 与 MiniApp 编排目标和验收。 - [tauri/src/README.md](../tauri/src/README.md):当前源码目录和依赖方向。 - [tauri/README.md](../tauri/README.md):Tauri/Web Host 的运行、回归与历史实施细节。 - [程序文件清单与功能说明.md](../程序文件清单与功能说明.md):实现文件和功能说明。 - [LineUp App 最终设计方案](02.正式方案/app_final_design.md):跨文档详细契约来源; 若与本文的产品术语或当前迭代顺序冲突,以本文为准并同步更新上游方案。