Skip to content

Reuse the original Codex claim when readiness is interrupted - #8279

Merged
loopx-agent merged 8 commits into
mainfrom
codex/codex-claim-capture-replay-20261107
Nov 7, 2026
Merged

loopx-agent merged 8 commits into
mainfrom
codex/codex-claim-capture-replay-20261107

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

The native Host can finish a managed Todo claim before its ready guard returns. A retry from the same captured decision now uses the original claim operation ID. The existing authority owner rechecks the current lease and refuses a replay after release. Once the claim is accepted, the Host still requires readiness for the same Todo and Turn.

A synthetic timeout after a real claim reproduced fresh claim receipts on File and SQLite. Replaying a released capture also reacquired its lease. Four regression cases now cover the original receipt, readiness after retry, and refusal after release. The focused native preparation and saved replan suites passed 60 cases on main.

The focused claim replay and saved replan checks passed 20 cases after the main update to 7108b92337.

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

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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

[P2] 跨版本重试会让旧捕获取得新租约。 旧版 Host 已为捕获写入 claim 后中断。释放该租约后,新版 Host 用逐字节相同的捕获成功取得 epoch 2,生成不同的 operation ID,并为原 Turn 输出 ready。File 和 SQLite 均复现。 操作 ID 派生

动机 / Motivation

Codex App 和 Codex App SSH 的 Host 在首次 claim 成功、ready 还没回传时,需要沿同一份捕获恢复。 本机更新 LoopX 前,Host 已拿到 claim,却在写回 readiness 前退出。租约随后释放。更新后的 Host 需要处理本地仍存在的原捕获。 同版本的恢复和退休保护成立。旧版产生的同一捕获仍能取得新租约。 检查原签名捕获、managed claim、ready guard、File 和 SQLite。

改动思路 / Approach

Host 从已校验 capture 读取 scope 和摘要,给现有 Todo claim 传操作 ID,再走原 readiness guard。Todo owner 检查租约与权限。新摘要 ID 稳定,但和旧版已持久化的 claim ID 没有可验证关联。 复用 canonical Todo claim 和 ready guard 的方向合理。operation ID 必须从第一次写入延续到恢复,升级是这条状态路径的一部分。 保持现有 Host、Todo claim 和 ready guard 的分工。修复只需补足已存在捕获的跨版本恢复,沿原 owner 处理。

具体改动 / Changes

基线为 7108b92337949ddcd6c59f773cc2e0ef10c185c5。已有规范绑定同一 Todo、Turn 和原始文件,PR 增加退休后必须重新取得 eligible capture 的要求。 改后规范 基线规范

  • 同版本恢复。 新版生成和恢复时,重试复用原 operation ID。释放后 File 与 SQLite 保留 epoch 1,未输出 ready。当前入口套件 51 项通过。
  • 已有捕获恢复。 旧版 Host 已为捕获写入 claim 后中断。释放该租约后,新版 Host 用逐字节相同的捕获成功取得 epoch 2,生成不同的 operation ID,并为原 Turn 输出 ready。File 和 SQLite 均复现。
  • 普通路径。 现有入口 51 项用例通过。

关键代码讲解

execute_codex_execution_preparation 只在原生上下文中导出 claim ID,并验证命令返回同一个 ID。Todo owner 继续检查传入 operation 和租约。ready guard 核对同一 Todo 和 Turn,但新租约取得后,这两个字段仍与旧捕获一致。 Host claim Todo owner ready guard

对主干的风险 / Risks

原调用会在 readiness 丢失后重试。本轮使用两份真实 CLI checkout,先允许第一次 claim 完成,注入中断,再使用真实 release。恢复前后原捕获逐字节相等。同版本控制未取得新租约,跨版本两次均产生新租约和 ready,风险集中在已经落盘的旧捕获。

当前入口套件 51 项通过。同版本的四个回归例放到原源码上均能捕获旧缺陷。独立双进程对照的两个同版本控制通过,两个跨版本恢复失败。 Quick premerge 的 6 项直接检查和 4 项选中检查通过。 当前 head 的同版本修复仍有实际价值。反例仅针对已由旧版 claim 的保存捕获。 远端 CI 未取样。

