Appearance
恢复、重试和人工审批怎样共享同一执行事实
前置:Graph 怎样被调度并持久化:Scheduler、State Machine 与 StateStore
核心问题:Checkpoint、Retry、Approval 看起来是三套机制,为什么它们必须共享同一个 execution identity 才能安全 resume?
单测使用 InMemoryCheckpointStore,生产换 PostgresCheckpointStore;Scheduler/Resume 代码不需要知道底层表结构。ToolTransient+attempt1 可 backoff;PermissionDenied 直接失败;run deadline 不足则不重试。
CheckpointStore Port
Module 09 已定义 checkpoint/resume 语义,Module 13 负责持久化表示。这里的 CheckpointStore 只定义 domain port:save/load/latest/fork 以及 schema/version compatibility。
Runtime 传入已经形成一致边界的 snapshot;Store 不自行猜哪些 Node 已提交。InMemory/Postgres 实现必须通过同一 crash/resume contract tests。
RetryPolicy Wiring
Module 11 定义 Reliability policy。最终 Harness 把 RetryPolicy 注入 Runtime/ToolExecutor,由它读取 error class、operation id、idempotency capability、attempt、remaining deadline 与 retry budget,返回 RetryDecision。
provider SDK 与具体 Tool 只能上报错误和 capability,不得各自再套一层不受控 retry loop。
Approval Port
Approval subsystem 接收已经冻结的 proposed action(含 action hash/version),持久化 request 与 decision,并把 approve/reject/edit 作为新的 Runtime input。
UI 只是交互端;批准事实必须与 operation identity、checkpoint 和审计记录关联,进程退出后仍可恢复。
一次 Approval → Crash → Resume 的接线
text
ToolExecutor proposes deploy(op-9)
→ ApprovalPort.create(op-9, action_hash=h1)
→ Runtime checkpoint: WAITING_APPROVAL
→ worker exits
→ user approves a-7
→ approval event wakes Run
→ Runtime loads checkpoint + verifies action_hash h1
→ RetryPolicy checks remaining deadline/idempotency
→ ToolExecutor executes deploy(op-9)如果进程在 deploy 成功但结果持久化前 crash,resume 仍使用同一个 operation_id=op-9 做幂等/reconciliation。这样 Approval、Retry、Checkpoint 不是三个旁路功能,而是围绕同一 logical operation 协作。
🔍 源码对照:Approval Gate 与 Checkpoint Boundary 必须共同参与 Resume
完整源码与通用分析见 11-05 HITL / Approval / Resume。这里不重复代码;这里关注集成:ApprovalGate、Checkpoint 与 operation identity 必须在 resume 时共同恢复,避免批准状态与副作用状态脱节。
源码说明
把 approval gate、storage、crash guard 放在一起看,可以把三个常被拆散的功能重新统一到“Execution Fact”上:Checkpoint 记录已经知道什么,Retry 决定某个未完成 attempt 能否再做,Approval 决定某个 side effect 当前是否允许开始。三者如果各自维护一套事实,resume 一定会出现矛盾。
工程边界
Auto-review 的产品 UX 不是我们要复刻的重点;真正要复制的是 stable action identity、pending approval、side-effect start、execution outcome 的一致状态模型。
Shadow Harness 对照
ExecutionRecord成为 retry/approval/checkpoint 共享引用对象。- 批准的是 immutable action digest;任何参数/target 变化都需要新 approval。
验证
构造 approved action 在真正执行前 crash、执行成功后 checkpoint 前 crash 两个窗口;两者 resume policy 必须不同且可从 ExecutionRecord 判定。
Failure Modes
三个 Port 没有共享同一个 logical operation identity
症状: checkpoint、retry attempt、approval action 各自生成无关联 ID。
为什么危险: 恢复后无法判断批准的是哪次动作、某次 retry 是否已经提交。
处理: Run/Node/ToolCall/operation_id 贯穿 CheckpointStore、RetryPolicy 与 Approval subsystem。
如何验证
| Case | 断言 |
|---|---|
| 三个 Port 没有共享同一个 logical operation identity | 创建 approval→retry→resume 链路,断言 checkpoint、attempt、approval 都能关联到同一 operation_id。 |
关联源码
自测
- 一个 Tool 需要人工批准,批准后执行成功却在 checkpoint 前 crash。Approval、Retry、Checkpoint 为什么必须共享同一 execution identity?
- 如果 Resume 只看“approved=true”而不看具体 pending action,会出现什么错误重放?