Skip to content

fix(context): preserve read scope when recovering stale cursors - #8541

Merged
huangruiteng merged 5 commits into
mainfrom
codex/historical-context-cursor-recovery
Nov 11, 2026
Merged

huangruiteng merged 5 commits into
mainfrom
codex/historical-context-cursor-recovery

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

When a saved selection no longer matches its cursor digest, quota context-read rejects the stale page and returns a command to restart at offset zero after verifying the original capture digest. Explicit field selections and field listings retain their original scope. This keeps a receipt-only diagnostic (for example, the recovery from #8529) from widening into a full body read. Historical initial-read cursors retain their full-capture recovery. An invalid original capture digest still yields no recovery command.

Target: main. Related integration: #8266.

Author Declaration

  • Written by: model_agent — OpenAI Codex (GPT-6).
  • Specification: Required work context, saved cursor and progressive read boundaries.
Criterion Disposition Evidence
Reject a changed selection digest Implemented Historical direct and recipe-only cursors reject the stale page.
Recover from the same verified file without repeating admission Implemented Historical initial reads restore the original bytes; wrong capture digests refuse recovery.
Preserve explicitly selected scope during recovery Implemented Direct, saved recipe, and field-list routes keep their selectors and listing depth; receipt recovery returns only the recorded receipt.
Retire historical readers Out of scope Both readers remain available for unfinished Turns.

The CLI options, stored descriptor format, and read authority are unchanged. The C1 rehearsal includes #8529 and #8518; integrate with the actual target after the shared changes are adopted.

Validation

Source tests ran at 36c8dfd9a77fd65390d930e621fd12bce06b177b. The package checks used runtime-equivalent builds of the shared branch and the local C1 composition. The latest commit changes the test oracle only.

Check Result Evidence
Real CLI, isolated packages Passed Two cursor forms emitted by 4fcdc7a1c300f5c7f4117f9ddb20192e32f15778 each recovered the same 6,080 bytes in the shared and C1 packages. Wrong capture digests refused recovery.
Scoped recovery parity Passed With File and SQLite captures, the previous composition suggested a full-body read in all six deliberately stale direct, saved-recipe, and list cases. Each fixed package kept scope in all six cases. No registry or runtime was created.
Source regression Passed 389 checks on this head, 248 on the local C1 composition, and 246 on main (beff0f3e55d1) with only the corrected assertions applied.
Reference suite Passed The five inherited failures were test assumptions. A nonterminal page in an otherwise empty observation records coverage with section digests deferred. The changed-profile case now exercises a historical unpinned cursor. Current pinned cursors still replay their original addresses and bytes.
Native reader and hook processes Passed The three versions returned the same 8,309 selected bytes in six pages. Terminal-first delivery left an interior gap, a forged page left the journal unchanged, and the correct missing page confirmed exactly two fields without recording full delivery.
Static and public boundary Passed Ruff, diff whitespace, bilingual RFC diff check, and scoped public-boundary inspection.

No active installation, new admission, model calls, or cost claims.

Frontend / Visual Evidence

UI impact: none. CLI JSON and reader documentation only.

Type of Change

  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Control plane

Shared-authority RFC fixture impact

N/A. No authority or provider behavior changes.

Boundary Checklist

  • Public-safe changes and validation evidence.
  • Existing reader and CLI flags retained.
  • No paired RFC changed.
  • DCO signed.

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.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

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

评审提交:2e124a3d2d1a45aee689bc0084c74ad135b6542f

动机 / Motivation

受影响的是拿着旧选读游标继续工作的调用者。主干拒绝旧选读摘要;调用者需自行拼回原捕获命令。候选验证原文件及摘要后,保持拒绝旧页并返回从字节零开始的完整读取命令。实际 File、SQLite CLI 各用 16 页读回原件。直接初读游标、历史 recipe 引用、显式选读和 index 的错误均返回原捕获读取命令。历史 reader 退役、安装采用和 C1 完整成本仍单独验收。

改动思路 / Approach

用类型化异常识别已核验原件上的选读摘要错误,复用原恢复命令生成器。只补齐原捕获恢复入口。 用真实 guard 分别生成 File 和 SQLite 捕获,提交旧排序摘要,再原样执行返回的命令,按 UTF-8 字节偏移读到 EOF。

具体改动 / Changes

关键代码讲解

context_selection_view 在兼容尝试后仍校验选读摘要;read_context_capture 在确认原件后接住 ContextSelectionDigestChanged,返回旧错误和完整读取命令。四个文件 +37/-11。依据 docs/reference/required-work-context.md 核对 reject-stale-selection、recover-original-bytes、retain-legacy-compatibility。 基线规范 · 实现

对主干的风险 / Risks

原摘要错误或原件被改都拒绝恢复;缺失指针仍返回原来的 typed list 诊断。原描述符不变,保持一条原回执,零新增准入或扣额。

语义与 CI 对齐

候选与主干各 303 项通过;原位置的五个 reader-reference 断言在两侧同因失败。6 项直接、19 项定向 premerge 检查、Ruff 和默认 mypy 通过;附加 scoped mypy 的五个已有诊断不变。读取器套件仍未通过严格 Change Quality。远程 CI 未查询。

我的整体评价 / Verdict

通过本项修复的代码评审。旧游标可直接恢复原捕获;共享读取器验证仍需单独处理。本次无产品首屏变更。已验证源 CLI 与两种本地存储;未验证已安装宿主的模型采用。

English verdict: APPROVE. Reject stale selection bytes and recover only the verified original capture. Existing reader-suite failures still hold strict qualification.

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 changed the title fix(context): recover stale selections from the original capture fix(context): preserve read scope when recovering stale cursors Nov 11, 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.

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

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

评审提交:2cf8577732054c4351706af3f4580e2125764f38

[P2] 紧凑选读失效后的恢复命令超出原预算,也无法按原预算执行。 紧凑引用的选读摘要失效后,回复逐个展开字段,把原引用替换成裸文件读取。112 个字段的有效首读为 1,356 字节,预算 12,000;拒绝回复为 16,050 字节,执行原样返回的命令又因分页元数据超限退出。

动机 / Motivation

宿主带着已保存的选读引用继续读同一捕获时,需要在工具原预算内恢复,并保留原来的可读字段。主干能拒绝不匹配的选读摘要,但没有可直接执行的恢复命令。本提交确认原文件摘要后,显式选读与索引保留各自范围;旧式首读继续恢复原始全文。File、SQLite 共八个普通用例通过:回执、旧 recipe、两级索引及历史首读均能按原范围恢复,错误文件摘要不提供恢复命令。紧凑引用的选读摘要失效后,回复逐个展开字段,把原引用替换成裸文件读取。112 个字段的有效首读为 1,356 字节,预算 12,000;拒绝回复为 16,050 字节,执行原样返回的命令又因分页元数据超限退出。验证覆盖源码 CLI 和原生引用格式。C1 两提交预演没有冲突,但本轮未运行其组合或安装宿主的模型采用。

改动思路 / Approach

沿用摘要校验和已有短引用,不另建恢复格式。本轮已核对原来源与显式范围;恢复命令仍需满足同一工具预算。 文件摘要仍先校验。context_selection_view 只把选读摘要不匹配改成 typed error。CLI 保持小范围回执与列表,但失败分支绕过了能压住输出大小的短引用。

具体改动 / Changes

关键代码讲解

四个文件,+99/−15。reject-stale-selection:旧选读拒绝,无正文。same-scope-and-source:普通显式、recipe、两级索引保留范围;旧首读读回原文件。bounded-restart:大选读的恢复失败,当前未满足。基线规范 摘要校验 恢复分支

只读回执、列表和旧首读在 File、SQLite 共八项通过;两个旧首读各七页,原文件摘要错误则无恢复命令。大选读原来由 reference-file 承载,错误回复改为直接重复所有选择。旧评审只覆盖上一提交的小范围和全文恢复。上一轮评审

对主干的风险 / Risks

影响的是使用有界 stdout 的宿主。即使完整收到超限回复,原样执行生成命令仍失败;1,200 字节预算对照也复现,回复达到 4,597 字节。显式原文件引用仍可用,失败不会重跑 guard、修改描述符或扣额。

语义与 CI 对齐

195 项 Python、Ruff、标准 canary 的 6 项直接和 19 项选中检查通过。宽范围 reader-reference 套件两边各 68 通过、相同五项失败;独立大选读用例属于当前新增恢复分支。未查询 hosted CI。

我的整体评价 / Verdict

请求修改。保持原有短引用的能力,在原预算内送达并执行同范围恢复命令;补齐宽选读和小回执两条对照,继续拒绝坏的原文件摘要。没有界面或首屏变更。验证覆盖源码 CLI 和原生引用格式。C1 两提交预演没有冲突,但本轮未运行其组合或安装宿主的模型采用。

English verdict: REQUEST_CHANGES. Small scoped recovery works. A valid 12,000-byte compact reader returns a 16,050-byte stale-cursor error, and its emitted restart cannot fit the original budget.

# selection or listing, including a receipt-only diagnostic.
# Historical initial-read has no explicit scope to preserve.
return {"ok": False, "schema_version": "context_capture_page_v1", "reason": str(exc),
"recovery_command": context_capture_read_command(path, digest,

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.

[P2] 保住紧凑选读的恢复预算。 同一份捕获的 112 项选读用短引用时,12,000 字节预算下首读成功;只让游标摘要过期,错误回复就因展开所有指针增至 16,050 字节。原样执行其中的命令也失败,因为裸文件读的分页元数据装不进同一预算。请沿用摘要绑定的短 reader reference 保存同一范围,验证回复和恢复首读都能在原预算内返回。

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.

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

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

本次评审对应提交 36c8dfd9a77fd65390d930e621fd12bce06b177b。

[P2] 紧凑选读失效后,恢复回复超出原预算,重试也会失败。 已有讨论

动机 / Motivation

宿主带着已保存的选读引用继续读同一捕获时,需要在工具原预算内恢复,并保留原来的可读字段。主干能拒绝不匹配的选读摘要,但没有可直接执行的恢复命令。本提交确认原文件摘要后,显式选读与索引保留各自范围;旧式首读继续恢复原始全文。File、SQLite 共八个普通用例通过:回执、旧 recipe、两级索引及历史首读均能按原范围恢复,错误文件摘要不提供恢复命令。紧凑引用的选读摘要失效后,回复逐个展开字段,把原引用替换成裸文件读取。112 个字段的有效首读为 1,356 字节,预算 12,000;拒绝回复为 16,050 字节,执行原样返回的命令又因分页元数据超限退出。评审覆盖源码 CLI 与摘要绑定的原生 reader。

改动思路 / Approach

沿用摘要校验和已有短引用,不另建恢复格式。本轮已核对原来源与显式范围;恢复命令仍需满足同一工具预算。 文件摘要仍先校验。context_selection_view 只把选读摘要不匹配改成 typed error。CLI 保持小范围回执与列表,但失败分支绕过了能压住输出大小的短引用。

具体改动 / Changes

关键代码讲解

五个文件,+110/−19。reject-stale-selection 已验证拒绝旧选读。same-scope-and-source 通过,显式读取、recipe 和两级索引保留范围,旧首读能恢复原文件。bounded-restart 仍未满足,宽选区的重试会退出。基线规范 摘要校验 恢复分支

八个 File、SQLite 对照验证回执、列表、历史 recipe 和旧首读。原文件摘要错误时不会返回恢复命令。本轮与上次评审共用同一 main 基线,唯一变化是引用测试。测试区分了未到末页的覆盖和终页的区段摘要,也改用历史未固定选区的游标核验导航变化。引用测试 上一轮评审

对主干的风险 / Risks

按原样执行恢复命令会因分页元数据超出预算退出。1,200 字节的独立对照返回了 4,625 字节,恢复也失败。已验证原文件和引用字节保持一致。C1 当前合入预演无文本冲突,组合行为仍待验证。

语义与 CI 对齐

195 项上下文测试和 73 项引用测试通过,Ruff 与标准 canary 的 6 项直接和 19 项选中检查也通过。主干原测试仍有五项失败,仅换入本次修正的测试后 73 项全过。独立的两个宽选区用例仍失败。

我的整体评价 / Verdict

请求修改。保持原有短引用的能力,在原预算内送达并执行同范围恢复命令;补齐宽选读和小回执两条对照,继续拒绝坏的原文件摘要。本轮核验 CLI 的拒绝、恢复和分页。C1 组合运行、已安装宿主和 Hosted CI 待验证。

English verdict: REQUEST_CHANGES. At 36c8dfd, scoped reads and 73 reference tests pass. A valid 12,000-byte compact reader still returns a 16,050-byte stale-cursor error. Its emitted restart fails under the same budget.

@huangruiteng
huangruiteng merged commit 3fcaa23 into main Nov 11, 2026
20 of 24 checks passed
@huangruiteng
huangruiteng deleted the codex/historical-context-cursor-recovery branch November 11, 2026 07:31
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.

2 participants