Skip to content

fix(codex): 修复任务假闲并补齐 RPC 生命周期#571

Open
xiaoxueSunn wants to merge 11 commits into
deepcoldy:masterfrom
xiaoxueSunn:fix/codex-false-idle
Open

fix(codex): 修复任务假闲并补齐 RPC 生命周期#571
xiaoxueSunn wants to merge 11 commits into
deepcoldy:masterfrom
xiaoxueSunn:fix/codex-false-idle

Conversation

@xiaoxueSunn

@xiaoxueSunn xiaoxueSunn commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

前置 PR:#537。请先审核 #537;当前只需审核 PR2 相对 PR1 的增量

问题

普通 Codex CLI 的 turn 尚未结束时,终端输入提示或短暂静默可能让飞书卡片和 Dashboard 提前显示「等待输入」。RPC 模式下,response、terminal notification、pane 重连和 worker restart 还可能以不同顺序到达,导致终态丢失、错配或旧异步后续回调污染新 CLI。

根因

屏幕启发式判断、structured bridge、RPC response / terminal 和 CLI generation 缺少统一的优先级、所有权与精确结算边界。旧逻辑在 native turn ID 不明确时还可能按唯一 pending 项猜归属。

修复

  • pending / started / terminal 结构化生命周期优先于屏幕信号,所有展示入口使用同一状态投影;
  • turn/start 被接受后建立 rpcActive,直到精确 terminal、可精确归属的失败或 stop 才释放;
  • terminal 按 native turn ID 和 dispatch attempt 归属,早到 terminal 可缓存并回放,无法确认归属时保持阻塞;
  • restart / engine shutdown 使用 engine + CLI generation engagement fence,旧异步后续回调不能修改新代状态;
  • fresh rollout 从 offset 0 读取,PID marker 只由同一 engine / generation 的清理方删除;
  • 重复 terminal first-terminal-wins,stop 不自动重发归属不明的输入;
  • 保留 fix(codex-app): 修复假忙/假闲 + Riff 关停/PM2 恢复 #537 的 durable ACK、input ownership、signed liveness、replay / engine shutdown / generation 语义。

变基与验证

本 PR 基于 #537@72783ba8,head 为 910705dd,包含 5 个增量提交。

  • tsc --noEmit 通过;
  • public domain audit、TypeScript build、Dashboard bundle 和 dist audit 通过;
  • 专项回归 18 个测试文件、468/468 项通过;
  • 全量单测 669 个文件通过、1 个跳过;10,701 项通过、23 项跳过,失败 0。

未执行 daemon 重启、真实 Codex app-server 的生产式 RPC 会话或飞书 live E2E;这些项目阻塞发布验证,不阻塞代码审核。

#537 以保留提交祖先关系的 merge commit 合入,本 PR 会只显示第二层增量;若仓库使用 squash 或 rebase merge,需要把本 PR 重新变基到最新 master

详细说明:https://bytedance.larkoffice.com/docx/GzoDdmVtSoQnj2xmChycyjRCnaf

本次未执行合并。

xiaoxueSunn and others added 2 commits July 23, 2026 19:10
…overy (PR 1-5)

Fixes three user-visible failures in the Codex App path:
- False idle: task still running but card/Dashboard show idle
- False busy: task finished but UI stays busy
- Wrong turn ownership: message routed to incorrect task turn

Root cause: three state sources (TUI screen, worker memory, runner
notifications) could override each other. Fix makes runner signed state
the single owner of idle/ready; display layer only projects it.

Also includes Riff shutdown (prepare/commit/abort fence) and PM2
recovery (exact start, descriptor guard, supervisor shutdown protocol)
as separate concerns with independent test gates.

Tests: 29/29 + 32/32 false-busy/false-idle cases pass; full unit
regression shows 0 new failures. tsc --noEmit passes.

Doc: https://bytedance.larkoffice.com/docx/TZUydIskCoJZT8xfMXzc2WI5ntc
xiaoxueSunn and others added 8 commits July 23, 2026 20:53
经典 Codex 在 structured turn 已 started 未 final 时,屏幕启发式会把
prompt/PTY 静默投影为 idle。统一用 projectRuntimeScreenStatus:
structuredTurnBlocking 优先于 promptReady;三入口(markPromptReady /
周期 screen update / 截图)共用;仅 codex allowlist 强门控;
submit verification/confirm 使用 30s/20s 有界 lease,到期 fail-open
防止掉 Enter 永久假忙。
…+ coco/codex history-append tests

RPC mode has no local transcript ingest, so a turn never reaches
'started' and relied solely on the 20s confirmation lease. A turn running
longer than 20s (e.g. approval pending) was pruned by pruneExpiredPreStartHeads
→ false idle. Add rpcActive flag + markRpcActive/stopRpcActive so the
lifecycle gate stays asserted for the full server-side run; hasBlockingTurn,
pruneExpiredPreStartHeads, preStartLeaseRemainingMs, and refreshNextPreStartLease
all respect it. stopCodexRpcEngine clears rpcActive turns + rejected-ready
evidence.

Add 5 RPC tests (codex-bridge-queue) and 3 coco/codex history-append return-value
tests (write-input).
@xiaoxueSunn
xiaoxueSunn force-pushed the fix/codex-false-idle branch from 1041c99 to d9f9958 Compare July 23, 2026 13: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.

2 participants