Skip to content

fix(chat): stop exact Turn terminals before reporting interruption - #6150

Merged
loopx-agent merged 1 commit into
mainfrom
codex/chat-turn-terminal-stop-20261011
Oct 10, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/chat-turn-terminal-stop-20261011

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Stopping an ordinary Codex Chat Turn currently ends the model Turn while its command can keep running. The controller also suppresses cancellation failures and reports the Session ready. This fixes the native transport and Core stop acknowledgment path so a successful stop means the selected Turn has ended and its native background terminals are absent on readback.

  • Wait for the native interrupt receipt and terminal Turn state, retain command item ownership from scoped native events (including completed items and commands omitted from native history), then cancel only matching native process IDs and verify removal. Older Turn terminals are preserved.
  • Preserve the Core interrupting fence and report an error when control, identity binding, terminal cancellation, or worker acknowledgment fails. Retry is supported; stopping during startup binds the current native Turn without borrowing the previous one. Transport closure is no longer credited as cancellation.
  • Update the existing subprocess smoke fixture for the native inventory APIs. The reviewed chat_runtime.py line ceiling moves from 2017 to 2024; type-density ceilings and other module budgets remain unchanged.

Validation: 278 focused agent/Core/single-flight/steering tests and 59 Goal/project/Lark compatibility tests passed; runtime subprocess smoke, Ruff, and diff checks passed. Real Codex app-server probes confirmed the selected Python process exited and its terminal disappeared before closing the server, while an older Turn terminal remained in native inventory. Initial real probes exposed omitted aborted command items and were retained as failures before the event-ownership repair.

This is the source fix for roadmap S4/S5 cancellation fencing and observable stop behavior. Installed App/CLI and original Lark-topic acceptance still need qualification on the reviewed/merged revision. Community release remains held until its remaining golden, privacy, and real receiver scenarios pass.

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; OpenAI; self_reported (host execution observation unavailable).

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

未发现阻塞问题。最强的剩余验证是安装后原飞书话题的停止和继续;本次评审不把源码验证当作安装或社区准出完成。原生 API 不支持会明确失败;重启后丢失原命令流、远程/MCP/委派任务停止均未获得本次认证。

动机

普通 Codex Chat 用户在工具执行中点击停止时,会遇到回答已停止而命令仍在运行的问题。

旧实现会显示已中断并允许继续发送,但原命令还能持续输出;本提交先确认原生回合结束,再精确取消该回合的终端,读回消失后才释放会话。

在同一真实 Codex 终端测试中,旧主干停止后 Python 进程仍存在;当前提交的进程退出,上一轮的后台终端仍保留。

本 PR 限于普通 Codex Chat 的当前回合停止,不承诺远程、MCP、委派任务或原生 Goal 的全部子任务停止。

安装后的 App/CLI 和原飞书话题尚未在此提交上验收;社区 Bot 的准出条件继续保持未通过。

改动思路

原生终端控制属于现有 Codex provider,停止是否完成及会话屏障属于现有 Core Turn owner;把两处一起修复才能避免取消失败后释放会话。

本 PR 同时交付原生精确取消和 Core 失败屏障,不新增取消服务、持久状态库或 CLI;安装与原话题验收由现有 Bot 运维任务继续承担。

反对直接合并的最强理由是:模型回合结束未必使真实命令退出,原生历史也未必保留被中断的命令。因此只等待中断回执、只看历史或关闭全部 transport 都不足够。相同真实终端测试在不可变旧主干上失败,在本提交上通过;保留原生事件中的命令身份才补上了实际暴露的缺口。未新增服务、持久状态或用户确认步骤。

具体改动

