
OmX Runtime 权威语义契约Authority 租约、Backlog、Replay 与 Readiness 的 Rust 侧真相源【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex导读本篇文章以 docs/contracts/runtime-authority-backlog-replay-readiness.md 为核心骨架系统梳理 OmXOh My codeX中由 Rust 完全持有的运行时语义契约。该契约取代了历史 JS 侧的运行时真相从同一时刻至多一个权威租约的 Authority 状态机到 Backlog 的四态流转、基于游标的持久化 Replay 恢复再到由derive_readiness()唯一产出的 Readiness 快照以及WorkerCli驱动的派发分类策略。读完本文你将掌握这套运行时契约的每一个状态转换规则、对应的源码实现与集成测试位置并能在实际运维中精确解释为何 recovery 被暂停这类诊断问题。背景为什么运行时真相必须由 Rust 持有OmX 是一个给 codex 注入 hooks、Agent 团队、HUD 等能力的工具其运行时涉及多进程协作leader、worker、tmux pane。在多进程、可能崩溃重启的场景下运行时状态必须有一个权威、可持久化、可重放的真相源而不是由某个 CLI 在读取时刻推断出来的临时观点。从仓库结构看crates/omx-runtime-coreCargo.toml承载了这套纯 Rust 的状态机实现crates/omx-runtimesrc/main.rs则把它暴露成可被外部进程调用的 CLI 接口。文档开头一句 This document captures the Rust-owned runtime semantics that replace JS-side truth 点明了设计动机运行时语义的权威性从 JS 迁移到 Rust 侧JS 侧team / doctor / HUD 等只能读取由 Rust 产出的快照而不是自行推断。Authority同一时刻至多一个活动租约租约的三元组文档定义运行时任意时刻最多持有一个活动 authority lease权威租约租约由三个字段构成字段含义owner持有租约的所有者标识如 worker 名lease_id租约唯一标识leased_until租约到期时间ISO 8601 字符串此外源码在 authority.rs 中还额外维护了stale: bool与stale_reason: OptionString用于标记过期/失效状态及原因——这正是 Readiness 判断是否可用的关键输入之一。状态机三个转换方法AuthorityLeasecrates/omx-runtime-core/src/authority.rs实现了一个严谨的租约状态机仅允许三种转换1.acquire(owner, lease_id, leased_until)—— 获取租约成功条件当前无人持有租约或请求者已经是当前 owner可视为续租式重获失败条件租约被其他 owner 持有返回AuthorityError::AlreadyHeldByOther { current_owner }。实现上authority.rsacquire 会顺带把stale与stale_reason清空。2.renew(owner, lease_id, leased_until)—— 续租成功条件当前租约确实由同一 owner 持有失败条件无人持有 →NotHeldowner 不一致 →OwnerMismatch { current_owner }。源码authority.rs通过match self.owner精确区分这两种错误。3.force_release()—— 无条件释放清空全部租约字段包括 stale 状态authority.rs用于兜底回收。文档补充的硬性约束A stale or expired lease must be marked stale before another owner is granted authority.即租约过期或失效后必须先被mark_stale(reason)标记为 stale才允许其他 owner 获得权威。mark_stale/clear_stale/is_stale/is_held/current_owner等辅助方法在 authority.rs 中均有实现to_snapshot()则将内部状态投影为可序列化的AuthoritySnapshot定义于 lib.rs。测试证据authority.rs 内置了完整测试acquire_and_renew_happy_pathacquire 后is_held()为 true同 owner renew 成功acquire_fails_if_held_by_otherworker-2 尝试获取 worker-1 的租约 →AlreadyHeldByOtheracquire_succeeds_for_same_owner同 owner 二次 acquire 放行renew_fails_if_not_held/renew_fails_if_owner_mismatch分别验证NotHeld与OwnerMismatchforce_release_clears_everything强制释放后is_held()与is_stale()均为 false。Backlog派发工作的四态生命周期状态迁移规则文档给出 Backlog 的严格流转路径pending ──notification── notified ──completion── delivered └───────────── failed新工作以pending入队通知notification把工作从pending移到notified完成completion把工作从notified移到delivered或failedpending/notified/delivered/failed是运行时快照中的四个计数见 BacklogSnapshot。DispatchLog 与 DispatchRecordDispatchLogcrates/omx-runtime-core/src/dispatch.rs逐条跟踪DispatchRecord每条记录携带字段说明request_id派发请求唯一 IDtarget目标如 worker / panestatusPending/Notified/Delivered/Failedcreated_at/notified_at/delivered_at/failed_at各阶段时间戳ISO 8601reason失败或通知通道等补充原因metadata可选附加元数据serde_json::ValueDispatchStatus枚举dispatch.rs以snake_case序列化Display输出pending/notified/delivered/failed。非法转换被强制拒绝文档强调非法转换如pending - delivered必须返回DispatchError::InvalidTransition。源码中每个mark_*方法都做了前置校验queue(request_id, target, metadata)空request_id→InvalidRequestId重复 ID →DuplicateRequestId入队即Pendingdispatch.rsmark_notified(request_id, channel)仅允许Pending - Notified并把channel记入reasondispatch.rsmark_delivered(request_id)仅允许Notified - Delivereddispatch.rsmark_failed(request_id, reason)允许从Pending或Notified两态失败——源码注释明确Allow failed from both Pending (target resolution failure) and Notified (delivery failure)与历史 TS 行为保持一致dispatch.rs。DispatchError的四个变体DuplicateRequestId/InvalidRequestId/NotFound/InvalidTransition及其 Display 文案见 dispatch.rs。快照与清理to_backlog_snapshot()遍历记录按状态累加pending/notified/delivered/failed四个计数dispatch.rsprune_terminal_records()移除已到达Delivered/Failed终态的记录dispatch.rs配合引擎层compact()控制事件日志与记录规模。测试方面dispatch.rs 覆盖了 happy path、Pending - Failed、InvalidTransition、NotFound、快照计数、剪枝、带 metadata 的序列化往返、终态后重复 ID 仍被拒绝等场景。Replay / Recovery游标式、持久化、去重ReplayState 三要素ReplayStatecrates/omx-runtime-core/src/replay.rs把恢复语义浓缩为三部分游标cursorrequest_replay(cursor)记录当前重放位置去重dedup内部用HashSetString按event_id去重——record_event(event_id)返回true表示新事件false表示已见过replay.rs延迟的 leader 通知defer_leader_notification()/clear_deferred()显式标记是否故意推迟对 leader 的通知让观察者能分辨为什么投递结果还没浮出水面。ReplaySnapshotlib.rs对外暴露cursor、pending_events、last_replayed_event_id、deferred_leader_notification四个可序列化字段。引擎层的重放实现文档的cursor-based and durable落实到 engine.rs持久化persist()在独占锁engine.lock保护下写入snapshot.json、events.json、dispatch.json、mailbox.json以及专门记录已见派发 ID的dispatch-seen.json账本engine.rs重放load()读取events.json后逐个事件调用replay_event()重建全部状态engine.rs严格性重复或乱序的派发历史会被replay_event拒绝而不是被静默修复——对应集成测试load_rejects_duplicate_and_out_of_order_legacy_dispatch_eventsengine.rs验证了重复 ID 报duplicate dispatch request id、乱序投递报dispatch record not found永久账本dispatch-seen.json采用 schema_version2、ledger_epoch1 的格式engine.rs保证已被 compact 或移除的派发 ID 在重载后依然永久保留、不可复用测试见 engine.rs。文档所说Replayed items must be deduplicated在派发维度上由此账本兜底而ReplayState的HashSet则负责事件维度的去重。Readiness由 Rust 产出的快照而非 CLI 推断核心结论文档强调三点Readiness 是Rust 侧产出的快照RuntimeSnapshot.readiness不是 CLI 的临时观点租约缺失、stale 或非法时运行时不 ready快照必须携带精确的阻塞原因exact blockers让运维者能直接看到为什么 recovery 被暂停。derive_readiness() 的计算逻辑derive_readiness()engine.rs基于AuthorityLease、DispatchLog、ReplayState三个输入计算ReadinessSnapshot只会在同时满足以下条件时返回ReadinessSnapshot::ready()权威租约被持有且非 stale没有 pending 的 replay 事件。所有阻塞原因被逐条收集进readiness.reasonsVecString阻塞条件写入的 reason 文案租约未被持有authority lease not acquired租约被标记 staleauthority lease is stale: {stale_reason}存在待重放事件replay has {n} pending eventsReadinessSnapshot结构ready: boolreasons: VecString定义于 lib.rs默认值为blocked(authority lease not acquired)——即全新运行时天然处于未就绪状态直到租约被成功获取。快照的默认行为与测试佐证lib.rs 的snapshot_defaults_to_blocked_state断言新建RuntimeSnapshot的ready()为 falsereasons恰为[authority lease not acquired]engine.rs 的snapshot_shows_blocked_without_authority验证同一结论derive_readiness_stale_authorityengine.rs验证 stale 租约下ready false且 reason 含staleprocess_acquire_authorityengine.rs验证成功 acquire 后快照ready()为 true。兼容视图喂给旧 TS 读者的只读快照为了不破坏 legacy TS 侧team / doctor / HUD读取习惯write_compatibility_view()engine.rs会把RuntimeSnapshot拆分成authority.json、backlog.json、readiness.json、replay.json、dispatch.json、mailbox.json等独立文件。测试compatibility_view_writes_section_filesengine.rs验证了这些文件均存在且内容合法——这就是Rust-authored snapshot如何成为 JS 读者唯一可信来源的落地方式。Dispatch 分类提交策略与结果判定WorkerCli 提交策略文档规则WorkerCli决定提交按键次数——Claude 按 1 次Codex/其他按 2 次。源码实现于 lib.rsWorkerCli::from_label(label)按小写去空白匹配claude/codex其余归入Other(String)submit_presses_for_worker_cli()Claude 1Codex | Other(_) 2测试worker_cli_submit_policy_matches_current_dispatch_behaviorlib.rs验证三种分支。结果分类DispatchOutcomeReason 与 QueueTransitionDispatchOutcomeReason枚举lib.rs统一了派发结果语义覆盖确认送达、延迟与失败三类送达确认DeliveredConfirmed、DeliveredConfirmedActiveTask在活跃任务上确认送达送达未确认DeliveredUnconfirmed延迟DeferredLeaderPaneMissingleader pane 缺失、DeferredShellNotInjectable失败FailedMissingTarget、FailedTargetResolution(reason)、FailedPreflight(reason)、FailedSend(reason)。QueueTransitionlib.rs把结果映射为对 Backlog 的三类动作KeepPending/MarkNotified/MarkFailed每个都携带reason。classify_dispatch_outcome() 的判定顺序classify_dispatch_outcome(target_present, target_resolved, preflight_ok, send_ok, confirmed, active_task, retry_remaining)lib.rs按优先级逐级短路目标 pane 缺失 →MarkFailed(FailedMissingTarget)目标无法解析 →MarkFailed(FailedTargetResolution)预检失败 →MarkFailed(FailedPreflight)发送失败 →MarkFailed(FailedSend)发送成功且已确认 →MarkNotified活跃任务则用DeliveredConfirmedActiveTask发送成功但未确认仍有重试机会retry_remaining→KeepPending(DeliveredUnconfirmed)保持 pending 等待重试重试用尽 →MarkFailed(DeliveredUnconfirmed)。与文档语义的对应文档最后的三个要点在此被源码精确承接Deferred leader-missing cases stay pendingDeferredLeaderPaneMissing场景由ReplayState.deferred_leader_notification显式跟踪且派发记录保持 pending运行时可在 pane 可用时重试Unconfirmed sends can stay pending while retries remain即classify_dispatch_outcome的第 6 步retry_remaining true时回到 pendingotherwise they fail with an unconfirmed reason重试耗尽后以DeliveredUnconfirmed落入 failed。对应测试dispatch_outcome_classification_distinguishes_confirmation_and_retry_pathslib.rs把四条路径confirmed / active_task / unconfirmed_retry / unconfirmed_failed全部断言了一遍。实操通过 omx-runtime CLI 观察运行时语义crates/omx-runtime是一个可直接运行的二进制入口 src/main.rs把上述契约暴露为子命令。其行为被 tests/execution.rs 以集成测试形式锁定查看契约摘要omx-runtime schema # 输出形如runtime-schema1 / commands... / events... / transporttmux / queue-transitionnotified omx-runtime schema --json # 输出 JSON含 schema_version、commands、events查看运行时快照omx-runtime snapshot # 未获取租约时authorityownernone ... readinessblocked(authority lease not acquired) omx-runtime snapshot --json omx-runtime snapshot --state-dirdir # 从持久化状态目录加载后出快照集成测试snapshot_json_subcommand_prints_valid_jsonexecution.rs断言快照 JSON 必然包含authority/backlog/replay/readiness四个对象且初始readiness.ready为 false。执行命令驱动状态机omx-runtime exec {command:AcquireAuthority,owner:worker-1,lease_id:lease-1,leased_until:2026-09-10T00:00:00Z} --state-dirdir omx-runtime exec {command:QueueDispatch,request_id:req-1,target:worker-2,metadata:null} --state-dirdir omx-runtime exec {command:MarkNotified,request_id:req-1,channel:tmux} --state-dirdir omx-runtime exec {command:MarkDelivered,request_id:req-1} --state-dirdir --compactexec会加独占锁runtime-mutation.lock、执行命令、可选--compact清理终态事件并持久化主快照与兼容视图文件。命令全集见RUNTIME_COMMAND_NAMESlib.rsacquire-authority、renew-authority、queue-dispatch、mark-notified、mark-delivered、mark-failed、remove-dispatch-records、request-replay、capture-snapshot及 mailbox 相关命令。初始化与 mux 契约检查omx-runtime init state-dir omx-runtime mux-contract # 输出 adapter-status / submit-policy / confirmation 等小结一套闭环的运行时一致性契约把五个部分串起来可以看到 OmX 的运行时一致性设计闭环Authorityauthority.rs保证同一时刻只有一个权威持有者过期必须显式 staleBacklogdispatch.rs用强制的状态转换保证派发记录永远可解释非法跳转直接报错Replayreplay.rs engine.rs以游标 去重 持久化事件日志支撑崩溃恢复并以dispatch-seen.json账本保证 ID 永久唯一Readinessengine.rs把前三者的健康度汇总成带精确 blockers 的官方快照Dispatch 分类lib.rs把发送结果严格映射回 Backlog 状态让未确认与延迟场景都可重试、可观测。对于任何需要在 OmX 上排查运行时为何不就绪派发为何卡在 pending的开发者这份契约docs/contracts/runtime-authority-backlog-replay-readiness.md加上上述源码路径就是最权威的排查起点。【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考