Pysolate backend / package profile / placement 单文档审查
审查状态:Historical fixed-target dossier。 下文的 Current 只表示固定 b94c989... snapshot 中的实现事实;本科生 guide 的当前 94fab78... 目标导航见 implementation/source-map.md。
源码仓库: /Users/yuzhe/projects/agent-python-runtime
精确 commit: b94c989785632d98634cdd5c2a6d4a1de6cc13ac
精确 tree: 6b8bb6a8d8274b8329a2aba444d13eac9fac19e9
范围(Scope): Wazero/CPython-WASI substrate;artifact/manifest/lock/import closure;plain、attrs-770、numpy-core package shard;execution-profile identity;placement;native OCI/runsc/RPC lane;typed unsupported/not_started promotion;non-replay fallback;backend conformance/evidence 边界。
本文只描述上述固定 snapshot 能证明的事实。审查期间未由本任务修改 /Users/yuzhe/projects/agent-python-runtime,未运行 campaign/CI,未将历史 evidence 当作该 commit 的运行结果。初始检查时 live checkout 与目标 commit/tree 一致且无 tracked diff;收尾复核时 live checkout 出现其他 semantic/streaming 文件的 concurrent tracked modifications,因此本文所有源代码结论均来自目标 commit 的 /tmp pinned archive,不混用这些漂移文件。
1. 审查结论与状态总览
核心结论是:当前 router 是 Host-owned 的、保守的 placement selector;package profile 是构建/验证期的封闭 artifact 描述,不是 package manager;WASM 与 native 是两个不等价 backend。 Host 只有在 source import 前缀、requirements、state class 与已验证 shard 相容时才选择 Pysolate-WASM;任何未知或不可静态确定的情形都选择 native,或在 native 不可用时返回 typed unavailable。WASM 执行后只有一种窄 promotion 合法:WASM 在 workspace/effect 尚未开始前返回 Host-authored UnsupportedRunError,Orchestrator 将其包装成 runtime_unsupported/not_started,再以 parent decision identity 发起 native child。普通 Python 异常、Guest 错误、超时、输出错误和已经启动的工作都不隐式重试。
| 状态 | 本 snapshot 能证明的内容 | 不能升级为的结论 |
|---|---|---|
| Current | registry.v1 的 base、attrs-770、numpy-core 三个命名 profile;严格 lock/manifest/import inventory/qualification;plain/base 当前 placement;Wazero fresh Guest;native OCI/runsc、Unix HTTP capability RPC、cleanup/lifecycle evidence;typed unsupported promotion。 | 不能说已支持任意 Python 包、任意 native extension、任意 NumPy ABI 或自动 package installation。 |
| Experimental | numpy-core 的 static-native package selection、固定 19 个 native modules + 2 个 support archives、PrepareNumpyCOWShard / DeriveNumpyI64COWDataset 等研究/机制 lane;native backend 的真实 runsc 需要外部环境。 | 不能说 NumPy 已由通用 scheduler 自动选择,不能说 COW 是通用 Python runtime snapshot 或生产性能优化。 |
| Historical | docs/evidence/attrs-770-profile-v1.json、semantic-placement-census-v0.json 等仓内报告记录过 profile/placement 结果,但它们各自绑定的 source commit 不是本审查 commit。 | 不能把历史 artifact digest、campaign/report 计数当成 b94c989... 的 live execution proof。 |
| Deferred | generic multi-shard Host placement(例如在 plain 之外根据 numpy-core/其他 shard 自动匹配)、将 package profile 完整纳入统一 ExecutionArtifact contract、更多 native/image backend、真实 production admission/performance。 | 不应从存在 numpy shard identity 或 helper API 推断这些能力已经接入默认 router。 |
| Unsupported | unknown/dynamic/late/relative/compound import 对 Pysolate-WASM 的静态资格;重复/未知 profile;未锁定 package;WASM/native 间的隐式等价;ordinary failure promotion。 | “native 被选中”不等于 native 已经证明能完成该任意任务;它只是保守 placement/兼容性 lane。 |
2. 源码地图(精确 snapshot)
下表给出可复查的 source path 和 symbol;行号只是该固定 tree 的辅助锚点,symbol 是主要锚点。
| 层 | 源码路径与 symbol | 结论 |
|---|---|---|
| untrusted request | runtime/request.go:RunRequest、DecodeRunRequest、RunRequestSHA256 | request 只有 code/inputs/声明性 Compatibility/Requirements,不携带 capability、credential、mount、budget;严格 JSON、重复键、unknown fields、requirements/compatibility schema 在进入 backend 前拒绝。 |
| source admission | runtime/source_compatibility.go:InferStaticImportRoots | 只接受 initial top-level import preamble;dynamic import、nested/late/relative/compound/multiline import 返回 ErrSourceCompatibilityIndeterminate,不猜测。 |
| named execution profile | runtime/profile.go:NewExecutionProfile、Validate、BindVerifiedArtifact、EvaluateRunCompatibility | profile 是 Host-owned admission policy;声明是 untrusted narrowing hint,不能安装包、选择 artifact 或授予 Host capability;binding 时才加入 artifact/manifest/import discovery/qualification identity。 |
| artifact contract | runtime/artifact.go:VerifyDistributionArtifact、validateDistributionManifest;runtime/execution_contract.go:ExecutionArtifact.Validate、NewShardProfile | manifest/sidecar 可把 profile、package、digest、import closure 绑定成 identity;但 generic execution artifact 的 backend-specific validation 仍只接受 WASM base/plain 与 native native-python,见第 5 节的边界。 |
| placement | runtime/placement/placement.go:Analyze、makeDecision、Orchestrator.Execute | 当前 Policy 只有一个 PlainShard;决策 identity 绑定 request digest、reason、state、analyzer、WASM shard identity 和 parent decision。 |
| portable backend | runtime/engine/wazero/engine.go:Factory.New、newEngine、runWithPrepares、PrepareNumpyCOWShard | Wazero 以 wasm bytes 计算 artifact digest,验证 config/profile 后创建 WASI runtime;每个 Run 以 fresh Guest instance 为原则;requirements/profile compatibility 在 workspace 使用前检查。 |
| native backend | runtime/engine/native/backend.go:Backend.ExecuteWithEvidence、validateConfig、reconcileRunsc;oci.go:writeOCIBundle;rootfs.go:VerifyOCIImageConfig、RootFSIdentity | native lane 绑定 OCI image config digest、rootfs tree digest、native artifact identity、runsc state、bounded resource、workspace lease、RPC plan,并在 terminal 前后做清理核对。 |
| native capability bridge | runtime/capabilityrpc/registry.go:Registry.Open、Check、Dispatch;http.go:HTTPHandler;native/python/_agent_runtime_host.py、runner.py | native Python 通过私有 Unix HTTP channel 调 Host Broker;channel/credential/invocation/execution/Plan identity、expiry、call identity 和 replay/ambiguous 状态由 Host registry 约束。 |
| evidence verification | runtime/verification/native.go:VerifyNative、VerifyNativeAttempt | native evidence 必须同时绑定 decision、artifact、image/rootfs、execution、Plan、receipts、cleanup、workspace lease 和 terminal status;这是 evidence validator,不是 external-world truth。 |
3. Artifact、manifest、lock 与 package profile:它是什么,为什么不是 package manager
3.1 封闭 registry 与 build-time selection(Current)
guest/build/profiles/registry.v1.json 固定:
base:kind=base,artifactagent-python-runtime.wasm,required roots 为agent_runtime/json/sys,无 package lock、无 recipe、无 private input。attrs-770:kind=pure-python-package,lockattrs-770.lock.json,recipeattrs-770-v1,import rootattr,private input 只有extension_patch。numpy-core:kind=static-native-package,locknumpy-core.lock.json,recipenumpy-static-v1,import rootnumpy,private input 为空。
guest/build/package_profile.py 的 validate_registry、load_registry、resolve_profile、load_package_contract 和 source_lock_projection 对字段集合、profile ID、文件名、kind、required import roots、lock/recipe/private inputs 做严格校验;重复 profile、路径逃逸、未知字段和非 registry profile 都失败。build-guest.sh 在 cache key 和 build recipe 之前先解析 registry,默认是 AGENT_RUNTIME_ARTIFACT_PROFILE:-base。这说明 profile 是构建选择和验证身份,不是运行时下载器。
它明确不做以下事情:
- 不根据
import pandas临时下载 pandas; - 不在 Guest 内执行 runtime package installation;
- 不解析开放世界 dependency graph;
- 不把 untrusted
CompatibilityDeclaration当成安装或授权请求; - 不因为 native lane 能运行较宽的 CPython 就把任意包变成已支持包。
3.2 Source lock、artifact manifest 与 import closure(Current)
构建链的闭环是:
registry profile
-> profile lock / recipe
-> source-lock projection + fetch/verify
-> deterministic package tree / native archive selection
-> CPython-WASI VFS staging + Wasm build
-> target-Guest import inventory
-> target-Guest restricted import qualification
-> manifest + sidecars
-> VerifyDistributionArtifact / verify-artifact.py
-> Host-bound ExecutionProfile
关键约束如下:
sources.lock.json固定 CPython 3.14.0、WASI SDK/toolchain/VFS 等 source/toolchain 的 URL、version、SHA-256、license、role 和artifact_relation;package profile 的 source projection 只引入被选 profile 所需的 source rows。attrs-770.lock.json绑定 source commit、archive digest、patch digest、package tree digest、file count/bytes 与 qualification operations。extension_profile.py的validate_lock、package_tree_identity、build_selection、validate_selection使 source patch 与复制后的 package tree 不能静默漂移。numpy-core.lock.json把 NumPy 固定为1.26.0b1的 source commit/archive digest、CPython/WASI SDK 版本、recipe/reference build identity、19 个native_modules和 2 个 support libraries。native_package_profile.py的registration_header生成PyImport_AppendInittabregistration;build_selection对 package tree、每个.aarchive digest/size、link count 和整体 selection identity 复核。policy 中runtime_package_installation、dynamic_native_loading、external_prebuilt_artifact均为false。guest/build/write-manifest.py将 artifact filename/size/SHA-256、repository commit、target、sources、packages、extension profile、import inventory/qualification sidecar 记录进 manifest;verify-artifact.py与 GoVerifyDistributionArtifact对未知字段、artifact digest、source set、package set、WASM imports/exports、sidecar digest 和 required roots fail closed。guest/build/import_inventory.py的 probe 是 target Guest 的importlib.util.find_spec/pkgutilinventory;guest/build/import_qualification.py不是泛化 benchmark,而是固定的 restricted-agent-body probes。numpy只被证明为numpy_core_oracle,其 probe 具体检查版本、arange、dtype、buffer、矩阵乘法等固定 oracle;这不等价于通用 NumPy API coverage。
runtime/profile.go:BindVerifiedArtifact 要求 manifest/artifact identity 与 named profile 一致,要求 ImportRoots 与 QualifiedImportRoots 非空且有界,并要求 profile 的 allowed imports 都在 qualified roots 中。此处的 qualified root 是目标 Guest 的导入资格证据,不是 Host 直接授予的 capability。
3.3 package shard 的真实状态(Current / Experimental / Deferred)
plain/base(Current):runtime/execution_contract.go:NewShardProfile接受plain -> base,并把 qualified imports、artifact digest、manifest digest、prepared baseline digest、idle policy canonicalize 后 hash。runtime/placement.Policy目前只存这一 shard;所以这是默认 placement 实际消费的 WASM shard。attrs-770(Current build profile;Deferred generic placement):其 artifact/manifest/qualification 闭环在 build/verifier 和VerifyDistributionArtifact结构中存在,仓内 historical profile report 也记录过一次 supported fixture;但当前NewShardProfile没有attrs-770shard 映射,Placement.Policy也没有 attrs shard。因此不能声称 router 会自动将import attr送入 attrs WASM。numpy-core(Experimental package profile / research lane;Deferred generic placement):static-native package selection、manifest identity、Go artifact fixture、PrepareNumpyCOWShard/derived dataset helper 与固定 NumPy oracle 存在;但当前NewShardProfile只认识numpy -> numpy-core,Policy不持有该 shard,Analyze只比较PlainShard.QualifiedImports(),WASMExecutionArtifact.Validate又只接受ProfileID=base, ShardID=plain。因此当前默认 placement 下import numpy会进入 native(ReasonNoQualifiedShard),而不会自动切换numpy-coreWASM shard。
这正是“package profile 不等于 package manager”的关键边界:profile build 支持、artifact verification、runtime profile identity、placement consumer 是四个不同接入点;前两者存在,不代表后两者已经完成多 shard 调度。
4. Execution profile identity 与 trust boundary
4.1 profile identity(Current)
NewExecutionProfile 只接受固定命名 ID base、attrs-770、numpy-core,allowed imports 最多 64 个、每个 root 严格校验且不可重复。BindVerifiedArtifact 是纯函数式绑定:不改变原 profile,而复制 allowed/import maps,加入 artifact SHA-256、manifest SHA-256、available roots、qualified roots。ExecutionProfileBindingSHA256(runtime/profile_binding.go)进一步将 schema、profile ID、artifact/manifest digest、allowed imports 和 deterministic verification identity canonicalize 后 hash。
因此应区分三个东西:
- untrusted declaration:request 中
compatibility.profile/imports,只能收窄 admission; - Host-owned policy:
ExecutionProfile的 named allowed imports; - verified artifact identity:
VerifyDistributionArtifact产出的 profile/artifact/manifest/package/import closure/qualification 关系。
runtime/engine/runner.go:Properties.Validate 可以校验 backend properties 是否能由这些 identity 重建;wazero.Engine.Properties 把 Wazero backend、profile、imports、artifact/manifest digest 和 profile binding digest 投影出来。这个 projection 是可验证描述,不是再次下载或重新测量 artifact。
4.2 backend-specific artifact contract 的不完整接缝(Deferred / 不确定项)
runtime/execution_contract.go:ExecutionArtifact.Validate 的硬编码是:
- WASM:
kind=wasm_distribution、profile_id=base、shard_id=plain、target=wasm32-wasip1,只允许 artifact/manifest digest; - native:
kind=oci_image、profile_id=native-python、无 shard、target 为linux/amd64或linux/arm64,只允许 image/rootfs digest。
这与 VerifyDistributionArtifact 能验证 attrs-770/numpy-core、NewExecutionProfile 能构造这两个 profile、以及 NewShardProfile 能构造 numpy shard 并不矛盾,但说明统一 artifact contract 尚未覆盖所有 package profile。engine.New 对 Wazero 只把实际 wasm bytes 的 SHA-256 与 bound profile artifact digest 比较;manifest 的真实性依赖调用方此前已执行 VerifyDistributionArtifact,Wazero constructor 本身不从 manifest path 重新取证。本文不能确认外层生产 caller 是否在所有入口都完成这一步,因此把“统一 package-profile artifact admission 已接通”列为 Deferred/不确定,而不是 Current。
5. Host 如何选择 placement
5.1 decision order(Current)
runtime/placement.Analyze(request, state, modelRisk, policy) 的决策优先级是:
- policy 必须是
static-v1,必须有 identity 非空的plainshard,state class 必须是显式枚举;否则ErrInvalidPolicy。 - 先计算
RunRequestSHA256,所有后续 decision identity 都 request-bound。 state != portable_value:native,reason=native_state_dependency。modelRisk:native,reason=model_risk_signal。- 有
Requirements:先ValidateRunRequirements;合法的 requirements 仍是 capability/compatibility declaration,不是 grant,placement 选择 native,reason=required_native_feature。 - 否则调用
InferStaticImportRoots:- inference error:native,reason=
source_indeterminate; - roots 不在
PlainShard.QualifiedImports()中:native,reason=no_qualified_shard; - request 的 compatibility declaration profile 不等于 plain shard 的 execution profile,或声明 imports 与静态 roots 不同:native,reason=
no_qualified_shard; - roots 合法且 qualified:若 Pysolate 可用,选择
pysolate_wasm,reason=qualified_plain_shard。
- inference error:native,reason=
- 如果 Pysolate 不可用而 native 可用,选择 native,reason=
pysolate_unavailable;两个 backend 都不可用则 typedStatusUnavailable。 - native 已被选择但 native 不可用时,返回
StatusUnavailable/reason=native_unavailable;不降级到较弱的 WASM。
makeDecision 对 WASM 加入 ShardID=plain 与 ShardSHA256;native decision 不伪造 WASM shard。ParentDecisionID 只在 promotion child 上出现。这个结构把“选择原因”和“可重算的 identity”分开,避免依赖普通错误字符串。
5.2 为什么 unknown / indeterminate 必须走 native
这里的 native 不是“已证明更安全/更强”的同义词,而是当前 Pysolate-WASM qualification 不足时的兼容性出口:
- Pysolate 的已验证 shard 只有有限
QualifiedImports;unknown import 没有可验证的 artifact/import closure 绑定。 - dynamic import、nested import、late import、relative import、compound/multiline import 会使静态 roots 不确定;把“不确定”当作“没有 import”会把未审查的 Guest execution 错放入 WASM。
CompatibilityDeclaration是 untrusted metadata,不能用它把 source 中实际没有出现的 imports 或未 qualification 的 imports 变成合格。Requirements的存在代表调用方声明需要当前 plain WASM contract 未覆盖的 feature;它只会收窄 admission,不是授权证明。- native runner 的 CPython surface 更宽,适合执行兼容性尚未被 WASM profile 证明的请求,但其成功仍需 native image/rootfs/RPC/cleanup contract;native selection 不是 arbitrary Python support claim。
因此 router 采用 fail-closed 的方向:未知不是 WASM 的 positive match,而是 native 的 conservative placement;native 不可用就显式 unavailable。 这比“先试 WASM,异常了再猜 native”保留了错误来源与 authority boundary。
5.3 placement 的可复查矩阵
| 输入条件 | 当前 decision | 说明 |
|---|---|---|
| 无 import、portable value、无 risk/requirements、plain 可用 | pysolate_wasm / qualified_plain_shard | 允许的最窄 WASM lane。 |
import json,且 json 在 plain qualified roots | WASM | 只证明该 root 在 profile qualification closure 内;不证明任意 Python code 都成功。 |
import numpy | native_sandbox / no_qualified_shard | 当前 Policy 没有 numpy shard consumer;不是自动选择 numpy-core。 |
__import__('json')、nested/late/relative/compound import | native_sandbox / source_indeterminate | 静态 contract 无法确定,拒绝猜测。 |
Requirements=[shell/subprocess/posix...] | native_sandbox / required_native_feature | 先做 typed requirements validation;合法 declaration 仍不授予 capability。 |
StateWorkspaceRef/StateProcessRef/StateOpaque | native_sandbox / native_state_dependency | state dependency 不能被 portable WASM 假装已迁移。 |
| model risk | native_sandbox / model_risk_signal | Host policy signal,非 Guest source proof。 |
| native unavailable 且原请求需 native | StatusUnavailable | 不退回 WASM,不使用较弱 execution。 |
Pysolate 运行中返回 typed UnsupportedRunError | native child promotion | 仅在 not_started outcome contract 通过时发生,见下一节。 |
| Pysolate 普通 error | 原 error | 永不隐式 promotion。 |
6. End-to-end lifecycle:direct lane、typed promotion、native lane 与重新选择
6.1 统一入口到 backend
raw request
-> DecodeRunRequest(Host strict JSON/schema)
-> Analyze(request digest + state + requirements + source imports + policy)
-> selected Decision(identity)
-> Pysolate Runner 或 native Backend
-> typed payload / typed unavailable / ordinary error
Wazero runWithPrepares 的前置顺序是:request size bound → DecodeRunRequest → AdmitRunRequirements → EvaluateRunCompatibility → deterministic admission → observation/invocation identity → timeout/workspace gate → prepared/COW choice → module init/runtime init → Guest source validation → capability Broker → trusted prepare chunks → callExecute → response/evidence validation → finalization/close。特别是 requirements 和 compatibility 在 ensureWorkspace 前检查,因此 typed requirements rejection 可保持 WorkspaceNotStarted。
6.2 为什么只允许 typed unsupported/not_started promotion
Orchestrator.Execute 在 placement 后执行所选 backend:
- 若 initial decision 已是 native,直接进 native;native error 不转 WASM。
- 若 initial decision 是 WASM 且成功,直接返回。
- 若 WASM 失败,只有
errors.As能拿到*UnsupportedRunError才继续。 NewUnsupportedOutcome(raw, executeErr)必须由 Host 根据 typed error 生成;普通ImportError: pretend native等 Guest exception text 不能升级。outcome 必须是runtime_unsupported、EscalationRequired、reason=required_features_unsupported、WorkspaceDisposition=not_started、EffectDisposition=not_started,并绑定 request SHA-256。- 只有 outcome validate 通过、native backend 存在且
NativeAvailable时,才生成 child decision:backend=native、reason=l2_not_started_promotion、ParentDecisionID=initial WASM decision.Identity。 - native child 失败时返回 child decision + promotion outcome + native error;不再回到 WASM,也不重复提交同一 WASM call。
“not_started”是 authority boundary,不是礼貌性标签:它说明此前 WASM backend 没有可继承的 workspace/effect;因此 child 可以是新的 physical attempt,但不宣称是原 Guest continuation,也不继承已开始的副作用。runtime/placement/placement_test.go 的 TestOrchestratorRunsPlacementBeforeBackendAndSupportsBoundedL2 与 TestOrchestratorNeverPromotesOrdinaryFailure 正是这两个分支的契约。
6.3 native OCI/runsc/RPC lane(Current implementation;运行环境依赖)
native.Backend.ExecuteWithEvidence 的实际顺序是:
validateConfig:要求 runsc/rootfs/state root、platform、host_uds=open、network=sandbox、image digest 与Artifact.ImageDigest相等、native artifact valid、Plan identity 非空、timeout/output/memory/pids bounds 合法;workspace 只允许与StateWorkspaceRef一起出现。VerifyOCIImageConfig对绝对 config path 的 JSON 内容重新 hash;RootFSIdentity对 rootfs 的 path/type/mode/size/content/symlink 做 bounded tree digest,拒绝空 root、special file、超限 rootfs。digest 与 native artifact 比较。- 为本次 physical attempt 生成随机
executionID,如有 workspace 则以该 ID acquire/snapshot/bind mount source。 - Host 创建 capability Broker、随机 credential/channel/invocation identity、短期 Unix socket 和
capabilityrpc.Registrychannel;channel 绑定 execution ID、Plan SHA-256、expiry、max frame bytes。 - 生成
pysolate.native-run.v1stdin envelope(request + Hosttrusted_prepare),写 OCI bundle:readonly root、/run/pysolateRPC bind mount、可选/workspacebind mount、proc/dev/tmp mounts、pid/network/ipc/uts/mount namespaces、memory/pids cgroup 与noNewPrivileges。 - 通过
runsc run --bundle执行/usr/local/bin/python3 /opt/pysolate/runner.py。container 内_agent_runtime_host.py只可通过带 Bearer credential 的 Unix HTTP/v1/ready、/v1/calls访问 Host Broker;runner.py先 ready,再执行 trusted prepare 与 request code,最终输出 bounded JSON。 - Host 收集 stdout/stderr、exit status、wall/CPU/RSS/cgroup/PSS/private dirty/I/O/PIDs;同时读取 capability receipts 和 workspace before/after tree。
- Host revoke channel、关闭 HTTP server/socket、
runsc delete --force并等待runsc list --format=json为空、unmount control root、release workspace lease、删除 scratch/runsc state;最后将 cleanup dispositions 投影成Evidence,再由VerifyNative做 identity/terminal/receipt/cleanup validation。
RPC 的 Dispatch 对相同 call_id + 相同 call digest 返回 Replayed=true 的缓存 response;相同 call_id 但 digest 不同返回 ErrCallIdentityMismatch;in-flight 返回 StatusAmbiguous;Broker error 返回 dispatch_outcome_unknown。这是channel 内的 call-idempotency/ambiguity contract,不是把整次 Python Run 变成可 replay 的语义等价物。
6.4 native lane 结束后,为什么后续无状态依赖调用可以重新选 WASM
StatePortableValue、StateWorkspaceRef、StateProcessRef、StateOpaque 是显式分类,而非由 backend 名称猜测。native 执行结束后:
- native physical execution 有自己的随机
executionID、自己的 process/container、自己的 channel/Plan/receipts 和 cleanup; - workspace state 若存在,必须由 workspace tree/lease lineage 表达;不能把 native process/heap/pointers 隐式装进下一个 WASM request;
- cleanup/release 完成后,后续 request 若只携带 portable values,
Analyze重新从 request/state/policy 计算 decision,可选 plain WASM;这代表fresh backend selection,不是恢复 native process,也不是复用 native interpreter state; - 若后续 request 仍是 workspace/process/opaque state dependent,state class 继续强制 native;不会因上一次 native 已“成功”而假装 state 已可移植。
因此 “native 之后又选 WASM” 是合法的无状态边界重选:逻辑数据通过显式 JSON/portable value 进入新 request,backend state 不跨 lane 隐式传播。cmd/pysolate-native-probe/main.go 的设计性 probe 也把 workspace write/read 留在 native lane,再对 StatePortableValue 请求单独调用 placement.Analyze 期待 WASM;该 probe 是机制/证据路径,不是 production benchmark。
7. Host / Guest / shared / private ownership
| 对象 | owner / trust | 生命周期与边界 |
|---|---|---|
| registry、lock、manifest、artifact/image/rootfs digest | Host/build pipeline | 由 registry/lock/verifier 产生;Guest 不能改 profile identity,也不能借 request metadata 安装包。 |
ExecutionProfile、ShardProfile、placement Policy/Decision | Host | profile/shard identity、qualified imports、decision parent、availability 和 state class 均由 Host 计算/验证。 |
| request code/inputs/result | Guest execution input/output;Host 只做 envelope/schema/size/identity gate | Guest 仍是 unchanged logical execution boundary;Host 的 import heuristic 只是 admission helper,不能替代 Guest source validation。 |
| WASI runtime、Wazero module、prepared/COW mapping | Wazero/Host lifecycle | 每次 generic Run 是 fresh Guest;COW/prepared 是特定实验/机制,不能解释成通用 live continuation。 |
| capability Plan/Grant/Broker/receipt | Host | Guest 只有 generated projection;真实 handler dispatch、grant、Plan identity、receipt 和 close 由 Host Broker 掌握。 |
| native process/container/rootfs/runsc state | Host native backend | 每次 native attempt 独立;OCI root readonly,RPC/workspace 是显式 bind mount;runsc/process/container 不向下一个 request 转移。 |
| Unix RPC channel/credential/socket | Host private | credential、socket path、channel ID、execution ID、Plan digest 只为本次 lane;channel expiry/revoke/cleanup 后不可再用。 |
| workspace tree/lease | Host workspace manager;Guest/native 可通过显式 mount 产生修改 | workspace 是跨调用的显式 shared state;必须以 lease/tree identity 传递,不能由 Python heap 或 backend name 推断。 |
| evidence | Host-authored projection of physical lifecycle | digest、counts、receipts、cleanup 和 resource aggregates 可审计;不包含“外部世界真相”,也不等价于 syscall trace 或 production security proof。 |
| raw bodies / credentials / private path details | private operational data | 本审查不将 raw source、inputs、RPC credential、private task body 或完整 native stdout 当作 public evidence;checked-in evidence 多为 digest/aggregate/projection。 |
8. Backend conformance 与 evidence 边界
8.1 可引用的静态测试契约(本审查未执行)
以下是固定 tree 中存在的测试,说明局部不变量;它们不是本次审查运行结果:
runtime/placement/placement_test.go:TestAnalyzerRoutingMatrix覆盖 pure/stdlib/shell/unknown import/dynamic/workspace/model-risk;TestAnalyzerReturnsTypedUnavailableWithoutWeakerExecution;两类 Orchestrator promotion/no-promotion 测试。runtime/source_compatibility_test.go:TestInferStaticImportRootsFailsClosed覆盖 dynamic、nested、late、relative、multiline、compound import。runtime/profile_test.go、runtime/artifact_test.go:named profile、manifest/package/import qualification binding、attrs/numpy fixture、legacy sidecar 缺失、digest/field/source/module drift fail closed。runtime/execution_contract_test.go:TestShardProfileIdentityIsCanonicalAndDefensive、TestExecutionArtifactValidationIsBackendSpecific、state/lease class explicitness;这也暴露了 WASM artifact contract 目前只认 base/plain。runtime/engine/runner_test.go:Properties 只能由 verified profile/artifact identity 重建,拒绝 incomplete artifact identity。runtime/engine/wazero/engine_test.go、trusted_prepare_test.go、cow_memory_linux_test.go:fresh Wazero/COW 形状、trusted NumPy profile、baseline drift、prepared/fallback 机制局部约束。runtime/engine/native/oci_test.go、rootfs_test.go、backend_evidence_test.go:readonly root/resources/mount、image config digest、rootfs content/mode/symlink/special-file rejection、lifecycle projection。runtime/capabilityrpc/native_python_test.go:real local CPython + generated projection + Unix HTTP Broker call/receipt 的机制 fixture;不是 runsc OCI E2E。runtime/verification/native_test.go:decision/artifact/evidence/receipt/cleanup mutation fail closed,区分 successful 与 failed attempt。guest/tests/test_package_profile.py、test_manifest.py、test_native_package_profile.py、test_extension_profile.py:registry、lock、tree/archive identity、merged source lock、static module registration、package selection drift。guest/tests/test_import_inventory.py、test_artifact_contract.py:target Guest inventory/qualification sidecar、unknown fields/duplicate keys、attrs/numpy manifest/package/source/qualification binding。integration/e2e/natural_placement_canary_test.go:自然 placement canary 的测试入口存在;不能由文件存在推断本次执行或生产覆盖。
8.2 仓内 machine-readable evidence 的正确读法
docs/evidence/attrs-770-profile-v1.json标为 historical profile report;其build.source_commit=26f2dd5...,不是审查目标b94c989...。它支持“曾有一个固定 attrs profile fixture/qualification 的记录”,不支持“目标 commit 已在生产支持 attrs”。报告自身的non_claims也明确排除通用 package manager、native extension、scheduler、完整 Open-SWE replay。docs/evidence/semantic-placement-census-v0.json的 target artifact source commit 为eb08ae94...,且semantic_backend=unknown、backend_contract_missing、integration_decision=no_go。对应docs/research/semantic-placement-census-v0.md的结论是 semantic overlay 没有 canonical backend requirement,当前 router 保留。这是 historical no-go,不能被改写成 target commit 的新 placement consumer。docs/evidence/natural-placement-open-swe-v1.json的 claim boundary 只支持“一条冻结 natural coding trajectory 在 Guest start 前的 conservative placement”;它明确不支持 coding task execution、native backend correctness、model success、general placement optimality。即使其 report 在仓内,也不能扩展为 production throughput/security 结论。- NumPy producer/admission/reuse evidence 若被引用,只能作为固定 NumPy operation/COW/producer lane 的历史或实验性 evidence;其
execution_profile_id=numpy-core不等于当前runtime/placement.Policy已实现 generic numpy shard selection。
9. Trade-offs、明确拒绝的替代方案与 failure semantics
- 保守 native vs 猜测 WASM:选择 native 会增加 container/transfer/RPC/cleanup 成本,但避免把未 qualification 的 import 或未确定 source 当成 portable;拒绝“unknown 默认 WASM”。
- 显式 typed promotion vs exception-text retry:typed
UnsupportedRunError可证明not_started和 request binding;普通异常无法证明副作用边界,拒绝“看到 ImportError 就 native retry”。 - WASM 与 native 分开 identity:WASM 绑定 artifact/manifest/profile/shard;native 绑定 OCI image/rootfs/native artifact。拒绝用同一 digest/schema 把二者写成等价执行。
- 封闭 package profile vs generic package manager:registry/lock/recipe 可复现、可验证、可审计,但覆盖有限;拒绝 runtime install、开放 dependency resolver 与任意 wheels。
- fixed NumPy static lane vs generic object ABI:19 个静态模块、2 个 support archive、固定 registration 和 oracle 能给出窄而可复查的机制;拒绝把它升格为任意 dtype/object/extension/native ABI。
- fresh native attempt vs process reuse:fresh execution/cleanup 简化 authority 和 evidence,代价是每次启动/验证/transfer;拒绝把 native runsc process/heap 作为后续 WASM 的隐式 state。
- aggregate lifecycle evidence vs full tracing:cleanup、resource sample、receipt 和 identity 足以验证 backend contract 的一部分,但没有 syscall-order trace、完整 instruction trace 或 external-world oracle;拒绝 production security/performance 宣称。
- current router vs semantic placement replacement:historical census 中 semantic backend contract 缺失且 integration
no_go,所以保留 current Host router;拒绝用一个 unknown semantic overlay 替换已决定的 Host placement。
10. What the implementation does not establish(Non-claims)
- 不证明 production-grade sandbox security;OCI config 的
noNewPrivileges、namespace、readonly root、bounded resources 和 cleanup checks 只是实现/fixture contract,不是完整 adversarial security audit。 - 不证明 production latency、throughput、cost、RSS 或 native-vs-WASM performance;
RootFSVerifyNanoseconds、wall time、resource samples 是单次 evidence fields,不是 benchmark theorem。 - 不证明 Wazero 与 native 语义等价;两者的 import/WASI/FS/state/capability/runtime behavior 不同,native 的 CPython broad compatibility 也不是 arbitrary Python correctness。
- 不证明 generic Python package support、package installation、wheel compatibility、dynamic loading、ctypes/dlopen、threads、subprocess 或 arbitrary NumPy API support。
- 不证明 package profile 被默认 placement 自动消费;尤其
attrs-770、numpy-core的 build/verifier 支持与当前plain-only Policy 是两个状态。 - 不证明 NumPy COW baseline 是 live Guest continuation、generic snapshot/restore、zero-copy transfer 或 production reuse scheduler。
- 不证明 native RPC 的 replay record 是整次 Run replay;它只处理一个 channel 中 call identity、completed cache 和 ambiguous in-flight outcome。
- 不证明 evidence receipt 是外部世界事实、完整 syscall trace、完整 source effect trace 或 model/provider task success。
- 不证明 historical JSON report 与本固定 commit 的 artifact/runner/evidence 同一;必须使用其内部 source/tree/digest identity 重新归类。
11. 答辩准备:一句话与追问回答
一句话: Pysolate 把 Host placement 变成一个带 request/profile/shard/state identity 的显式决策:只有已验证 plain WASM shard 能证明的 portable source 才进 Wazero;未知或不确定就走 native,WASM 只有在尚未开始 workspace/effect 且返回 typed unsupported 时才允许一次有 parent identity 的 native promotion;native 完成后若下一次调用只依赖 portable value,Host 可以重新选择 fresh WASM,但绝不恢复或假装继承 native process state。
“为什么不先试 WASM?” 因为 ordinary failure 无法证明 workspace/effect 尚未开始;只有 Host typed UnsupportedRunError + runtime_unsupported/not_started 才具备 promotion contract。先试会把执行失败、部分副作用和兼容性 rejection 混在一起。
“为什么 unknown 走 native?” 因为 unknown 不是 positive qualification。动态/late/relative/compound import 不能由 Host heuristic 安全补全;native 是 compatibility fallback,若 native 不可用则显式 unavailable,而不是静默使用较弱 WASM。
“package profile 是不是 package manager?” 不是。它是封闭的 registry/lock/recipe/artifact/manifest/import qualification identity;没有 runtime install、开放 resolver 或 untrusted package request authority。
“NumPy 已经接到 scheduler 了吗?” 不是当前结论。numpy-core 有 static build/profile、manifest binding、fixed native-module inventory 与 experimental COW helper;但 Placement.Policy 仍只消费 PlainShard,ExecutionArtifact.Validate 的 WASM contract 仍是 base/plain,所以默认 import numpy 走 no_qualified_shard -> native。
“native 成功后为什么还能回 WASM?” 因为重新选择发生在新的 request 上,前提是 state class 是 portable_value;portable JSON lineage 与 native process/lease/channel 完全不同。若依赖 workspace/process/opaque state,仍强制 native。
“这些测试是不是 production proof?” 不是。unit tests 证明局部 invariant,Unix HTTP test 证明 local generated projection/Broker seam,OCI/rootfs tests 证明 config/digest/cleanup shape,历史 JSON 只支持其声明的 frozen denominator 与 claim boundary。本文没有将它们升级为 production security、performance 或 arbitrary Python support。
12. 审查不确定项(保留,不猜测)
- 固定 snapshot 中未发现一个可由
Placement.Policy自动枚举、验证并选择attrs-770/numpy-core的多-shard scheduler;因此 generic package-profile placement 归 Deferred。 ExecutionArtifact.Validate对 WASM 的 base/plain 硬编码与 profile/manifest verifier 的 attrs/numpy 支持之间存在 contract 接缝;需要后续 pinned-source review 才能确认外层 caller 是否始终先完成VerifyDistributionArtifact,本文不把 constructor 的 digest check 扩大解释为 manifest verification。- native
runsc的实际可执行性、宿主 kernel/cgroup/mount 权限和 image/rootfs 内容不由源码或 local RPC fixture 证明;本审查只确认 lane 的 source contract 与 validator。 - 历史 evidence 的 source commit/tree/平台与目标 commit 不同;未执行 campaign/CI,也未重新生成 artifact,因此不能给出本 commit 的 live timing、coverage 或 success count。
QualifiedImports与固定 import qualification 只界定窄 admission/qualification surface;它们不能回答 CPython C-level lazy import、direct WASI effect、native extension internals 或任意动态行为的完整 coverage。
复现与边界记录: 源码以 git archive b94c989785632d98634cdd5c2a6d4a1de6cc13ac 的 pinned snapshot 阅读;源仓库未写入、未 commit/push;本轮未运行 campaign/CI。