Repository navigation
Description
Client or integration
Codex App
Area
Cursor provider adapter / Responses continuation / loop control
Summary
A fresh Codex App task routed through OpenCodex 2.31.0 to cursor/grok-4.6 remained active for roughly 45 minutes while repeatedly emitting near-equivalent future-tense progress messages and making successful read-only tool calls. It never created the requested file, ran a test, committed, or produced a bounded blocker. The operator had to interrupt it.
This is a sanitized compatibility report. The current evidence does not prove whether the repeating behaviour originates in the Cursor upstream model, the Codex client continuation policy, or OpenCodex state/transport handling. It does prove that the combined route has no effective semantic no-progress boundary for this failure class.
Reproduction
- Run Codex App on Windows 11 through a local OpenCodex 2.31.0 proxy.
- Start a fresh task on
cursor/grok-4.6. - Give it a bounded repository task: inspect existing policy pages, create one small hub page following the existing patterns, run the relevant checks, then stop.
- Let the model inspect the repository with its available tools.
- Observe repeated planning/commentary and additional successful read-only calls without any repository state change.
- Manually interrupt the turn.
This precise 2.31.0 trace was captured once. The same near-identical planning-without-completion symptom class has appeared in two earlier local tasks, but this report relies only on the captured Cursor run below.
Expected behaviour
After a bounded amount of activity, the route should do one of the following:
- make an observable state change and continue;
- finish the requested task;
- return a typed, actionable blocker;
- terminate as a no-progress failure without replaying potentially side-effecting work.
Repeated successful reads and reworded promises should not allow one coding turn to remain active indefinitely.
Logs or error output
duration before manual interruption: approximately 45 minutes
persisted continuation states inspected: 18
state items: 78 -> 141
tool calls: 13 -> 28
tool outputs: 12 -> 27
requested file created: no
worktree dirty after interruption: no
test run: no
commit: no
terminal blocker before interruption: no
The assistant repeatedly produced variants of the same future-tense message: the existing page still needed adding, it would inspect the pattern, then create the page and open a Preview. Tool traffic continued, but the promised mutation never occurred.
Persisted-state inspection also found:
- the exact proxy-generated
multi_agent_modeguidance remained at one copy, so the accumulator fixed for Tool-heavy Codex App sessions can enter an unbounded continuation loop with WebSocket forwarding #326 was not recurring; - a different client developer block marked
apps_instructionsaccumulated from one to four exact copies; - the supposedly fresh delegated task inherited 17 source-task user messages, including earlier loop-related context.
Those last two points are correlated context inflation, not a claimed root cause. Their ownership may be in Codex App rather than OpenCodex.
Why this is not an existing report
- [Bug] Cursor Auto repeats tool continuations on Windows PowerShell 5.1, causing excessive token usage #604, fixed by PR fix(cursor): steer Windows bridge shell away from PS 5.1 syntax loops #627, is a Windows PowerShell command-failure recovery loop. No shell syntax or runtime-contract failure preceded this incident.
- Tool-heavy Codex App sessions can enter an unbounded continuation loop with WebSocket forwarding #326, fixed by PR fix(responses): reconstruct dropped SSE output items + dedupe replayed multi-agent guidance (#334, #326) #350, was caused by exact proxy-generated multi-agent guidance accumulating per continuation. That exact guidance stayed deduplicated here.
- [Bug] exec_command intermittently returns empty tool results with implausible wall_time (zero-output completion class) #2472 covers empty successful tool results. This trace retained 27 tool outputs for 28 calls and does not establish an empty-result loss.
- Cursor/Grok 4.6 via OpenCodex can terminate with upstream_stall_timeout after a silent stream #2210 covers a silent Cursor stream ending in
upstream_stall_timeout. This turn remained active and kept producing assistant and tool traffic. - [Bug]: Cursor adapter large-context turns collapse or rate-limit while direct Cursor remains healthy #1527 covers large-context collapse and rate pressure. This report is specifically about repeated planning with no state delta and no bounded terminal result.
Suggested investigation and acceptance criteria
- Add privacy-safe diagnostics that distinguish client-driven continuations, OpenCodex continuation requests, and one still-active Cursor stream.
- Track progress-relevant event classes across the live Cursor turn. Reworded commentary and successful read-only calls must not reset the no-progress budget.
- Make the cutoff capable of cancelling an already active Cursor stream. A guard that only runs before the next request cannot stop this class.
- Emit one typed terminal result on cutoff, including completed work and the blocker.
- Do not automatically retry after any potentially side-effecting tool call.
- Deduplicate repeated client developer blocks where safe, and expose enough provenance to identify which layer injected them.
- Add a representative regression: inspect a small fixture repository, create one file, run one check, and either complete or return a typed blocker within a fixed time/tool budget.
Version
OpenCodex 2.31.0; Codex runtime 0.147.x.
Operating system
Windows 11 Home 25H2, OS build 26200.9168, x64.
Provider and model
cursor / grok-4.6
Screenshots and supporting files
No repository screenshots or prompt captures are attached because they would contain private task content. The sanitized counters above are from the persisted OpenCodex continuation state.
Redacted configuration
{
"client": "Codex App",
"proxy": "local loopback",
"provider": "cursor",
"model": "grok-4.6"
}Checks
- I searched existing issues and related fixes.
- I removed task content, repository details, local paths, credentials, tokens, account data and personal data.
- I separated observed facts from suspected ownership and root cause.
Activity
github-actions commentedon Aug 25, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
lidge-jun commentedon Aug 25, 2026
리뷰 · 우선순위 66 / 80
설명: 이 이슈는 Codex App 이 OpenCodex 2.31.0 을 거쳐
cursor/grok-4.6으로 보낸 작업이, 읽기만 반복하고 파일을 만들지 않은 채 약 45분 동안 같은 계획 말을 되풀이했다고 한다. 작성자는 stephen-drew 이다. 지금 열려 있다. 품질 봇이 한 번 닫았다가 정보가 채워져 다시 열렸다. 라벨은 bug, tools 이다. 지금 CURRENTdevHEAD 는 6e6d5cd 이다. 직전은 316043e 였고 이번 시간에 2598 2599 2601 2602 가 착지했다. origin/dev package.json 은 2.32.1-preview.20260825 다. 본문이 적은 숫자는 이렇다. 이어진 상태 기록 18개, 상태 항목 78에서 141, 도구 호출 13에서 28, 도구 결과 12에서 27. 요청한 파일은 만들어지지 않았고 작업 폴더는 더러워지지 않았다. 터미널 차단도 없었다. 운영자가 직접 끊었다. 내가 구현하지 않고 머지하지 않는다. 태그하지 말 것. 배포하지 말 것.HEAD 에서 이 종류의 구멍은 그대로다. src/stall-timeout.ts 8줄 DEFAULT_STALL_TIMEOUT_SEC 는 300초다. 주석은 업스트림이 조용할 때만 센다고 적는다. src/bridge.ts 358줄도 업스트림 활동만 스톨 시계를 되돌린다고 적는다. 874줄과 875줄은 어댑터 이벤트가 올 때마다 stallTicks 를 0 으로 돌린다. 1402줄부터 1405줄 박동도 활동이 있으면 다시 0 이다. 1405줄 한도에 닿으면 1420줄
upstream_stall_timeout을 내고 1424줄에서 업스트림을 취소한다. 그러나 계획 말과 읽기 도구가 계속 오면 시계는 절대 차지 않는다. 45분 동안 살아 있던 이번 기록과 맞다. 침묵 스톨이지, 진전이 없다는 뜻의 한도가 아니다.이번 시간 착지는 이 구멍을 막지 않는다. 2597 과 2598 은 빈 완료를 관찰하고 생산자 경로를 핀으로 막는다. emptyCompletionRetry 는 src/config.ts 3000줄에서 아직 기본 false 다. 본문은 도구 결과가 27개 남았다고 한다. 빈 결과가 사라진 경우가 아니다. 그래서 2472 와 2423 을 이 이슈로 닫지 말 것. 2472 는 2598 이 Completes 로 이미 닫았다. 내가 다시 열지 않는다. 2423 은 아직 열려 있다. 2599 와 2601 은 카탈로그 너비 2574 쪽이다. 2602 는 2497 보안 리뷰 기록이다. 그 열차는 루프 한도와 무관하다. 2210 은 조용한 스톨이다. 본문이 이미 갈랐다. 2210 을 이 이슈로 닫지 말 것. 1527 은 큰 문맥 붕괴다. 섞어 닫지 말 것.
350 이 고친 프록시 안내 중복은 HEAD 에서도 막혀 있다. src/server/responses/collaboration.ts 511줄 injectDeveloperMessage 는 520줄에서 524줄까지 재생 접두의 마지막 multi_agent_mode 안내가 지금 넣을 글과 같으면 526줄에서 527줄에서 그냥 돌아간다. 본문도 그 안내가 한 장만 남았다고 한다. 326 회귀가 아니다. 다만 같은 함수는 이미 들어온 클라이언트 developer 칸을 접지 않는다. 태그가 없는 글은 재생 접두에 같은 생성 칸이 있을 때만 삽입을 건너뛴다. 본문이 본 apps_instructions 가 1장에서 4장으로 늘어난 일은, 프록시가 그 칸을 접지 않는다는 뜻이다. 소유가 Codex App 일 수 있다. 지금 leftover-close 할 차량도 없다.
Cursor 쪽 이미 열린 줄기를 끊는 손잡이는 있다. src/adapters/cursor/live-transport.ts 1397줄부터 1399줄은 AbortSignal 이 오면 소켓을 닫는다. 1010줄은 열기 전에 이미 취소됐는지도 본다. 다리의 스톨 경로 1424줄 cancelUpstreamOnce 가 그 신호를 탄다. 문제는 손잡이가 없는 것이 아니라, 진전 없는 활동을 한도로 세어 그 손잡이를 당기는 시계가 없다는 것이다. 요청 사이에만 도는 가드는 살아 있는 Cursor 줄기를 못 끊는다. 본문 제안 3번과 맞다. src/runtime 은 없다. default-aliases.ts 와 model-presets.ts 도 없다. 2463 2464 2465 를 이 이슈로 닫지 말 것. CursorCredentialRouter 는 여전히 src/providers/cursor-pool.ts 28줄 클래스뿐이다. 이 이슈의 차량이 아니다. 프리뷰 배포가 아니다.
라인 8 - src/stall-timeout.ts DEFAULT_STALL_TIMEOUT_SEC 는 300초다. 침묵만 센다
라인 358 - src/bridge.ts 업스트림 활동만 스톨 시계를 되돌린다
라인 874 - src/bridge.ts 어댑터 이벤트가 올 때마다 stallTicks 를 0 으로 돌린다
라인 1405 - src/bridge.ts 침묵 한도에 닿아야만 upstream_stall_timeout 이다
라인 1424 - src/bridge.ts 그 경로에서만 업스트림을 취소한다. 활동이 있으면 닿지 않는다
라인 1397 - src/adapters/cursor/live-transport.ts AbortSignal 이면 이미 열린 Cursor 줄기를 닫는다. 진전 시계가 이 신호를 안 당긴다
라인 520 - src/server/responses/collaboration.ts multi_agent_mode 안내는 같은 글이면 넣지 않는다. 350 구멍은 막혀 있다
라인 526 - 태그가 없는 developer 칸은 이미 들어온 복사본을 접지 않는다
2210/2472/2423 - 다른 구멍이다. 이 이슈로 닫지 말 것
2595/2583 - 이 이슈의 차량이 아니다
메인테이너의 판단이 필요한 지점
너의 추천
버그로 받는다. 다만 지금 합칠 차량은 없다. 소유를 가르는 진단(클라이언트 이어가기 / 프록시 이어가기 / 하나의 Cursor 줄기)을 먼저 두고, 읽기 성공과 같은 말의 계획을 진전으로 세지 않는 한도를 산 줄기에 걸어 취소를 당기게 하는 쪽이 맞다. 그 한도가 당기면 이미 열린 Cursor 줄기도 끊어야 한다. 1397줄 손잡이는 이미 있다. 내가 구현하지 않고 닫지 않는다. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.
이 댓글은 grok-bot이 작성했습니다
docs(responses): define semantic progress ownership (#2600) (#2628)
lidge-jun commentedon Aug 25, 2026
Investigated and recorded on
devby #2628 (squashe6dba5435). No proxy cutoff added, and that is the finding rather than a deferral.Your framing was the right one, and I want to confirm it held up: every existing bound was satisfied while nothing changed, and each measures something other than progress.
MAX_ACTIVE_TURNS = 256Your numbers are the proof: 78→141 items, 13→28 calls, 18 continuations. Growth on every axis the proxy can see, zero on the one that matters.
Not a #350 regression. #350 deduplicated proxy-generated
multi_agent_modeguidance, that code still runs (collaboration.ts:511), and you observed one copy. This is a pre-existing ownership gap that became visible after continuation reliability improved. The accumulatingapps_instructionsblocks are client-authored and outside #350's contract, as you suspected.Why I did not add the cutoff you suggested in items 2-4. OpenCodex sees protocol events, tool names, payloads, bytes and timing. It cannot see your workspace, and a tool name does not prove absence of side effects. Every heuristic available at this layer fails one way or the other: counting continuations or comparing prose misses your incident, because items and calls kept changing; classifying read-like tools as no-progress kills legitimate slow work. And you were right to warn about retry-after-cutoff replaying side-effecting calls.
Your item 3 is the sharpest part of the report — a guard that only runs before the next request cannot stop this class. That is true, and it is also why the guard has to live where the workspace does.
What shipped: the ownership decision recorded in
structure/, plus two tests pinning the boundary conditions — that 257 sequential continuations are accepted (so nobody reads 256 as a turn budget), and that a 32-continuation chain with unique tool evidence is valid slow progress (the false-positive case any future bound must not break).If a client sends an explicit privacy-safe progress marker, the proxy can enforce that contract. Enforcing an inferred one would be claiming knowledge it does not have. Closing on that basis — reopen if you disagree with the layer call, it is the part most worth arguing.
docs(responses): define semantic progress ownership (lidge-jun#2600) (l…
docs(responses): define semantic progress ownership (lidge-jun#2600) (l…