Skip to content

Recover native execution preparation without repeating claims - #8307

Merged
loopx-agent merged 5 commits into
mainfrom
codex/native-preparation-readback-20261107
Nov 8, 2026
Merged

loopx-agent merged 5 commits into
mainfrom
codex/native-preparation-readback-20261107

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Problem context

When a native Hook loses readiness after starting a bound claim, a later Hook can replay both the claim and guard from the same captured action. The authority keeps lease acquisition idempotent, but retries still cost control-plane work and can leave the current Turn waiting for readiness.

Change

Reserve the automatic attempt under the existing native session lock before invoking the ordinary claim. Give that capture a stable claim operation ID. When preparation or Hook delivery is interrupted, surface readback for the original claim receipt, current lease and verified ready capture. A same-session hint stays available until the Hook observes a verified read of the ready capture. A matching active lease lets the original captured Turn finish its readiness check. A fresh eligible capture can still prepare new work.

Validation at merged head

  • Head 441e8952f7cadc77263fa194b63e5c81dc99fd64: all 6 direct and 19 selected local premerge checks passed. After the latest main integration, 25 focused native readback/claim cases passed.
  • The File and SQLite regressions discard a successful Hook response, re-present the original capture, and verify original readback with unchanged provider events. A forged or damaged ready source does not mark delivery. After the exact bytes are restored, the observed read can stop the hint.
  • A previous main-integrated candidate with the same behavioral repair passed 219 source tests. Its model delivery and task-level cost were not measured.

Earlier validation (historical heads)

  • A synthetic timeout occurs after a real managed claim on both File and SQLite. The first Hook returns the original claim operation and read-only commands. Later PostToolUse and SessionStart events keep the count at one claim and one automatic guard. A matching lease reaches ready through the same Turn. A released lease stays released with the same epoch.
  • The native journal covers same-source reservation, rejection of a different source, a one-time recovery hint and eligibility for a new capture. The prepared reader also rejects a replaced ready capture and retains its original digest.
  • Head 14f9f76e451dd09bc493e6292239263080a96fa3 on main c0b6aded5d173dd474a22ff0b33955d4d93a7732. Source tests 212 passed, 0 skipped. Isolated wheel 9 passed, with changed Python modules verified against the commit. Ruff passed. Standard local premerge ran 6 direct and 19 selected checks with zero mechanical failures and 0 manual holds. The injected test qualifies recovery in the native CLI Hook; full model delivery and task-level costs remain to be measured.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent, gpt-6.1-sol, OpenAI, runtime_reported, reasoning_effort=max

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

[P1] 旧捕获在升级路径可重新领取已释放租约。 用旧版 c0b6ade 领取后释放 epoch 1,在同一 session 重放未交付的旧捕获,新版用未出现过的 operation ID 再次领取并返回 ready,File、SQLite 均变成 active epoch 2。 ID 派生

[P2] 恢复提示持久化早于送达。 在 readback_sent 写入后、提示输出前终止进程,下一次 PostToolUse 和 SessionStart 均无恢复提示;原租约仍 active,同一来源不会再给回执。旧版的对应重入虽重复 claim/guard,但会给 ready。 提示标记

动机 / Motivation

Codex 原生 Hook 负责领取当前 Todo 的执行租约,并让宿主拿到同一 Turn 的就绪决定。 如果进程在领取后中断,恢复必须区分原领取是否提交、租约是否已退役、就绪结果是否交给宿主。旧路径会再次发起领取和准入,也可能重新激活已释放租约。 本次在真正调用前登记尝试,并为当前版本的新捕获绑定稳定操作 ID;实测它修复了同版本在领取后、guard 前中断的路径。旧捕获和恢复提示丢失仍有反例。 本次只修改原生 Context Hook 及回读指引,执行权仍来自普通 managed claim、原 Todo 与现有 lease owner。

改动思路 / Approach

保留 native session journal 绑定同源捕获;由普通 claim、lease provider 和原 should-run 验证实际执行。Hook 生成回执与恢复指引,局部 marker 没有独立执行权。 在 native session lock 内做一次预约合理。能重复读取的同源回执可复用原 owner;当前代码仍把本地标记当交付完成,旧捕获也没有原执行的兼容 fence。 保留单一的普通 claim 和准入 owner,先把原捕获可安全接回;本次无需增加产品状态或把所有 Host 迁移为新协议。