语义与 CI 对齐

旧版从 Todo owner 获取原先的非确定性 ID。新版从捕获 SHA-256 派生另一个 ID。managed claim 只对已知 ID 执行原租约 replay,因此对这份旧捕获走了新 claim。 通过既有 managed claim owner 找回并校验原捕获与 claim 的关联。若旧捕获无法证明这项关联,则拒绝从该捕获领取租约,要求重新获取 eligible preparation capture。用跨版本 File 和 SQLite 测试覆盖写入后中断与释放。 退休租约的规范

我的整体评价 / Verdict

对 e165096b71969f088185e14f77855ca1a8d46c5a 请求修改。保留现有 owner 和同版本的稳定操作 ID,先补齐已经写入的旧捕获跨版本行为。 升级前已写入 claim 的捕获需要恢复原 claim,或给出可执行的重新准备路径。

English verdict: REQUEST_CHANGES. Same-version claim replay passes. The pre-upgrade capture reacquires a released lease and emits ready for the original Turn on both File and SQLite.

…x-claim-capture-upgrade-20261107

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
@loopx-agent
loopx-agent requested a review from maxliux5 as a code owner November 7, 2026 12:45
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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

[P2] 重新编码的捕获能冒充新准入。 仅给真实新版捕获副本追加一个空格,JSON 值和绑定标记完全相同。没有执行新的 live guard。用副本的新 SHA-256 执行 context-project 后,下一次实际 Hook 在两种 backend 都把退休的 epoch 1 变成活跃 epoch 2,并为原 Turn 产生不同 operation 和 ready。旧捕获副本自加标记也能复现。 绑定入口

动机 / Motivation

Codex App 与 Codex App SSH 的原生 Host 在上下文读取或重试前必须保留原领取身份。 真实 claim 已写入,ready 丢失,随后原租约释放。用户重新打开同一个保存的决定,可能读到原字节或重新编码的副本。 真实旧捕获兼容和同版本重试得到验证。重新编码的保存决定仍能替代真实准入。 核对当前主干对照的 6 个改动路径、两种存储与现有恢复入口。GitHub 文件列表的其余 22 个路径与当前主干逐字相同。

改动思路 / Approach

真实 should-run 把标记写进原决策。当前 context-project 在解析文件后把 marker 推成 claim 绑定,随后 Hook 从该 digest 派生 operation。两段需要共享可验证的原始事实。 原 guard 与既有 claim/lease owner 的分工合适。决定是否可领取的 provenance 必须先独立验证,文件完整性只负责读取。 作用范围是原生 quota should-run 的真实 capture、context-project 重放和原生 hook。保持既有历史可读性和原 canonical owner。

具体改动 / Changes

基线为 32167518b3c2646fd9b6a3a6e0aaf74b258a7b70。规范要求原文件与同一 Todo、Turn。当前 head 进一步规定保存后的呈现保留原 claim 绑定及退休保护。 基线规范

  • 真实旧捕获。 旧版生产的真实捕获在升级后及重新展示后均保留退休的 epoch 1。新版真实捕获重新展示后,活动租约沿用原 operation 和 ready,退休时继续拒绝。File 和 SQLite 各三例通过,原捕获与原 receipt 保持。
  • 真实新版捕获。 旧版生产的真实捕获在升级后及重新展示后均保留退休的 epoch 1。新版真实捕获重新展示后,活动租约沿用原 operation 和 ready,退休时继续拒绝。File 和 SQLite 各三例通过,原捕获与原 receipt 保持。
  • 原始来源核验。 仅给真实新版捕获副本追加一个空格,JSON 值和绑定标记完全相同。没有执行新的 live guard。用副本的新 SHA-256 执行 context-project 后,下一次实际 Hook 在两种 backend 都把退休的 epoch 1 变成活跃 epoch 2,并为原 Turn 产生不同 operation 和 ready。旧捕获副本自加标记也能复现。

关键代码讲解

