Skip to content

fix(turn): validate original capture before retry preview - #8437

Merged
huangruiteng merged 3 commits into
mainfrom
codex/turn-recovery-capture-preview-20261109
Nov 10, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/turn-recovery-capture-preview-20261109

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

修复可复现的续跑诊断缺陷:原始 decision capture 缺失或被改动时,turn inspect-journal --retry-failed-turn 仍报告可以继续,而 turn run-once 会在调用 Host 前拒绝。现在普通检查与 --watch 均复用执行入口的只读校验,在需要重新调用 Host 时明确拒绝不可用捕获;恢复原字节后仍可继续原 Turn。

  • Intended base: current main@7e03545abae842db8e15cf3b6f64a98312a0e4d8. The implementation and specification baseline is 8f6e88cb2a0fb76aba32bce979ba51293c1981f8; the current target and spec readback use the current base.
  • Outcome basis: the reproduced defect above and docs/reference/effect-interpreter-packet.md, “Public read-only consumer”, at that revision. No separate public issue.

Author Declaration

  • Written by: model_agent — OpenAI Codex.
  • Self-check: reviewed the shared typed recovery decision, existing capture IO verifier, CLI/watch paths and native internal inspection callers. This changes the existing diagnostic path; it adds no operation or UI journey.
Criterion Disposition Implementation / evidence
Match execution preflight before Host reinvocation implemented executor.inspect_loopx_turn_journal consumes the existing typed action and reinvoke_host fields, then calls stage_turn_decision_capture under the journal lock
Refuse absent, altered and invalid original captures without effects implemented 20 regression cases across v0/v1 and normal/watch modes; canonical journal and session bytes stay unchanged
Preserve saved-result recovery and terminal replay implemented File/SQLite real CLI cases recover validation without capture, invoke no additional Host and settle once
Restore original input and continue the original Turn implemented File/SQLite × historical v0/current v1 cases resume the same session with the original source, then replay without repeated effects

Scope And Continuation

Complete within this author scope: the diagnostic repair, durable regression coverage and owning reference documentation. Independent PR review, required CI, the uncompleted full-suite qualification and merge remain separate gates.

Bounded refactoring was applied at the same boundary: inspection now holds the existing journal lock through assessment and the read-only input check. It reuses the verifier and typed decision rather than adding another state machine or helper. The low-level require_decision_capture=False compatibility default matches the executor API; the public CLI explicitly enables strictness in both modes. No new semantic vocabulary, persisted state or configuration is introduced.

Validation

  • Tested revision: 9732c420c6852d6c7ed482044c1955a5af42277d.
  • Run state: finished — the local commands have ended; full-repository validation remains incomplete.
  • Input classes: synthetic, public_fixture.
Check kind Result Public-safe evidence / limitation
unit passed python -m pytest -q tests/test_turn_inspection_session_host.py tests/test_loopx_turn_journal_inspection.py tests/test_loopx_turn_driver.py: 251 passed on the current-main head.
regression_parity passed The updated inspection suite against pinned base 8f6e88c: 20 expected negative regressions fail, 14 existing cases pass. Final candidate passes all 34 cases, including inspection after restoring original bytes
real_entrypoint / real_backend passed Eight isolated real CLI scenarios over the File provider and SQLite 3.53.4 (Node.js 24.21.0), with synthetic Codex transport. Historical input is generated by released v2.2.0; the candidate consumes both v0 and v1 records. Four scenarios verify refusal/restoration/same-session single settlement; four verify retained-result recovery and terminal replay without capture
static passed Repository Python lint roots plus changed CLI adapter; mypy: 17 source files; whitespace and bilingual RFC checks
static passed Changed-path public scan: zero errors/warnings. Full public-tree scan: zero errors, 49 advisory warnings outside the changed paths
integration passed Standard premerge against current target 7e03545aba: 6 direct and 14 selected checks pass, including the CLI hard budget, public boundary and exact-scope quality verification.
unit failed Full local repository run was interrupted (exit 130): 1 failed, 6017 passed, 841 skipped and 56 subtests passed. The failed case is tests/test_chat_agent.py::test_transient_recovery_requires_complete_native_terminal_and_effect_readback[native-error-before-terminal-info0]. An earlier run also had five import-path/environment failures; those five pass after clearing inherited Python path controls
regression_parity passed That Chat recovery case passes in a matched isolated base/head check with the same interpreter, arguments and environment. Its implementation and test are unchanged by this PR. This does not explain the full-run failure or establish full-suite success