具体改动 / Changes

基线为 c0b6aded5d173dd474a22ff0b33955d4d93a7732。以既有捕获绑定、原同一 Todo/Turn 准入以及当前 task lease 条件作为验收。 基线规范

  • 当前版本接回原执行。 同版本在普通 claim 提交后、ready guard 之前中断,File 与 SQLite 都返回原操作的只读回执及租约;两次后续 Hook 零次自动 claim/guard,同 Turn 手工确认 ready 且租约不变。
  • 已释放的执行不可复活。 用旧版 c0b6ade 领取后释放 epoch 1,在同一 session 重放未交付的旧捕获,新版用未出现过的 operation ID 再次领取并返回 ready,File、SQLite 均变成 active epoch 2。
  • 原结果可回读。 在 readback_sent 写入后、提示输出前终止进程,下一次 PostToolUse 和 SessionStart 均无恢复提示;原租约仍 active,同一来源不会再给回执。旧版的对应重入虽重复 claim/guard,但会给 ready。 同版本的 ready journal 已写入但宿主未收到回执时,PostToolUse 没有原地址,SessionStart 仍自动重跑一次 claim 和 guard;claim receipt 与 lease epoch 不变。
  • 真实模型和成本。 旧捕获的租约复活和恢复地址丢失必须修复;模型实际收到上下文的成功率和完整成本没有验证。

关键代码讲解

native_execution_preparation_request 在 journal 锁内登记尝试;execute_codex_execution_preparation 调用普通 claim 和同一 Turn guard,并核对返回的操作 ID。handle_native_context_command 核对工作目录并分流恢复,但先写 ready 再投影给宿主。现有四个故障组合 覆盖同版本 guard 超时和释放,未覆盖旧版本和送达窗口。文档改动只描述这一路径。

对主干的风险 / Risks

同版本的 ready journal 已写入但宿主未收到回执时,PostToolUse 没有原地址,SessionStart 仍自动重跑一次 claim 和 guard;claim receipt 与 lease epoch 不变。 应从已保存的 ready digest 读回。每份合成夹具先跑 context delivery off 和不同 cwd,均不启动 claim/guard;新捕获和错误摘要仍由既有 owner 处理。 #8279 也触及旧执行的验证;它是并行方案,不能替代此 head 的证据。

源码聚焦套件 256 通过、11 跳过;四项失败中,两项 full/delta 在同基线复现,另两项大捕获断言精确 head 单独重跑通过,初次差异原因未证。独立 File/SQLite 断点均完成;隔离 wheel 重现旧捕获恢复已释放租约与丢提示。 Standard premerge 的 6 项直接检查和 19 项选中检查在重跑通过;初次 semantic-vocabulary smoke 未通过,单独与标准重跑均通过。 与当前 main 0a9dda8 可组合;早一版分段首读组合 75 项通过,现行组合回归:6 passed, 30 deselected in 95.96s (0:01:35)。 前次大捕获不稳定的原因未证明。 远端 CI 未取样。

语义与 CI 对齐

原生入口继续依赖普通 claim 和当前 lease。保留并核对原 claim 操作与 lease generation。旧 capture 缺可校验绑定时,只提供只读恢复或要求 fresh eligible capture,不运行新 claim。 把已预约、原 ready 已持久化、提示已交付分别处理。可重复给出已绑定的只读地址;等宿主确认送达再抑制,禁止以重新 claim 来替代恢复。 复验时,在 claim 返回、ready journal 持久化和读回提示渲染前中断真实 quota context-hook,用相同 session 重入,对照 File/SQLite 的 stdout、receipt、epoch 和调用数。新增 state 与恢复事件留在 native 适配器内,未增加共享权限;跨版本兼容和送达义务仍须对齐。

我的整体评价 / Verdict

请求修改。已验证的同版本改进值得保留,但一条路径错误地恢复了已释放执行,另一条在故障后没有把用户接回原任务。两者分别影响长期执行边界和当前开工。最小修复应复用原回执、同源捕获和原 lease 校验。 旧捕获的租约复活和恢复地址丢失必须修复;模型实际收到上下文的成功率和完整成本没有验证。