_emit_quota_result 在真实准入时记录绑定标记。project_saved_context_capture 从保存的文件读取该标记,直接将本次传入的 SHA 交给 native recovery。execute_codex_execution_preparation 用这个值派生 operation ID,再调用原 claim owner。后置 guard 仍检查同一 Turn,且能在新租约已取得后给出 ready。 guard 保存后展示 claim

对主干的风险 / Risks

新 head 相对当前主干 32167518b3c2646fd9b6a3a6e0aaf74b258a7b70 只改动 6 个路径。旧跨版本审查用例已在两 backend 按原捕获重跑。新增副本反例逐步读回原 receipt、原 bytes 和新 lease。原 receipt 仍保留,新 epoch 与 ready 是实际新增效果。 上次发现

真实旧版和新版捕获的六个对照通过。旧捕获加标记、新捕获只加空格在 File 与 SQLite 各复现一次新租约。 Quick premerge 的 6 项直接检查和 4 项选中检查通过。 GitHub 当前文件列表含 22 个已集成且与目标主干逐字相同的路径。实际 6 个变更路径均已审查。 远端 CI 未取样。

语义与 CI 对齐

context-project 将可由文件内容提供的布尔标记和调用方提交的摘要作为 claim 来源。摘要只校验所给 bytes 的完整性。重编码的字节被当作新的 live guard 绑定,既有 managed owner 对不同 ID 走首次领取。 通过既有 guard 或 authority 记录核验该捕获的原绑定,展示时只传回已核验的原 operation 或 digest。来源无法验证时仍允许读回,Host 要求重新走合格 guard。补同 JSON 异摘要和旧捕获自标记的回归。

我的整体评价 / Verdict

对 8e7c9d6a92cbf2089583d279322d59de987047ad 请求修改。旧版捕获和新版真实捕获的恢复行为已经验证,当前阻塞集中在保存来源可自证绑定。 原跨版本反例已修复。新头仍需把自动领取绑定到可验证的 live guard 来源,再复验同版本、旧版及重新编码的副本。

English verdict: REQUEST_CHANGES. The authentic upgrade and same-version replay cases pass. A byte-reencoded copy of the same decision still acquires a new lease and emits ready without a fresh live guard on both File and SQLite.

Comment thread loopx/cli_commands/quota_capture.py Resolved

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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

[P2] 重新编码的捕获能冒充新准入。 仅给真实新版捕获副本追加一个空格,JSON 值和绑定标记完全相同。没有执行新的 live guard。用副本的新 SHA-256 执行 context-project 后,下一次实际 Hook 在两种 backend 都把退休的 epoch 1 变成活跃 epoch 2,并为原 Turn 产生不同 operation 和 ready。旧捕获副本自加标记也能复现。 绑定入口

动机 / Motivation

Codex App 与 Codex App SSH 的原生 Host 在上下文读取或重试前必须保留原领取身份。 真实 claim 已写入,ready 丢失,随后原租约释放。用户重新打开同一个保存的决定,可能读到原字节或重新编码的副本。 真实旧捕获兼容和同版本重试得到验证。重新编码的保存决定仍能替代真实准入。 核对当前主干对照的 6 个改动路径、两种存储与现有恢复入口。

改动思路 / Approach

真实 should-run 把标记写进原决策。当前 context-project 在解析文件后把 marker 推成 claim 绑定,随后 Hook 从该 digest 派生 operation。两段需要共享可验证的原始事实。 原 guard 与既有 claim/lease owner 的分工合适。决定是否可领取的 provenance 必须先独立验证,文件完整性只负责读取。 作用范围是原生 quota should-run 的真实 capture、context-project 重放和原生 hook。保持既有历史可读性和原 canonical owner。

具体改动 / Changes

