Files

29 KiB
Raw Permalink Blame History

LineUp App 架构设计

状态: 当前权威设计基线 更新日期: 2026-08-04 适用实现: Tauri 2 Desktop Host 与同代码 Web Reference Host 本文取代: DESIGN.mdM4_COMPATIBILITY_AND_RELEASE.mdTECHNOLOGY_SELECTION.md

1. 设计结论

LineUp 是用户安装和使用的主应用;LineUp Runtime 是 LineUp App 内部提供给小程序的核心 运行环境。 Runtime 不是与小程序平级的产品 App,也不是一个独立客户端。

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 的默认交互入口:

Interact MiniApp
├── IM Mode:文字、图片、短消息、任务和结果投影
├── Audio Mode:实时语音(后续)
├── Video Mode:实时视频(后续)
└── IM 标准交互的默认 Renderer Providernotice / choice / confirm / input

当前实现仍保留兼容名称:

产品概念:Interact MiniApp
当前 app_scopechat
当前目录: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 基线

唯一客户端实现与验收基线是:

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 历史中,不能作为架构、协议、目录或验收依据。

开发命令:

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.1Tailscale 浏览器 使用受信任的 Tailscale 地址。0.0.0.0 仅是服务器监听地址,不能作为浏览器 API 目标。

4. Runtime 的唯一所有权

Runtime 是以下对象的唯一所有者:

Transport
Conversation Store
sync loop
outbox
协议兼容与原始 Envelope 校验
作用域筛选与 message_id 去重
MiniApp Inbox 与 ACK
MiniApp Registry、Instance、Focus、Lifecycle
Tool Router、Inventory、Capability、Surface、审计与恢复

当前消息路径必须保持单向:

AppServer / Remote Agent
  → LineUp Runtime
    → 协议、scope、权限、去重和持久化
      → MiniApp SDK Inbox / Tool Call
        → MiniApp UX
          → SDK Result / Progress / Lifecycle Request
            → Runtime 校验、审计、outbox
              → AppServer / Remote Agent

禁止项:

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 管理“哪些实例正在运行”。二者不能 混为一个状态。

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 自己的布尔状态作为事实来源:

focus stack:
  chat:audio-001
  draw-and-guess:game-001

foreground:
  draw-and-guess:game-001

background:
  chat:audio-001

当扩展 MiniApp 关闭或失败时,Runtime 必须恢复焦点栈中的前一有效实例。重启后,Runtime 恢复有界的实例与焦点状态;startingstopping 中断的实例必须安全降级为 suspended, 不得伪装为已完成的 Host 操作。

7. MiniApp SDK v1

下一阶段的核心交付是 LineUp MiniApp SDK v1。SDK 不是万能 API,而是 Runtime 根据 Manifest、实例状态、权限和 Policy 开放的最小请求集合。

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

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

interface MiniAppToolAPI {
  subscribe(listener: (call: MiniAppToolCall) => void): Unsubscribe;
  get(call_id: string): MiniAppToolCall | undefined;
  reportProgress(call_id: string, progress: MiniAppToolProgress): Promise<CommandReceipt>;
  complete(call_id: string, result: JsonObject): Promise<CommandReceipt>;
  fail(call_id: string, failure: MiniAppToolFailure): Promise<CommandReceipt>;
  cancel(call_id: string, reason?: string): Promise<CommandReceipt>;
}

completefailcancel 都是对 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

noticechoiceconfirminput 是 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_idconversation_idapp_session_idapp_scopeinstance_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

interface MiniAppLifecycleAPI {
  requestForeground(): Promise<CommandReceipt>;
  requestBackground(): Promise<CommandReceipt>;
  requestClose(reason?: string): Promise<CommandReceipt>;
}

MiniApp 只能请求生命周期变化;Runtime 决定是否允许。若接受关闭,则按上面的 app_closed 收敛普通 Tool、 处理 Surface 并恢复焦点;若用户只想暂时离开,应请求后台化。

Surface 与 Capability 也只能请求:

MiniApp requestOpenSurface / requestCapability
→ Runtime 校验 Manifest、Policy、实例状态和用户确认要求
→ Host Provider 执行受限操作
→ Runtime 记录审计并返回受控结果

不应在 SDK v1 提供 fetch、任意网络、任意文件系统、剪贴板、麦克风、摄像头或 Tauri 直接调用。高风险能力以后通过 Capability Request 按需开放。

8. Tool Contract 与 Inventory

MiniApp 只能在 Manifest 中声明 ToolAgent 只能调用当前 Runtime 已公布 Inventory 中的 Tool。

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;
    }
);

统一调度路径:

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 收到可靠结果

noticechoiceconfirminput 是 Agent 调起的 Runtime 统一 interactive Tool/交互记录 能力。Interact 提供会话语义和呈现,Runtime 持有记录与可靠结果路径;其他 MiniApp 只能作为当前 前台界面被 Interact 交互层覆盖,不能调用、实现或取得该交互的内容与结果。

可回答交互的请求以相对 expires_in_ms 指定期限;Runtime 计算和持久化 expires_at,缺省 15 分钟, 仅接受 1 分钟至 24 小时。notice 不等待回答,也不接受期限。

建议稳定拒绝码至少包括:

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 必须满足:

签名 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 与生产 Manifestapp_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 已完成:第二次升级

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 的关键结构位于:

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:定义并验证 MiniApp SDK v1

冻结 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 与参考实现稳定后,再按顺序推进:

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 改动至少满足:

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. 相关文档与源码导航