ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

IronClaw Reborn Agent-Turn 持久化契约:基于进程日志的 Turn 投影、并发锁、幂等与租约恢复机制

IronClaw Reborn Agent-Turn 持久化契约:基于进程日志的 Turn 投影、并发锁、幂等与租约恢复机制 人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载导读本文是 IronClaw 开源仓库中docs/internal/reborn/contracts/turn-persistence.md契约文档的技术解读。该契约回答了 Agent OS 最核心的问题之一一个 Agent 回合turn从被接受、排队、运行、阻塞、恢复直到终态它的可执行状态究竟存在哪里、由谁写入、如何保证不重放副作用。读完本文你将理解ironclaw_processes::ProcessJournalStore如何作为唯一的持久化权威ironclaw_turns如何在它之上投影出 turn/turn_run/active_lock/checkpoint/admission_reservation/idempotency_key 六类记录以及 active-lock、幂等、准入预留、租约恢复和脱敏边界五组规则在源码中的落地方式。1. 契约定位Turn 持久化到底是什么turn-persistence.md是 Reborn 契约族中的一份已实现Status: Implemented2026-07-25契约依赖 turns-agent-loop.md、host-api.md、events-projections.md 与 runtime-profiles.md 四份姊妹契约。它要回答的核心事实是Agent-turn 协调层并不拥有自己的持久化快照而是从持久化进程日志durable process journal投影出一组领域概念。契约明确列出这些被投影的概念被接受的 turn 元数据与规范绑定引用accepted turn metadata and canonical binding references可执行进程的生命周期状态executable process lifecycle state每个规范线程只有一个活跃进程的并发约束one-active-process-per-canonical-thread进程租约/检查点元数据process lease/checkpoint metadata活跃已接受运行的持久化 turn 准入预留durable turn-admission reservations面向适配器的变更的幂等结果idempotency outcomes回放/恢复所需的脱敏生命周期游标redacted lifecycle cursors。同时契约明确划出一条边界它不拥有规范转录/消息存储。Transcript 与线程消息历史始终留在转录/线程存储边界内——turn 持久化层只存引用与元数据不存对话内容本身。从仓库实现看这个单一权威 投影的设计被crates/kernel/ironclaw_processes/README.md总结为一句话the journal is the store; everything else is a projection over it日志是存储其余一切都是其上的投影。该 README 明确指出ironclaw_turns的TurnRunState是对该日志的类型化投影而非第二个持久化存储。2. 逻辑记录族六类投影记录与所有权契约规定ironclaw_processes::ProcessJournalStore是权威存储ironclaw_turns契约暴露以下投影记录族记录所有权 / 内容turns一条被接受的内向消息scope、actor、accepted-message ref、source/reply binding refs、创建时间戳。turn_runs单个进程快照的 Agent-turn 视图bindings、status、已解析运行画像resolved run profile、checkpoint/gate refs、租约字段与日志游标。turn_active_locks规范 scoped 线程上进程并发所有权的 Agent-turn 视图。turn_checkpoints进程挂起/检查点记录的 Agent-turn 视图。turn_admission_reservations将每个已接受运行绑定到 tenant/actor/project/agent 总量与类别桶直到终态释放的预留证据。turn_idempotency_keys针对 scoped submit/resume/cancel 幂等键的先前净化结果。契约强调两点实现原则Agent-turn 元数据以有界进程元数据载荷bounded process metadata payload形式存储。AgentTurnProcessRuntime把协调器操作映射到进程的 submission、control、journal 与 tree 端口然后重建这些 turn 视图——不持久化一份平行的 turn 快照。从源码结构看这份映射被拆成了四个独立模块mod.rs 中的注释明确说明runtime orchestration、durable metadata、checkpoint storage、store adapter 各居一模块避免投影入口变成又一个组合根runtime.rs运行时编排、metadata.rs持久化元数据、loop_checkpoint.rs检查点存储、store_adapter.rs存储适配器外加event_projection.rs进程日志到 turn 事件视图的投影。2.1 有界元数据载荷的源码实证元数据载荷的实际结构定义在 metadata.rs 的AgentTurnProcessStateMetadataturn_id、actor、accepted_message_ref被接受 turn 的身份与绑定引用resolved_run_profile_id/resolved_run_profile_version已解析运行画像的标识与版本output_contract不可变的终端输出契约legacy 元数据缺省为普通 assistant 消息allow_steering显式持久化的 SteeringPolicy 开关——源码注释说明它被显式持久化而非从resolved_run_profile派生因为busy-submit 准入需要在不重新解析画像的情况下读取它legacy 行缺省为允许resolved_run_profile、resolved_model_route、model_usage、execution_outcome运行画像快照、模型路由、用量与执行结果subagent_depth、subagent_activation_provenance、spawn_tree_descendant_cap子代理谱系字段subagent_activation_provenance在运行创建时设置一次、永不修改product_context、resume_disposition、ownerless_thread产品上下文、恢复处置、以及 ownerless 线程标记——后者用于区分__system__槽位下的 ownerless 运行与无显式 owner 的 actor-fallback 运行legacy 行缺省视为 actor-fallback。这个载荷在 runtime.rs 的submit_turn_with_resolved中被序列化为json!({ agent_turn: metadata })后随SubmitProcessRequest一并提交同时携带process_kind: ProcessKind::AgentTurn、exclusive_within_scope: true与由幂等键构造的ProcessOperationId——这恰好同时落地了唯一权威与同线程互斥两条契约。3. Active-lock 规则同线程单活跃进程的并发所有权契约对 active lock 的规定如下锁键是规范TurnScopetenant、agent、可选 project、thread键排除TurnActor.user_id、channel ID、source binding refs 与 reply binding refs——也就是说同一线程上的不同用户/渠道提交会竞争同一把锁锁存储当前所属TurnRunId、显式TurnStatus、单调递增的TurnLockVersion、acquired_at、updated_atQueued、Running、CancelRequested、Blocked 运行保持持有锁终态运行包括 legacyRecoveryRequired记录恰好释放一次锁runner 的 claim/resume/block/cancel-request 转换会更新锁状态/版本但所有权始终属于同一 run。从底层看这把锁在进程层面对应SubmitProcessRequest.exclusive_within_scope: trueProcessJournalStoreError::ActiveProcessConflict见 journal_store.rs会在同一 scope 已有活跃进程时拒绝新提交错误信息携带process_kind、status、suspension与cursor供调用方判定同线程 busy。4. 幂等规则重复键必须重放而非重跑面向适配器的变更会持久化净化后的幂等结果规则如下submit_turn成功时记录已接受的 turn/run ID 与已接受响应类型submit_turn的同线程 busy 是瞬态不创建 turn/run、不获取准入、也不缓存为 submit 幂等重放——即 busy 不消耗幂等记录容量/策略准入拒绝是可重放的且不创建 turn/run 或预留记录resume_turn与cancel_run记录 scoped 运行操作结果幂等记录包含一个脱敏重放信封redacted replay envelope携带响应关键字段status、事件游标、准入原因/容量元数据、重试元数据、取消的already_terminal状态。契约还明确了一个微妙语义重复的幂等键必须重放先前已接受的 submit 与准入拒绝结果而不是重新执行准入、锁获取或状态转换同键的同线程 busy 提交可以在线程解锁后稍后成功legacy 持久化的SubmitThreadBusy重放行在快照/DB 加载时被忽略。在实现层幂等键被铸成ProcessOperationId::from_trusted(idempotency_key.as_str())随提交请求写入runtime.rs子运行则使用child:{key}、重试使用retry:{key}前缀同一文件的submit_child_turn与retry_turn把同一操作 ID 只生效一次下沉到进程日志的事务语义中。5. Turn 准入预留规则容量账本与原子插入准入预留admission reservation是契约中最精细的部分之一预留不是谓词所有配置的 tenant、actor-user、project、agent 总量/类别桶必须与 turn/run 创建原子地一起检查与插入每个已接受的 V1 运行都会记录 unlimited 与 limited 规范桶预留用于遥测与未来限额变更可拒绝 unauthorized/profile-invalid 请求的 submit 准入策略检查在返回同线程 busy 元数据之前执行同线程 busy 仍在容量预留之前检查且从不消耗准入槽位容量拒绝返回一个确定性的安全AdmissionRejected载荷axis kind、total/class 桶、适用时的准入类别、限额、活跃计数、可选重试提示不得暴露外部桶 ID 或原始 provider 内部信息缺失限额意味着 unlimited不可用的非 AllowAll provider 以AdmissionRejectionReason::Unavailable失败关闭fail closed不创建 run/预留Queued、Running、Blocked、CancelRequested、RecoveryRequired 运行保持预留resume 复用已有预留终态转换Completed、Failed、Cancelled及未来终态恰好释放一次预留。已释放的预留证据仅在对应终态 run 处于有界终态记录保留窗口内保留活跃容量核算不得扫描无界的历史释放记录限额变更不驱逐现有运行新准入在活跃预留降到限额以下之前被拒绝快照/DB 加载器必须为早于预留行存在之前的 legacy 非终态运行合成未释放的预留证据避免迁移/重启后活跃容量被绕过。这一规则的工程动机很清楚准入账本如果允许释放历史无界增长容量核算就会退化成全表扫描如果迁移时不合成 legacy 预留重启后限额就会被已存在运行静默击穿。6. Runner 租约与检查点规则claim、心跳、恢复与隔离这是整个契约的执行语义核心共八条Claim原子地将 queued 运行移到Running存储 runner ID/lease token递增claim_count记录last_heartbeat_at与lease_expires_at更新 active-lock 元数据。Heartbeat仅对匹配且未过期的 runner ID/lease token 续约成功的心跳刷新last_heartbeat_at并延长lease_expires_at。物理适配器可以拆分高变更的租约元数据与低变更的 turn 快照表但所有读、恢复与终态转换 API 必须呈现一个逻辑运行状态活性判断必须依据持久化租约元数据而不是要求每个心跳都产生一个生命周期事件。过期租约恢复过期的Running与CancelRequested租约清除当前 runner 所有权只有恢复解析为Cancelled、Queued或Failed时才发出脱敏恢复事件。仍在完整租约 TTL 宽限窗内的安全检查点保持不变包括其过期所有权元数据直到后续清扫解决它。恢复直接收敛到已定局状态而非停在一个独立 recovery 状态取消收敛到终态Cancelled无检查点或停在无副作用回放检查点BeforeModel、BeforeBlock的运行回到Queued停在有副作用或无法识别检查点的运行或已耗尽有界回收预算的运行收敛到终态Failed。不确定的副作用工作绝不自动重试active lock 在结果变为终态的那一刻恰好释放。完整转换表见 turn-runner.md 第 3 节。Block阻塞一个运行需要匹配且未过期的租约写入检查点记录在运行上存储最新 checkpoint/gate refs清除当前租约所有权保持 active lock。Resume 载荷只在宿主内存中暂存随后的进程检查点命令把不透明 ref、schema 元数据与有界载荷在一个日志行中原子持久化。检查点隔离进程检查点记录以稳定的 run/process 身份与 turn 资源 scope 为界用匹配 ref 但外部 scope 或 run的读取返回无状态从而保持 tenant/thread/run 隔离。载荷有界与脱敏检查点载荷字节有界且 debug 脱敏生命周期事件、公共 turn/run、传输与幂等投影只暴露元数据与 refs绝不暴露原始检查点载荷字节。终态 runner 结果需要匹配且未过期的 runner ID/lease token且仅当 run 仍持有 active lock 时才释放它。6.1 源码中的租约与恢复实现在 journal_store.rs 中DEFAULT_PROCESS_LEASE_DURATION为 90 秒。过期恢复的判定实现在 state.rs 的apply_recover_expired其中三个关键常量/分支与契约一一对应MAX_CRASH_RECOVERY_RECLAIMS: u64 3state.rs#L44崩溃回收的有界预算LEASE_EXPIRED_FAILURE_CATEGORY lease_expired与CRASH_RETRY_EXHAUSTED_FAILURE_CATEGORY crash_retry_exhaustedstate.rs#L47-L50两条净化失败类别CancelRequested 过期租约 → 立即终态Cancelled无宽限期取消不重入已提交工作无检查点且claim_count 3→ 立即回QueuedResumed无已提交内容可回放立即回收安全停在无副作用检查点BeforeModel/BeforeBlock且未超预算 →等过期后一整租约 TTL 的宽限窗requeue_awaits_gracestate.rs#L810-L846因为过期只证明心跳停止而心跳饿死的活 worker与死 worker看起来一样活 worker 会在一个 TTL 内续租。宽限窗是 zombie fence 的第一半第二半是写入缝的租约围栏——run 转换携带 lease token 且ensure_lease拒绝不匹配者转录终结在追加前向日志询问已 claim run 的租约见 state.rs#L748-L760 的长注释对应回归测试run_parked_before_a_model_call_is_resumed_after_lease_expiry_not_failed位于 lease_wedge.rs停在副作用检查点BeforeSideEffect或无法识别类别 → 终态Failed类别lease_expired未知类别按副作用失败关闭claim_count达到 3 → 终态Failed有检查点则lease_expired无则crash_retry_exhausted。检查点类别随进程快照而非仅检查点行持久化checkpoint_kind字段使清扫在不读取检查点载荷的情况下即可判定并在存储重开后依然有效。6.2 检查点存储的适配器实现loop_checkpoint.rs 中的ProcessLoopCheckpointStore把LoopCheckpointStore::put_loop_checkpoint映射为进程日志的record_process_checkpoint生成TurnCheckpointId将 run_id 铸为ProcessId在 turn scope 之上叠加invocation_id构成检查点 scope载荷经ProcessCheckpointPayload::new有界化元数据携带turn_id、schema_id、schema_version、kind、gate_ref。值得注意的是LoopCheckpointKind::Final映射为None无进程级类别且link_to_process: false——契约语义是final 是终态证据绝不是续跑点也不链接到进程。读取侧get_loop_checkpoint以相同的三要素checkpoint_id、process_id、scope查询天然实现外部 scope/run 读到空的隔离要求。7. 脱敏边界只存元数据与引用契约最后一条硬性边界Turn persistence 只存储元数据与引用。它不得在 turn/run/checkpoint/idempotency 记录中持久化原始 prompt、assistant 内容、工具输入、密钥、宿主路径或后端错误细节。这条边界在实现中多路落实失败原因只保留稳定净化类别SanitizedFailureAgentTurnProcessCommitObserver从提交中提取的是failure.category()与受限 detailruntime.rs检查点载荷以ProcessCheckpointPayload有界写入读取侧经RedactedCheckpointPayload::new包装后才暴露loop_checkpoint.rs事件投影只搬运游标、状态、脱敏原因与元数据引用event_projection.rs 中TurnEventProjectionFromProcessJournal直接以进程日志为视图源。AgentTurnProcessRuntime的resume_turn、cancel_run、retry_turnruntime.rs还共同执行契约的另两条操作约束resume/cancel/retry都先校验state.actor与请求者一致否则TurnError::Unauthorizedretry_turn拒绝非终态运行、拒绝CheckpointRejected类失败failure_prohibits_retry、拒绝被后到运行超越的旧运行并只允许BeforeModel/BeforeSideEffect/BeforeBlock三类检查点作为重试起点——对应测试 tests.rs 中的retry_rejects_checkpoint_rejection_without_creating_a_process该选择器同时被映射进scripts/reborn-e2e-rust.sh的回归清单。8. 相关契约与进一步阅读turn-runner.mdTrusted worker 侧执行模型含 §3 完整过期租约恢复转换表与 §3.1 无检查点 pre-model 失败重驱RedriveIfCheckpointless细则processes.md进程生命周期契约含持久化布局/processes/materialized/...多键事务、ProcessLifecycleStatus词汇与租约过期策略events-projections.md事件投影视图边界runtime-profiles.md运行画像解析与 SteeringPolicy源码入口投影模块 crates/kernel/ironclaw_turns/src/process_projection/mod.rs权威存储 crates/kernel/ironclaw_processes/src/journal_store.rs恢复实现 crates/kernel/ironclaw_processes/src/journal_store/state.rs以及进程 crate 的设计说明 crates/kernel/ironclaw_processes/README.md。适用前提说明本文描述的规则、常量与路径均以当前仓库快照为准如默认租约 TTL 90 秒、崩溃回收预算 3 次、终态保留窗口的有界语义这些数值属于实现细节而非对外 API 承诺后续版本可能调整请以仓库源码为最终依据。赞分享人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载相关推荐IronClaw loop 层契约解析ironclaw_loop_contracts 如何让 agent loop 与 turn 内核解耦IronClaw loop 层契约解析ironclaw_loop_contracts 如何让 agent loop 与 turn 内核解耦 本文是 IronC人工智能AI 应用交互助手AI AgentWeKan 持久化作业设计检查点、租约与幂等重放的重启安全作业契约WeKan 持久化作业设计检查点、租约与幂等重放的重启安全作业契约 本文基于 WeKan 仓库中 Admin Panel → Problems 下的设计文档前端移动开发UI组件跨平台IronClaw 持久化通知收件箱设计解析ironclaw_notifications 的记录语法、生命周期与幂等发布契约IronClaw 持久化通知收件箱设计解析ironclaw_notifications 的记录语法、生命周期与幂等发布契约 本篇技术指南围绕 IronClaw人工智能AI 应用交互助手AI Agent上一篇Gemini API 安全设置与 Responsible AI 实战使用 Safety Settings 精确控制内容过滤阈值下一篇Apache HTTPD 换行符解析漏洞CVE-2017-15715——基于 vulhub 的 FilesMatch 绕过复现与原理分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表