基线为 32167518b3c2646fd9b6a3a6e0aaf74b258a7b70。规范要求原文件与同一 Todo、Turn。当前 head 进一步规定保存后的呈现保留原 claim 绑定及退休保护。 基线规范

  • 真实旧捕获。 旧版生产的真实捕获在升级后及重新展示后均保留退休的 epoch 1。新版真实捕获重新展示后,活动租约沿用原 operation 和 ready,退休时继续拒绝。File 和 SQLite 各三例通过,原捕获与原 receipt 保持。
  • 真实新版捕获。 旧版生产的真实捕获在升级后及重新展示后均保留退休的 epoch 1。新版真实捕获重新展示后,活动租约沿用原 operation 和 ready,退休时继续拒绝。File 和 SQLite 各三例通过,原捕获与原 receipt 保持。
  • 原始来源核验。 仅给真实新版捕获副本追加一个空格,JSON 值和绑定标记完全相同。没有执行新的 live guard。用副本的新 SHA-256 执行 context-project 后,下一次实际 Hook 在两种 backend 都把退休的 epoch 1 变成活跃 epoch 2,并为原 Turn 产生不同 operation 和 ready。旧捕获副本自加标记也能复现。

关键代码讲解

_bind_native_claim_capture 在真实准入时记录绑定标记。project_saved_context_capture 从保存的文件读取该标记,直接将本次传入的 SHA 交给 native recovery。execute_codex_execution_preparation 用这个值派生 operation ID,再调用原 claim owner。后置 guard 仍检查同一 Turn,且能在新租约已取得后给出 ready。 guard 保存后展示 claim

对主干的风险 / Risks

新 head 相对当前主干 32167518b3c2646fd9b6a3a6e0aaf74b258a7b70 只改动 6 个路径。8e7c9d6 的发现及回执单独保留。本轮在 97799d3 重跑原始来源和副本对照,并分别读回原 receipt、原 bytes 和新 lease。原 receipt 仍保留,新 epoch 与 ready 是实际新增效果。 上次发现

真实旧版和新版捕获的六个对照通过。旧捕获加标记、新捕获只加空格在 File 与 SQLite 各复现一次新租约。 当前 head 的 Quick premerge 通过,执行 4 项选中检查,包含 maintainability ratchet 的直接门。 主干基线与本次 head 的六个实际差异已核对。 远端 CI 未取样。

语义与 CI 对齐

context-project 将可由文件内容提供的布尔标记和调用方提交的摘要作为 claim 来源。摘要只校验所给 bytes 的完整性。重编码的字节被当作新的 live guard 绑定,既有 managed owner 对不同 ID 走首次领取。 通过既有 guard 或 authority 记录核验该捕获的原绑定,展示时只传回已核验的原 operation 或 digest。来源无法验证时仍允许读回,Host 要求重新走合格 guard。补同 JSON 异摘要和旧捕获自标记的回归。

我的整体评价 / Verdict

对 97799d322e75ec6b7efd77487482c6606698fbc1 请求修改。旧版捕获和新版真实捕获的恢复行为已经验证,quota 传输整理后,副本仍可触发新领取。此结论和 GitHub 回执均绑定当前提交。 原跨版本反例已修复。新头仍需把自动领取绑定到可验证的 live guard 来源,再复验同版本、旧版及重新编码的副本。

English verdict: REQUEST_CHANGES. The authentic upgrade and same-version replay cases pass. A byte-reencoded copy of the same decision still acquires a new lease and emits ready without a fresh live guard on both File and SQLite.

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>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
loopx-agent previously approved these changes Nov 7, 2026

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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

动机 / Motivation

Codex App 和 SSH 的原生 Hook、进程外预采集与本地 canonical lease owner。 真实 should-run 与 native Hook 分进程。已有会话的显式目录可由外部 guard 预采集,同一会话继续呈现原文件和验证 ready。 外部 guard 的同会话来源在本次头保留,改动过的副本及错误会话环境仍然被拒绝。 按当前主干检查 7 个实际改动路径,包括 guard、读回与 Hook、摘要登记规则、测试和规范。 显式关闭下的保存读回与压缩后恢复对照也通过。现场宿主发布采用和实际耗时另行验证。

改动思路 / Approach