English verdict: REQUEST_CHANGES. At 14f9f76, File and SQLite source and wheel probes show that a legacy capture can reacquire a released lease and an interrupted readback can suppress further recovery.

@mergify

mergify Bot commented Nov 7, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @loopx-agent.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 7, 2026
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
@loopx-agent
loopx-agent force-pushed the codex/native-preparation-readback-20261107 branch from 14f9f76 to 44e2cd0 Compare November 8, 2026 10:30
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 8, 2026

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent, gpt-6.1-sol, OpenAI, runtime_reported, reasoning_effort=max

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

当前 head 44e2cd0777c758903f384ef6c580c8da6e0ce65a,PR 目标快照 fe36f31fdedd9e5ad804e73be251c473b0e60007,实际 diff 共同祖先 4e949f405528fd8087f0623526c62f890c1ce982。

动机 / Motivation

原生 Hook 开始领取 Todo 后,Agent 需要知道原租约是否生效,并用同一 Turn 继续。base 的会话重开会重新调用 claim 和就绪检查,即使原操作已有回执。当前 head 把原认领、租约和已保存的就绪捕获留作只读恢复,一次自动领取就够。就绪检查已成功但 Hook 输出丢失时,同一会话仍收不到恢复提示。 本轮是本地 native Hook 与原捕获恢复的源码评审,已安装宿主交付和完整成本另行验收。

改动思路 / Approach

保留现有普通 claim、lease provider 和 should-run 的准入决定。原生日志只预约自动尝试、固定 ready capture,并给出原回执的只读入口。当前设计复用原会话日志和回执读者。准备已成功与响应已交给宿主需要分别记录,这样可以重复给出恢复地址而无需重新认领。

具体改动 / Changes

实际 diff 共 6 个文件、+367/-79。当前 main 仅在 codex_context.py 有一处重叠改动,合并树可构造。当前审查覆盖实际 diff、已有原捕获身份规则、正常认领及 File/SQLite 两种丢响应路径。

关键代码讲解

  • native_execution_preparation_request 先验证当前 session 的 live capture 绑定,再预约 claim。失败后重复给出原回执;会话恢复可以从现有 ready 记录取回原捕获的地址。日志与 readback 分支
  • codex_execution_preparation_readback_context 复用普通回执、租约和校验过的捕获 reader。旧未绑定快照和重新编码的副本不能触发自动 claim。原回执与捕获 reader
  • handle_native_context_command 在 ready 内容构造后调用 record_native_execution_preparation_delivered,随后才写 Hook stdout。就绪输出调用顺序

依据原有工作上下文规范,original-claim-fence 的旧捕获与已退役租约保护已验证,same-session-readback 在成功输出丢失的窗口未满足。保留原 Todo、Turn、捕获摘要与租约是恢复前提。原捕获与租约规则

对主干的风险 / Risks

[P2] 就绪输出丢失后,同一会话还需要原回读入口。 用实际 quota context-hook 完成认领和 ready guard,丢弃首个成功响应,再呈现同一捕获并触发 PostToolUse。当前 File 和 SQLite 都输出空对象,日志已是 ready/delivery_confirmed=true。触发 SessionStart 后能读回同一 ready capture,只有一次 claim/guard,原租约与回执字节不变。base 在同会话也沉默,但重开会再调用一次原幂等 claim/guard。当前改进解决重开时的重复调用,提前确认仍妨碍不重开会话的恢复。提前确认分支

让待交付的 ready 捕获在同会话继续可读。可用现有受信读回观察确认具体 ready capture 后再抑制提示。回归用 File/SQLite 丢弃成功输出,要求后续同会话 Hook 给出原 ready 摘要及只读入口,同时核对 claim、guard 调用数和 lease generation。

语义与 CI 对齐

本轮 51 项原生准备定向测试通过,标准 premerge 执行 6 项直接检查与 19 项选中检查,无阻塞失败。同 base 的 Lark 模块预算非阻塞失败单列。首次 ready guard 本身失败时,两种存储的后续 Hook 都可再读原回执,旧版一次性失败提示已修复。成功输出丢失的对照仍需上述修复。重开后的恢复命令已实际读回原 Turn 的 ready 状态。 远程 CI 未查询,丢失输出由本地测试注入。

