Pysolate authority spine 单切片源码审查
基线状态:Historical fixed-target dossier。 本文的
Current只表示下述b94c989...snapshot 中的实现事实,不是本科生 guide 的当前94fab78...目标。当前目标导航见implementation/source-map.md。审查对象:
/Users/yuzhe/projects/agent-python-runtime的精确 commitb94c989785632d98634cdd5c2a6d4a1de6cc13ac,tree6b8bb6a8d8274b8329a2aba444d13eac9fac19e9。审查方法:先读取本说明库的
WORKER_BRIEF.md,再以git show <commit>:<path>、固定 commit 的符号/行号和 focused tests 取证;不跟随 live worktree 漂移,不修改实现仓库,不运行 campaign,不 commit/push。一句话结论:本切片的 authority spine 是 Host 注册/封存
Spec + Grant -> Plan,Host 决定 presentation/origin,Guest 只经一个受约束 ABI/RPC 入口提交 JSON,Broker 在同一 Plan 下做 admission、approval 和 handler dispatch,Host 最后生成 receipt/effect evidence 并决定 terminal disposition。生成的 Python spelling、工具 schema、receipt 或 transport replay 都不是新的 authority issuer。
0. 范围、状态与证据纪律
0.1 本切片覆盖
严格覆盖以下关系,而不是重新审查整个运行时:
CapabilitySpec(源码类型名为capability.Spec)、Plan、Grant的 Host authority;- direct/programmatic/both Guest presentation,以及 Guest spelling 与 enforcement 的分离;
- Wazero
host_call与 native Unix-HTTP capability RPC 的 Host ABI bridge; - Broker 的 admission、origin/identity、schema/limit 检查、approval lease、handler dispatch;
- receipt、transport/effect evidence、observation 投影、ambiguity/reconciliation 和 terminal disposition;
- identity、limits、privacy、non-replay 约束及它们的失败语义。
明确不展开 semantic predispatch 的内部算法、candidate discovery、AST/静态分析、prepared data/COW、benchmark/campaign 或任意 Python 支持。CallStreaming 的 write ceiling 只在这里作为 authority 边界出现,不把 semantic predispatch 当成本切片的证明对象。
0.2 状态标签
- Current:可在冻结 commit 的源码/测试中直接定位的实现事实。
- Observed:本次在固定 target 上实际执行或从 machine-readable test output 观察到的结果。
- Framing:由源码结构作出的保守架构解释,不额外升级成外部世界事实。
- Historical:旧提交、旧 artifact 或设计背景;本审查没有把它们当作 target 行为证据。
- Deferred:当前接口/代码有明确 seam,但 durable reconciliation、跨后端完整 parity 等留待后续。
- Unsupported:当前实现/证据不能支持的强 claim。
Current / Observed:开始取证时实现仓库 HEAD 为目标 commit,tree 与 brief 一致,源码工作树无修改;源码读取按精确 commit 完成。目标说明库中其他未跟踪 review prompt 不属于本文件的审查对象。
Historical:本文件不使用旧 campaign 或旧 benchmark 来证明 authority spine;若未来引用旧 artifact,必须另列其 producer commit/artifact identity。
1. 源码地图与符号锚点
以下路径均相对于上述 target commit;符号优先于易漂移的行号。
| 层 | 精确源码路径与 symbols | authority 作用 / 证据 |
|---|---|---|
| Spec/Plan/Grant | runtime/capability/registry.go: Spec, PythonProjection, ApprovalRequirement, Registry.Register, Registry.Seal, Plan.Identity, Plan.EvidenceDocument, Plan.ToolSchemas, Plan.Grants, Plan.Present | canonical Host definition、封存 plan digest、公开 projection;handler/grant body 不进入公开 Plan document |
| Grant identity | runtime/capability/grant.go: Grant, GrantBinding, NewGrant, Grant.Identity, validGrant | canonical policy 的 SHA-256 identity;Grant 不保留 policy bytes |
| Presentation | runtime/capability/presentation.go: Presentation, Plan.Present, validProgrammaticParentCallID; runtime/capability/registry.go: generatePythonPreludeForParent | direct/programmatic/both 是同一 Plan 的 projection,不是三套 registry/handler |
| Run/origin wiring | runtime/config.go: RunConfig, RunConfig.Validate; cmd/apyrun/main.go: runIdentity, capabilityPlan, programmaticParentCallID, BrokerFactory | Host 选择 surface、parent、direct allowance、approval mechanism;默认 direct |
| Broker | runtime/capability/broker.go: Config, NewBroker, Broker.Call, Broker.CallStreaming, record, Finalize | 唯一 admission/dispatch seam;校验 identity、预算、Plan、schema、approval 与 handler |
| Approval | runtime/approval/controller.go: Proposal, Request, Record, Controller.Authorize, Approve, Reject, BeginDispatch, Complete, AbortApproved | Host-owned waiting/lease/linearization;不直接 dispatch handler |
| Wazero bridge | runtime/engine/wazero/engine.go: instantiateCapabilityHost, hostCall, runWithPrepares, projectHostEvidence | agent_runtime_v1.host_call 把 Guest memory 中的 bytes 送入同一 Broker;Host 注入最终 evidence |
| Native bridge | native/python/_agent_runtime_host.py: _identity, _post, ready, call; runtime/capabilityrpc/http.go: HTTPHandler; runtime/capabilityrpc/registry.go: Registry.Open, Check, Dispatch | invocation/execution/plan/credential 绑定的 Unix HTTP channel;仍回到同一个 Broker |
| Receipt/effect evidence | runtime/receipt/receipt.go: Receipt, NewAuthorized, BindSource, ValidIdentity; runtime/capability/transcript.go: TransportEvidence, EvidenceHandler, TranscriptEntry | Host 生成 operation identity、request/result digest、approval/parent/source binding;live transport evidence 与 result 同 frame |
| Response validation | runtime/response.go: RunResponse, validateCapabilityReceipts, WorkspaceReceipt.ValidateForStatus; runtime/engine/wazero/observation.go: capabilityCalls, complete, fail | Guest 不可 author Host plan/ref/receipt;最终 response/effect disposition 由 Host 重新投影/验证 |
| Terminal disposition | cmd/apyrun/workspace_binding.go: prepareDisposition, stageExport, publish, discard; cmd/apyrun/main.go: response validation/publish path | status/policy 决定 export/discard;先 stage 和 validate,最后原子 publish;不是事务 rollback |
2. Authority 对象与 ownership
2.1 Spec + Grant -> Plan:封存的 authority root
Current:Spec 是 canonical Host-owned definition,包含 capability name/version/description、effect class、playback policy、HandlerIdentity、input/output schemas,以及可选的 Python projection、approval requirement 和(本切片不展开的)pre-dispatch contract。Handler 接口明确指出:authority 与 schema selection 留在 Host,Guest 只能提交 JSON arguments(runtime/capability/registry.go:48-61,98-114)。
Current:Host 先用 NewGrant(policy) 对 bounded canonical JSON policy 做 canonicalization,并将 pysolate.capability-grant.v1 + policy 的 SHA-256 保存为 Grant.policySHA256。Grant 只暴露 Identity();GrantBinding 进入 Plan 时只有 capability name 与 policy_sha256(runtime/capability/grant.go:14-65)。
Current:Registry.Register 在 registry 未封存时完成 Spec normalization、input/output schema preparation、handler non-nil 检查、captured playback 的 EvidenceHandler 检查、Grant identity 检查和 Python name collision 检查。Registry.Seal 只允许一次,排序 specs/grants 后编码包含 schema version、max calls、capabilities、grant bindings 的 plan document,并对该 document 取 SHA-256 形成 Plan.identity(runtime/capability/registry.go:239-286,289-321)。
因此 authority 链是:
Host policy bytes + Host handler
-> NewGrant / Spec normalization
-> Registry.Register
-> one-shot Registry.Seal
-> Plan(identity, maxCalls, specs, grant identities, private registrations)
-> Broker admission / handler dispatch
Plan.EvidenceDocument() 只投影 frozen spec 与 grant identities,不投影 handler 或 raw grant policy(registry.go:360-367)。Plan.ToolSchemas()、Plan.PythonPrelude() 和 Plan.Present() 都是 defensive projection;它们不会扩展、替换或重新封存 Plan。
Framing:Plan digest 证明的是这组规范、预算和 grant identity 的一致性;它不是签名,也不单独证明 handler binary/source 的真实性或 policy 的外部世界语义。HandlerIdentity 被绑定进 Spec/Plan,但实际 handler implementation 仍是 Host-private registration。
2.2 ownership 边界
| 对象 | Host-owned | Guest-owned | shared / explicit join |
|---|---|---|---|
| authority | Registry、Spec、raw policy、Grant、Plan、handler、max calls、Broker config | 无 | ToolSchema/generated wrapper 只投影 Plan |
| identity | run identity、Plan SHA、parent/child sequence、channel credential、approval request、receipt ID | Guest local variables、自己构造的 JSON request | call ID 由 Guest spelling 产生,但必须通过 Host identity predicate |
| enforcement | Broker lookup/schema/limits/origin/approval/dispatch、ABI module/context、RPC registry | 只能调用 _agent_runtime_host 并处理返回值 | JSON bytes 经过 ABI/RPC 后重新 decode;不共享 mutable authority |
| privacy | raw Grant policy、handler closure、approval controller、RPC credential、source resolver token、workspace temp/capsule | Python namespace、result/logs、call spelling | receipts/transcripts 仅输出 bounded digest/evidence |
| effect evidence | result/transport evidence、receipt、observation、workspace snapshot/disposition | Guest result/model output contract | Host 将 evidence 加入最终 response,并严格验证 |
Current invariant:Guest response 自带 capability_plan_sha256 或 execution_ref 会被 projectHostEvidence 拒绝;Guest 不能通过填充 receipts 把它们升级成 Host evidence(runtime/engine/wazero/engine.go:1260-1359)。
3. Presentation 与 enforcement:Guest spelling 不是 authority
3.1 三种 surface 是同一 Plan 的 detached projection
Current:Plan.Present(mode,parentCallID) 的规则是:
direct:公开ToolSchemas,parent 必须为空;programmatic:要求合法 parent,生成带 parent 的 Python prelude,不公开 direct tools;both:同时公开ToolSchemas与 programmatic prelude,且要求合法 parent;- 其他 mode 或非法 parent 直接
ErrInvalidProgramSurface。
Presentation 只含 mode、tool schema、Python prelude、parent ID;不含 handler、Grant policy bytes 或 Broker pointer(runtime/capability/presentation.go:18-55)。
generatePythonPreludeForParent 生成的函数最终都执行:
Python wrapper / alias / module.method
-> _capability_call(canonical Spec.Name, arguments)
-> _agent_runtime_host.call(JSON request)
-> response.status == "ok" ? result : RuntimeError
direct 与 programmatic 的差异只在 call ID:direct 为 capability-<sequence>;programmatic 为 <parent>:program:<sequence>(runtime/capability/registry.go:680-734)。这说明 Python module、method、global alias 是 presentation spelling,不是第二套 authority namespace。
3.2 direct/programmatic origin binding
Current:cmd/apyrun/main.go 从 canonical request bytes 的 digest 前缀得到 Host runIdentity(host-<first-8-bytes>),先封存 capabilityPlan,再在非-direct surface 中生成 programmaticParentCallID = runIdentity + ":program"。每个 per-run Broker 获得同一个 Plan、RunIdentity、parent binding;both 额外打开 AllowDirectCalls(main.go:125-130,232-267)。
Current:Broker.call 在解析、bounded JSON 和 duplicate-key gate 后,在锁内计算预期 programmatic child:
expected = parent + ":program:" + (programmaticCalls + 1)
命中预期值才标记 programmaticCall=true 并绑定 ParentCallID;若存在 parent binding,非匹配的 reserved :program: 或不允许的 direct call 被拒绝。both 允许 parent-bound programmatic calls 与 ordinary direct calls 共用同一 Broker;它不允许 direct call 冒充 reserved programmatic namespace(broker.go:224-254)。
runtime/response.go:501-510 对最终 receipt 再验证该关系:没有 parent 时不能伪装成 :program:;有 parent 时 CallID 必须是 parent 加单调 sequence。ParentCallID 是 Host 在 admitted call 上补入的字段,不是从 Guest receipt 可信读取。
Framing:origin 不是“调用者在 Python 中写了什么名字”,而是 per-run Broker 在 Plan、parent、sequence、direct policy 和 call budget 上做出的 Host admission 结果。run_id/parent/call ID 只能在这些绑定关系中产生 authority;孤立的 string 相似性不够。
4. End-to-end call/data/lifecycle path
Host policy + handler
-> NewGrant + Spec
-> Registry.Register
-> Registry.Seal -> Plan(identity, maxCalls, grant/spec projection)
-> Plan.Present(direct | programmatic | both)
-> per-Run Broker{RunIdentity, Plan, parent, direct policy, approval controller}
-> engine context / RPC channel binds Plan + execution/invocation identity
Guest generated wrapper or direct JSON
-> Wazero agent_runtime_v1.host_call
OR native _agent_runtime_host.call -> Unix HTTP /v1/calls
-> capabilityrpc identity/credential/expiry/plan check (native only)
-> Broker.Call / CallStreaming
-> bounded JSON + duplicate-key + call ID/origin + call budget
-> Plan lookup + input schema canonicalization
-> optional Host source resolver (only opaque Host authority can bind it)
-> approval Authorize / BeginDispatch, if Spec requires it
-> exactly one live Handler.Call / EvidenceHandler.CallWithEvidence
-> output schema + effect semantics + live transport evidence validation
-> approval Complete
-> Host Receipt + optional TranscriptEntry
-> same ABI/RPC response
-> Host finalization, evidence projection, response validation
-> terminal run/workspace disposition
4.1 Host admission before handler
Current:Broker.Call 的关键顺序是:
- raw frame 非空且不超过
maxCallBytes = 1 MiB;UTF-8、duplicate JSON key、unknown field、call ID、capability name、non-empty valid JSON arguments; - parent/child identity、direct/programmatic origin、per-Plan
MaxCalls、call ID uniqueness; - Plan lookup;未注册 capability 记录
denied并 dispatch zero; - streaming mode 下拒绝
EffectWorkspaceWrite; - 用注册时准备的 input schema canonicalize arguments;失败不进 handler;
- 若有 Host
SourceBindingResolver,只能由其内部 authority token 解析 source binding;外部 plugin 不能 mint; - 非 live playback/branch 和 semantic staged seam 是相邻路径;本文件只把它们作为 dispatch 前 gate,不展开其内部语义;
- 对
Spec.Approval != nil进入 approval controller; - 通过
BeginDispatch后才调用 handler。
CallLifecycleObserver 只收到 body-free intent/started marker,而且源码明确说 observation failure 不决定 capability 是否执行(broker.go:27-47,180-192)。因此 lifecycle marker 是 evidence seam,不是 authority gate。
4.2 Approval 与 handler 的唯一 dispatch seam
ApprovalRequirement 是 Plan-bound policy;Controller 本身“never dispatches capabilities”,只负责 waiting/lease/audit(runtime/capability/registry.go:91-96;runtime/approval/controller.go:1-3)。
Controller.Authorize:
- 校验 Run/Plan/Call/Parent/Capability、argument body bound 和 lease(最大 24 h);
- 只把
arguments做 SHA-256,Record 只保存ArgumentsSHA256; - 写入 Host
Request,状态初始为waiting,并以 context、timer 或 Approve/Reject 唤醒; - 状态只有
waiting/approved/rejected/expired/cancelled,决策一次性。
Broker.Call 获得 permit 后马上调用 BeginDispatch(ctx, requestID)。这是源码注释标明的 cancellation/dispatch linearization point:
- lease 已过期:变成
expired,不启动 handler; - context 已取消:记录
cancelled_before_dispatch,不启动 handler; - 成功:原子写入
DispatchCommittedAt,随后在同一调用路径调用 handler; Complete(requestID,"ok"|"error")只能对 approved、已 commit、未执行的记录成功一次;重复/late completion 失败。
因此“approve”本身不等于 effect;只有 BeginDispatch 成功后 handler 才能开始,handler 的结果还要通过 output schema/effect evidence gate。AbortApproved 只能在 dispatch commit 前把 permit terminalize 为 cancelled_before_dispatch,不能 revive 或 mark executed。
4.3 Handler/result/effect evidence
live handler 通过两条 Host-owned interface 之一执行:
- 普通
Handler.Call(ctx,args); - captured capability 必须实现
EvidenceHandler.CallWithEvidence(ctx,args),在同一 call frame 返回 result 与TransportEvidence,避免共享 “last result” race。
Broker 对 result 做 output schema canonicalization、Spec result semantics、maxCallBytes 检查;captured live handler 还必须提供 Kind=http 的合法 evidence。TransportEvidence 只包括 kind/status/media type/body bytes/body SHA,不能泄露 endpoint 或 headers(runtime/capability/transcript.go:9-57)。
成功路径是:Complete("ok") -> record Receipt(outcome="ok") -> 可选 recordTranscript -> encode response。handler error 或 invalid result 走 Complete("error") -> Receipt(outcome="error")。如果 approval audit completion 本身失败,Broker 不假装成功,而是记录 outcome="ambiguous",返回 approval_audit_failed;这保留“handler 可能已执行但 Host audit 未闭合”的不确定性。
5. 两个 ABI bridge 与 non-replay
5.1 Wazero:一个同步 Host ABI import
Current:instantiateCapabilityHost 在 agent_runtime_v1 中注册 host_call 与 materialize_value。hostCall:
- 标记 Host-call attempt;检查 request/response pointer length 均不超过 1 MiB;
- 从 Guest linear memory 读出并复制 request bytes;
- 从 context 取得 per-run Broker;
- 根据 context 的 streaming flag 调
Broker.Call或Broker.CallStreaming; - 可选 cold-I/O continuation 只等待该 call function,成功后把 bounded response 写回 Guest memory;
- 失败/越界返回
-1,不把异常变成伪成功 response。
这条路径没有第二个 Guest、没有第二个 Broker、没有“approved result cache”或第二次 Function.Call。approval wait 发生在原来的 host_call 同步调用中;因此源码结构支持的 Current/Framing 是“同一 ABI call 的 Host-side wait/return”,不是通过重启 Guest 或 replay transcript 恢复。
Observed limitation:真实 Guest hot-approval E2E 需要 AGENT_RUNTIME_GUEST;本次环境未提供该 artifact,因此没有把 same-frame continuation 升级成现场 Observed(见第 8 节)。
5.2 Native:Unix HTTP transport 仍回到同一 Broker
native/python/_agent_runtime_host.py 每次请求组装:schema version、channel ID、invocation ID、execution ID、Plan SHA;使用 Unix socket HTTP,带 invocation credential、bounded JSON request/response。call() 只有在 HTTP 200、status == "completed" 且 broker_response 为 object 时返回;其他状态报 Host tool call outcome is ambiguous。
capabilityrpc.Registry.Open 要求 channel identity、credential length、expiry、transport、Broker RunIdentity 和 Plan digest 一致。Check/Dispatch 每次再验证 credential、invocation/execution、expiry、revocation、Plan digest;因此 RPC 是 transport/authentication boundary,不是新的 capability registry。
Current:Registry.Dispatch 将 validated call 投给 opened.config.Broker.Call。native 与 Wazero 的统一点是 Plan/Broker/handler/receipt semantics;native 的 Unix HTTP、credential 和 in-flight call table 是额外 transport 层。
6. Receipt、evidence、ambiguity/reconciliation 与 terminal authority
6.1 Receipt 是 Host-authored operation evidence,不是外部世界真值
receipt.NewAuthorized 绑定:RunID、Plan SHA、CallID、ParentCallID、ApprovalRequestID、capability、operation index、request digest、outcome 以及可选 response digest;ReceiptID 是稳定的 operation identity。BindSource 只有在 Host 传入合法 SourceBinding 且 capability 相同、原 receipt 尚未绑定时才能重算 v3 identity(runtime/receipt/receipt.go:30-113)。
Current invariant:最终 response 中每条 receipt 必须:
- 具备 required fields、bounded string、合法 digest/outcome;
- Plan SHA 与 Host 投影的 Plan 一致;
ReceiptID == operationIdentity(receipt);- programmatic parent/call sequence 合法;
- source binding 只有在 parent/call/source 三者关系完整时成立。
Wazero projectHostEvidence 先拒绝 Guest 伪造 Host fields,再覆盖 receipts、capability_calls、Host Plan SHA 和可选 execution ref;DecodeAndValidateRunResponse 再做第二层 response/receipt validation。Receipt 因而证明“Host Broker 以该 Plan、identity、arguments/result digest 记录了这个 operation/outcome”,不证明 provider、HTTP endpoint 或外部世界已经按 digest 所代表的语义完成。
6.2 effect evidence 的两层
- Capability-level:
Receipt的 request/response digest、outcome、approval request、parent/call identity;captured call 的TranscriptEntry再绑定 argument/result digest 和 boundedTransportEvidence。 - Run/workspace-level:
observationLifecycle.capabilityCalls把 receipt digest、result digest、approval ID、parent/call、source binding 投影为 observation event;WorkspaceReceipt绑定 request、initial/final workspace/tree digest、policy、entry count/bytes 和 optional capsule digest。
WorkspaceReceipt.ValidateForStatus 由 Host response status + disposition policy 计算 expected exported/discarded;cmd/apyrun 先 DecodeAndValidateRunResponse,再 prepareDisposition,stage export 到临时文件、复核 final snapshot 未改变、重编码并再次验证,最后 publish 或在任一失败路径 discard。这表示 terminal disposition 的 issuer 是 Host orchestration,不是 Guest result 中的自报字段。
Framing:receipt/evidence 是可审计的 identity/effect projection,不是 transaction log 或 undo log。observation terminal event 也不回滚已发生的 handler/provider/workspace mutation。
6.3 Ambiguity 与 reconciliation
有两个必须分开的语义:
A. Wazero 同步 ABI
approval audit completion 失败、handler error 与 Host close/finalize error 都可能使调用 terminal outcome 非成功;Broker 用 error 或 ambiguous receipt 保留状态,不再次执行 handler。没有第二个 Guest run、第二次 Function.Call、或 transcript replay 来“修复”一个 pending approval。
Broker.Finalize(success) 检查 playback/branch 未消费项并调用 staged claimer;CloseJournal() 明确是 no-op,源码没有 durable transaction journal。finalize failure 会阻止正常 evidence publication,不被解释为 external effect 已撤销。
B. Native RPC
Registry.Dispatch 对同一 call_id 维护 digest/inFlight/response:
- 相同 call ID 但 digest 不同:
ErrCallIdentityMismatch; - 原 call 仍 in-flight:返回
status=ambiguous, error_code=call_in_flight; - 原 call 已 completed:返回缓存的 broker response,
Replayed=true; - Broker call 本身返回 transport-level error:保留 in-flight 记录,返回
status=ambiguous, error_code=dispatch_outcome_unknown; - channel expiry/revoke 后不再 admission。
这是 Current 的 bounded transport reconciliation:completed response 可以被 transport 层重取,in-flight 不确定则 fail closed。Replayed=true 只表示已完成响应的 transport replay,绝不证明 Guest frame 被恢复、Guest code 又跑了一遍或 handler 被再次 dispatch。native Python bridge 对 ambiguous status 直接抛错;本 commit 没有一个 durable reconciliation endpoint 可以从外部确认未知 dispatch 是否在 provider 侧落地。
6.4 terminal disposition 状态关系
| 阶段 | Host authority | handler/effect | evidence/disposition |
|---|---|---|---|
| invalid Plan/Grant/presentation/Broker/channel | Host admission reject | zero | 无合法 run authority;不应伪造 receipt |
| invalid call/origin/unknown capability/schema/budget | Broker deny | zero | 相关路径可记录 denied receipt;origin mismatch 在最早 gate 可能不记 operation |
| approval waiting | Controller owns lease/status | zero | digest-only waiting Record;Guest/handler 不获得新权力 |
| reject/expire/cancel before dispatch | Controller/Broker terminalize | zero | denied receipt/approval record;late approve/complete 失败 |
BeginDispatch success | Controller linearization + Broker | one handler attempt | DispatchCommittedAt;取消不触发 replay |
| handler error/invalid result | Broker validates | effect may have been attempted | error receipt;audit completion failure升级 ambiguous |
| successful handler + valid evidence | Plan/Broker/handler all pass | one live effect | ok receipt;captured path可写 transcript |
| RPC in-flight uncertainty | Registry refuses to guess | may or may not have happened | transport ambiguous,不自动重发 |
| final Run/workspace response | Host validates status/policy | no implicit rollback | exported only after staging+revalidation;否则 discarded |
7. Invariants:identity、limits、privacy、non-replay
7.1 Identity invariants
- Plan identity 是 canonical plan document 的 digest;Broker 必须只接受 sealed Plan。
- Grant identity 是 canonical policy digest;Plan 公开 binding,不公开 raw policy。
- Broker
RunIdentity、RPCExecutionID、channel Broker identity 必须一致;RPC request 还必须带同一 Plan SHA。 - Programmatic call 必须是 Host parent 下一个精确 sequence;reserved
:program:不能由 direct path 任意借用。 - 每个 Broker
CallID只消费一次;同一call_id不能携带近似/不同 arguments。 - Receipt identity 绑定 Run/Plan/Call/Parent/Approval/Capability/Operation/Request digest;source-bound v3 另绑 exact source occurrence。
SourceBindingResolver需要内部 authority token;Guest/plugin 自报 source fields 不会自动成为 receipt identity。
7.2 Limits and fail-closed points
- capability raw call 与 RPC frame:1 MiB;Guest
host_callrequest/response capacity 同样 bounded; - Plan
MaxCalls是 Host config,Broker 在分配 operation 前检查; - approval lease >0 且不超过 24 h;默认 controller audit capacity 为 1024 records;
- receipt 数最多 256,fields/string/digest/outcome 有 bounded validation;
- transport evidence body bytes 不超过 capability call bound;
- workspace disposition 先 snapshot/stage/validate,不能以 post-hoc status 直接声称 published capsule;
- invalid/malformed/expired/revoked/ambiguous paths 不自动降级为 success,不自动再发 handler。
7.3 Privacy invariants
- Grant/Plan/EvidenceDocument 不带 raw policy 或 handler;
- approval
Record只保存 arguments digest,不保存 raw arguments; - Receipt 保存 request/result digest,不把 raw body 当作 authority evidence;
- TransportEvidence 不含 endpoint、credential 或 headers;
- RPC credential 仅用于 invocation-bound channel;
- source binding 与 observation 传递 identity/digest/位置字段,不把 Host-private resolver token 交给 Guest。
7.4 Non-replay invariant
Current / Framing:同一逻辑 call 的 live handler dispatch 次数由 Broker admission + per-call identity + approval linearization 共同限制为一次。Wazero approval wait 是原 ABI call 内的同步等待;native completed-response replay 是 transport cache 行为;两者都不是“第二次 Guest execution”。任何声称“approval 后通过重跑 Guest/复用 transcript 恢复原 frame”的解释,都超出本 commit 代码。
8. Tests 与 machine-readable evidence
8.1 本次实际执行
Observed / PASS:在 target worktree 上运行:
go test ./runtime/approval ./runtime/capability ./runtime/capabilityrpc ./runtime/receipt ./runtime/engine/wazero
ok github.com/.../runtime/approval
ok github.com/.../runtime/capability
ok github.com/.../runtime/capabilityrpc
ok github.com/.../runtime/receipt
ok github.com/.../runtime/engine/wazero
实际输出均为 ok,耗时约 0.3–0.9 s。另运行:
go test ./runtime ./runtime/observe ./runtime/verification
实际输出三个 package 均 ok。
Observed / PASS-with-skips:对 real Guest authority path 运行了以下 focused E2E test selection(exit 0)。所有测试均明确输出 AGENT_RUNTIME_GUEST is not set; real WASI artifact required 并 SKIP:
TestBothSurfaceAdmitsDirectAndProgrammaticCallsThroughOneRealGuestBroker;TestProgrammaticSurfaceUsesSameBrokerForOrderedRealGuestCalls;TestHotApprovalResumesSameRealGuestWithoutReplay;TestRealGuestApprovalRejectExpireAndCancelDoNotDispatch;TestRealGuestAndNativeRPCHaveEquivalentCapabilitySemantics。
所以本次可现场宣称的是 unit/contract package evidence;不能把真实 WASI Guest frame continuation、Wazero/native differential 或 E2E handler-count=one 说成现场 Observed。
8.2 重点测试符号与覆盖含义
runtime/capability/plan_test.go:TestSealedPlanIsOrderIndependentAndRejectsLateRegistration、TestPlanEvidenceDocumentRecomputesIdentity、TestPlanIdentityBindsHandlerIdentity、TestBrokerUsesOnlyASealedPlanAndBindsReceipts;覆盖封存、digest、handler identity、receipt Plan binding。runtime/capability/projection_test.go:TestPlanPresentsDirectProgrammaticAndBothWithoutChangingRegistry;覆盖 presentation 不改变 registry。runtime/capability/approval_test.go:TestApprovalRequiredCapabilityDispatchesOnlyAfterSameBrokerApproval、TestBothSurfaceApprovalBindsParentOnlyToProgrammaticCalls、TestApprovalRejectionExpiryAndCancellationNeverDispatch;覆盖同一 Broker、origin 和 zero-dispatch terminal states。runtime/approval/controller_test.go:TestControllerApprovesExactlyOnceAndKeepsBodySafeAudit、TestCancelledContextCannotCrossDispatchCommit、TestApprovedPermitCanBeAbortedBeforeDispatchWithoutExecution、bounded capacity;覆盖 lease/status/linearization/audit privacy。runtime/capabilityrpc/registry_test.go:TestRegistryDispatchesAndReplaysCompletedExactCall、TestRegistryReturnsAmbiguousForConcurrentDuplicate、identity/expiry/revocation tests;覆盖 transport replay 与 ambiguous 分离。runtime/capabilityrpc/native_python_test.go:TestUnixHTTPNativePythonUsesGeneratedProjection;覆盖 native Python projection/RPC channel。runtime/response_test.go:TestRunResponseCapabilityPlanIsHostOnlyAndBindsReceipts、TestRunResponseWorkspaceReceiptIsHostOnlyAndValidated;覆盖 Guest Host-evidence rejection、receipt identity/Plan binding、workspace status/policy disposition。runtime/engine/wazero/engine_test.go:TestFactoryRequiresBrokerForProgrammaticToolsAndApproval等;覆盖 Host config 与 Broker mechanism 一致性。integration/e2e/programmatic_approval_test.go、unified_transport_test.go:真实 artifact 存在时才证明 same Guest/unified transport;本次因 artifact 缺失只得到 SKIP,不升级为通过。
Evidence boundary:测试能证明 deterministic contract、identity、zero-dispatch 和 transport state machine;不能单凭 receipt 证明外部 provider truth、不能把 cache replay 当 hot continuation、不能把成功 fixture 当任意 Python 支持。
9. Design patterns、trade-offs 与 rejected alternatives
9.1 Design patterns
- Sealed authority object:
Registry可写、Plan只读;封存后拒绝 late registration,避免 execution-time authority expansion。 - Projection/enforcement split:
ToolSchema、Python wrapper、alias 和 direct/programmatic surface 只描述调用方式;Broker/Plan 才执行 authority。 - Single dispatch seam:Wazero import、native RPC、approval continuation 都汇入同一
Broker.Call/handler registry,不建立第二套 approved registry。 - Digest-bound evidence:Plan/Grant/request/result/receipt/source/transport/workspace 各自绑定 digest 与 identity,避免把 raw body 复制到所有边界。
- Linearized approval:
BeginDispatch是取消与执行的锁内线性化点;approval decision、dispatch commit、completion 是不同状态,不把“approved”伪装成“effect happened”。 - Fail-closed ambiguity:RPC in-flight/dispatch outcome unknown 进入 ambiguous,不盲目 retry;完成响应 replay 与未决执行严格分开。
- Stage then publish/discard:workspace/capsule 先准备并验证,再由 Host 原子 publish;失败不会把临时文件误当作已发布 effect。
9.2 Trade-offs
- 一个 Plan/Broker 服务两个 presentation:避免 direct/programmatic 各自复制 handler、Grant 和 receipt semantics;代价是 parent/sequence/direct allow 的 admission 逻辑更严格。
- digest-only Grant/approval/receipt:减少 raw policy/argument/result 泄露和跨层复制;代价是排障/审计需要另外的 Host-private context,digest 不能独立证明外部语义。
- 同步 ABI approval wait:保留原 Guest call frame、避免 rerun/replay;代价是 Guest slot 在 lease/call duration 内被占用,且取消/close error 必须显式处理。
- RPC idempotency table:相同 completed call 可安全重取,避免网络重试造成第二次 dispatch;代价是 in-flight 不确定只能返回 ambiguous,当前无 durable reconciliation。
- Host-side response projection:Guest 不能 author Host evidence;代价是最终 response 还需一次 merge/size/identity validation,late failure 不会 undo 已发生 effect。
- Plan 只保存 Grant identity:Plan public evidence privacy 好;代价是 generic Broker 不知道 raw policy 的业务语义,具体 handler/adapter 必须是受信 Host registration。
9.3 明确拒绝的替代解释
- 把 Python module/method/global alias、tool schema 或 call spelling 当成 authority boundary;
- 为 programmatic surface 建第二个 registry、第二套 handler 或 approved-result cache;
- 让 Guest 自己指定 parent、Plan、Grant、approval 或 source identity;
- 把
Approve解释成已产生 logical/effect authority;真正的 seam 是BeginDispatch后的一次 handler attempt; - approval 后重启 Guest、重放 transcript 或第二次 dispatch,并把它称为 hot continuation;
- 把 receipt、transport response、workspace digest 或 observation terminal event 解释为 external-world truth/rollback;
- 依赖
CloseJournal()作为 durable transaction reconciliation;该符号在本 commit 是 no-op; - 把 semantic predispatch candidate/analysis 或 source spelling纳入本切片的 authority proof。
10. Deferred、Unsupported 与主要不确定项
Deferred
capabilityrpc.Registry只有内存中的 in-flight/complete table;没有跨进程、重启后可查询的 durable reconciliation 或 provider-side effect query。- native Python path 的 generated projection 与 RPC receipt semantics 有 unit/integration code seam,但真实 Guest/native differential 需要
AGENT_RUNTIME_GUESTartifact;本次未现场验证。 - Grant policy 的 generic schema/semantic enforcement 不在 Broker;具体 adapter 如何把 raw policy 贯彻到 handler closure,需要按 capability slice 单独审计。
Broker.CloseJournal()没有 durable journal;若论文需要 crash recovery/at-least-once/at-most-once 外部 effect 结论,需要新增 Host-owned protocol。
Unsupported
- 不证明 Grant digest 是签名、可信执行环境证明或外部 policy authority;
- 不证明 receipt/effect evidence 等于 provider/HTTP/world state;
- 不证明 approval 后任何 backend 都能恢复同一 Python stack/heap/local state;Wazero 同步 ABI 的 same-frame 解释不能外推到任意 native process failure;
- 不证明 exact fixture 的成功意味着 arbitrary Python、dynamic import、native extension 或 shell/network 能力;
- 不证明 direct 与 programmatic 在所有 backend、配置和真实 artifact 上具有字节级输出等价;
- 不证明 semantic predispatch、prepared data、COW 或 benchmark/campaign 的 novelty、latency dominance 或 production safety;
- 不把 channel-level cached response replay 解释成 Guest non-replay proof 的反例,也不把它解释成 Guest hot continuation 的证据。
主要不确定项
- Current but unobserved E2E:本次缺少
AGENT_RUNTIME_GUEST,所以TestHotApprovalResumesSameRealGuestWithoutReplay的 handler-count、local Guest state preservation 和 Wazero/native parity 未现场执行。 - Transport ambiguity boundary:RPC 对 Broker 返回 error 统一为
dispatch_outcome_unknown,但没有 durable external reconciliation;未知状态的 provider-side truth 不可由本 slice 查询。 - Grant semantics boundary:
Grant在通用 Plan/Broker 中是 opaque digest;具体 policy 是否在每个 handler 正确 enforcement,不可从 Grant 类型自身推出。 - Terminal/effect join:Host 能校验 receipt、transport/workspace digests 和 response status/disposition 的一致性,但这些字段仍是 Host observation;它们不构成 effect rollback 或外部系统的独立 attestation。
11. 答辩口语解释
这条 authority spine 的核心不是把 Python 写成一个更像工具的名字,而是 Host 先把 capability 的 Spec、Grant identity、handler 和调用预算封存成一个 Plan。direct、programmatic 和 both 只是这个 Plan 的不同 presentation;生成的 module/method/alias 都会回到同一个 Host Broker。Guest 无论用哪种 spelling,都只能通过 Wazero 的一个同步
host_call,或 native 的 invocation-bound Unix HTTP channel,提交 bounded JSON。Broker 先检查 Plan、call budget、call ID、parent/child origin、schema 和 approval;只有 approval 的 dispatch linearization 成功后才调用一次 handler。结果、approval ID、request/result digest、transport evidence 和 workspace disposition 都由 Host 生成/验证,Guest 自己写的 Plan、receipt 或 execution reference 不算数。所以“approve”不是 effect,“receipt”也不是外部世界真值;它们分别是 Host 允许一次 handler attempt、以及 Host 记录该 attempt 的证据。取消、过期、拒绝和 in-flight ambiguity 都 fail closed,不靠第二次 Guest run 或 provider replay 修复。RPC 对已经完成的 response 可以做 transport replay,但这不等于 Guest continuation;当前也没有 durable reconciliation。能答辩的是 one Plan / one Broker / one live dispatch seam / identity-bound evidence / fail-closed ambiguity,不能答辩成任意 Python、签名式 Grant authenticity、外部 effect rollback 或所有后端的 hot continuation。