评审整个提交 34acd0f3b0ff6cb71c0771ea81e0712ce7d72d47(6 文件,413+/36-),基线 5c62c5c03f13cc84176338100f2bded12801530e。

  • chat_agent.py:现有 _request 在分派锁竞争时也遵守共同截止时间;两个原生事件读取路径保留确切 thread/Turn/item 身份。interrupt 等原生回合进入终态后遍历完整分页,将该回合的命令 item 与终端相交,只取消相应 native processId,再读回终端消失。没有以 OS PID、命令字符串或全部线程清理作为取消授权。
  • chat_runtime.py:开始阶段即使停止先赢,也保存当前原生回合 ID;停止失败保留 interrupting 和原 active claim,回执/worker 未确认不显示“已中断”。同一回合支持重试,迟到结果不能借用下一回合。原生 Goal pause、attached host 不支持中断及 queued/completing 分支保持既有边界。
  • 两个既有测试文件:RPC 拒绝、不完整/循环分页、错误归属、历史漏掉中断命令、已完成/迟到命令、假终端回执、锁竞争、开始竞态和失败重试。扩展已有 subprocess smoke 的原生 inventory fixture,未另建演示框架。
  • module_metric_baseline.json:同一指标测得 runtime 2007→2024 行,Any35/dictAny0 不变;仅将该模块已评审债务上限2017→2024,保留可读的错误和身份处理,未放宽硬协议/实验门禁或其他模块预算。最初超限失败保留在记录中。

规范映射:docs/architecture/rfcs/loopx-overall-roadmap-v0.md,spec_revision 5c62c5c03f13cc84176338100f2bded12801530e;固定版本规范。S4 的 current-Turn 取消/旧执行屏障由两个既有 owner 和实测覆盖;S5 的共享 Chat/Turn 与真实失败反馈由 Core/Lark 兼容测试覆盖。伴随 conversation RFC 的 Packaging 行保留为安装后验收,不宣称完整 S4/S5 或实时 IM 旅程准出。

对主干的风险

337 个相关测试通过(278 agent/Core/steering/single-flight +59 Goal/project/Lark);既有 runtime smoke、Ruff、diff 和 full premerge 的5 direct +14 selected checks 通过。Goal 的 wait_for_ci=false,未查询或等待 GitHub CI。change-quality policy 未启用,没有伪造该 receipt。

真实配对测试使用同一脚本与固定合成任务:先保留上一回合120秒后台终端,再启动当前回合90秒输出命令并停止。基线模型中断后当前终端和 Python PID 都存在;本提交两者均在关闭 app-server 之前 消失,旧终端 native row 保持不变。应急/fixture 清理从未计为产品停止通过。该脚本 SHA256 01060399c866d819fc297e0269ba293a865701a5c5546ee0f758b2ba2cf849a0;只归一化时间和随机身份,未归一化存在性或错误。

早期真实探针暴露原生历史漏项,修复后以上同脚本旧/新对比重新验证;最初测试 fixture 缺项和依赖缺失也保留,当前准确提交的检查覆盖其修复。Core 并发测试的 adapter 是受控 fixture,不能替代真实原生或飞书 receiver 测试。原生 RPC 独立升级,缺能力时失败并保留会话屏障;这会把过去的假成功变成可重试错误,属于明确的正确性修复。

我的整体评价

justified_increment:现有生产入口已交付可实测的精确停止和失败屏障;long_horizon=improved、user_experience=improved,保留其他回合及同回合重试,不增加人工步骤。架构选择 retain/proportionate;复用既有 native provider/Core owner 和 typed Turn vocabulary,未新增 opt-in/default-off 主张。下一步仍由当前 Bot 任务完成成对安装和原话题验收,社区 Bot 继续 HOLD。

English verdict: APPROVE - 34acd0f. The exact ordinary native Turn stop invariant is supported by a failing immutable-base real-process probe, a passing same-harness head probe, preserved older terminals, and Core failure/retry/startup fencing. Installed original-topic and broader executor qualification remain separate release gates.

@loopx-agent
loopx-agent merged commit 0fa3f0c into main Oct 10, 2026
5 checks passed
@loopx-agent
loopx-agent deleted the codex/chat-turn-terminal-stop-20261011 branch October 10, 2026 18:22
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.

1 participant