The current-main merge exposed one stale inspection test guard that still monkeypatched the retired build_turn_envelope symbol. The test now patches only the current build_loopx_turn_plan entry and still verifies that inspection reaches no live or write path. The affected journal-inspection file passes 32/32 cases; the complete final focused cohort passes 251/251.

The end-to-end harnesses are temporary acceptance probes, so only aggregate results are reported publicly. Durable public regressions are in tests/test_turn_inspection_session_host.py; provider-level acceptance is not yet a checked-in reproducer. These are source-checkout correctness checks with synthetic Host output, not installed-runtime adoption or live-model qualification.

Frontend / Visual Evidence

UI impact: none. The existing CLI diagnostics and reference text change; no App, website, documentation chrome or first viewport changes.

Type Of Change / Area

  • Bug fix
  • Documentation update
  • Test update
  • Area: Control plane; Host/runtime integration.
  • Direction: Core control-plane hardening. Shared-authority RFC fixture impact: N/A; no promotion, provider routing or compatibility projection changes.

Boundary Checklist

  • Diff and PR text contain no private state, credentials, raw traces, internal links or local machine paths.
  • No benchmark work is duplicated.
  • The change stays within the reproduced defect.
  • No paired RFC changed; the bilingual gate passes.
  • UI impact is none.
  • The commit includes a DCO sign-off.

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 · gpt-6.1-sol · OpenAI · runtime_reported · max

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

动机 / Motivation

准备恢复一个失败回合、先用CLI检查是否可继续的操作者和Agent。 原Session仍可用时,缺失或被修改的原决策捕获未阻止inspect报告可以重调Host,随后run-once却拒绝;调用者会拿到相互矛盾的恢复建议。

原Host超时后保存了可恢复的Session,但同一Turn的原决策文件丢失。操作者先inspect,再尝试原Turn续跑。 同一冻结34项测试在当前main出现20个目标负例失败、14项原行为通过;候选相关251项通过。独立真实File/SQLite CLI四格均在缺失时exit1、恢复原字节后exit0,再续原Session成功,终态删除捕获后仍只回放、不再执行Host。

验证覆盖当前源码、隔离真实File/SQLite、原CLI与合成Host超时/恢复;真实模型采用、安装版和长期运行收益未验证。

改动思路 / Approach

只在既有恢复判定为continue且reinvoke_host=true时,复用dispatch的原捕获验证器,并在原journal锁内保持同一检查快照;不publish、不新建捕获、不重跑guard。 4条路径 +144/−66;两个CLI调用、既有executor检查、参考说明及现有测试夹具。

原journal、Session和capture继续各自保有来源;原TypeScript owner决定何时需要Host,Python沿用stage验证provider文件。新增flag属于public adapter前提,没有新持久状态、权限或恢复服务。原Session失败先处理,避免capture错误覆盖更早的拒绝;保存结果与terminal继续原阶段,不为只读检查补造来源。

具体改动 / Changes