真实 should-run 先写不可变 capture,再写同一 native 目录的独立摘要。无 ambient ID 时,只有显式目录可读出原会话;显式 ID 错配不写。保存读取与 Hook 各自核验该来源。 quota 在捕获写入后绑定真实摘要,已配置的私有目录拥有会话线索,原生 Hook 只恢复同一来源。claim、失响应与退休判定仍走既有 canonical owner。 限原生 guard 真实来源绑定。普通 CLI 和独立 claim owner 保持原入口。

具体改动 / Changes

基线为 32167518b3c2646fd9b6a3a6e0aaf74b258a7b70。原 capture 的准入已由真实 Host guard 执行。保存读回保留原工作身份,只有独立记录的 live 来源可被用于领取。 基线规范

  • 已有会话预采集。 App 和 SSH 在 File/SQLite 的四种已有会话组合中,外部进程不带线程环境也能用原样捕获取得一次原 claim、原 Turn ready。四个带真实线程环境控制和四个主干控制同样通过。
  • 拒绝可伪造来源。 真实新版捕获副本只加一个空格,或真实旧版捕获副本自加旧标记,均可读但没有第二次 claim 或新租约。两个后端上给 guard 显式错配线程 ID 也不能覆盖独立摘要,之后原来源仍可恢复。
  • 原 operation。 已验证的原样退休捕获走同一 operation 并被 canonical lease owner 拒绝。旧版原始捕获仍可读,无新的 claim。

关键代码讲解

capture_decision 只在真实成功的 native should-run 后登记来源。record_native_claim_source 在显式私有目录复用真实会话,错配直接返回。prepare_codex_context 和 Hook 分别核验摘要。后续保持原 managed operation 与 ready 读回。 guard 会话 Hook

对主干的风险 / Risks

前两轮的副本和进程外预采集问题分别保留原证据。当前提交按各自工作负载重跑,独立摘要和原租约读回一致。 早期副本回执

独立来源 12 项、已附着目录 12 项和错配 2 项通过。原文件、租约和已有回执逐项读回。 摘要架构套件候选 243 通过、1 项同基线失败,既有 consumer 清单失败已消失。 Quick premerge 的 6 项直接检查和 4 项选中检查通过。 与当前主干组合通过。 保存后选择的匹配套件两边有相同的两项 full/delta 失败。摘要 owner 的剩余失败同样可在基线复现。 远端 CI 未取样。

语义与 CI 对齐

兼容性由真实入口对照验证。保存文件读取、原工作领取、发布采用各有独立证据范围。

我的整体评价 / Verdict

批准 b341dd80a3cbba8d9edfed01116dce0ec35dd24c。同一会话的原样外部捕获恢复已验证,两种副本、退休和错误环境均维持保护。 显式关闭下的保存读回与压缩后恢复对照也通过。现场宿主发布采用和实际耗时另行验证。

English verdict: APPROVE. The same explicit session now recovers a genuine external preflight on App and SSH. Independent File and SQLite checks preserve active and retired claim semantics, reject reencoded and marked copies, and keep the original binding on session mismatch.

@huangruiteng
huangruiteng dismissed loopx-agent’s stale review November 7, 2026 13:41

The merge-base changed after approval.

@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, @huangruiteng.

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 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

APPROVE — exact head 7f480c08184861f1f54f080476301f355f02a53d.

Re-reviewed after integrating current main 0a9dda8c.

  • Preserves the genuine live-guard provenance digest separate from the saved decision bytes; reencoded or self-marked captures can be read but cannot acquire a new lease.
  • Same-version retries reuse the original claim operation; released authentic captures remain refused; explicit-session prequota recovery retains the original Turn and ready path.
  • The only merge conflict was the test helper signature, resolved by retaining both context_delivery/goal_suffix and write_scopes.

Exact-head verification: claim/readiness plus saved-replan suites pass 77; Python compile, changed-file Ruff, and diff hygiene pass. Merge commit carries DCO. No blocking finding remains at this exact head.

@loopx-agent
loopx-agent merged commit 90ffbe2 into main Nov 7, 2026
7 of 11 checks passed
@loopx-agent
loopx-agent deleted the codex/codex-claim-capture-replay-20261107 branch November 7, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants