Desktop:进程边界与本机能力
沿 Main 边界阅读本机能力
Desktop session 表达 Main 持有的本机执行上下文,Server session 表达 Agent 会话;跨边界时需要明确配对。本机 PluginHost 管插件投影和回执。普通文件操作属 Local File V4 架构族(Desktop 协议 v3 起不再有独立的 Local File wire 版本,path-free 不变):账本在 Agent,执行与附件组装在 Main;Renderer 只提交无路径的草稿意图。
这些宿主共同位于本机责任范围,不意味着它们共享同一状态机。chat 提交与观察统一走 Work 路径(register-runtime-v2-ipc 已删除);runtime-v2.1 入口不再放行(见下表 RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED)。
Gateway 协议硬门族(426 / fail-closed)
钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db 起,Desktop↔Agent 只剩一个协议版本 DESKTOP_PROTOCOL_VERSION = 3(Agent ADR-0090 D4、Desktop ADR-0087 D3:版本即能力,不再协商 feature token),所有 Desktop 准入边界对非 3 的版本统一返回 426 DESKTOP_UPGRADE_REQUIRED(chat 受理按 ADR-0093 只在声明了本机执行协议或携带本机执行载荷时检查,见下表),body { code, message: "请升级 AidaWork 客户端。", expectedProtocolVersion: 3 },Desktop 映射到升级提示、不做容错解码。原 desktop_protocol_version_required、local_execution_recovery_protocol_upgrade_required、LOCAL_FILE_PROTOCOL_UPGRADE_REQUIRED 三个码已删除。Interaction Kernel 与 Runtime Work 的协议门是另外两扇门,不要合并理解。
| 错误码 / 信号 |
入口 |
判定 |
阻断范围 |
DESKTOP_UPGRADE_REQUIRED |
chat POST /(头 X-AIDA-Protocol 有值且 ≠ 3;或没带头却携带本机执行载荷 localExecutor / localFilesV4 / assembleSubmittedLocalFileAttachments / pluginTask / pluginTools / userSkill;均审计 desktop_protocol_version_rejected);chat POST / /validate-local-executor / 路由预览的 localExecutor.version;本机执行回执、Local File 回执与投递、durable recovery GET /pending(头 Aida-Local-Execution-Protocol-Version)、桌面分发 |
版本 ≠ 3;载荷缺 version 按 schema 违规(不算升级信号) |
整次 chat 提交 / 该端点 |
RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED |
chat POST 按提交 wire + policy 校验;取消提交、api-runs cancel、active-run 分别有独立门(见协议地图) |
非支持的提交 wire;skill-v2 与 policy 不匹配另有码 |
该 Runtime/Run 路径 |
interaction_protocol_upgrade_required |
api-conversation-interactions 全路由中间件 |
头 Aida-Interaction-Protocol-Version 未接受(Kernel 现为协议 2) |
该对话 Interaction API |
ADR-0093(钉点 Agent e2adc9a3c325,状态 Proposed、代码已落地):本机执行协议只约束本机执行。chat POST 没带 X-AIDA-Protocol、请求体也没有本机执行载荷(清单 LOCAL_EXECUTION_CHAT_BODY_FIELDS)时,不再 426,进入 Runtime Work 协议检查和后续受理;这只证明通过协议门,最终工具集合仍须分别核验能力与执行绑定;这是为不做本机执行的客户端(如移动端第一阶段)准备的。Desktop 始终带头 3,行为不变;本机执行回执、Local File、durable recovery、桌面分发入口仍按 ADR-0090 D4 硬切。
载荷里没有合法的 localFileCapability 不再触发 426,只是本轮不注册 Local File V4 工具(localFileV4Admitted)。Desktop 侧 shared/generated/protocol-version.ts 由 Agent tool-client 生成;pending-read 恢复把 426 映射为 PENDING_LOCAL_READ_PROTOCOL_UPGRADE_REQUIRED。跨端(Desktop Electron / E2E)验收按两个 ADR 的记载尚未运行。
证据钉点:aida-agent e2adc9a3c325a258a88d68103de87e6630a3b676,aida-desktop 8eecd12081dbb5c725c1be3754dfaae7b845aa31。
证据与范围
-
aida-desktop · CONTEXT.md L1388–1418 · Dual session identity · 4346d79eb364(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)
-
aida-desktop · apps/desktop/electron/plugin-host/plugin-host.ts L659–689 · listProjections · 4346d79eb364
-
aida-agent · docs/architecture/lifecycle-map.md L42–98 · e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)
-
aida-desktop · apps/desktop/electron/local-files-v4/assemble-submitted-attachments.ts L49–80 · assembleSubmittedLocalFileAttachments · 4346d79eb364
-
aida-desktop · apps/desktop/electron/agent-loop/register-runtime-work-ipc.ts L251–276 · submitSubmission · 4346d79eb364(register-runtime-v2-ipc 已删除)
-
aida-agent · packages/agent/src/runtime/work/run-work-admission.ts L16–57 · bindAdmittedWork · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/chat-routes.ts L374–412 · DESKTOP_UPGRADE_REQUIRED_BODY · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/chat-routes.ts L489–529 · chatBodyCarriesLocalExecution · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/request-schemas.ts L74–91 · LOCAL_EXECUTION_CHAT_BODY_FIELDS · e2adc9a3c325
-
aida-agent · docs/adr/0093-chat-admission-separates-runtime-and-local-execution-protocols.md L26–58 · 本机执行协议只约束本机执行 · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/chat-routes.ts L381–421 · RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/api-conversation-interactions.ts L465–495 · interaction_protocol_upgrade_required · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/api-durable-local-execution-recovery.ts L66–72 · DESKTOP_UPGRADE_REQUIRED_BODY · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/protocol-version.ts L1–38 · DESKTOP_UPGRADE_REQUIRED · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/chat-routes.ts L520–524 · desktopPayloadVersionUnsupported · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/api-local-execution-receipts.ts L42–47 · DESKTOP_UPGRADE_REQUIRED_BODY · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/api-local-file-v4.ts L82–87 · DESKTOP_UPGRADE_REQUIRED_BODY · e2adc9a3c325
-
aida-agent · packages/agent/src/gateway/api-desktop-distribution.ts L55–59 · DESKTOP_UPGRADE_REQUIRED_BODY · e2adc9a3c325
-
aida-desktop · apps/desktop/shared/generated/protocol-version.ts L1–8 · DESKTOP_PROTOCOL_VERSION · 4346d79eb364
-
aida-desktop · docs/adr/0087-local-capability-convergence-and-protocol-v3.md L30–32 · DESKTOP_PROTOCOL_VERSION = 3 · 4346d79eb364
-
aida-agent · packages/tool-client/src/types/runtime-execution.ts L6–46 · RUNTIME_EXECUTION_PROTOCOL · e2adc9a3c325
结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。
远程 Desktop 设备目录(钉点 e2adc9a3c325 / 8eecd12081db)
- 迁移 188 +
DesktopExecutionDirectory:登记 desktop_execution_devices、online lease、continuation_context.remoteDesktop。
- chat 可带
executionTarget / remote binding;无头本机载荷规则仍受 ADR-0093 约束。
- 真机远程登记、租赁续期、跨设备执行 未核实。视图
remote-device。
Mermaid 实现图册
九张 Desktop 图:信任边界、持久提交 unknown、executor 租约、Plugin 条件产物、本机回执恢复、更新安装策略、Delivery UML、Stop 核对时序、artifact 输入物化时序。与服务端九张图对照;具体枚举与概念流程已分别标明。
Runtime 提交 wire 与原 Work identity
chat POST 的 Runtime 提交门接受缺省/空值(无 policy)、runtime-work-v1(无 policy),以及 runtime-work-skill-v2 且携带合法 skillExecutionPolicy;其他非空头为 RUNTIME_EXECUTION_PROTOCOL_UNSUPPORTED,头与 policy 不匹配为 RUNTIME_WORK_SKILL_POLICY_MISMATCH,均返回 426。原 Work binding 仍是 runtime-work-v1;取消提交、补充材料等路由单独判定,见协议地图。
证据:提交门 与 实际 chat POST 调用。
Desktop 实现图谱(固定代码快照)
基线:4346d79eb364b502ef87c0869a494dfed7964419,Desktop 0.2.5。下列图为代码阅读的结构化表达,不代表运行验收。D02 状态图与 D08 时序图使用实际 phase 名;UML 图区分类与接口,其余图为概念结构、调用时序或策略流程,不新增协议状态。
图索引
D01 信任边界:安装信任与资源授权分开
flowchart LR
accTitle: Desktop 实现图 D01
accDescr: Main 与 Renderer 和执行进程的权限边界,安装信任不等于资源授权或操作系统沙箱。
R["Renderer / preload"]
M["Electron Main"]
A["Agent 服务"]
V["Main Credential Vault"]
I["installed capability 授权"]
P["独立资源授权"]
W["Plugin / Skill 进程"]
F["本地文件与产物索引"]
R -->|"受限 IPC"| M
M -->|"当前身份绑定的请求"| A
V -->|"Main 专用凭据"| M
M --> I
I -->|"identity + request + executor 检查"| W
M --> P
P -->|"Computer Use / 连接授权 / 文件操作"| F
W -->|"Host API"| M
M -->|"opaque ID 与私有路径映射"| F
不能把此图读成沙箱:安装后的执行不再等待通用 per-call/always-allow 确认,也不由 ClientAccessMode 决定(旧 PluginExecutionApprovalGate 与 directory-batch 已随 eb0f30dc 移除);但身份、原任务、包完整性、请求摘要检查仍存在。Computer Use 窗口许可、连接授权、typed user action 和本地文件 effects 各有自己的边界。批准运行的进程拥有 OS 用户文件权限与网络,working directory 不是 OS sandbox。
证据:apps/desktop/electron/installed-capability-authorization.ts;Skill 实际 wiring;Plugin 实际 wiring。
D02 持久提交与 unknown:实际 phase 的局部状态图
以下是 submission delivery phase 的有意局部视图,不是 Run 状态机;省略 queued/reply/rejected 等 admission outcome。图中的 accepted 是服务器接受原提交,不是业务执行成功。
stateDiagram-v2
accTitle: Desktop 实现图 D02
accDescr: 提交阶段保存原 command,结果未知只查询原提交,不自动重放。
[*] --> prepared: prepare 冻结原始 intent 并更新 Store
prepared --> sending: beginSending 唯一首次发送屏障
prepared --> withdrawn: 发送前撤回
sending --> accepted: 原 command 的有效 ACK
sending --> unknown: recover 发现持久 sending
unknown --> accepted: 查询并验证原 Message/binding
unknown --> unknown: 查询仍 unknown
note right of unknown
不创建替代 command
不重新发送物理提交
404 / not_started 不授予重发
end note
note right of accepted
保留原 binding
不降级回 sending
end note
这里的 Store 保存不等于强耐久落盘:当前实现先推进内存,加密磁盘发布为异步 best-effort,失败只告警且不写明文;图不保证断电后记录必然存在。见 Store 持久性边界。
身份切换/摘要不符是拒绝操作,不虚构一个 phase。Stop 使用独立 command,先 unresolved,再解析并一次性绑定原 rootRunId 为 prepared;未知 Stop 仅 queryStop。由于 Stop 与 submission 的建立条件不同,不把两者折叠成同一个状态机。
证据:提交一次物理发送;recover/accept 实际转换;发送与撤回屏障;原提交查询;Stop 绑定与查询。
单次发送屏障只约束仍保有的 Store 记录,不是跨崩溃或记录丢失的 exactly-once 保证。
D03 Desktop executor:租约与 inbox,不是第二个模型循环
sequenceDiagram
accTitle: Desktop 实现图 D03
accDescr: Desktop 注册租约并并行续约与拉取 inbox,原 effect owner 执行。
participant Tick as Main lifecycle tick
participant Host as DesktopExecutionHost
participant Auth as 当前身份 owner
participant API as Agent executor API
participant Work as 原 Work coordinator
participant Effect as 原 effect owner
Tick->>Host: tick(已有连接时不重复启动)
Host->>Auth: owner + registration
Host->>API: GET capabilities
Host->>API: POST self/lease
API-->>Host: lease(验证 deviceId)
par 心跳续约
Host->>API: POST self/lease
API-->>Host: 同 deviceId / leaseId
and inbox 接收
Host->>API: GET self/inbox(leaseId / revision / after)
API-->>Host: 分页 items + ETag
Host->>Work: accept(items, scopeDigest)
Work->>Effect: 复用既有执行 owner
end
alt 身份变化
Auth-->>Host: invalidate
Host->>Host: generation++ / abort / clear
else 连接故障
Host->>Host: clear + 有界退避
Note over Host,API: 不在普通网络失败时 DELETE,避免迟到删除误伤新租约
end
心跳与接收并行,任一路失败会结束本连接;正常 close 才 best-effort 删除已捕获 lease。inbox 只是连接交付,不创造新的模型或 effect ledger。
证据:连接生命周期;注册/并行心跳/分页 inbox/释放。
D04 Plugin 条件产物:Worker 声明不能代替 Main 事实
sequenceDiagram
accTitle: Desktop 实现图 D04
accDescr: 原 Work 与 installed identity 校验后运行 Worker,Main 验证真实 committed artifacts。
participant Agent as Agent 原 pending Work
participant Main as Main delivery
participant Auth as installed capability 检查
participant Journal as PluginHost 调用链
participant Worker as MCP Worker
participant Lease as Main PluginCallLease
participant Registry as ArtifactRegistry
Main->>Agent: 查询原 pending request
Agent-->>Main: 精确 work/package/tool binding
Main->>Journal: settle 原调用
Journal->>Auth: 检查 identity / request / executor / task
Note over Auth,Worker: 无通用逐次执行确认;目录/电脑/连接等资源另行授权
Main->>Agent: dispatch 前重查同一 pending wait
Journal->>Worker: invokeTool(manifest contract)
Worker->>Lease: artifacts.create / artifacts.commit
Lease->>Registry: 注册当前调用产物
Registry-->>Lease: Main 已提交 artifact refs
Worker-->>Journal: structuredContent + artifacts
Journal->>Lease: committedArtifacts()
alt declaration / returned / committed IDs 一致
Journal-->>Main: succeeded result
else 校验失败或派发后结果不确定
Journal-->>Main: failed 或 unknown(依 effect / executionState)
end
Main->>Agent: 原调用 receipt settlement
图中的 PluginHost 调用链参与者压缩了 Journal 与 runtime 验证步骤,不表示验证函数定义在 journal 类中。实际 plugin-runtime.ts 完成条件产物校验:produced 必须完整列举当前调用全部 committed IDs;非 produced 要求零产物;outputKey/version/声明 schema 也必须一致。派发后的非 read effect 若无法证明 completed,代码可能返回 unknown,不能简化为“报错即无副作用”。
证据:原 wait 绑定与派发前重查;真实执行与结果/unknown 分类;产物创建提交;Main committedArtifacts;条件产物语义。
D05 本地写入结果与回执交付:恢复不等于再次写盘
以下刻画 coordinator 的可证实控制流;executor 内部恢复状态没有在图中虚构成 enum。
sequenceDiagram
accTitle: Desktop 实现图 D05
accDescr: 恢复原 Operation 的结果和回执,不把重送回执等同重复写盘。
participant UI as Main 恢复入口
participant Coord as LocalFileV4Coordinator
participant API as Agent pending / receipts
participant Exec as LocalFileV4Executor
participant Local as 本地结果与写入事实
participant Diag as 安全诊断
UI->>Coord: recoverPending(run/invocation/session)
Coord->>API: queryPending
API-->>Coord: 原 operation deliveries
Coord->>Exec: executeDelivery(原 operation + digest + scope)
Exec->>Local: 按原 operation 解析执行/恢复事实
alt 可提供原 receipt body
Exec-->>Coord: response + responseDigest
Coord->>API: submitReceipt(同 operationId/requestDigest)
alt Agent 接受
API-->>Coord: ACK
Coord->>Exec: markWriteReceiptDelivered
else 永久拒绝或交付失败
Coord->>Exec: 永久拒绝时记 rejection
Coord->>Diag: 未确认;保留原 operation 身份
end
else LocalFileV4ReceiptUnavailableError
Exec-->>Coord: 原 receipt metadata
Coord->>API: reconcileReceipt(original)
end
这里 fs/change 不走 read-unavailable 的降级路径。重送原 receipt 与重新执行文件 mutation 必须分开;不能从网络失败推断“没有写入”。只有完成 settlement 后 coordinator 才 releaseOperation;失败通知用安全错误码,不把任意文件错误或 receipt body 写日志。恢复期间仍计入 update-blocking activity。
证据:恢复与更新阻塞计数;提交 receipt / 标记 delivered / 拒绝;原 metadata 对账与未确认处理。
D06 自动安装策略:ready 与 installed 分开
此为概念策略图,不是 UpdateState enum 的完整转换图。
flowchart TD
accTitle: Desktop 实现图 D06
accDescr: 启动和空闲安装分别检查待安装状态、工作活动、静默时间及尝试次数。
Start["启动读取 updater snapshot"]
Pending{"启动时已有 ready + pendingRestart?"}
BG["正常工作台;后台 check / download"]
Gate{"安装条件满足?"}
Block["阻止新 IPC;复查 busy / idle"]
Reserve["持久记录本版本尝试次数;再复查"]
Apply["调用 updater apply"]
Hold["保留待安装;不中断现有工作"]
Start --> Pending
Pending -->|"否"| BG
Pending -->|"是"| Gate
BG -->|"idle-install 默认关闭;开启后轮询"| Gate
Gate -->|"无 busy;自动次数未超限;idle 分支另验时间"| Block
Gate -->|"不满足 / 读取失败"| Hold
Block -->|"通过"| Reserve
Block -->|"条件变化"| Hold
Reserve -->|"通过"| Apply
Reserve -->|"条件变化;回退预留计数"| Hold
Apply -->|"失败;解除 admission block"| Hold
启动只为启动前已下载的待安装更新等待;新下载不阻塞正常启动。Idle 分支要求系统 idle/locked ≥10 分钟、工作静默和 resume 静默 ≥60 秒、无阻塞活动;每 30 秒检查。自动尝试每版本最多 3 次(显式 retry 另处理)。不会通过取消任务来制造 idle。安装是否成功由 updater/下次启动确认,图没有虚构 apply → installed。
证据:阈值与默认值;启动及 idle 判定;阻止新工作、预留次数、复核及失败。
D07 UML:提交协调器、Store 与传输接口
这是实际类与接口的 UML 局部结构图,不是把所有名词都当类。Delivery 通过构造参数持有 Store,并由工厂取得 RuntimeWorkBoundTransport 接口;它没有实现或继承该接口。连线只表达关联/依赖,不使用无源码依据的组合菱形。
classDiagram
accTitle: Desktop 提交协调器的 UML 依赖
accDescr: RuntimeWorkDelivery 使用 Store 与按 scope 取得的 BoundTransport,Store 管理命令状态,传输接口提供发送和只读查询。
class RuntimeWorkDelivery {
+submit(request) Promise
+stop(input) Promise
+resumePreparedStop(request) Promise
+reconcileUnknownStop(request) Promise
}
class RuntimeWorkDeliveryStore {
+prepare(request) Promise
+prepareStop(stop) Promise
+bindStopTarget(stop, target) Promise
+beginSending(request) Promise
+recover(scopeDigest) Promise
+acknowledgeStop(request, ack) Promise
}
class RuntimeWorkBoundTransport {
<<interface>>
+assertCurrent() Promise
+send(request) Promise
+sendStop(request) Promise
+queryStop(request) Promise
+query(request) Promise
+view(binding) Promise
}
RuntimeWorkDelivery --> RuntimeWorkDeliveryStore : options.store
RuntimeWorkDelivery ..> RuntimeWorkBoundTransport : transportForScope 返回
成员签名为阅读而简写,queryStop 在实际接口中可选。请求/记录等 TypeScript 类型没有被画成额外运行实例。Store 的内存状态推进与磁盘耐久性也不能等同:当前版本的加密持久发布是异步 best-effort,失败只告警,不落明文。
证据:传输接口及协调器注入;Store 类及持久性边界;Stop 的建立与一次绑定;ACK 与首次发送屏障。
D08 Stop 时序:先绑定原目标,unknown 只核对
此图补足 D02 的 Stop 专用路径,不重画 submission 状态机。为突出分支,图中 Transport 聚合了接口调用及其服务端响应,不表示它是另一个状态权威。
sequenceDiagram
accTitle: Stop 目标绑定与未知结果核对时序
accDescr: Stop 先记录原来源,解析原 Root 后仅一次发送;不确定结果只查原 Stop ACK,不创建替代命令。
participant Caller as Main 调用方
participant D as RuntimeWorkDelivery
participant S as DeliveryStore
participant T as BoundTransport / Agent
Caller->>D: stop(commandId, sourceRef, submission 或 resolved)
D->>S: prepareStop(原身份与来源)
S-->>D: unresolved 或既有记录
Note over D,S: 非 unresolved / prepared 直接返回既有记录
D->>T: assertCurrent
opt unresolved 且没有已知 binding
D->>T: query(原 submission)
T-->>D: 原提交结果
D->>T: assertCurrent;验证 binding
end
alt unresolved 且无 binding 或不是 root_run
D-->>Caller: 保持 unresolved,不发送
else 已取得原 Root 或已有 prepared 目标
opt 尚未绑定
D->>S: bindStopTarget(原 rootRunId,冻结 body)
end
D->>S: beginSending(只允许 prepared)
D->>T: assertCurrent;sendStop(原冻结命令)
alt ACK 可确认
T-->>D: 原 Stop ACK
D->>T: assertCurrent
D->>S: acknowledgeStop
else 发送或 ACK 保存出现异常
D->>S: recover(sending 转 unknown)
D-->>Caller: 抛出异常,不重发
end
end
Caller->>D: 稍后 reconcileUnknownStop(原命令)
D->>S: recover + prepare,读取原记录
opt 记录为 unknown 且 queryStop 可用
D->>T: assertCurrent;queryStop(原冻结 Stop)
T-->>D: ACK 或 null
D->>T: assertCurrent
alt 有 ACK
D->>S: acknowledgeStop
else null
D-->>Caller: 保持原 unknown
end
end
仅 prepared 且从未跨过发送屏障的 Stop 可走 resumePreparedStop。身份校验失败、目标冲突均中止操作;图省略其异常箭头。ACK 表示控制屏障已接受,不表示已经撤销物理副作用。Store 的磁盘 best-effort 边界见 D07,不能把图中方法返回解释成强耐久落盘证明。
证据:Stop 来源解析与目标绑定;prepared 恢复与 unknown 只读核对;冻结目标校验与单次发送;recover 与 ACK 语义;ACK 控制屏障而非回滚。
D09 文件时序:artifact 引用物化为调用内只读副本
D04 讲产物创建与结算;这里追踪已有产物作为输入的 files.materialize 分支。verifyArtifactInput 是函数参与者,不是独立服务;原产物与调用目录副本必须分清。
sequenceDiagram
accTitle: Plugin artifact 输入物化时序
accDescr: Main 核验调用 token、capability、原参数引用与作用域后读取 artifact 字节,在独立调用目录写只读副本并返回路径;finish 清理调用目录。
participant W as Plugin 调用进程
participant L as Main PluginCallLease
participant V as verifyArtifactInput 函数
participant F as 本机文件系统
W->>L: files.materialize(callId、token、artifact 引用)
L->>L: 解析 HostRequest;核验 active、callId、token
L->>L: file-input capability;引用必须来自原 args
alt artifactId 或 session / conversation / run 缺失
L-->>W: PLUGIN_FILE_DENIED
else 引用具备原作用域
L->>V: registry、artifactId、scope、100 MiB 上限、readBytes
alt 核验失败或没有字节
V-->>L: 错误或无 bytes
L-->>W: PLUGIN_FILE_DENIED
else 返回已验证字节
V-->>L: bytes 与 displayName
L->>L: assertActive;限制扩展名,生成随机 input 路径
L->>F: 调用目录内 writeFile(wx,0400)
alt 写入失败
L-->>W: PLUGIN_FILE_DENIED
else 写入成功
L->>L: assertActive;记录 materialized 路径
L-->>W: 调用内 path(不是原 artifact 路径)
end
end
end
Note over L,F: lease.finish 时 abort、撤销调用资源,并 rm 调用目录
每个 lease 的目录使用独立随机文件系统身份;复制后再次核验 active,防止撤销中的结果继续发布。0400 是文件权限,不是 OS sandbox,也不代表任意已安装进程没有其他用户级权限。此图仅覆盖 artifact 引用分支,不把 selected-file 授权流程或产物输出混入同一链路。
证据:独立调用目录与原 args 引用集合;调用凭证校验;artifact 输入核验与副本写入;finish 撤销与目录清理。
本次快照新增与非基线内容
- 条件产物:以上第 4 图对应 pin
8eecd12081dbb5c725c1be3754dfaae7b845aa31 之后的新 Host 核验。Report 四个合同场景已回默认 System,但仅证明 Desktop 自有冻结 fixture 路径,不等于所有官方包验收。Report 门禁与专用 producer 限制。
- 轨迹采集:由 Main 的 developer + panelVisible 偏好控制,新提交前最多等待 2 秒诊断 ready handshake;身份/设置失效撤销本地采集。不是额外的 Run authority,也没有独立的 start-capture 按钮/IPC。设置、2 秒界限、invalidate。
- 发布渠道不是本基线:GitHub PR #4 是 draft,head
2eb1d524a9c9050c81beb8f77c38174f471ac3a7;stable/beta/preview 的安装/配置/feed 隔离不可放进 master 实现图。当前图只描述 master 更新协调与安装策略。