一次 Run 从请求到清理
一句话
一次默认 Wazero Run 由 Host 先做 admission 和配置绑定,再启动 Guest、处理 capability calls、验证 response,最后完成 Broker、Guest 与临时资源的 terminal cleanup;workspace、observation 和部分 evidence 只在配置后接入。
先看一个例子
Agent 提交一段 Python:读取一项允许的信息,计算结果并返回 JSON。请求只包含 run_id、code、inputs 和可选 output schema;它不能自行带 credential、mount、capability grant 或预算。
一次正常的 Wazero physical attempt 可以压缩为六个检查点:
1. Host 接收并 admission 请求
2. 绑定 artifact/profile、Plan、可选 workspace 与 timeout
3. 创建并初始化 fresh Guest
4. Guest 执行;Host Broker 处理 capability call
5. Host 按启用的机制投影 evidence 并验证 response
6. Finalize、可选 publish/discard、close 与 cleanup
若请求在第 1 步声明当前不支持的 requirement,Host 可以返回 typed unsupported/not_started,Guest 根本不会创建。若 Guest 已开始后 timeout,则不能假设 effect 没发生并自动换 backend 重试。
真实机制
Admission。 cmd/apyrun 先读取 Host-owned operator config,再 bounded decode RunRequest。重复 JSON key、unknown field、超出大小或 unsupported requirement 会在 Guest 前失败。Request requirements 只能收窄选择,不能授予新 authority。
Binding。 Host 验证 Guest artifact 和 execution profile,建立 timeout、Plan/Broker 与可选 workspace。普通 Run 默认走 Wazero;streaming、prepared-data、COW 和 native 是显式 seam,不是每次都会经过的隐藏步骤。
Guest execution。 配置了 workspace 时,Engine 才为本次 attempt 获得 workspace lease。随后它 instantiate 一个 module,调用初始化和 source validation,再执行代码。Guest 通过 bounded ABI 请求 Host call。Broker 在 handler 前检查 Plan、call identity、schema、budget 和 approval。
Response。 Guest 只能返回自己负责的 result/error envelope。在 Wazero 路径中,Host 拒绝 Guest 自报的 trusted fields;配置了相应机制时,再投影 receipts、Plan identity、execution reference 和 call metrics,最后验证完整 RunResponse 与 output schema。Native 使用独立的 aggregate lifecycle/evidence schema,不经过这段 Wazero 投影。
Terminal cleanup。 Host finalize Broker,关闭 module 和 temporary;若启用了 workspace 或 observation,再释放 lease、记录 observation,并按 workspace policy stage/export 或 discard。Export 先写临时 capsule、校验 snapshot 和 receipt,最后才 publish。Close、evidence 或 publish 失败会影响整个调用;实现不会把 cleanup failure 隐藏在一个早先的 status: "ok" 后面。
需要区分三件事:
- Logical result:Guest 的 result/error 通过 Host validation。
- Terminal state:Host 决定这次 Run 不再继续。
- Cleanup:本次 Host-owned 资源已关闭或处置。
三者相关,但不是同义词。Cleanup 也不会撤销已经发生的文件 mutation 或远端 operation。
为什么重要
技术上: 每个失败都有明确阶段。Admission 可以证明整个 Guest/attempt 没有启动;Guest 已运行后,approval rejection、expiry 或 dispatch 前 cancel 仍可证明某个 capability handler 没有启动。执行后的 timeout、ambiguous operation 和 cleanup failure 不能被错误归类为安全 replay。
产品和业务上: 调用者可以区分 unsupported、Guest error、Host runtime failure、publish failure 和 ambiguous effect。Workspace 结果只有经过 stage、validation 与 publish 后才对外出现,半成品不会因为 Guest 已算出结果就自动发布。
不能推出什么
status: "ok"、receipt、digest 或 terminal event 都不是外部世界真值或 rollback log。- 不是每次 Run 都会使用 native、streaming、prepared-data 或 private-COW。
- 普通 exception、ImportError、timeout、OOM 和 cancel 不能触发隐式 replay。
- 当前 observation 不是 syscall、Python locals、heap 和完整 WASM memory 的全景 trace。
术语卡
- Admission:Host 在 Guest 启动前检查请求和支持范围。
- Broker:Host 侧 capability call 的 admission 与 dispatch 入口。
- Logical result:经过 Host 验证的 Guest result/error。
- Terminal state:Run 不再继续后的最终处置状态。
- Cleanup:关闭 Guest、temporary、workspace lease 和 staged output。
继续阅读
- 前置:Host、Guest 与 Run
- 后续:Fresh Guest 的真实含义、Receipt、effect truth 与 ambiguity
- 说明文档:
implementation/01-execution-core.md、implementation/02-authority-spine.md、implementation/08a-workspace-lineage.md - 源码 owner:
cmd/apyrun/main.go、runtime/engine/wazero/engine.go、runtime/response.go、cmd/apyrun/workspace_binding.go