Repository navigation
fix(agent-prompt): hold the ingest floor on the render-gate submit path - #18196
danielamir-2k1 wants to merge 4 commits into
Conversation
worker-start failed with agent_prompt_stalled at dispatch_input on Windows for both Codex and Claude Code TUIs, five attempts in a row. The dispatch payload (10,714 and 12,773 bytes observed) reached the composer and stayed there unsubmitted; pressing Enter manually minutes later submitted it and the agent ran normally. So the paste landed and the Enter was swallowed. Agents exposing a settlement signal take the renderGate branch, which awaited only the gate and skipped getAgentPromptSubmitDelayMs entirely. The open-loop branch would have waited 500 ms settle plus ceil(bytes/64) ms of ConPTY ingest -- about 670 ms for the observed payloads. The render gate is a readiness signal, not proof of ingest: it can resolve on a redraw that happens before the child attaches the completed bracketed paste, so Enter is written too early, dropped, and no working edge is ever observed. agent-prompt-injection.ts already says the submit delay is "Never capped -- a cap silently reintroduces the mid-paste Enter it exists to prevent". The renderGate branch was an unconditional bypass of exactly that protection. Now both waits run and the later one governs, so it no longer matters why the gate resolved early. The gate's own heuristic is not the whole story: its ingest-deadline clock starts at gate construction, before the paste chunks are written, while the non-gate floor is computed after the write loop completes. That asymmetry is left as-is here; the floor now covers it either way. Verified: new test fails on unfixed code at the pre-floor assertion and passes after (re-confirmed by reverting the hunk by hand and re-running). Named prompt-submission and orchestration suites 6 files / 75 tests pass; orca-runtime.test.ts 1216 tests pass; tsc --noEmit -p config/tsconfig.node.json exits 0. Not yet effective in the installed app: Orca 1.4.192 must be rebuilt from this checkout before dispatch stops stalling at runtime. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FsG5xmiAcEkp1vaxutcb1N
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe agent prompt submission path now waits for render readiness, the calculated submission delay, and post-paste echo handling. New helpers derive paste probes, detect tail echoes and valid collapsed-paste placeholders, and apply platform-specific timeouts. The runtime tracks output emitted after the paste baseline. Tests cover stale and retry echoes, timeout fallback, placeholder handling, platform deadlines, and settlement-adjusted timing bounds. Merge Risk: ⚪ Minimal · up to The render-gated submission path now waits for prompt ingestion and post-paste echo handling before sending Enter, with regression coverage for timing, stale output, retries, placeholders, and timeout behavior. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Description checkExplanation The description is complete and follows the repository template. It explains the problem, implementation, linked issue, testing, platform impact, visual proof, and checklist status. The unchecked full-suite item is explained with the pre-existing Windows failure. Full details: Linked Issues checkExplanation The changes address issue
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the render-gate submit timing fix and its new characterization test.
orca-runtime-write-terminal-agent-prompt.ts— the settlement-agent (renderGate) branch now awaits the byte-count ingest floor alongside the gate, so the later of the two governs and Enter can never overtake the paste ingest.agent-prompt-submission-render-gate-floor.test.ts— mockscreateAgentPromptRenderGateto resolve immediately and asserts no Enter is written before the floor, exactly one at/beyond it.
The fix is sound: Promise.all takes the later of the gate's settlement and the open-loop floor, so the floor is purely a lower bound — it adds nothing when the gate already waits past 500 ms + ingest. The test is non-vacuous (it fails on unfixed main, where the gate branch awaited only the gate) and mirrors the existing agent-prompt-submission-windows-submit-delay.test.ts conventions. Existing gate-characterization tests (real gate + large prompt, hard-cap arithmetic) still hold under the added floor because they assert >= bounds that the floor cannot shorten. No security, wire-compat, or cross-platform concerns.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
…g Enter
On Windows, Codex 0.144 consumes a bracketed paste as per-keystroke composer
redraws. For a 10-30 KB dispatch preamble that outlasts the render gate's hard
cap (CLAUDE_AGENT_PROMPT_RENDER_TIMEOUT_MS + ingest), so the gate resolved on
its timer and Enter was written while the composer was still ingesting; Codex
treated it as a newline and the prompt sat unsubmitted (agent_prompt_stalled).
Reproduced live on a warm, verified-idle Codex pane (dispatch ctx_0853813f2cd5);
a Claude Sonnet pane on the same build submitted in 24 s because its composer
collapses the paste to a placeholder almost immediately.
Time floors cannot cover a CPU-bound redraw burst, so the render-gate branch now
polls the pane's waitText until it contains the paste tail (last 24
whitespace-stripped chars) or a paste placeholder ("[Pasted text", "[Pasted
Content"), then settles 250 ms and proceeds. Capped at 20 s on win32 write
hosts and 3 s elsewhere; on timeout it falls through to today's behavior. The
open-loop branch is unchanged.
Verified: 12 new unit tests + 4 new render-gate-floor tests; the five
prompt-submission suites pass 85/85; tsc --noEmit -p config/tsconfig.node.json
exits 0; oxlint clean on changed files.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MG6S695eZtECtDNakW3EUJ
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Team
Run ID: 799b3955-01a8-4b59-b8f8-c494cf06f880
📒 Files selected for processing (5)
src/main/runtime/agent-prompt-paste-echo.test.tssrc/main/runtime/agent-prompt-paste-echo.tssrc/main/runtime/agent-prompt-submission-render-gate-floor.test.tssrc/main/runtime/agent-prompt-submission-windows-submit-delay.test.tssrc/main/runtime/orca-runtime-write-terminal-agent-prompt.ts
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
There was a problem hiding this comment.
Important
The paste-echo wait can be satisfied by stale scrollback text rather than this paste's echo (see the inline comment). In the retry path this PR targets, that can let Enter overtake the still-running redraw burst again.
Reviewed changes
Since the prior Pullfrog review, this PR layered a paste-echo confirmation on top of the render-gate ingest floor.
agent-prompt-paste-echo.ts— new module deriving a 24-char whitespace-stripped probe from the paste tail and matching it (or a[Pasted ...]placeholder) against pane text, with win32/other timeout constants.orca-runtime-write-terminal-agent-prompt.ts— the render-gate branch now pollswaitTextafter the floor for the paste echo, settles 250 ms, then writes Enter, capped at 20 s (win32) / 3 s with fall-through on timeout.- Tests — new unit tests for the module plus five echo-path tests in the render-gate-floor suite; the windows-submit-delay suite updated for the added settle.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
CodeRabbit found that generic collapsed-paste placeholders could be supplied by the prompt itself. Pullfrog found that whole-scrollback matching reused prior-attempt echoes.\n\nCapture the PTY output sequence after each paste write and inspect only subscribed output that follows it; keep collapsed-placeholder recognition inside that scoped stream. Added prompt-supplied-placeholder, pre-write-scrollback, and retry-paste regressions in agent-prompt-paste-echo.test.ts and agent-prompt-submission-render-gate-floor.test.ts.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Since the prior Pullfrog review, this PR scoped the paste-echo confirmation to terminal output emitted after the paste write and guarded the placeholder path against payload-supplied fragments.
orca-runtime-write-terminal-agent-prompt.ts— captured anoutputSequencebaseline immediately after the paste write, subscribed to terminal data to accumulate apostPasteOutputbuffer limited to bytes past that baseline, and requiredoutputSequence > baselinebefore accepting a tail or placeholder match.agent-prompt-paste-echo.ts— split the match intoisAgentPromptPasteEchoObserved(literal tail) andisAgentPromptPasteEchoPlaceholderObserved(collapse marker), and addedpastePayloadContainsPlaceholderFragmentto disable placeholder evidence when the payload itself supplies a fragment.- Tests — new cases for a probe already in scrollback before the write and for the retry path (the first attempt's echo no longer satisfies the second), plus a payload-supplied-placeholder guard; the windows-submit-delay suite updated to emit a placeholder and account for the settle.
The prior concern is resolved: the echo wait can no longer be satisfied by tail or placeholder text that pre-dates the paste write, so a retry's Enter can no longer be gated by the previous attempt's echo. The two new production functions are narrowly scoped and the added tests fail without the fix (the scrollback-probe and retry cases assert countSubmits(writes) stays at the prior count across the floor+settle window). Targeted suites pass (36/36).
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

ELI5
When Orca pastes a dispatch prompt into a Codex or Claude Code terminal, it waits for the terminal to say "I've redrawn" and then presses Enter. On Windows that redraw can happen before the terminal has actually finished swallowing the paste, so Enter lands mid-paste and is dropped. The prompt sits in the composer forever and Orca reports
agent_prompt_stalled. This change makes Orca also wait the byte-count-based minimum it already uses on the open-loop path, so Enter is never written before the paste could possibly have been ingested.What Changed
src/main/runtime/orca-runtime-write-terminal-agent-prompt.ts: on the render-gate branch, awaitPromise.all([renderGate.wait(), waitForAgentPromptDelay(getAgentPromptSubmitDelayMs(...))])instead of the gate alone. The later of the two now governs. The non-gate branch is unchanged.New test
src/main/runtime/agent-prompt-submission-render-gate-floor.test.ts: resolves the render gate immediately and asserts no Enter is written before the ingest floor elapses, exactly one after.Why
worker-startfailed withagent_prompt_stalledatdispatch_inputon Windows for both Codex and Claude Code TUIs, five attempts in a row (payloads 10,714 and 12,773 bytes). The paste reached the composer and stayed there unsubmitted; pressing Enter manually minutes later submitted it intact and the worker ran normally. So the paste landed and the Enter was swallowed.Agents that expose a settlement signal take the
renderGatebranch, which awaited only the gate and skippedgetAgentPromptSubmitDelayMsentirely. The open-loop branch would have waited ~670 ms for these payloads. The render gate is a readiness signal, not proof of ingest: it can resolve on a redraw that fires before the child has attached the completed bracketed paste.agent-prompt-injection.tsalready documents that the submit delay is "never capped — a cap silently reintroduces the mid-paste Enter it exists to prevent"; the gate branch was an unconditional bypass of that protection.Not addressed here (separate ticket-worthy defect): the gate's own ingest-deadline clock starts at gate construction, before the paste chunks are written, while the non-gate floor is computed after the write loop. The floor now covers it either way.
Linked Issue
Fixes #17066
Related: #16377, #16902, #17291
Visual Proof
N/A — no UI change. Behavior change is in prompt-submit timing; evidence is the test below and the live reproduction described under Testing.
Testing
New test fails on unfixed
mainat the pre-floor assertion (expect(countSubmits(writes)).toBe(0)) and passes with the fix. Re-confirmed by reverting the production hunk by hand and re-running.npx vitest runonagent-prompt-submission-render-gate-floor.test.ts,agent-prompt-submission-runtime.test.ts,agent-prompt-submission-windows-submit-delay.test.ts,agent-prompt-submission-verification.test.ts: 69/69 pass.tsc --noEmit -p config/tsconfig.node.json: exit 0.oxlinton the two changed files: clean.Live reproduction on Windows 11 with Orca 1.4.192:
agent_prompt_stalled5/5 (3 Codex, 1 Claude Sonnet, 1 retry); every one recovered byorca terminal send --enteron the stalled terminal, which submitted the already-injected prompt intact. Built this branch (rebased onf737f349) withbuild:win, installed it, and dispatch acceptance is being run on it now.Platforms actually tested: Windows. macOS/Linux take the same code path; the added wait is bounded by the existing platform-specific
getAgentPromptSubmitDelayMs.Note:
orca-runtime-tests/terminal-creation-and-readiness-part-07.spec.tsfails 52/52 on pristinemainon this Windows machine (selector_not_found), independent of this change.I manually tested these changes locally
Automated tests added/updated, or explained why not below
AI Disclosure
Root-caused and implemented with Claude Opus 5 (Claude Code); rebased onto current
main, re-verified, and packaged with Claude Fable 5.1. The failing test was written and confirmed by a Claude subagent, then independently re-verified by reverting the fix by hand.Review
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
No security surface touched. Cross-platform: adds a bounded wait already computed per platform; no path or shortcut impact. SSH: the write path is the same; the delay is derived from the write-host platform, not the client. Mobile: N/A. Performance: adds at most the existing open-loop submit delay (~0.5–1 s for typical dispatch payloads) on the closed-loop path, only when the gate resolves earlier than the floor.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred) — typecheck, targeted tests, oxlint andbuild:winpass locally; fullpnpm testnot run locally because of the pre-existing part-07 failure noted above.🤖 Generated with Claude Code