评审提交0fb8a777a1b1c6a2cb7f7dd4776c59e888df4270,当前main为5f132dd66585cd5a229a7c9f480e54b0db1cdb62,实际共有祖先8f6e88cb2a0fb76aba32bce979ba51293c1981f8。4条路径 +144/−66;两个CLI调用、既有executor检查、参考说明及现有测试夹具。 原公开consumer契约

  • dispatch-parity:会重调Host的检查必须执行与dispatch一致的原捕获前提。 同一冻结34项测试在当前main出现20个目标负例失败、14项原行为通过;候选相关251项通过。独立真实File/SQLite CLI四格均在缺失时exit1、恢复原字节后exit0,再续原Session成功,终态删除捕获后仍只回放、不再执行Host。
  • read-only:检查不改journal/Session/capture,也不执行或记账。 v0/v1×普通/watch×缺失、改写、symlink、malformed、目录20格拒绝且journal/Session字节不变;恢复原文件即可检查。已有保存结果和终态不需新的Host输入。
  • recovery-boundary:缺失恢复原捕获,同Session续跑;缓存结果和终态回放不取得新输入。 同一冻结34项测试在当前main出现20个目标负例失败、14项原行为通过;候选相关251项通过。独立真实File/SQLite CLI四格均在缺失时exit1、恢复原字节后exit0,再续原Session成功,终态删除捕获后仍只回放、不再执行Host。
  • legacy:v0原envelope和v1完整source均保留各自原来源。 v0/v1×普通/watch×缺失、改写、symlink、malformed、目录20格拒绝且journal/Session字节不变;恢复原文件即可检查。已有保存结果和终态不需新的Host输入。

关键代码讲解

  • handle_turn_journal_inspection:普通CLI显式要求原捕获检查。 源码
  • inspect_loopx_turn_journal:原锁内先Session/recovery再按reinvoke_host读捕获。 源码
  • stage_turn_decision_capture:复用原source绑定和文件验证;stage无publish副作用。 源码
  • recoveryResumePhase:host-result验证失败回Host;task-postcondition/cached结果保留原阶段。 源码

stage只读取并绑定原source;没有调用publish_for_host。validation失败是否回Host与原TypeScript recoveryResumePhase和executor的_host_attempt_requirements一致。候选增加的20格覆盖v0/v1、普通/watch、五类坏文件,独立CLI另覆盖File/SQLite和原Session续跑,避免只证明serializer或假观察。

对主干的风险 / Risks

最强风险是错误放行缺失来源,或反过来阻断不需要新输入的终态/缓存恢复。v0/v1×普通/watch×缺失、改写、symlink、malformed、目录20格拒绝且journal/Session字节不变;恢复原文件即可检查。已有保存结果和终态不需新的Host输入。 独立四格观察到缺失exit1、原文件恢复exit0;检查前后原journal与capture字节保持,再续跑使用resume,最终移除capture后replayed且Host总次数仍为2。

251项相关Python、独立真实CLI四格通过;冻结34项在main20失败14通过。首次并发premerge中semantic和CLIbudget在120秒超时,原失败保留;同一两项串行通过,随后标准串行premerge原限制内6项直接+14项选中全部通过。

作者早先全仓测试exit130,报告1failed/6017passed/841skipped/56subtests,涉及native-error-before-terminal-info0。孤立base/head各通过不能解释该整跑失败。本轮保留未知原因;当前未改chat_agent原生parser,251项相关路径和原生CLI恢复对本次不变量提供独立证据,不声称全仓绿色或历史失败已修复。没有查询远端CI、dismiss、合并或生产安装。

我的整体评价 / Verdict

当前范围内支持批准:长程恢复建议与原执行前提一致,用户避免矛盾重试。原验证器和typed recovery词汇被复用,代码规模与问题相称;锁内复用检查是本次有界整理,没有新持久owner。历史v0和v1均保留,public强制门与低层兼容默认的边界已明确,未获得Host或结算执行权限。

检查了CLI普通/watch输出与调用链;差异没有页面、首屏、样式、设置或可见控件变更,既有CLI检查就是本次用户入口。 本轮未新增浏览器截图或安装版视觉验证。

验证覆盖当前源码、隔离真实File/SQLite、原CLI与合成Host超时/恢复;真实模型采用、安装版和长期运行收益未验证。

English verdict: APPROVE at 0fb8a77. Inspection now checks the original capture before Host retry, preserves read-only behavior, and retains cached-result and terminal recovery. Historical full-suite failure attribution remains unknown.

…apture-preview-20261109

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng merged commit 7b6d0b1 into main Nov 10, 2026
14 of 18 checks passed
@huangruiteng
huangruiteng deleted the codex/turn-recovery-capture-preview-20261109 branch November 10, 2026 05:16
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