Pysolate 抽象、设计模式与 trade-off
本文以
b6458b41f0fa32085fdd4cad0a528d98602569d2的 post-review 状态为当前语境, 只综合已有实现锚点,不把这份文档写成逐文件审计报告。
1. 统一抽象:一次 Run 的两条账本
Pysolate 的基本边界不是“把 Python 提前跑一段”,而是把一次潜在 effect 拆成两条账本:
Guest facts / candidate
↓ Host qualification
Host-authorized physical preparation
↓ exact dynamic occurrence
Guest logical claim
candidate 是 exact target Guest 对已见 source 的语法/语义事实;它只能说明“可能有一个 call”。
qualified 是 Host 将该事实与 Plan、arguments、policy、freshness、privacy、lineage 和 budget 做完精确 join。
physical 是 Host 发起的一次有界、可丢弃的 read/decode/prepare attempt。
logical 只有在原 Guest 到达未改变的 exact occurrence 时才成立,并且是 one-shot claim。
因此,physical completion 不是 logical success;未到达、source drift、argument drift、提前异常、取消和 replay
只能得到 reject、cancel、orphan 或 discard,而不能自动升级为 effect、cache hit 或第二次 live call。
当前 semantic streaming 的 final-source gate 已复用既有最终 source SHA 并更新 ready record;这保留了 append-only
source lineage,也不需要重新解析 final AST。它仍不改变“prefix analysis 是事实、final occurrence 才是 claim point”的分层。
2. 核心对象
2.1 Plan、Grant 与 Presentation
Spec 描述 capability 的名字、schema、effect class、handler identity 和 playback/approval 规则。
Grant 是 Host 对 policy canonical bytes 的身份承诺;Guest 看不到 raw policy,Plan 只暴露 grant identity。
Host 在 registry 中注册 Spec 与 Grant,封存成不可变 Plan,并把规范、grant binding、max calls 等纳入 Plan identity。
direct、programmatic、both 是同一 Plan 的 presentation projection,不是三套权限系统。
Python wrapper、module alias 和 tool schema 只改变 spelling;它们不能自行产生 Plan、Grant 或 authority。
2.2 Broker 与 receipt
Broker 是 capability 的单一 mediator:它检查 call identity、origin、schema、预算、Plan、approval 和 handler,
再把一次合法请求送入唯一的 live dispatch seam。Wazero host_call 与 native Unix-HTTP RPC 都回到这个 Broker,
而不是各自建立一套“可信工具注册表”。
receipt 是 Host-authored operation record,绑定 Run/Plan/call/parent、approval、request/result digest、
source occurrence(如适用)和 outcome。它回答“Host 记录了什么 operation”,不回答 provider 或外部世界是否真的
完成了对应语义;receipt 也不是 undo log,terminal event 不是 rollback。
2.3 Guest evidence 与 Host evidence
Guest 可以提供 model output、bounded result、异常位置、timeline,以及由 exact Guest analyzer 产生的 body-free facts。 这些内容要经过 Host strict decode、重算 digest、校验 binding 后才能进入 Host 账本;Guest 自报的 Plan、receipt、 execution reference、capability metrics 或 workspace receipt 不具备权威性。 Host evidence 包括 Broker receipt、call count、approval/transport outcome、execution identity、workspace snapshot、 terminal disposition 和 cleanup。它是对 Host 可观察物理生命周期的投影,不是完整 syscall trace、外部世界 attestation 或完整事务日志。
2.4 Workspace Root、Attempt 与 disposition
workspace.Root 是不可变、可移植的 lineage record,表达 workspace digest、parent identity、depth 和 delta;
本地 Ref 只是当前 Manager 的 materialization handle,不是 portable identity。
Branch 和 Attempt 从 base 做私有的普通文件复制。Attempt 用于一次运行的可变写入:成功且 response/close 校验通过
才 Publish,错误、malformed response 或未完成路径则 Discard。Branch 的 Seal 生成 immutable Root;SelectRoot
只选择候选,不做隐式 merge。
这形成“stage → validate → publish/discard”的有限提交语义,但不承诺撤销已经发生的外部 effect。workspace receipt
描述 Host 的 snapshot 与 disposition,而不是给 Guest 额外 authority。
2.5 Prepared runtime 与 fresh consumer
prepared runtime 复用的是已编译/初始化的 module 成本,或供 clone 使用的 sealed linear-memory baseline;普通 prepared slot 是 single-use,不是 pool。private-COW 的每个 consumer 都重新 instantiate module、创建 private mapping、关闭 module 和 temporary;上一个 Run 的 frame、globals、WASI handle、Broker context 和 file descriptor 不会成为下一个 Run 的隐式输入。 所以 prepared runtime/COW 是 fresh execution 的 substrate,不是 continuation、checkpoint、persistent interpreter 或完整 heap snapshot。
3. 设计模式、问题与代价
3.1 Object capability + mediator
解决的问题: 防止 AST、Python spelling、Guest JSON 或异常文本自行铸造 authority,并统一 Wazero/native 的调用边界。 选择: Host 封存 Plan/Grant;Guest 只提交 bounded JSON;Broker 负责 admission、approval、dispatch 和 receipt。 代价: Host 需要维护 registry、schema、identity、approval 和 transport binding;每次调用还要支付校验、编码与 evidence 投影成本。 未选替代: 让 AST/candidate 直接授权、让 wrapper 持有 handler、或给 direct/programmatic 各建一个 registry;这些方案会 把 presentation 与 enforcement 混在一起,或产生重复的 authority seam。
3.2 Typestate / state machine
解决的问题: 区分 planned、started、completed、ambiguous、claimed、cancelled 等状态,避免把“准备过”“批准过” 或“收到异常”误读成“effect 已发生”。 选择: Plan 有 open→sealed;approval 有 waiting→dispatch committed→completed/denied;staged object 有 Planned→ReadIssued→SourceVerified→TypedStaging→Sealed→Claimed,或 Orphaned/Cancelled/Rejected;workspace 有 Mutable→Leased,Attempt 有 active→Publish/Discard。 代价: 状态转换、terminal guard、late result 和 cleanup 路径增多;接口必须明确 owner,否则容易留下 ready body、active lease 或不可解释的 ambiguous outcome。 未选替代: 用几个布尔字段、普通 error string 或 generic cache status 表示生命周期;它们无法表达线性化点、一次性消费和 fail-closed replay。
3.3 Transactional commit/discard(有限提交语义)
解决的问题: speculative physical work 或失败 Run 不应污染后续 workspace,也不应把未到达 occurrence 的结果发布为 logical effect。 选择: workspace 先建 private Attempt、snapshot、stage export,最后由 Host publish;prepared result 在 claim 前保持 run-private, 未消费时 orphan/cancel/reject 并清理 body。 代价: 需要复制、双重校验、临时文件、cleanup 和 disposition bookkeeping;物理工作可能最终被浪费。 未选替代: 立即写入共享 base,或假设所有外部 effect 都能回滚。Pysolate 只提供 publish/discard 边界,不伪装成全系统事务。
3.4 Immutable record + digest-bound identity
解决的问题: 防止 source、Plan、artifact、object、consumer 或 parent drift,同时减少 raw policy、arguments 和 body 在边界间传播。 选择: sealed Plan、Grant identity、Root identity document、receipt、source digest、typed descriptor 和 Host evidence 都以 canonical record/digest 表达;变化会生成新 identity 或被拒绝。 代价: canonicalization、copy、digest 重算和 identity join 增加 CPU/内存成本;digest 只证明 canonical bytes equality,不能证明 正确性、作者身份、外部语义或 backing-memory alias。 未选替代: 共享可变 object、直接传路径/指针、或把 non-empty digest 当作 authority token;这些方案会扩大 alias、隐式 state 和 stale-data 风险。
3.5 Explicit placement strategy
解决的问题: 避免把“先试 WASM、失败后凭异常重跑 native”误当作安全兼容性策略,并使 backend 选择可解释、可重算。
选择: Host 根据 request identity、state class、requirements、model risk、静态 import qualification 和 backend availability
生成显式 Decision。未知/动态/未 qualification 的 source 走 native 或 typed unavailable;只有 Host-authored unsupported/not_started
才能创建带 parent decision 的 native child。
代价: 保守策略会 false reject 或把本可进 WASM 的请求送入更贵的 native;WASM/native 各自需要 artifact、lifecycle、cleanup 和 evidence contract。
未选替代: exception-text retry、普通 timeout/import error promotion、native 成功后恢复同一 WASM state。后续无状态 request 可以重新选择
fresh WASM,但这只是重新 placement,不是迁移或恢复 native process/heap。
3.6 Private-COW
解决的问题: 在保持 fresh consumer 和 mutation isolation 的同时,降低重复初始化线性 memory 的物理成本。
选择: Linux sealed memfd 作为 immutable baseline,consumer 用 MAP_PRIVATE mapping;写页触发私有 COW,active lease 保护 image,
MADV_DONTNEED 丢弃 consumer 私有脏页。
代价: Linux-only、需要 memfd/seal/mmap/page-fault 支持,仍有 baseline 构建、module 初始化、mapping 和 close 成本;只覆盖 bounded linear memory,
不覆盖 Python frame、globals/tables、WASI、native extension 或 Host state。
未选替代: persistent mutable interpreter、完整 VM/heap checkpoint、filesystem COW 或宣称 zero-copy。它们要么泄漏 hidden authority/state,
要么超出已有 source contract;COW 只是在 fresh execution 下复用一层 substrate。
4. Fresh execution 与 reuse 的关系
fresh execution 是语义基线:每个 Run 都有新的 Guest、execution identity、Broker context、temporary 和可见的 logical boundary。 reuse 只能针对明确命名的对象,并且必须有该对象自己的 owner、identity、lifetime、copy/alias boundary 和 close authority。
| reuse 对象 | 复用的是什么 | 不复用什么 |
|---|---|---|
| whole-Run memoization | Host 保存的 canonical completed value | 旧 Guest、旧 receipt、旧 effect authority |
| single-flight | 同一 identity 的 in-flight computation | completed value、跨进程状态 |
| typed/materialized response | 受限 descriptor/body 的一次性 materialization | generic object ABI、pointer alias |
| prepared runtime/image | 初始化成本或 linear-memory baseline | Python continuation、完整 heap |
| workspace Root/Attempt | 文件树 lineage 或私有分支 | interpreter、capability、共享可变目录 |
| prepared-data staging | 一次 Host-authorized physical read/decode | durable cache、logical occurrence |
| 因此“reuse”不是一个 generic cache。cache hit、flight waiter、COW clone、Root selection 和 staged claim 的语义彼此不同; | ||
| 任何 reuse 失败、未命中、平台不支持或 identity drift,都应回到 fresh/ordinary path,而不是保留 hidden interpreter state。 | ||
| 这也解释了与 EAGER 的关系:Pysolate 不是宣称 fresh 一定快,而是让显式授权且可丢弃的 physical work 在 source tail 生成期间有机会重叠, | ||
| 同时把后续 authority 和 logical effect 留在原始 dynamic boundary。它仍支付 qualification、staging、join、materialization、fresh-start、cleanup | ||
| 和 orphan 成本;不能给出对 persistent-interpreter EAGER 的 universal wall-clock dominance。 |
5. 哪些是模式,哪些可能构成论文叙事
以下本身属于成熟的工程设计模式或既有 substrate,不应单独包装成论文创新:object capability、mediator、typestate/state machine、 immutable record、digest-bound identity、stage-then-publish/discard、explicit placement,以及 Linux private-COW。 prepared runtime、whole-Run memoization、single-flight、workspace full-copy lineage 也更接近实现机制,而非独立新颖性。 较有统一解释力的论文叙事是它们如何组合成一个边界:fresh isolated execution 不必放弃跨执行优化,只要 authority、physical work 和 effect truth 由 Host 持有,logical effect 仍由 Guest 的 exact dynamic occurrence 触发。 candidate→qualified→physical→logical 的分离、Host-owned receipt/evidence、typed non-replay placement 和可丢弃 preparation 是这条 framing 的具体实例。 固定 NumPy lane 可以展示 object-bound、one-shot 的 prepared-data 语义;semantic pre-dispatch 可以展示 source-prefix overlap opportunity; workspace Attempt、prepared runtime 和 private-COW 则展示隔离与复用 substrate。它们不应被拼成 generic cache、generic object ABI、 完整 rollback、任意 Python optimizer 或 private-COW 自身的创新。 最终应坚持的 trade-off 是:更细的安全调度空间换来更多 Host bookkeeping、identity joins、copy/cleanup 和保守拒绝。Pysolate 的贡献边界是 在不把 persistent interpreter 当作 authority 容器的情况下,保留这些受约束的 overlap/reuse 机会;不是证明所有 workload 更快、所有 effect 可提前, 也不是证明 receipt 等于外部世界真相。