Repository navigation
fix(context): persist current recovery before material planning - #7628
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
APPROVE — 未发现阻塞问题。 本结论绑定 head 6743ce72593121b2e15a9f8ef84355c31c94e46c,实际 merge base ce4c78088ea464cb31231513882bed6bb6933156;这是共享 GitHub 作者账号下的 COMMENTED approval conclusion。
动机 / Motivation
使用原生上下文恢复的 Agent,在当前 capture 已保存、材料规划仍在运行时遭遇进程退出。
旧版恢复会返回上一轮要求,可能遗漏当前新增的停止条件;本 head 先持锁保存当前完整来源,再规划展示,compact 与 resume 均能恢复当前 Turn。
真实 CLI 中断恢复读到当前完整要求与原 Turn,旧 capture 保持原样,未读内容没有晋升为 baseline。
本 PR 不切换 C1 writer,不改变默认阅读策略,也不证明模型保留、tokens、账单或长期净收益。
改动思路 / Approach
当前来源发布属于既有 IO adapter 的正确性不变量,材料裁剪和差分判断仍归原 TypeScript owner;移动发布时机比新增事务或恢复库更小。
本 PR 完成既有 native should-run/context-project 到 session journal、context-read 的中断恢复修复,不改 canonical authority、调度或执行权限。
保存到磁盘的 session journal 负责找回上下文,不能等可选的材料规划完成后才指向当前来源。这里复用原 _locked、_save、不可变 archive 和 context-read,不增加恢复库、配置或第二份决策。先提交完整来源及空读取范围,再调用 planner;成功得到 required view 后才替换恢复引用。已完成的旧 baseline 可用于原 codec 比较,但当前未读来源仍是 pending。
| 规划入口发生硬退出 | 原 base | 当前 head |
|---|---|---|
| compact 后读取恢复来源 | 上一轮正文,FAIL | 当前完整正文,PASS |
| resume 后读取恢复来源 | 上一轮正文,FAIL | 当前完整正文,PASS |
| 关闭态 / 错 Agent 与 Turn | 原响应 / 拒绝且零 journal 写入 | 相同 |
表格来自同一独立 CLI harness;只在规划入口暂停后,对刚创建的临时子进程发送 SIGKILL。真实文件、锁、journal、生命周期归约和 reader 均未伪造。
具体改动 / Changes
规范依据是 docs/reference/required-work-context.md,spec_revision ce4c78088ea464cb31231513882bed6bb6933156,采用变更前的文本。下列原文准则在本 head 均为 implemented:
An interrupted pending delivery requires full recovery.:先保存当前完整来源;两条硬退出恢复反例从 base 失败变为 head 通过。Context delivery off remains unchanged.:同输入关闭态零 journal 写入、原 journal 字节不变,错误 Agent/Turn 同样在写入前拒绝。Recovery reads the same immutable capture without re-admission or spend.:原 Turn、最终 stop、digest 与完整正文一致;临时测试未创建 registry/runtime,也未准入或扣额。
关键代码讲解
project_codex_context:持原 session 锁保存 archive,局部publish_recovery同步写入 recovery 与空 ranges 的 pending,保存成功后才设置recovery_committed。planner 返回新 required view 时复用同一发布函数;中断不会再选中前一个 capture。_capture_required_context:可接收内部已保存的 archive,避免再次写完整来源;原 TS planner 仍负责材料投影,未知/不可裁剪/不划算时继续完整来源。该参数没有暴露给外部输入。
完整 diff 为三文件 +93/-15,其中 production +27/-15、测试 +58、双语说明 +8;没有状态格式迁移。检查了未改的 quota 与 saved-projection caller、session lookup、字节验证、分页和生命周期 owner。已读取最新 main ee7b65f124f5f461b3e5f9f6fb45eae0e6c317f4,上述共享路径相对 base 无变化。#7627 会修改同一 adapter,后续重放仍须保留此次顺序。
对主干的风险 / Risks
最强反例是“完整 archive 已写出,但 planner 直接退出”,已有异常返回或 wire 故障测试并不覆盖它。独立 SIGKILL 对照中,base 两项均成功执行 reader 却返回旧正文;head 两项均返回当前完整要求,pending 范围为空、失效后没有 candidate,原文件字节不变。成功材料路径仍能提供 required view,选中详情与不完整读取不会被当作完整 baseline。
PASS:三个受影响模块 199 项,configured mypy、限定 Ruff、标准 premerge(6 direct、2 catalog、8 risk、1 public,零 hold)。5 项要求显式原生 Codex/loopback binary 的 opt-in 测试为 SKIPPED,本轮未运行,未把它们算作通过。验证覆盖实际 adapter/CLI 与物理存储,不覆盖正式安装或模型输入保留。
同一 review harness 包含 page-view registration,因此普通 native journal saves 为 3→3、材料路径 3→4,关闭态 0→0;它与 PR 中只计 adapter 的 2→2、2→3口径不同,增量一致。新增一次小 journal 发布换取可恢复的当前来源,未重复创建 archive,不据此宣称延迟收益。
语义与 CI 对齐
复用既有 TS lifecycle/codec 和 transport vocabulary;Python 只承担 filesystem/host IO,没有新的语义 owner、prose classifier 或执行义务。默认仍关闭,开启态只修复发布顺序;文档明确未读来源不能建立 baseline。wait_for_ci=false,未查询、轮询或等待 CI;本地检查与合并资格分别保留。
我的整体评价 / Verdict
本切片达到可独立验收的恢复正确性目标。long_horizon 与 user_experience 均有具体改善:当前承诺和停止条件不会在这一崩溃窗口退回旧版,沿已有命令恢复即可,无新增确认或人工准备轮次。archive 复用与局部 helper 是合适的有界重构;保留现有 journal/capture reader 兼容,不需要新框架。
视觉核验不适用:检查了 quota_capture/native_context_capture_view、现有 App 机器配置入口;此 diff 只调整 IO 发布顺序和文档,未改 rendered presentation。未验范围为真实原生 Codex opt-in、安装态、下游模型保留、持续成本与父级 C1 完整收益。APPROVE 只评价该 exact head;COMMENTED 不是 GitHub 正式自批准,也不授予 merge。
English verdict: APPROVE for the exact head; real CLI crash recovery is fixed, with native-host and long-horizon benefit limits retained.
原生上下文已写出本轮 capture、但材料规划尚未返回时,session journal 仍可能指向上一轮。此时进程退出,后续 resume/compaction 会恢复旧来源。
本修复在可选材料规划和编码前,先持现有 session 锁发布当前完整 capture 引用及 pending delivery;材料 planner 复用同一 archive,成功产生 required view 后再切换引用。未读内容不建立 baseline,原有 scope、digest、权限、完整读取及关闭态行为保留。
这是从 #7430 提取的独立修复,直接基于 main
ce4c78088ea464cb31231513882bed6bb6933156,无需合入 C1 新 schema 或其他未合 PR。仅改既有 IO adapter、真实 CLI 回归和中英文使用说明,没有新增决策 owner、配置或 Host。Validation
6743ce72593121b2e15a9f8ef84355c31c94e46c:三个受影响模块 199 passed / 5 skipped。五项 skip 保留既有LOOPX_NATIVE_CHECKPOINT_BIN显式原生 Codex/loopback opt-in;不宣称这些项已验证。quota context-project子进程,在材料规划时直接退出进程;随后走真实恢复 reader,核对当前来源、摘要、原 Turn 和旧文件不变。相同断言在原 main 的 compact/resume 两种路径均失败,修复后均通过;不创建 registry/Goal,也不准入或扣额。Cost and scope
同负载、相同 typed owner 和真实隔离文件 IO 的 base/head 对照,范围为当前 project 调用,不计两组相同的 SessionStart 初始化:
额外一次 journal 写入只用于先保存可恢复的当前完整来源;未重复写 archive。表中只计已确认实际 full delivery 的对照。此处交付的是中断恢复正确性,没有新增延迟、模型保留、tokens/cache、账单或长程成果收益资格。
入口为现有 native
should-run/context-project,恢复为原context-read;不改 UI 或默认文件阅读策略。回滚此提交会恢复旧发布顺序,canonical state 和捕获格式不迁移。C1 的 caller/writer 切换与原 quota 成果/完整成本对照仍在 #7430;本 PR 可独立评审,作者实现已完成,合并仍走维护者流程。