Vinculum effect and replay semantics
状态:Proposed design。 本文细化 architecture.md 中的 Effect Plane、Ambiguity Firewall 与 Qualified Replay;不声称任意外部系统都能回滚或重放。Canonical mechanism names 见 concept-catalog.md,来源边界见 references.md。
1. 基本原则
Agent execution 的 replay 必须把“计算重放”和“效果处理”分开:
replay(computation) ≠ repeat(real-world effects)一次工具调用至少有三种身份:
- logical operation:业务意图;
- attempt:一次派发或恢复尝试;
- provider request:外部系统看到的 request / idempotency identity。
重试只允许发生在这三者关系明确时。网络 timeout 后“没收到响应”不等于 provider 没执行。
每次 operation 走同一条治理主线;Tier A/B/C 只改变 adapter 可提供的保证上限:
classify effect
→ journal intent
→ authorize / stage
→ dispatch one attempt
→ success | failure | ambiguous
→ readback / reconcile if needed
→ select recovery and replay mode任何 ambiguous outcome 都先进入 Ambiguity Firewall,而不是直接回到 dispatch。
2. Canonical effect classes
| 类别 | truthful guarantee | 恢复语义 |
|---|---|---|
read_only | 无意图写入;仍需考虑读触发计数/会话等隐性效果 | 通常只需记录输入与版本 |
reversible | adapter 能在并发保护下恢复声明的业务状态投影 | 仅在 version/digest guard 成立时恢复 declared projection;不声称整个 provider exact rollback |
compensatable | 另一个效果可恢复净业务含义,但原历史保留 | compensation,不称 rollback |
irreversible | commit 后没有受支持的恢复机制 | 预授权、预览、人工确认、强审计 |
unknown | 无法可靠分类或验证 | 默认拒绝写;只能 record/infer/document |
Effect class 与 commit policy 正交:即使某操作可逆,也不代表生成代码可自行 commit。
3. Tier A:完全可控的内部系统
3.1 假设
系统拥有:
- authoritative database / object store;
- schema、事务与版本控制;
- effect adapter;
- audit ledger 与 final-state oracle;
- 可部署 replay fixture 或 isolated tenant。
3.2 推荐路径
intent journal
→ policy/approval
→ atomic mutation + ledger transition(同 store 时)
→ independent readback
→ final-state oracle可采用:
- transaction / optimistic concurrency / fencing token;
- outbox/inbox;
- business projection before/after digest;
- isolated tenant、snapshot database、ephemeral environment;
- exact restore only when no concurrent newer state is overwritten;
- deterministic fixture clock / RNG / IDs。
3.3 可重放能力
在完整 snapshot 与 deterministic dependencies 下,可达到 R1/R2;若 oracle 定义充分,可评估 R3。真实生产写入通常不在 replay 时重复,而是在 clone/snapshot 中执行。
3.4 仍然困难的点
- DB 事务不能覆盖邮件、支付、消息队列等 provider;
- 同 store atomicity 不代表跨系统 exactly-once;
- internal service 也可能包含 hidden cron、cache、trigger 或 read-side effect;
- concurrent actors 会使 exact rollback 不再安全。
4. Tier B:已知、但不受我们完全控制的外部系统
4.1 假设
系统有官方 API / schema / versioning,且可实现专用 adapter;但 provider 的内部状态和部署不可控。
4.2 每个 adapter 必须声明
AdapterQualification
├── provider / API version range
├── request and response schema digests
├── authentication scope
├── effect class
├── idempotency semantics and retention window
├── readback oracle
├── ambiguity rules
├── retry / rate-limit policy
├── rollback or compensation implementation
├── test/sandbox coverage
└── expiry / requalification trigger4.3 派发协议
- 在本地 durable journal 写
intent; - 绑定 logical operation、attempt 和 provider idempotency key;
- policy/approval 通过后派发;
- 保存 bounded provider request ID、API version、response digest/code;
- 用 provider readback 或 webhook reconciliation 取得后状态;
- 只有在结果被确定为 applied / not-applied 后才允许下一动作;
- timeout/connection reset 进入
ambiguous,禁止盲目重试。
Stripe 的 idempotency key 是此类机制的典型例子,但它只在 provider 声明的语义与窗口内去重请求;不能推导跨 provider 事务或任意 exactly-once。
4.4 replay 策略
- recorded stub:返回原 response,用于上层 deterministic replay;
- provider sandbox:在测试 tenant 重新执行;
- state model/digital twin:重放在本地状态机中;
- live read-only verification:只读当前 provider state;
- live write replay:默认禁止,除非 disposable scope、fresh approval 和 cleanup oracle 都成立。
4.5 drift 处理
- 每次运行冻结 catalog/API/schema/policy digest;
- adapter qualification 有版本窗口和过期条件;
- canary 检查 schema、状态码、readback 和 idempotency;
- 检测到未知字段/行为时进入 degraded/quarantined,而非 permissive parsing;
- 保存旧 adapter/replayer 以验证历史证据,新的执行使用新 cohort。
5. Tier C:完全未知或无法可靠建模的外部系统
例如临时网页、无版本 UI、第三方 CLI、未文档化 API、人工工作流或系统背后的 hidden automation。
5.1 能诚实做到什么
最多做到:
record → infer → document → bound uncertainty可以记录:
- interaction surface identity:URL/app/window/tool/version;
- before/after 可观察状态;
- 输入事件和时间;
- network/domain/resource fingerprints;
- UI/DOM/screenshot/response 的脱敏 digest;
- observed side-effect candidates;
- 人工确认与 residual uncertainty。
可以推断:
- 可能写入的资源;
- repeated action 是否看起来幂等;
- 哪些观察与状态变化相关;
- 哪些 selector/endpoint/field 可能构成稳定 contract。
但推断必须标为 inferred,不能自动升级成 authority、exact effect class 或 replay guarantee。
5.2 默认政策
| 操作 | 默认 |
|---|---|
| 未知系统只读观察 | 允许在受限网络/文件范围内 record |
| 可能写入但可预览 | stage + 人工确认 |
| 明确不可逆或高影响 | 拒绝自动执行 |
| 不清楚是否执行成功 | ambiguous + 停止 |
| 重放 | 只在 recording/stub/clone 中;不 live repeat |
5.3 为什么“录屏/日志”仍不够
- 可观察 UI 不一定是 authoritative state;
- DOM/视觉变化可能由 A/B test、locale、广告或时间驱动;
- 点击可能触发后台异步任务,结束时尚未显现;
- 相同动作在不同账户、tenant 或风控状态下语义不同;
- recorder 自身可能漏掉 service worker、native helper 或 side channel。
所以 Tier C 的最高真实声明通常是:
在给定时间和环境中观察到某交互与某可见状态变化;系统记录了证据与不确定性,但不能证明完整 effect footprint 或 exact replay。
6. Manifest-Bound Receipt
每个 operation 应返回由 Host 校验并绑定到 exact authority、intent 与 attempt 的 bounded receipt:
{
"run_id": "host-generated",
"call_id": "host-bounded",
"tool_id": "catalog-qualified",
"transaction_id": "host-generated",
"operation_id": "host-generated",
"attempt_id": "host-generated",
"catalog_digest": "sha256:...",
"handler_digest": "sha256:...",
"policy_digest": "sha256:...",
"effect_manifest_digest": "sha256:...",
"adapter_qualification": "sha256:...",
"effect_class": "compensatable",
"commit_policy": "user-approved",
"provider_request_ref": "bounded-id",
"request_digest": "sha256:...",
"response_digest": null,
"dispatch_outcome": "ambiguous",
"readback": "pending",
"recovery": "reconciliation-required",
"uncertainty": ["response_lost_after_dispatch"]
}Receipt 是 evidence,不是成功本身。Verifier 仍需检查 adapter qualification、journal continuity 和 final-state oracle。
7. 失败与恢复矩阵
| 失败点 | 允许动作 | 禁止动作 |
|---|---|---|
| intent 前 | 安全重建 intent | 假称已派发 |
| intent 后、dispatch 前 | 同 operation 继续或取消 | 生成新 logical operation 重复执行 |
| dispatch 中连接丢失 | readback / webhook / reconciliation | blind retry |
| applied 后 ledger 未完成 | 用 provider identity 修复 ledger | 重做效果 |
| rollback version conflict | quarantine / 人工决策 | 覆盖新状态 |
| compensation 失败 | 记录 partial business state | 报告 rolled_back |
| unknown system outcome | record uncertainty / stop | 自动推断成功或失败 |
8. One Effect Plane
如果 direct Agent call 和 generated-program Python call 走不同 registry、policy、budget 或 journal,Agent 可通过选择表示方式绕过治理。因此两者必须汇入同一个 Host effect plane:
Direct tool ─┐
├→ typed registry → policy → journal → adapter → receipt
Python call ─┘生成代码只拥有调用已授权 wrapper 的能力,不持有 provider credential,不决定 approval policy,不伪造 receipt。