我的整体评价 / Verdict

这是 justified_increment。原生恢复保留了一次性 claim 和原租约,失败提示重读及重开时的原捕获恢复已有证据。同一会话的成功输出丢失仍增加人工恢复步骤,应该在原日志和 reader 内补齐。当前 diff 无前端布局或首屏变化。实际宿主采用和完整成本未验证。

English verdict: REQUEST_CHANGES. Interrupted readiness now exposes repeatable readback. A lost successful Hook response still suppresses same-session recovery because delivery is marked before stdout is sent.

Comment thread loopx/cli_commands/quota_capture.py Resolved
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
…red-readback-20261109

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
…red-readback-20261109

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent / OpenAI / gpt-6.1-sol / max / runtime_reported

动机 / Motivation

当前复审 head 441e8952f7cadc77263fa194b63e5c81dc99fd64,实际基线 1cba745f52548446f83f1838e5aadfcb31b01152。复核了旧捕获重取租约和两条 Hook 提示丢失的讨论。匹配的 File/SQLite 复现中,上一提交在成功输出被丢弃后返回空。

受影响的是通过原生 Codex Hook 自动恢复 Todo 租约及读取就绪材料的执行者。 Host 完成了 claim 和 guard,但提示在送到模型前丢失。修复后重现原捕获仍可读原回执、当前租约和校验后的就绪文件。 File 和 SQLite 都能重新读到同一份就绪材料;期间没有再领取、再跑 guard 或改变事件账本。 这个切片提供可验证的工具回读,模型是否保留整份上下文仍由原覆盖规则判断。

按 docs/reference/required-work-context.md 在 1cba745f52548446f83f1838e5aadfcb31b01152 的契约核对 original-claim-and-lease、ready-source-recovery。

改动思路 / Approach

准备状态由原生日志保存,原领取操作、租约和同一 Turn 的 guard 继续由既有权威路径校验。 这一切片从 Hook 投递中断恢复到真正能读取的同一份就绪材料。 先持久化原 attempt,再由已校验的 ready 读取判断是否收起提示。工具输出证据与完整模型保留分别记录。

具体改动 / Changes

6 个文件(+390/−81)。准备和恢复仍使用现有 Hook、原生日志及普通 CLI;测试覆盖真实 File/SQLite 领取、回读和失败恢复。

关键代码讲解

  • native_execution_preparation_request 从原生日志识别原执行。同源重入保留原回读,已观察 ready 时才安静。Legacy source or inactive lease needs fresh eligible guard。
  • codex_context_hook 核验读取到的实际工具页。同一会话仅信任已验证的 ready 捕获。Keep readback on mismatch。
  • codex_execution_preparation_readback_context 返回可执行的原回执和 lease 回读。只在文件与原摘要一致时给出 ready 恢复路径。Bad file leaves original receipt and lease readers。

对主干的风险 / Risks

同会话提示在就绪材料尚未被验证前可以重复。回读只用原身份;文件损坏时不会带未验证的地址。已退休的租约需新的合格 capture。

语义与 CI 对齐

实际对照含 guard 超时、已释放 lease、未绑定旧源、伪造页、损坏及恢复后的准确读回。 主干集成后 219 个生命周期及准备测试通过;当前合并候选复跑了受影响的真实 Hook 恢复用例。25 passed, 194 deselected in 156.22s (0:02:36)。6 个直接检查、19 个选中检查通过。 按本 Goal 的 wait_for_ci=false 使用本地验证。

我的整体评价 / Verdict

Approval conclusion (author-owned PR; GitHub blocks formal self-approval) APPROVE。 三个既有讨论均有当前代码和实际回归支撑,可以进入合并门禁。

English verdict: APPROVE - head 441e8952f7cadc77263fa194b63e5c81dc99fd64 restores exact native ready readback after a lost Hook result, preserves original claim generation and suppresses hints only after verified ready reads.

@loopx-agent
loopx-agent merged commit 456349c into main Nov 8, 2026
26 of 32 checks passed
@loopx-agent
loopx-agent deleted the codex/native-preparation-readback-20261107 branch November 8, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant