Repository navigation
fix(turn): validate original capture before retry preview - #8437
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 · 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>
Goal And Delivered Outcome
修复可复现的续跑诊断缺陷:原始 decision capture 缺失或被改动时,
turn inspect-journal --retry-failed-turn仍报告可以继续,而turn run-once会在调用 Host 前拒绝。现在普通检查与--watch均复用执行入口的只读校验,在需要重新调用 Host 时明确拒绝不可用捕获;恢复原字节后仍可继续原 Turn。main@7e03545abae842db8e15cf3b6f64a98312a0e4d8. The implementation and specification baseline is8f6e88cb2a0fb76aba32bce979ba51293c1981f8; the current target and spec readback use the current base.docs/reference/effect-interpreter-packet.md, “Public read-only consumer”, at that revision. No separate public issue.Author Declaration
executor.inspect_loopx_turn_journalconsumes the existing typedactionandreinvoke_hostfields, then callsstage_turn_decision_captureunder the journal lockScope 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=Falsecompatibility 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
9732c420c6852d6c7ed482044c1955a5af42277d.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.8f6e88c: 20 expected negative regressions fail, 14 existing cases pass. Final candidate passes all 34 cases, including inspection after restoring original bytes7e03545aba: 6 direct and 14 selected checks pass, including the CLI hard budget, public boundary and exact-scope quality verification.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 controlsThe current-main merge exposed one stale inspection test guard that still monkeypatched the retired
build_turn_envelopesymbol. The test now patches only the currentbuild_loopx_turn_planentry 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
Boundary Checklist