feat(doct): add app server design - #1889
Conversation
There was a problem hiding this comment.
结论:建议修改后再合并。
这次改动提出了 App Server 的目标架构,但文档中有几处关键设计还没有和现有代码对齐。主要问题不是文档措辞,而是这些设计一旦被当作实施依据,可能导致运行时归属、权限边界和远程执行位置出现偏差。
以下结论基于提交 abaec1f。
一、当前架构和目标架构混在了一起
问题
docs/architecture/product-architecture.md:197 把相关章节定义为“当前仓库的代码组织”,但 :203、:213、:256 已经列出了尚不存在的 App Server、App Server Transport 和 apps/app-server,同时没有展示当前实际使用的 agent-runtime-ipc。
同一文件 :558 说下面是“当前调用链”,但 :564 已经把所有富客户端都接到了 App Server。另一方面,docs/architecture/app-server-architecture-design.md:380 又明确说明 App Server 的进程和 crate 还没有创建。
目前 TUI 的真实路径仍然是:
- src/apps/cli/src/main.rs:858-868:在内嵌运行时和 shared_runtime::connect_or_start 之间选择。
- src/apps/cli/src/agent/runtime_client.rs:252-255:客户端只有 Embedded 和 Shared IPC 两种实现。
风险
后续开发者会把尚未实现的目标结构误认为当前事实,进而在不存在的边界上增加代码,或者过早删除仍在生产路径中的 agent-runtime-ipc。架构文档也会失去作为排查问题和评审改动依据的价值。
建议
把文档明确拆成三部分:
- 当前架构:只描述仓库中已经存在并运行的代码和调用链。
- 目标架构:单独展示 App Server 完成后的结构,并醒目标注“尚未实现”。
- 迁移过程:列出每个现有模块将迁移到哪里、旧路径何时退出,以及退出前必须满足的验证条件。
二、单个 App Server 管理多个工作区,与现有运行时所有权模型冲突
问题
docs/architecture/agent-runtime-deployment-design.md:192-217 要求工作区不再作为实例或进程的识别条件,同时仍要求 CoreRuntimeOwnership 充当唯一入口。
但现有实现并不支持这一点:
- src/crates/assembly/core/src/runtime_ownership.rs:174-214:共享运行时在创建时绑定一个工作区;第二个工作区接入时会返回 SharedRuntimeWorkspaceMismatch。
- src/crates/services/services-core/src/runtime_ownership.rs:27-40:当前识别条件只有产品标识和规范化后的本地路径,没有安全域或执行域信息。
风险
如果只按文档调整进程模型,却不先迁移所有权模型,会出现两种结果:第二个工作区仍然无法接入;或者为了支持多工作区绕过现有唯一入口。后者可能造成会话串用、资源释放错误,以及本地与远程工作区共用错误的执行环境。
建议
先确定一种可以落地的所有权方案:
- 方案一:由 App Server 维护按“工作区、产品、安全域、执行域”区分的运行时租约。
- 方案二:继续把工作区保留为实例识别条件,一个实例只负责一个工作区。
无论选择哪种方案,都应补充以下测试:同时打开第二个工作区、远程工作区接入、内嵌模式与共享模式冲突、所有客户端断开后的资源释放,以及重新连接后的所有权恢复。
三、一个统一的功能组合无法同时安全覆盖本地和托管部署
问题
docs/architecture/agent-runtime-deployment-design.md:187-194 和 docs/architecture/app-server-architecture-design.md:297 希望桌面端、TUI、VS Code 和托管服务共用一个 App Server 功能组合。
但当前功能组合没有对应的 App Server 类型:
- src/crates/assembly/product-capabilities/src/lib.rs:144-156:没有 AppServer。
- :1101-1115:桌面端拥有完整功能,CLI、ACP 和 SDK 只拥有核心兼容功能,Server、Remote、Web 和 MobileWeb 基本为空。
- :661-665:插件运行时只对 ProductFull、Desktop 和 Cli 开放。
风险
如果直接沿用桌面端或 CLI 的组合,托管服务可能获得文件系统、进程、插件等不应开放的本地能力;如果沿用 Server 或 Web 的组合,又不足以支持完整的智能体流程。最终很容易变成“先开放全部能力,再依靠各接口自行判断”,从而扩大安全边界并造成不同客户端行为不一致。
建议
为 App Server 定义独立的后端功能组合,并把以下三层权限分开管理:
- App Server 实际装配了哪些后端能力。
- 当前客户端可以提供哪些宿主能力,例如文件选择器、剪贴板和界面展示。
- 当前连接可以调用哪些网络方法。
至少应分别为本地桌面部署和托管部署建立允许与拒绝测试,证明托管部署不会继承本地高权限能力。
四、终端执行不应作为客户端反向请求
问题
docs/architecture/app-server-architecture-design.md:313-321,尤其是 :317,把文件选择器、剪贴板、终端、截图和 Computer Use 一起归入客户端反向请求。docs/architecture/agent-runtime-deployment-design.md:291-302 也采用了相同方向,但又要求远程工作区中的命令在目标主机执行。
当前代码中,src/crates/contracts/runtime-ports/src/lib.rs:705 的 TerminalPort 负责命令执行,PTY、Shell 和终端会话由终端服务管理。这些都属于执行环境,而不是界面宿主。
风险
在共享、托管或远程工作区中,命令可能被错误地发送回运行 GUI 或 TUI 的控制端机器执行。这样不仅会在错误的机器上读写文件,还可能绕过目标执行环境中的权限审批、取消、审计、子进程回收和资源限制。
建议
把“终端界面”和“终端执行”明确分开:
- 客户端只能负责打开、聚焦和展示终端界面。
- PTY、Shell、命令执行、进程生命周期和取消必须留在目标工作区所在的 Runtime Services。
- 协议中应明确记录命令的执行域,并加入远程工作区测试,证明命令不会回落到控制端机器。
五、还需要统一的三个契约
1. Headless CLI 是否允许接入共享会话
问题
docs/architecture/app-server-architecture-design.md:447-453 规定 CI 和 Headless CLI 直接使用内嵌运行时,不作为 App Server 客户端;但 agent-runtime-deployment-design.md:134-143、product-architecture.md:784-790 以及 SDK、CLI 设计又保留了接入共享会话的路径。当前 src/apps/cli/src/main.rs:107-110 明确拒绝非交互模式使用 --shared。
风险
脚本作者无法知道哪种行为才是稳定契约,退出码、输出格式、取消和断线处理也可能因入口不同而产生差异。
建议
只保留一种明确结论。如果允许接入共享会话,需要同时定义命令入口、调用方角色、输出格式、退出码、取消和断线语义;如果不允许,就从其他文档中删除这条目标路径。
2. 首次连接的身份验证信息不完整
问题
docs/architecture/app-server-architecture-design.md:176-194 的初始化请求只有客户端自报的名称、版本和能力,但部署设计要求第一条消息同时完成实例身份、客户端身份和认证。当前 IPC 的 InitializeRequest 已经包含 instance_identity、token、client_id 和 client_version,见 src/crates/adapters/agent-runtime-ipc/src/protocol.rs:78-86。
风险
客户端自报信息不能证明其身份。如果协议没有明确认证凭据、实例绑定和校验顺序,错误客户端可能连接到错误实例,失败重试还可能形成资源消耗或探测通道。
建议
补充认证凭据的来源和作用域、实例绑定方式、服务端校验顺序、凭据轮换与撤销方式,以及连续失败时的限制。把错误令牌和错误实例作为必须通过的协议测试。
3. 迁移期间仍在使用的 IPC 契约被过早弱化
问题
src/crates/adapters/agent-runtime-ipc/AGENTS.md:15-38 把现有 IPC 标为仅用于迁移,但同时删掉了原先明确规定的请求、响应和事件大小限制、空闲超时、操作预算、本地 Named Pipe/UDS 边界,以及未知字段处理规则。App Server 还没有实现,--shared 目前仍依赖这条生产路径。
风险
在替代方案可用之前,现有 IPC 失去明确的安全和资源限制。后续修改可能在没有意识到的情况下放宽消息大小、连接范围或操作数量,形成内存、连接和兼容性问题。
建议
在最后一个旧客户端退出前,继续保留完整的“当前生产契约”。另外列一张迁移表,说明哪些限制会原样进入 App Server,哪些限制准备调整,以及调整所依据的测试或测量结果。
合并前还需要补充的信息
PR 描述仍是未填写的模板,标题中的 feat(doct) 也可能是拼写错误。当前分支比最新 main 少 6 个提交,并且 GitHub 没有报告任何检查结果。
建议在修改上述设计后:
- 变基到最新 main。
- 补充 PR 的范围、设计原因、兼容性和安全影响。
- 写清楚哪些内容是当前事实、哪些是目标设计、哪些仍待实现。
- 附上与本次文档变更对应的验证结果。
我已在这个提交上完成本地验证:相关 Rust 测试共 200 项通过,仓库结构检查、核心边界检查及其自测、Markdown 本地链接检查和 git diff --check 均通过。这些结果说明本次改动没有直接破坏现有代码和基础检查,但不能消除上述架构与迁移风险。
abaec1f to
79a8794
Compare
79a8794 to
57d4ca0
Compare
Summary
Fixes #
Type and Areas
Type:
Areas:
Motivation / Impact
Verification
Reviewer Notes
Checklist