打开文档导航

Typed non-replay promotion

一句话

WASM 只有在 Host 能用 typed outcome 证明 workspace 和 external effect 都是 not_started 时,才允许创建一次绑定 parent decision 的 native child;普通异常、timeout 或可能已产生 effect 的失败必须停下。

先看一个例子

Host 已生成一份 initial WASM decision。WASM backend 在 workspace acquire、Guest 创建和 capability dispatch 之前,又返回 Host-authored UnsupportedRunError,指出 exact request 所需 feature 当前不受支持。

如果此时还没有 acquire workspace,也没有 dispatch capability,Host 可以说:“这次 attempt 确定没有开始,换 native 不会重复任何东西。”

另一种情况是程序已经向远端服务提交请求,随后 timeout。换 native 再跑一次也许会提交第二遍。错误文字相同,安全含义完全不同。

真实机制

Initial placement 选择 WASM 后,Orchestrator 只识别 Host-authored UnsupportedRunError。当前真实 Wazero producer 是 Guest 前的 requirement admission;普通运行时异常不会产生这个类型。正常 router 对显式 requirements 应在 L1 直接选择 native,因此 L2 promotion 是 Experimental 的 bounded catch,不是运行中发现任意 incompatibility 的通用路径。该错误必须转换并验证为一份 exact request-bound outcome:

schema_version: 1
kind: runtime_unsupported
escalation_required: true
escalation_reason: required_features_unsupported
required_features: [...]
workspace_disposition: not_started
effect_disposition: not_started
evidence.request_sha256: sha256:...

这份 outcome 不是 Guest 自己打印的字符串。只有全部字段和 request digest 匹配,native backend 也 available,Host 才生成 child decision:

parent: initial WASM decision
child backend: native
reason: l2_not_started_promotion
parent_decision_id: parent identity

Native child 是一次新的 physical attempt,不是旧 Guest continuation。它使用新的 execution ID、container、RPC channel 和 terminal evidence;只有配置了 workspace 时才会 acquire 新 lease。Child 失败后不会再回 WASM,也不会循环 retry。

以下情况不能自动 promotion:

  • Python 抛出普通 ImportError,即使文本写着“请改用 native”;
  • Guest response malformed、普通 runtime error 或非零状态;
  • Timeout/cancel 后 Host 不能证明 handler 没有开始;
  • Workspace 已被 acquire 或修改;
  • Capability dispatch 已 commit,结果为 error 或 ambiguous;
  • Provider 可能已完成 effect,但 response 丢失。

这些失败没有 not_started 证明。自动重放会把兼容性 fallback 变成副作用重复执行。

Pure source-pass 的 original-source fallback 看起来也像“换一条路径”,但时点不同。Plugin disabled、not_applicable 或 transform error 都发生在 Agent formal execution 与 authority-bearing work 开始前,所以 Host 可以执行 unchanged original request;derived execution 一旦开始,失败后也不 replay 原程序。这个 pre-execution selector 不是 WASM→native promotion,没有 parent/child placement attempt,也不能把它推广成 post-effect retry。

另一个容易混淆的场景是:某次 native Run 完成并彻底 cleanup 后,下一份新 request 只携带 portable JSON value。Host 可以重新运行 placement 并选择 WASM。这是 fresh backend selection;若请求仍依赖 native process、workspace Ref 或 opaque state,state class 会继续强制 native。系统没有把旧 native heap 或 process 迁移进 WASM。

为什么重要

技术上: Promotion 的合法性由 typed lifecycle fact 决定,不依赖异常名称。Parent/child identity 也让 evidence 能回答“为什么发生了第二个 physical attempt”。

产品和业务上: 这个 Experimental seam 展示了兼容性 fallback 怎样避免把不确定失败变成静默重复扣费、重复发布或重复写入。无法证明安全时,系统宁可报告 error/ambiguous,让 reconciliation 或人来决定。

不能推出什么

  • unsupported 本身不够;workspace 与 effect 还必须同时是 not_started
  • Timeout、cancel 或 error 不代表外部操作一定没有发生。
  • Native child 不继承旧 WASM state,后续 WASM 选择也不继承旧 native state。
  • Receipt/evidence 记录 Host 所见,仍不是远端系统的最终事实证明。
  • Source-pass transform 前的 original-source fallback 不表示 derived execution 或 capability effect 之后也能安全重放。

术语卡

  • Promotion:从初始 WASM decision 创建一次 native child attempt。
  • not_started:Host 能证明相关 workspace/effect 尚未开始的 typed disposition。
  • Parent decision:产生 promotion 之前的 exact placement decision。
  • Child attempt:绑定 parent identity、拥有独立 execution lifecycle 的新尝试。
  • Non-replay:无法证明未开始时,不自动重放可能含 effect 的执行。

继续阅读