Skip to content

fix(orchestration): an OpenCode worker gets its task only once its input box exists - #24115

Open
brennanb2025 wants to merge 11 commits into
mainfrom
brennanb2025/opencode-worker-waits-for-input-box
Open

brennanb2025 wants to merge 11 commits into
mainfrom
brennanb2025/opencode-worker-waits-for-input-box

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 29 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1180 $\color{#cf222e}{\Huge{\mathbf{−}}}$​74 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1106
Prod 17 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​327 $\color{#cf222e}{\Huge{\mathbf{−}}}$​69 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​258

ELI5

When a coordinator starts an OpenCode worker, Orca waits until OpenCode looks ready, types the task in, and presses Enter. Two things went wrong. First, Orca treated a terminal title reading just "OpenCode" as ready, but OpenCode sets that title a moment before it draws its input box, and many shells set the title to opencode seconds earlier, so the task was often typed into nothing and lost. Second, OpenCode 2 ignores an Enter that arrives before it has finished drawing its input area, so on a busy machine the task could sit in the box unsent. Both times the start still reported success. Now Orca waits for the moment OpenCode puts its cursor inside its input box, and presses Enter once more two seconds later unless it can already see the task was taken.

What Changed

The problem. orca orchestration worker-start --agent opencode (or opencode2) returned a receipt saying the worker was ready and its input was accepted, but OpenCode's input box stayed empty: the task never arrived, and the worker never reported back. Eight people reported it on macOS, Linux and Windows, across OpenCode 1.18.x and 2.x (#13911, #22580).

Why it happened, part 1: the task was typed before the box existed. Worker start waited for the terminal to look idle (the tui-idle wait), which accepts a title holding only the agent's name as "ready". OpenCode writes its OpenCode title 30–161 ms before it draws the input box (15 of 15 recorded launches). A shell that auto-titles the pane (for example a zsh preexec hook that titles the pane with the running command) writes opencode the moment the command starts, seconds earlier; with that title present the wait settles as soon as it is registered, before OpenCode has drawn anything. Main already had the right wait, waitForFreshWorkerComposer, which waits only for the agent's own input-box marker, but worker start used it for ZCode alone (agent === 'zcode'), and only for a start on this computer: a start on a paired host (worker-start --on <host>) waited tui-idle for every agent.

Why it happened, part 2: OpenCode 2 drops an early Enter. OpenCode 2.x ignores an Enter that arrives before it has drawn its Build · <model> mode row. Measured without Orca in the loop: an Enter after that row submitted 67/67 times; an Enter before it left the brief stuck 14/18 times, the whole brief sitting in the box as [Pasted ~N lines]. Worker start presses Enter about 0.5 s after the paste, which is after the row in normal conditions, but the row can trail the input-box marker by more than 0.5 s when the machine is loaded (about 9% of runs, mostly under load). Waiting for the input box (part 1) exposes this, and live QA on the head before the retry saw it once: 1 of 10 OpenCode 2.x starts stuck while the receipt said accepted. The renderer's launches that paste and submit a prompt hit the same thing more often, because they press Enter only 50 ms after pasting (the same measured timing left 3 of 5 briefs stuck). This stuck case is not new: main showed it too (one OpenCode 2.x start in the first QA round, after a long wait on a slow machine), and main's renderer launches use the same 50 ms gap. This PR now fixes it rather than leaving it.

What is different for you.

  • On macOS, Linux and Windows (including SSH to those hosts), an OpenCode or OpenCode 2 worker started in a fresh terminal gets its task only once its input box is on screen. This also holds for a worker started on a paired Orca host with worker-start --on <host>, once that host runs this version (the wait runs on the host that owns the terminal; an older host keeps the old wait, and nothing changes on the wire).
  • A freshly started OpenCode or OpenCode 2 worker gets one extra Enter 2 s after the first, which submits a brief that OpenCode 2 left in the box. It is skipped when Orca already sees the task was taken (OpenCode's status plugin reports a turn started for this task) or when OpenCode is showing a question or permission prompt, so it never answers one.
  • OpenCode fresh starts return their receipt up to about 2 s later than before: about 0.1 s later when status hooks are on and the first Enter landed, the full 2 s when they are off or the brief needed the second Enter.
  • When the shell auto-titles the pane, the task now waits for OpenCode's boot, a few seconds, instead of being typed at once and lost. Otherwise the start takes about as long as before.
  • If the box never appears within the start budget (60 s by default), the start fails loudly instead of silently losing the task, exactly as ZCode already does (a local start tears the worker down; a paired-host start records the failure the same way it records a tui-idle timeout today).
  • A ZCode worker started with --on now waits for its input box too, the same wait a local ZCode start already used; before, that path waited tui-idle.
  • The renderer's paste-and-submit launches of OpenCode and OpenCode 2 get the same extra Enter: the checks "fix" launch, the pull-request checks fix launch, quick launch and quick commands, notes, review notes and browser-annotation sends, source-control agent actions, work-item direct launch, background automation drafts, and web-runtime terminal creation. For those, the pane's paste stays reserved and delivery is reported 2 s later.
  • Codex's existing renderer retry Enter (1.2 s) now goes through the same check: it is skipped when Codex's pane shows a question or permission prompt, or when a new turn already started. That only drops a retry that would have answered a prompt or done nothing.
  • Reused terminals (--terminal), structured workers, coordinator dispatch, re-dispatch, orca terminal send and every other agent are unchanged.

This PR is step 2 of a plan to stop Orca treating a terminal title that only names the agent as proof the agent is ready or idle. Step 1 (#24083) changes only what the sidebar and dashboard display for such a title. Step 2 (this PR) stops worker start from typing a task on it, for the agents whose input-box marker has been recorded, and makes sure the task it types is submitted. Later steps stop the rest of Orca from acting on it: the end of an agent's turn (notifications, mail pushed to the agent, workspace cleanup), then the status reported over the wire and on the phone. This PR changes no title classification or settle rule, so it does not depend on #24083 and the two can merge in either order.

Mechanism:

  • Evidence on the agent row. Each row in the shared agent table (tui-agent-config.ts) gains an optional composerReadyCaptures: the committed terminal recordings in which that agent's existing input-box marker (draftPasteReadySignal) fires at the box. Worker start derives its lane from it: a row with evidence waits for the marker alone; a row without keeps tui-idle. zcode (its existing recording), opencode (three 1.18.32 recordings) and opencode2 (one 2.0.18 recording) carry it. The hard-coded agent === 'zcode' check is gone.
  • One lane choice, used by both start paths. It lives in launched-agent-composer-readiness.ts: waitForLaunchedAgentComposer picks the lane for a freshly launched agent (the module and function name draft feat(source-control): start the AI buttons' agents through agent.launch (step 2 of 2) #23748 uses, so the two PRs converge on one function), and waitForWorkerAgentReady adds the one rule both starts share: a caller-supplied --terminal was not freshly launched, so its marker may be long gone and it keeps tui-idle. The local start and the paired-host attach both call it.
  • Windows gets the same wait. Eight OpenCode boots (1.18.32 and 2.0.18) were recorded on Windows 11 in PowerShell launched the way Orca launches it: six through Orca's bundled conpty.dll, and two through the system ConPTY as a control. In all 8, on both backends, OpenCode's own bracketed-paste enable arrived before its input box, it never turned bracketed paste off while booting, and the unchanged marker fired on exactly the read that first drew the box. So no platform check is needed: the lane comes from the agent's evidence alone. Git Bash, cmd and WSL panes, and Linux, are inferred rather than recorded: the marker's anchor still comes from OpenCode itself, and the revocation below handles a shell prompt that toggles bracketed paste. Known, unrecorded case: the standalone Orca server running under Bun spawns terminals through Bun.Terminal rather than node-pty, and no capture of that path exists.
  • The marker is revoked when bracketed paste is turned off. OpenCode's marker (render-cursor-after-bracketed-paste: the cursor is shown after bracketed paste, ESC[?2004h, is enabled) now also ends at ESC[?2004l, the same mechanism Grok, DSH and ZCode use for leaving the alternate screen. No new signal id. Why: zsh, fish and bash 5.1+ enable bracketed paste at their prompt and disable it just before running the command, so without this any launcher spinner that shows the cursor before OpenCode starts would count as "input box ready". OpenCode itself never sends ESC[?2004l while booting (0 in all 15 recordings).
  • One retry Enter, as data. The agent row's existing one-retry setting, submitRetryDelayMs (until now only codex, 1200 ms), is set to 2000 ms for opencode and opencode2, and both paths read it through one shared reader. Worker start passes a new send option, retrySubmitAfterLaunch, only from a start that launched the terminal (local deliverWorkerDispatchPreamble, and the paired-host attach when it created the terminal; the attach now delivers its preamble through that same helper instead of a copy). The runtime sends the retry inside the existing per-pane prompt serialisation, after re-checking the pane's generation, the handle's target and that no permission prompt appeared; a refused retry leaves the first Enter's result standing. Agents whose composer Orca already waits for before the first Enter (claude, codex) are excluded on this path.
  • The retry is skipped for the same reasons on both paths. During the delay the runtime registers this send and watches for a turn it started (the existing prompt-to-turn correlation, fed by OpenCode's status plugin, which posts working 59–77 ms after a real submit and nothing for a stuck brief); a turn it sees, or a question or permission prompt, cancels the retry, and no post just means the retry goes out. The renderer reads the status the agent already reports for that pane from the existing status store and skips on a waiting or blocked pane, or on a turn that started after the first Enter (comparing the host's own timestamps, never the renderer's clock). With status hooks off, both send the retry blind.
  • Draft paste effect. The same scanner drives desktop and worktree-create draft paste for OpenCode, OpenCode 2 and mimo-code: they no longer fire on a cursor shown after the shell's own prompt, and otherwise fire where they did. mimo could only be affected if it turned bracketed paste off before its box, and then a bracketed paste would be wrong for it anyway.
  • Scanner seam fix. On the revocable path, the 7 characters carried over to rejoin a split anchor were searched for the marker a second time, so a 6-character marker could be assembled across the seam: ESC[?2004h | Search ESC[?25 | l more text fired though no show-cursor was ever sent. Carried characters are now used only to spot anchors and leave sequences split across reads. Latent for today's one-character markers (grok, DSH, ZCode); required before OpenCode's 6-character marker moves onto that path.
  • Setup bookkeeping. waitForFreshWorkerComposer now returns the same result as the tui-idle wait, so worker start records the wait-for-setup outcome on this lane too. Pre-existing bug on main: a ZCode worker in a wait-for-setup worktree left its setup receipt stuck at running with no setup_settled stage. Fixed here for ZCode and OpenCode alike.
  • Recordings. Four OpenCode boot recordings are committed under src/main/runtime/__fixtures__/ in the existing timed shape (.txt + .meta.json + .timing.json): 1.18.32 slowest boot (3.9 s of silence, 161 ms from title to box), 1.18.32 with hidden-pane replies, 1.18.32 first launch on an empty home, and 2.0.18 with hidden-pane replies. The repo scanner prints clean on each; the only path is a same-length /Users/USER1/… placeholder. The Codex suite's timed-fixture reader moved into the shared replay harness so both use one reader. The terminal serialize replay suite reads every recording in that folder, so the four new ones are baselined there with their pre-existing grid-restore counts (16, 16, 16 and 14; no byte differences, no regressions; the serializer is unchanged).
  • Comment sweep. The old worker-start rule, and the "ConPTY never forwards DECSET 2004" claim, which its author retracted in docs(tui-agent-config): correct the OpenCode readiness-budget rationale #22593 (795b64b9a6a): two test comments and the matching production comment on the blind-paste fallback in agent-paste-draft.ts.

Residual (temporary). The input-box wait does not stop early when something goes wrong during boot, so these starts fail only after the full budget (60 s by default), with the error timeout:

  • A pane whose agent crashes, is not installed, rejects a command-line flag, or whose setup fails. The shell keeps running in the pane, so nothing exits. The follow-up needs a check of which process holds the pane's foreground (is the agent still the program in front, or has the pane fallen back to its shell?); racing the wait against the pane's process exiting would not catch these cases.
  • A pane whose own process really exits during boot (the pane is closed or its process dies). Here the old tui-idle wait failed at once with terminal_exited; the input-box wait does not watch for exit. Racing it against the exit would fix this case.

Both apply to OpenCode and OpenCode 2 (local and --on) and to ZCode started with --on. A local ZCode start already behaves this way on main.

Why

  • Evidence for the wait. 15 real OpenCode launches (1.18.32, 2.0.14, 2.0.18) were recorded on a Mac. Per the capture batch's own replay, the existing marker fired at the end of OpenCode's first input-box frame in 15/15 runs and never before it; the 4 recordings committed here re-check that in this PR's tests.
  • Evidence for the retry. An extra lone Enter after a submit that had already landed changed nothing in 60/60 runs across OpenCode 2.0.18 and 1.18.32: at +1.2 s, at +2 s, and 1 s into a streamed reply (no abort, no second request, no second message; identical to the controls). A second Enter 2 s after a stuck one submitted 7/7. 2 s is the measured point; 1.5 s is only inferred.
  • Rejected: "name title plus 3 s of quiet". On the slow 1.18.32 recording with a shell auto-title, the stream is silent from 2.6 to 6.5 s and the box arrives at 6.7 s, so a quiet rule fires before the box on about 43% of poll phases (computed from the recording and the code, not run).
  • Rejected: paste blind after the budget. It brings the silent loss back exactly where the marker cannot be seen.
  • Rejected: derive the lane from draftPasteReadySignal alone. It would also move grok (its inline mode never fires the marker, so 60 s failures), mimo (marker set by parity, never recorded), codex and DSH, without evidence.
  • Rejected: a required field with "uncaptured, temporary" rows. 36 agents have no marker at all, so they could never leave such a list.
  • Rejected: wait for OpenCode 2's Build · <model> row instead of retrying. It would key readiness on text that depends on the agent's mode and model name, and it needs its own committed capture; the retry reuses an existing per-agent setting and is measured harmless.
  • Rejected for now: an honest "not submitted" receipt from the status plugin. Status hooks being on in settings does not mean Orca's OpenCode plugin loaded (its install can fail silently), and its first post arrives only after a real submit (37–49 ms after the Enter, 8/8 panes), so a missing plugin and a stuck brief are both silent. Deriving the receipt from it would have given every OpenCode start on such a host about 32 s of extra wait and a false outcome_unknown. The receipt stays as on main; the plugin signal is used only to skip an unnecessary retry, where silence costs nothing.
  • Differences, each labelled:
Difference Label Why, or the follow-up that removes it
Readiness for OpenCode's first input comes from its own terminal bytes, not a protocol "ready" event Temporary Removed by putting the worker's brief on OpenCode's launch line; blocked because the brief names the worker's own terminal handle, which exists only after the terminal is created
A missing input-box marker fails the start after the budget Intended Orca refuses to guess; a timeout rather than a protocol error
Per-agent readiness is evidence on a data row, read by one agent-agnostic lane Intended The analogue of a declared driver capability
The marker's anchor is revoked on ESC[?2004l Intended In-repo precedent: the alternate-screen revocation
The receipt still says accepted/ready when a brief is still stuck after the retry Temporary Follow-up: Orca's OpenCode plugin posts once when it loads, so a missing plugin can be told apart from a stuck brief; then turn on the honest receipt. Evidence: the first plugin post arrives 37–49 ms after the Enter (8/8), so today both are silent
Codex worker starts get no retry Enter (render-gated agents are excluded in worker start); codex keeps its renderer retry Temporary Follow-up: decide whether codex worker starts should also get it
--on gets the input-box wait and the retry, but its attach receipt says ready without observing a turn Temporary, pre-existing for every agent Follow-up: turn observation on the attach, mapped to the existing remote start_unknown
First Enter's gap: renderer 50 ms after the paste, worker start 500 ms plus ingest Intended Both pre-exist; the retry covers both
The renderer reads only the pane's hook status; worker start also sees permission prompts from the title and screen, and ties a turn to this exact send Intended No new status producer; only the runtime can correlate a turn to a send
With status hooks off, both paths send the retry blind Intended A blind second Enter is measured harmless; absence of a post proves nothing

Linked Issue

Fixes #13911 / STA-3952 (macOS tested live on the final head; Windows PowerShell panes covered by capture; Git Bash, cmd, WSL and Linux inferred).

Part of #22580 / STA-8331 (the OpenCode half; its Crush and Devin reports are other mechanisms).

Related #6011 / STA-676.

Live QA

Real Orca worker starts (orca orchestration worker-start) on a second Mac (M4 MacBook Air), against real OpenCode 1.18.32 and 2.0.18 in isolated homes with auto-update off. A brief counts as delivered only when its unique token shows up as a submitted message in OpenCode's own session store; "lost" means an empty input box, "stuck" means the brief sat unsent in the box.

Scenario main (before) this PR, d0b92d044c1 (the final code; the later merge of main changed only the brief's text)
OpenCode 1.18.32 3/8 delivered; all 5 lost when the shell auto-titles the pane 10/10
OpenCode 2.0.18 (opencode2 --standalone) 2/8 delivered; all 5 lost with an auto-title; 1 stuck 10/10
OpenCode 2.0.18 on a heavily loaded machine (1-minute load 14–54) not run 10/10, none stuck
OpenCode 2.x installed as plain opencode 1/3 5/5
First (cold) launch on an empty OpenCode home 1/4 5/5
Worktree created with wait-for-setup brief lost; setup receipt succeeded delivered; setup receipt succeeded, setup_settled recorded
  • On main every one of these starts reported ready and input accepted, including every lost one.
  • Before the retry Enter was added, 2 of 30 OpenCode 2.x starts on this branch left the brief stuck under load while the receipt said accepted. With the retry, 0 of 44 starts on the final head were stuck or lost.
  • Recorded terminal bytes on the final head: with status hooks off, two Enters about 2010 ms apart every time; with hooks on, a single Enter when the turn was seen within about 0.2 s. In one start the first Enter came 55 ms before OpenCode 2 drew its mode row and was dropped; the retry at +2008 ms submitted it.

Main, OpenCode 1.18.32: the start reported success, but the input box is empty and the task is gone.

main: OpenCode 1.18.32 input box empty after a start that reported success

Main, OpenCode 2.0.18: the same loss.

main: OpenCode 2.0.18 input box empty after a start that reported success

This branch before the retry Enter: under load, OpenCode 2 kept the brief in the box unsent while the receipt said accepted.

before the retry: the brief sits in OpenCode 2's input box as Pasted ~84 lines, never submitted

Final head, OpenCode 2.0.18 at a load average of 52: the task was submitted (the red line is the free model's own rate-limit reply, after the submit).

final head: the TASK block submitted in OpenCode 2 under heavy load

Visual Proof

The change is when the task is typed and submitted, not what is drawn; the before/after screenshots are in "Live QA" above.

Testing

  • Platforms actually tested: macOS, unit and replay tests, plus the live QA above. Windows PowerShell panes are covered by the Windows capture (six boots through the bundled conpty.dll, two through the system ConPTY; replayed through the scanner, not an end-to-end worker start). Git Bash, cmd, WSL, Linux and SSH are inferred (the marker comes from OpenCode's own bytes; shells that arm and revoke bracketed paste around a command are handled by the revocation).
  • launched-agent-composer-readiness.test.ts: an exhaustive per-agent lane record (adding an agent fails to compile until someone decides), and evidence that checks itself: every cited recording is committed with its sidecar, the row's current signal fires on it, and for OpenCode rows the first ready read is exactly the read that shows the input box (4/4).
  • opencode-worker-composer-transcript.test.ts: each OpenCode recording replayed through the real runtime at its recorded read times, behind a zsh launch that auto-titles the pane opencode. The worker-start lane settles on the input-box read (6.7 s on the slow boot, after 3.9 s of silence); main's tui-idle wait on the same feed settles before OpenCode's first byte.
  • draft-paste-ready-scanner-chunking.test.ts: every committed recording on the revocable path (grok alt and inline, DSH, ZCode, OpenCode ×5, OpenCode behind a zsh launch ×4) fed whole, one character at a time, in its recorded reads and in 12 seeded chunkings. Ready always lands on the read holding the offset a plain string walk finds. A regression guard for grok, DSH and ZCode.
  • Scanner cases: the seam negative case, and the zsh-launch revocation case.
  • launched-agent-worker-readiness.test.ts (renamed from zcode-worker-readiness.test.ts): zcode, opencode and opencode2 wait for the box and ask for the retry; codex, claude, grok and mimo keep tui-idle; reused terminals keep tui-idle and ask for no retry; a timeout never delivers.
  • federation-launched-agent-readiness.test.ts (paired-host start): a terminal the attach created for opencode, opencode2 or zcode waits for the box, never calls tui-idle, and asks for the retry; a reused --terminal keeps tui-idle and asks for none; a box that never appears fails the attach at agent_readiness with timeout and types nothing.
  • agent-prompt-launch-submit-retry.test.ts (real runtime, fake PTY): opencode and opencode2 send a second Enter exactly at the row delay; a send that did not launch the agent sends one; codex, claude and aider send one even when asked; a permission prompt after the first Enter stops the retry; a pane that exits before the retry keeps the first result.
  • agent-prompt-launch-turn-observation.test.ts (real runtime, hook status rows): a turn after the first Enter skips the retry; no post sends it; the plugin's first done post (empty prompt) does not count as a turn; a hook permission prompt skips it; a pane exit during the wait keeps the first result; the receipt stays unsupported throughout.
  • Renderer: OpenCode and OpenCode 2 get the retry from their row; a waiting prompt or a started turn skips it; a pure table test of the skip rule (7 cases); agents without the row setting still send one Enter.
  • workers-new-worktree.test.ts: on the composer lane, a wait-for-setup worktree's receipt reads succeeded and a setup_settled stage is recorded.
  • Ablations (each producer reverted alone, its test files re-run):
    • lane choice reverted to agent === 'zcode': 7 fail;
    • paired-host attach reverted to tui-idle: 4 of 5 fail (the reused-terminal case passes either way, as it should);
    • OpenCode evidence dropped: 14 fail; revocation removed: 9 fail; seam fix removed: 1 fails; composer result shape reverted: 1 fails;
    • retry write removed: 2 fail; fresh-launch option dropped: 6 fail; OpenCode rows' retry delay dropped: 6 fail (runtime and renderer);
    • codex/claude exclusion removed: 1 fails; pre-retry turn skip removed: 1 fails; the retry's best-effort catch made to rethrow: 4 fail;
    • renderer skip check removed: 2 fail; renderer turn check removed: 3 fail; both runtime permission checks removed: 2 fail (each alone is covered by the other, on purpose: the last one re-reads the status right before the write).
  • tc:node and tc:web pass at d0b92d044c1 and again after merging main at 63a7311c839; after the merge, 134 related test files pass (3111 tests); check:code-quality:changed reports 0 findings; oxlint is clean on every touched file; 122 related test files pass (2939 tests), including orca-runtime.test.ts, pty-transcript-secret-scan.test.mjs and the terminal serialize replay suite.
  • I manually tested these changes locally (live QA on a second Mac for the final head: see "Live QA")
  • Automated tests added/updated, or explained why not below

Review

  • Verified by me: the 4 committed recordings are byte-identical to the raw captures and their read lengths cover each file exactly; the marker read equals the read that ends OpenCode's first input-box frame in all 4; OpenCode sends no ESC[?2004l in any of them; docs(tui-agent-config): correct the OpenCode readiness-budget rationale #22593's commit message retracts the ConPTY claim; the paired-host attach fails a composer timeout through the same agent_readiness failure path a tui-idle timeout already takes (both waits throw timeout); OpenCode's plugin reports permission and question prompts as waiting, which both retry checks skip on.
  • Not verified: a live worker-start --on <host> start (covered by unit tests only); an end-to-end worker start on Windows; Git Bash, cmd, WSL, Linux, tmux or daemon behaviour of the marker; the standalone server's Bun.Terminal spawn path; mimo's stream; a user typing into a freshly started OpenCode pane within the 2 s window (the retry would submit their partial text; codex's renderer retry already behaves this way).
  • Follow-ups (not yet ticketed):
    • Orca's OpenCode plugin posts once when it loads, then derive an honest "not submitted" receipt from it.
    • Fail at once when the pane's agent is gone: a foreground-process check, plus racing the wait against the pane's process exiting (see "Residual").
    • Put OpenCode's brief on its launch line, removing the terminal-bytes readiness wait for it.
    • Turn observation on the --on attach, so its receipt can say start_unknown.
    • Decide whether codex worker starts should get the retry Enter.
    • A renderer turn-start check, so its paste-and-submit result says whether the prompt was taken.
    • Revoke codex-composer-prompt's bracketed-paste anchor, the remaining un-revoked one.
    • A mimo-code boot recording.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred): targeted typecheck, lint and tests pass locally; the full suites and build are left to CI

…put box exists

Worker start waited tui-idle, which settles on a title holding only the agent's
name. OpenCode sets that title before drawing its input box, and a shell
auto-title names the pane at spawn, so the brief could be typed into nothing.

- composerReadyCaptures: optional per-agent evidence; worker start takes the
  marker-only lane iff a row cites captures (zcode, opencode, opencode2)
- waitForLaunchedAgentComposer picks the lane; Windows-hosted panes on
  OpenCode's signal stay on tui-idle until a ConPTY capture exists (temporary)
- waitForFreshWorkerComposer returns the tui-idle result shape, so the
  wait-for-setup outcome is recorded (fixes ZCode's receipt stuck at running)
- render-cursor-after-bracketed-paste is revoked on ESC[?2004l
- scanner seam fix: carried chars no longer re-searched for the marker
- four timed OpenCode boot captures (1.18.32 x3, 2.0.18) committed
@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium risk] Adjusts worker task dispatch timing and adds test fixtures.

The PR does not appear safe to merge until a failed federated start cleans up the terminal and worktree it created.

Findings

  1. P1 Failed starts leave resources behind ▶

Summary

This PR waits for a freshly launched OpenCode worker’s input box before delivering its task, adds a guarded retry Enter, and applies the readiness path to paired-host starts. It also adds terminal-recording and worker-start tests.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Start worker] --> B{Freshly launched agent with captured composer marker?}
  B -->|Yes| C[Wait for input-box marker]
  B -->|No| D[Wait for TUI idle]
  C --> E[Deliver task and first Enter]
  D --> E
  E --> F{Turn started or prompt waiting?}
  F -->|Yes| G[Skip retry]
  F -->|No, eligible fresh launch| H[Retry Enter]
Loading

Reviews (7) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..."

@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Comments Outside Diff

These findings could not be posted inline.

  • P1 Unsent tasks appear ready src/main/runtime/orca-runtime-write-terminal-agent-prompt.ts:162 ▶

    When a freshly launched OpenCode worker accepts a task into its composer but neither Enter starts a turn, this change marks the prompt receipt as unsupported even when OpenCode's status plugin can report a turn start. Worker-start treats that receipt as enough to mark the dispatch ready instead of leaving its outcome unknown. The start can therefore report success while the task remains unsent.

@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds timed OpenCode terminal captures and a loader that replays their chunks at recorded times. It updates draft-paste scanning to revoke markers when bracketed paste is disabled and to avoid joining previously scanned bytes across chunk boundaries. Agent configuration now identifies composer-ready captures. New worker starts select a readiness lane using that configuration. Launched prompt delivery can retry Enter after a configured delay. Tests cover scanner chunking, capture replay, readiness selection, and worker startup.

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 07ff2

A fast OpenCode response can finish before the retry delay and still receive an unwanted second Enter. The impact is bounded; compare turn timestamps regardless of state to avoid this extra input.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 07ff2

The change strengthens readiness checks and guards delayed submission against observed progress, approval requests and stale sessions. No newly introduced security failure was established, but ownership continuity across delayed writes and session replacement could not be fully confirmed.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The new runtime action is one additional Enter directed to the worker's selected terminal, including execution on a paired worker host. Its security-sensitive outcome is unintended terminal input under that terminal's existing authority; no broader authority grant is established by the inspected dispatch plumbing.

Trust Boundaries and Controls

  • observed — The runtime checks cancellation and lifecycle generation before retrying. It rejects a current permission state or a permission-sequence advance, while turn verification also checks generation and blocked state during polling. These are substantive controls, but they do not independently establish durable session-ownership continuity.

Resilience and Maintainability Implications

  • observed — Later observation binds a receipt to process incarnation and generation and reports replacement explicitly. This protects receipt interpretation, but production evidence was insufficient to confirm every replacement, interruption and recovery transition before delayed input.

Hardening Proposals

  • proposed — For the inherited renderer retry, consider treating a newer turn timestamp as progress even after completion and binding retry eligibility to the original terminal session. This would strengthen terminal-state and ownership guarantees without implying a newly introduced vulnerability.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.34% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 41 functions across 36 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: OpenCode workers now wait for the input box before receiving tasks.
Description check ✅ Passed The description is complete and directly related to the changes. It includes the user impact, mechanism, rationale, linked issues, visual proof, testing details, limitations, follow-ups, and checklist…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — full read of the 30-file diff at 24a023e; focused tests, pnpm tc:node, the changed-code quality gate, and the PTY-transcript secret scan all pass.

  • Lane selection moves onto row evidence. A new composerReadyCaptures field on the agent row, plus a Windows-host check, decides between waitForFreshWorkerComposer and tui-idle, and local-worker-start replaces the hard-coded agent === 'zcode' branch with one agent-agnostic lane call. ZCode, OpenCode and OpenCode 2 wait for the input-box marker; every other agent keeps the prior wait.
  • The composer wait now yields a wait result. waitForFreshWorkerComposer returns the tui-idle result shape, so persistWorkerSetupWaitOutcome records the wait-for-setup outcome on this lane too — fixing a pre-existing stuck running setup receipt for ZCode as well.
  • Scanner revocation and seam hardening. render-cursor-after-bracketed-paste is revoked on \x1b[?2004l, and carried bytes no longer re-enter the marker search, so the launching shell's own bracketed-paste toggle cannot be mistaken for a mounted composer.
  • Evidence and tests. Four committed OpenCode boot recordings with timed sidecars, an exhaustive per-agent lane record, self-checking capture evidence, chunking-invariance tests, and runtime replays behind a synthetic auto-titling zsh launch.

ℹ️ Windows-hosted OpenCode panes keep the old title-based wait

The gate intentionally leaves OpenCode on tui-idle for local ConPTY, WSL, and Windows SSH/paired hosts until a bundled-conpty.dll capture exists, so the silent task-loss this PR fixes on macOS/Linux still occurs there — and the linked issues include Windows reports. The PR body notes no follow-up ticket was filed, so the remaining Windows gap and the planned capture are only visible in this description; a tracking issue would keep that from being lost after merge.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…its input box

`worker-start --on <host>` launches the agent through the federated attach on
the worker host, which still waited tui-idle for every agent. An OpenCode
worker there could get its task typed before its input box existed, the same
loss the local start no longer has. The attach now takes the same wait as a
local start: a terminal it created waits for the composer marker when the
agent's row cites captures of it (OpenCode, OpenCode 2, ZCode) and the pane is
not Windows-hosted; a caller-supplied --terminal keeps tui-idle. Both paths
share one helper so the fresh-vs-reused rule lives in one place.

Also drops the retracted "ConPTY does not forward DECSET 2004" claim from the
blind-paste comment in agent-paste-draft.ts.
…put box too

A capture through Orca's bundled conpty.dll (Windows 11, PowerShell launched as
Orca launches it, OpenCode 1.18.32 and 2.0.18, 8 of 8 runs) shows OpenCode's
bracketed-paste enable always arriving before its input box, no disable while
booting, and the composer marker firing on exactly the read that first draws
the box. The temporary Windows host check that kept these panes on tui-idle is
therefore removed: the lane comes from the row's evidence alone, and the
pty-host-platform lookup added only for that check goes with it.
Comment on lines +221 to 225
const wait = await waitForWorkerAgentReady(runtime, terminalHandle, {
agent,
reusesTerminal: Boolean(params.terminal),
timeoutMs: readinessTimeoutMs
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Failed starts leave resources behind

If a newly created federated OpenCode worker never emits its input-box marker, this wait times out. The failure path records a failed attachment but does not close the terminal or remove a worktree created for the worker. The worker host can retain an unused terminal and worktree after reporting that the start failed; local worker start, by contrast, tears down its resources on failure.

Knowledge Base Used: Terminal runtime and interaction

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 1e7ec356-4175-4950-9fcf-f06ca2693e8e

📥 Commits

Reviewing files that changed from the base of the PR and between 24a023e and cd62861.

📒 Files selected for processing (10)
  • src/main/runtime/launched-agent-composer-readiness.test.ts
  • src/main/runtime/launched-agent-composer-readiness.ts
  • src/main/runtime/opencode-worker-composer-transcript.test.ts
  • src/main/runtime/orca-runtime-activate-managed-worktree.ts
  • src/main/runtime/rpc/methods/orchestration/federation/federation-launched-agent-readiness.test.ts
  • src/main/runtime/rpc/methods/orchestration/federation/federation.ts
  • src/main/runtime/rpc/methods/orchestration/worker/launched-agent-worker-readiness.test.ts
  • src/main/runtime/rpc/methods/orchestration/worker/local-worker-start.ts
  • src/main/runtime/rpc/methods/orchestration/worker/workers-new-worktree.test.ts
  • src/renderer/src/lib/agent-paste-draft.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment on lines +221 to +223
const wait = await waitForWorkerAgentReady(runtime, terminalHandle, {
agent,
reusesTerminal: Boolean(params.terminal),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

rg -n -C 8 --glob '*.ts' \
  '\b(failFederatedAttachmentWithReceipt|prepareRemoteAttachmentAuthority|persistFederatedReadinessStage|tearDownFailedWorkerStart)\s*\(' src/main/runtime
rg -n -C 6 --glob '*.ts' \
  'residualResources|terminalOwnership|federationAttachStart' \
  src/main/runtime/rpc/methods/orchestration

Repository: stablyai/orca

Length of output: 42247


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- federation.ts ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federation.ts | sed -n '150,290p'
printf '%s\n' '--- failure helper and receipt ---'
rg -n -C 30 --glob '*.ts' 'function failFederatedAttachmentWithReceipt|failFederatedAttachmentWithReceipt|residualResources' src/main/runtime/rpc/methods/orchestration/federation src/main/runtime/orchestration
printf '%s\n' '--- terminal release symbols ---'
rg -n -C 20 --glob '*.ts' 'releaseStructuredWorkerSession|worker-release|tearDownFailedWorkerStart|close.*terminal|terminal.*close|kill.*terminal' src/main/runtime

Repository: stablyai/orca

Length of output: 45668


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- federation-start-receipt.ts ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federation-start-receipt.ts
printf '%s\n' '--- federation effects ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federation-effects.ts
printf '%s\n' '--- failRemoteAttachment definitions/callers ---'
rg -n -C 35 --glob '*.ts' 'failRemoteAttachment\s*\(' src/main/runtime
printf '%s\n' '--- worker release definitions ---'
rg -n -C 35 --glob '*.ts' 'getWorkerTerminalResourceByOwner|beginWorkerTerminalRelease|workerRelease|releaseWorkerTerminal|terminal resource' src/main/runtime/rpc/methods/orchestration/worker src/main/runtime/orchestration

Repository: stablyai/orca

Length of output: 45667


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- federation setup persistence ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federation-setup.ts | sed -n '1,260p'
printf '%s\n' '--- federation control ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federation-control.ts | sed -n '1,280p'
printf '%s\n' '--- residual/effect consumers ---'
rg -n -C 15 --glob '*.ts' 'residual_resources|residualResources|isFederationResidualEffect|action === .created.|kind === .terminal.' src/main/runtime --glob '!*.test.ts'

Repository: stablyai/orca

Length of output: 42537


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- federated release host ---'
cat -n src/main/runtime/rpc/methods/orchestration/federation/federated-worker-release-host.ts
printf '%s\n' '--- release callers and cleanup bindings ---'
rg -n -C 25 --glob '*.ts' 'releaseRemoteAttachment|orchestration\.federationRelease|federationRelease' src/main/runtime --glob '!*.test.ts'

Repository: stablyai/orca

Length of output: 44748


🏁 Script executed:

#!/bin/bash
set -e
rg -n -C 45 --glob '*.ts' 'requestRemoteAttachmentTerminalRelease\s*\(' src/main/runtime
rg -n -C 25 --glob '*.ts' 'createWorkerTerminalResourceStatement|findTransferableWorkerTerminalResource|terminal_handle.*remote_dispatch_attachments' src/main/runtime/orchestration/db

Repository: stablyai/orca

Length of output: 42642


Close a created terminal when federation readiness fails.

When waitForWorkerAgentReady fails, execution reaches failFederatedAttachmentWithReceipt before prepareRemoteAttachmentAuthority. The failure path records the terminal as residual metadata but does not close it or create terminal ownership. federationStop skips failed attachments, and federationRelease returns no_owned_resource for this pre-authority path. A failed attachment can therefore leave its created terminal running without a task.

Add failure cleanup for the newly created terminal. Do not close a reused or external terminal.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — re-review of the commits since the prior review at 24a023e: af2dc3e (paired-host readiness) and cd62861 (temporary Windows host gate removed), plus the shared lane helper.

  • A paired-host worker start now waits for the input box. orchestration.federationAttachStart routes through a new waitForWorkerAgentReady helper, so a worker launched on a paired host takes the same composer-marker wait a local start takes; a reused --terminal still keeps tui-idle. Previously worker-start --on <host> always used tui-idle, leaving the silent task-loss the local start had just fixed.
  • The temporary Windows host gate is removed. getLaunchedAgentReadinessLane drops its platform argument, and the getTerminalPtyHostPlatform / getLiveTerminalPtyId lookup added only for that check goes with it, so an OpenCode / OpenCode 2 worker on any host now waits for the input-box marker. Commit cd62861 cites an 8/8 capture through the bundled conpty.dll, consistent with the earlier verification in #22593 that DECSET 2004 arrives in order on real Windows ConPTY.
  • Comments and tests realigned. The retracted "ConPTY does not forward DECSET 2004" claim is dropped from agent-paste-draft.ts and from the scanner test's describe, and the worker-readiness cases are consolidated into launched-agent-worker-readiness.test.ts. The three focused readiness suites (73 tests) pass.

ℹ️ The Windows change is described only in the commit message

The shipped behaviour now contradicts every Windows statement in the PR description: it still says Windows-hosted panes keep tui-idle, that no bundled-conpty.dll capture exists, and lists "a Windows recording … to remove the host check" as a follow-up, while the Review section still describes the host-platform lookup that no longer exists. A reviewer or future reader working from the description is misled, and the row's composerReadyCaptures remain macOS-only, so the self-checking evidence test does not cover the Windows lane.

Technical details
# Windows lane exists only in the commit message

## Affected sites
- `src/main/runtime/launched-agent-composer-readiness.ts:21` — `getLaunchedAgentReadinessLane` is platform-blind, so OpenCode takes the composer-marker lane on Windows panes.
- `src/shared/tui-agent-config.ts` — the `opencode` / `opencode2` `composerReadyCaptures` cite only `opencode-1-18-32-*` and `opencode-2-0-18-*` fixtures, all `platform: darwin`.
- PR description — "Windows-hosted panes are unchanged for now", "No recording through Orca's bundled `conpty.dll` exists yet", and the "Not verified" / "Follow-ups" / "Review" sections that still assume the host check is present.

## Required outcome
- The description matches the shipped behaviour: Windows panes on the composer lane, the host check removed, and no Windows-capture removal still listed as a follow-up.
- Optional: commit the bundled-`conpty.dll` capture and cite it on the row, so the Windows lane has the same committed-evidence trail the macOS rows carry.

## Context
- #22593 (`795b64b9a6a`) already measured DECSET 2004 arriving in order on two Windows ConPTY backends with the marker firing every run; `cd6286109c` adds an 8/8 capture through the bundled DLL, recorded only in the commit message.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…de boot captures

The transcript replay suite reads every capture under runtime/__fixtures__, so
the four OpenCode boot recordings this branch adds are replayed through the
serialize round trip too. Each shows the round trip's known grid divergences
after a resize (16, 16, 16 and 14 checks), and no I1 byte difference or I3
regression. The serializer and this suite are unchanged from main, so these
are pre-existing limitations surfaced by new inputs; record their counts like
the other captures' baselines.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Keep OpenCode readiness on the Windows idle path. · launched-agent-composer-readiness.ts:10-20

src/main/runtime/launched-agent-composer-readiness.ts:10-20
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep OpenCode readiness on the Windows idle path.

getLaunchedAgentReadinessLane ignores the host platform. Fresh opencode and opencode2 starts therefore enter waitForFreshWorkerComposer in both local-worker and federation paths. If Windows loses the bracketed-paste anchor, the composer marker cannot be detected. The hard timeout then fails the worker start before prompt delivery.

Suggested fix
-export function getLaunchedAgentReadinessLane(agent: TuiAgent): LaunchedAgentReadinessLane {
-  return TUI_AGENT_CONFIG[agent].composerReadyCaptures?.length ? 'composer-marker' : 'tui-idle'
+export function getLaunchedAgentReadinessLane(
+  agent: TuiAgent,
+  platform: NodeJS.Platform = process.platform
+): LaunchedAgentReadinessLane {
+  const useWindowsIdle =
+    platform === 'win32' && (agent === 'opencode' || agent === 'opencode2')
+  return !useWindowsIdle && TUI_AGENT_CONFIG[agent].composerReadyCaptures?.length
+    ? 'composer-marker'
+    : 'tui-idle'
}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: d115132e-dc73-416e-aa8e-1b0f4e26b1ef

📥 Commits

Reviewing files that changed from the base of the PR and between cd62861 and 5ff7d77.

📒 Files selected for processing (1)
  • src/main/daemon/serialize-grid-transcript-replay.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment on lines +38 to +43
// OpenCode boot captures: rows on its true-colour background, and the row a shrink leaves
// behind, restore inexactly after a resize. Pre-existing: they landed with no serializer change.
'opencode-1-18-32-timed-boot-hidden-pane': 16,
'opencode-1-18-32-timed-boot-slow': 16,
'opencode-1-18-32-timed-first-launch': 16,
'opencode-2-0-18-timed-boot-hidden-pane': 14,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

rg -n -C 10 'new-fail|KNOWN_PREEXISTING_I2_FAILURES' src/main/daemon/serialize-grid-transcript-replay.test.ts
rg -n -C 8 'I2|checkpoint|new-fail' src/main/daemon/serialize-grid-roundtrip.ts
sed -n '180,245p' src/main/daemon/serialize-grid-transcript-replay.test.ts

Repository: stablyai/orca

Length of output: 7757


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- replay test: setup and assertion path ---'
sed -n '1,80p' src/main/daemon/serialize-grid-transcript-replay.test.ts
sed -n '150,230p' src/main/daemon/serialize-grid-transcript-replay.test.ts
printf '%s\n' '--- roundtrip classification ---'
sed -n '296,345p' src/main/daemon/serialize-grid-roundtrip.ts
printf '%s\n' '--- PR diff for the reviewed file ---'
git diff --no-ext-diff --unified=25 8cc28545a2514cf14cd25187b9bd24a6d9e03ba1 5ff7d779449c6f97aedce9f3092bad2583eb7c23 -- src/main/daemon/serialize-grid-transcript-replay.test.ts

Repository: stablyai/orca

Length of output: 12143


Assert OpenCode I2 failure identities, not only their count.

For the default two-seed run, each non-null gridDiff.new adds one new-fail. The OpenCode entries compare only the aggregate count. A different I2 mismatch can therefore replace the known resize mismatch and still pass. Store and compare the expected failureSignatures for each OpenCode transcript.

…one retry Enter

OpenCode 2 drops an Enter that arrives before it has drawn its mode row
(`Build · <model>`). Worker start pastes at the input-box marker and sends
Enter about 0.5 s later, so on a loaded machine the brief could stay in the box
as `[Pasted ~N lines]` while the receipt said accepted. Measured: an Enter after
the mode row submitted 52/52; one before it stuck 14/18; a second Enter 2 s
later submitted every stuck brief (7/7); a lone extra Enter after a landed
submit, even mid-reply, changed nothing (60/60 across 2.0.18 and 1.18.32).

The agent row's existing one-retry setting, `submitRetryDelayMs`, is set to
2000 ms for opencode and opencode2, and both paths now read it:
- worker start (local, and `--on` when the attach launched the terminal) sends
  one extra Enter after that delay, under the same per-pane serialisation and
  generation/permission checks as the first; a refused retry leaves the first
  Enter's result standing. Render-gated agents (claude, codex) are excluded.
  Coordinator dispatch, re-dispatch, `terminal send` and reused terminals are
  unchanged.
- the renderer's submit-after-ready paste already sent the row's retry Enter
  (codex); it now covers OpenCode too, which it pastes at the same marker with
  a 50 ms Enter gap.

The paired-host attach now delivers its preamble through the same helper as a
local start instead of a copy of it.
Comment thread src/shared/tui-agent-config.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor config/evidence question inline.

Reviewed changes — incremental re-review of the commits since the prior Pullfrog review at cd62861; the substantive one is 245572e, which adds a retry Enter to a launched OpenCode worker's first dispatch on top of the composer-wait fix reviewed earlier.

  • A launched OpenCode worker's first dispatch gets one retry Enter. RuntimeAgentPromptWriteOptions gains retrySubmitAfterLaunch; writeTerminalAgentPrompt sends a second \r after the agent row's submitRetryDelayMs, under the same request / generation / permission checks as the first, and threads the resulting submits count into bytesWritten and every receipt. omp (paste-frame) and claude/codex (render-gated) are excluded, and a reused terminal keeps one Enter.
  • The launch flag is threaded through both start paths. deliverWorkerDispatchPreamble (local start and federated attach) takes launchedTerminal: !params.terminal; the federated attach now shares that helper instead of an inline copy. opencode/opencode2 set submitRetryDelayMs: 2000, and the renderer's existing draft-paste retry reads it through a new shared getAgentSubmitRetryDelayMs, so OpenCode draft pastes now get the retry too.
  • Tests. A new main-process suite asserts the second Enter fires exactly at the row delay, that non-launch / render-gated / plain agents keep one Enter, and that a pane exit before the retry leaves the first Enter standing; the renderer suite covers the OpenCode retry, and the federated/local readiness suites assert the retrySubmitAfterLaunch flag.

The commit message documents the stray-Enter risk well (a lone extra Enter after a landed submit changed nothing, 60/60 across 2.0.18 and 1.18.32), which is the concern the worker path's permission guard was added for.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

],
// Why: OpenCode 2 drops an Enter sent before its mode row is drawn, which can trail the box
// by over a second under load; a second Enter 2 s later submitted every stuck brief measured.
submitRetryDelayMs: 2000

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rationale here describes OpenCode 2, but the same submitRetryDelayMs: 2000 is set on the OpenCode 1.18.x opencode row (and the opencode2 row points back to it). The committed 1.18.x captures show the composer marker firing at the box, and the commit message ties the Enter-drop to 2.x's mode row, so the first Enter should already land for 1.18.x — is the retry needed there, or should the field be scoped to opencode2? As written, every launched 1.18.x worker start and every 1.18.x draft paste now pays a 2 s retry that may never fire.

The OpenCode rows' retry Enter (one extra Enter 2 s after the first) is blind in
the renderer's submit-after-ready paste, which reaches every OpenCode launch that
pastes and submits a prompt. If OpenCode asked for a tool permission or a
question inside those 2 s, the Enter could answer it.

The renderer now reads the status the agent already reports for that pane (the
same hook status the sidebar shows) before sending the retry. It skips the retry
when the pane is waiting on the user (a permission or question prompt) or when
a new turn started after the first Enter, since the first Enter then landed.
With no reported status (status hooks off) it stays blind, as the worker-start
retry does. Turn clocks are compared with each other, never with the
renderer's clock, so a remote host's clock skew cannot flip the decision.

Also adds the missing test for the worker-start retry's own permission guard:
a pane that reports a permission prompt after the first Enter gets no second
Enter.
…k was submitted

A freshly launched OpenCode worker's first dispatch reported "accepted" once
the bytes were written, even when the brief stayed unsubmitted in the input
box. Orca's OpenCode status plugin posts `working` for every real submit and
nothing for a stuck brief (QA: 59-77 ms after the Enter; 10/10 forced-stuck
briefs posted nothing), so with status hooks on that post is now the evidence:

- the retry Enter is skipped when the first Enter already started a turn for
  this request, which also keeps it away from a user typing or a prompt that
  follows a landed submit;
- the receipt is observable (provider `opencode`/`opencode2`, observation
  `supported`): a turn observed after either Enter reports the worker ready,
  and none within the existing observation window reports the existing
  `outcome_unknown` / `turn_start_unobserved` / `turn_unobserved`. The
  terminal and dispatch capability are kept, so the user can still press Enter
  and a later worker report settles the dispatch.

OpenCode's boot `done` post with an empty prompt is not a turn start: only a
`working` post after the first Enter, claimed by this request, counts. With
status hooks off nothing changes (blind retry, `unsupported` receipt).
Coordinator dispatch, re-dispatch and `terminal send` stay unchanged. The
receipt's provider type is widened in typed code to the agents whose turn
start Orca observes, including antigravity, which it already carried.
…tops the OpenCode retry Enter

Main and the renderer now skip the retry for the same two reasons: the pane is
waiting on the user, or a turn started. This pins main's half with a hook-reported
permission prompt, as OpenCode's plugin posts it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 7af4cc64-45e0-498d-b280-8f6e396c93a5

📥 Commits

Reviewing files that changed from the base of the PR and between 245572e and 07ff2e5.

📒 Files selected for processing (12)
  • src/main/runtime/agent-prompt-launch-submit-retry.test.ts
  • src/main/runtime/agent-prompt-launch-turn-observation.test.ts
  • src/main/runtime/agent-prompt-submission-verification.ts
  • src/main/runtime/orca-runtime-write-terminal-agent-prompt.ts
  • src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts
  • src/renderer/src/lib/agent-paste-draft.test.ts
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/lib/agent-submit-retry-guard.test.ts
  • src/renderer/src/lib/agent-submit-retry-guard.ts
  • src/renderer/src/runtime/runtime-terminal-inspection.ts
  • src/shared/runtime-terminal-contracts.ts
  • src/shared/tui-agent.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Comment on lines +18 to +34
*/
export function isSubmitRetryStillOwed(
beforeSubmit: PaneTurnStatus | undefined,
now: PaneTurnStatus | undefined
): boolean {
if (!now) {
return true
}
if (now.state === 'blocked' || now.state === 'waiting') {
return false
}
if (now.state !== 'working') {
return true
}
// Host-stamped turn clocks compared with each other, never with this renderer's clock.
return beforeSubmit?.state === 'working' && turnStartOf(beforeSubmit) === turnStartOf(now)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

sed -n '1,100p' src/renderer/src/lib/agent-submit-retry-guard.ts
sed -n '210,280p' src/renderer/src/lib/agent-paste-draft.ts
rg -n 'turnStartedAt|state: .done.' src/main/agent* src/main/runtime src/renderer/src/store src/shared/agent-status-types.ts

Repository: stablyai/orca

Length of output: 40742


🏁 Script executed:

set -o pipefail
base=8cc28545a2514cf14cd25187b9bd24a6d9e03ba1
head=07ff2e5214ec8a876b764a2bae864f8a6176b5f2
printf '%s\n' '--- diff stat ---'
git diff --stat "$base" "$head"
printf '%s\n' '--- changed paths relevant to question ---'
git diff --name-only "$base" "$head" | rg 'agent-submit-retry-guard|agent-paste-draft|agent-status|server-status|opencode|codex|agent-status-types' || true
printf '%s\n' '--- guard and caller diff ---'
git diff --unified=35 "$base" "$head" -- \
  src/renderer/src/lib/agent-submit-retry-guard.ts \
  src/renderer/src/lib/agent-paste-draft.ts
printf '%s\n' '--- status application ---'
cat -n src/main/agent-hooks/server/server-status-application.ts | sed -n '1,210p'
printf '%s\n' '--- persistence validation ---'
cat -n src/main/agent-hooks/server/server-persistence-validation.ts | sed -n '1,210p'
printf '%s\n' '--- live status builder ---'
cat -n src/renderer/src/store/slices/agent-status-live-entry-builder.ts | sed -n '90,235p'
printf '%s\n' '--- turn-started-at tests ---'
cat -n src/main/agent-hooks/server-turn-started-at.test.ts | sed -n '50,190p'
printf '%s\n' '--- lifecycle tests ---'
cat -n src/main/agent-hooks/server-opencode-lifecycle.test.ts | sed -n '1,130p'
rg -n -C 8 'agentType: .(codex|opencode).|turnStartedAt|state: .(working|idle|done).' src/main/agent-hooks src/renderer/src/store/slices src/shared/agent-status-types.ts | head -n 500

Repository: stablyai/orca

Length of output: 42285


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- retry guard tests ---'
cat -n src/renderer/src/lib/agent-submit-retry-guard.test.ts
printf '%s\n' '--- retry caller tests ---'
cat -n src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts
printf '%s\n' '--- exact turn timestamp tests ---'
cat -n src/main/agent-hooks/server-turn-started-at.test.ts | sed -n '55,190p'
printf '%s\n' '--- exact live builder and status type ---'
cat -n src/renderer/src/store/slices/agent-status-live-entry-builder.ts | sed -n '105,135p'
cat -n src/shared/agent-status-types.ts | sed -n '55,115p'
printf '%s\n' '--- OpenCode lifecycle and transcript tests ---'
cat -n src/main/agent-hooks/server-opencode-lifecycle.test.ts | sed -n '1,115p'
cat -n src/main/runtime/opencode-worker-composer-transcript.test.ts | sed -n '1,130p'
printf '%s\n' '--- prompt submission and Enter handling references ---'
rg -n -C 6 'sendRuntimePtyInputVerified|inputKind|submit|\\\\r|empty prompt|Enter|carriage return' src/main src/renderer/src/lib src/shared | head -n 600

Repository: stablyai/orca

Length of output: 42440


Compare turn timestamps before filtering by state.

isSubmitRetryStillOwed compares timestamps only for working status. A new turn can start and finish before the retry delay, leaving a done status with a newer turnStartedAt. The guard then returns true, and agent-paste-draft.ts sends a second '\r' to the completed agent session. This violates the skip-after-progress behavior and injects unwanted input.

Suggested fix
   if (now.state === 'blocked' || now.state === 'waiting') {
     return false
   }
+  if (beforeSubmit && turnStartOf(beforeSubmit) !== turnStartOf(now)) {
+    return false
+  }
   if (now.state !== 'working') {
     return true
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*/
export function isSubmitRetryStillOwed(
beforeSubmit: PaneTurnStatus | undefined,
now: PaneTurnStatus | undefined
): boolean {
if (!now) {
return true
}
if (now.state === 'blocked' || now.state === 'waiting') {
return false
}
if (now.state !== 'working') {
return true
}
// Host-stamped turn clocks compared with each other, never with this renderer's clock.
return beforeSubmit?.state === 'working' && turnStartOf(beforeSubmit) === turnStartOf(now)
}
*/
export function isSubmitRetryStillOwed(
beforeSubmit: PaneTurnStatus | undefined,
now: PaneTurnStatus | undefined
): boolean {
if (!now) {
return true
}
if (now.state === 'blocked' || now.state === 'waiting') {
return false
}
if (beforeSubmit && turnStartOf(beforeSubmit) !== turnStartOf(now)) {
return false
}
if (now.state !== 'working') {
return true
}
// Host-stamped turn clocks compared with each other, never with this renderer's clock.
return beforeSubmit?.state === 'working' && turnStartOf(beforeSubmit) === turnStartOf(now)
}

…il a missing plugin can be told apart

Step 2 made a launched OpenCode worker's receipt observable whenever status
hooks were on in settings. But "on in settings" does not mean Orca's OpenCode
plugin loaded: its install can fail silently, and the plugin's first post
arrives only after a real submit (37-49 ms after the Enter, 8/8 panes), so a
plugin that never loaded looks exactly like a stuck brief. On such a host every
OpenCode worker start would have waited about 32 s longer and reported
outcome_unknown for a worker that was working, which is worse than before.

The receipt is back to what main reports for OpenCode (`unsupported`, so the
start is ready). What stays is the useful part of the hook signal: during the
retry delay Orca still watches for a turn this request started, and skips the
retry Enter when it sees one. No post (a stuck brief, or a plugin that never
loaded) simply means the retry goes out, as before. The watch registers the
request only for that wait and always releases it, and a pane that exits during
the wait leaves the first Enter's result standing, with hooks on or off.

The receipt's provider type is back to its previous values, since nothing
needs the widening now.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found in the new commits.

Reviewed changes — incremental re-review of the three commits since the last Pullfrog review at 245572e: deb5c06, f5229ee, 07ff2e5. They close the loop on the retry Enter by making it state-aware on both paths and by making a launched OpenCode worker's receipt honest about whether the task was submitted.

  • The renderer's retry Enter is now gated on reported state. deb5c06 adds agent-submit-retry-guard.ts and wires it into agent-paste-draft.ts: it reads the pane's hook status before the first Enter and again after the row's submitRetryDelayMs, then skips the retry when the pane is waiting/blocked (a permission or question prompt) or when a turn started after the first Enter. With no reported status it stays blind, as before. This reaches every row with a retry delay (codex, opencode, opencode2), not just OpenCode.
  • A launched OpenCode worker's first dispatch now has an observable receipt. f5229ee widens resolveAgentPromptObservedProvider so OpenCode/OpenCode 2 with status hooks on is a settlement provider: the correlation request is registered before the retry wait, an inline observation probe (timeoutMs: submitRetryDelayMs, output evidence disabled) skips the retry when the first Enter already started a turn, and a turn that never starts leaves the existing outcome_unknown receipt instead of a false ready. The receipt's provider type is widened to AgentPromptObservedProvider.
  • Main's permission case is pinned. 07ff2e5 adds a worker-start test where a hook-reported permission prompt after the first Enter suppresses the retry.

I independently traced the register-before-retry ordering against the correlation ledger and the verifier (no spurious turn_started, no mis-attributed claim, no double registration), and re-checked the renderer guard's clock semantics. The guard's remaining blind spots (a working→working new turn for OpenCode, and a turn that completes inside the retry window) are equivalent to or weaker than the blind retry it replaces, and the commit message records the extra Enter as harmless, so I don't consider them defects.

ℹ️ The observable receipt is only in the commit message, not the PR description

The PR description's "What is different for you" and "Mechanism" still describe only the composer wait and the scanner change. They do not mention the retry Enter, and they do not mention that a launched OpenCode/OpenCode 2 worker with hooks on can now settle as turn_start_unobserved / outcome_unknown where main always returned a ready receipt. That is a coordinator-visible behavior change (the tool keeps the terminal and dispatch capability, and a later worker report still settles it), so a reader working from the description will not expect it.

Technical details
# OpenCode's post-write turn observation is undocumented

## Affected sites
- `src/main/runtime/agent-prompt-submission-verification.ts:69` — `resolveAgentPromptObservedProvider`
  returns `opencode`/`opencode2` when `retrySubmitAfterLaunch` and hooks are on, so the receipt is
  `observation: 'supported'` rather than `'unsupported'`.
- `src/main/runtime/rpc/methods/orchestration/worker/worker-start-readiness-settlement.ts:93` — an
  unobserved turn returns `state: 'outcome_unknown'` with `turn_start_unobserved`; main returned
  `ready`.
- `src/shared/tui-agent-config-types.ts:51` — the `submitRetryDelayMs` field and the retry Enter it
  drives are not described either.

## Required outcome
- The description's "What is different for you" and "Mechanism" cover the retry Enter and the
  turn-observed receipt, including that a launched OpenCode worker whose turn is never observed
  now reports `outcome_unknown` (rescuable via a later worker report) instead of a false `ready`.

## Context
- The PR-description staleness flagged earlier was about the Windows gate; this gap is new to
  `245572e`/`f5229ee` and is the only reason I am not approving alongside the clean delta.

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found in the new commits.

Reviewed changes — incremental re-review of the single commit since the prior Pullfrog review at 07ff2e5: d0b92d0, which changes how a launched OpenCode worker's retry Enter is decided and reverts the earlier observable-receipt design.

  • The OpenCode observable receipt is removed. resolveAgentPromptObservedProvider and the AgentPromptObservedProvider type are deleted (net-neutral against main), and settlementAgent is again only antigravity/claude/codex. A launched OpenCode / OpenCode 2 worker's receipt is therefore provider: 'unsupported', observation: 'unsupported' again, so it no longer settles turn_start_unobserved / outcome_unknown the way f5229ee made it. The rationale — a status plugin that never loaded is indistinguishable from a brief stuck in the box — is sound, and it brings the receipt back in line with main.
  • The retry-Enter decision moves into a dedicated helper. observeAgentPromptTurnStartWithin registers the correlation request, runs verifyAgentPromptSubmission (allowOutputEvidence: false) for the row's retry delay, and returns true as soon as this request's turn starts; agent_prompt_stalled means "retry", while any other error rethrows into an outer best-effort catch. The request is always forgotten in finally, so nothing stays queued behind a receipt that does not own the turn.
  • Tests realigned. The rewritten agent-prompt-launch-turn-observation suite pins the skip/retry paths against the unsupported receipt, and the status-hooks mocks the removed provider needed are dropped. I ran both touched suites: agent-prompt-launch-submit-retry (8 tests) and agent-prompt-launch-turn-observation (5 tests) pass.

I traced the register/forget ordering against the correlation ledger and the outer catch: for OpenCode the accepted-unsupported receipt matches main, and codex/claude never reach the helper (render gate / no retry delay), so the settlement path is unchanged. No new issues.

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…-worker-waits-for-input-box

# Conflicts:
#	src/main/runtime/rpc/methods/orchestration/federation/federation.ts
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review status: ready for Brennan's review at 63a7311c839 (not merged; merging is Brennan's call)

The problem. orca orchestration worker-start --agent opencode (or opencode2) reported the worker ready and its task accepted, but OpenCode's input box stayed empty and the task was lost. Orca took a terminal title that only names the agent as "ready", and that title arrives before OpenCode draws its input box; a shell that auto-titles the pane made the loss near-certain. Live QA on main: 10 of 10 briefs lost whenever the shell auto-titled the pane.

What changes for the user. An OpenCode or OpenCode 2 worker started in a fresh terminal now gets its task only once its input box is on screen, on this computer and on a paired host (--on). Because OpenCode 2 ignores an Enter sent before it finishes drawing its input area, Orca presses Enter once more 2 s later, unless it can already see the task was taken or a prompt is waiting. If the box never appears, the start fails loudly after the budget instead of silently losing the task. OpenCode starts return their receipt up to about 2 s later.

Fixed during review (all pushed):

  • worker-start --on <host> still had the original bug (the paired-host attach waited on the title for every agent); it now uses the same input-box wait.
  • The temporary Windows fallback was removed after a Windows capture through Orca's bundled conpty.dll showed the marker arriving at the box in 8 of 8 boots (6 bundled, 2 system ConPTY).
  • Live QA found OpenCode 2 leaving the whole brief unsent in its box under load (2 of 30 starts) while the receipt said accepted; main does this too. Fixed with one extra Enter 2 s later: measured harmless in 60 of 60 runs (including mid-reply), and it rescued 7 of 7 stuck briefs. The same retry now covers the app's own paste-and-submit OpenCode launches (checks fix, quick commands and similar), which had the same bug on main with a 50 ms Enter gap.
  • Codex's existing renderer retry now skips when a question or permission prompt is showing, so neither retry can answer one.
  • A stale production comment repeating a retracted Windows claim; the terminal serialize replay suite baseline for the four new recordings (CI red); PR description corrections.

Tried and backed out. An honest "not submitted" receipt from OpenCode's status plugin. Its install can fail silently, and its first post comes only after a real submit, so a missing plugin and a stuck brief look the same. That would have given every OpenCode start on such a host about 32 s of extra wait and a false "not submitted". The receipt stays as on main.

Deferred (follow-ups, not yet ticketed):

  • An honest receipt, once Orca's OpenCode plugin posts when it loads.
  • Fail at once when the pane's agent is gone. Today a crashed or missing agent fails after the full 60 s with timeout, because the shell keeps the pane alive.
  • Put OpenCode's brief on its launch line.
  • Turn observation on the --on attach.
  • Whether codex worker starts should get the retry.
  • A renderer check that the prompt was taken.
  • Revoke Codex's remaining bracketed-paste anchor.
  • A mimo-code recording.
  • Nits: a scanner doc comment; the retry lines sit in a file that is @ts-nocheck on main too.

Verified:

  • Live on a second Mac, final head vs main, delivery judged in OpenCode's own session store:
    • OpenCode 1.18.32: 10/10 (main 3/8).
    • OpenCode 2.0.18: 10/10 (main 2/8).
    • OpenCode 2.0.18 at load 14–54: 10/10.
    • 2.x installed as plain opencode: 5/5 (main 1/3).
    • Cold launch: 5/5 (main 1/4).
    • Wait-for-setup: delivered, with a receipt of succeeded.
  • Recorded terminal bytes show the retry doing its job: two Enters about 2010 ms apart with hooks off, one when the turn was seen. In one start the first Enter was dropped 55 ms before OpenCode 2 drew its mode row, and the retry submitted it.
  • Five review rounds plus a narrow check, and a readiness checklist on the final diff: no P0 or P1 open.
  • tc:node and tc:web pass at the final head; 122 related test files pass (2939 tests); ablations turn each mechanism's tests red.
  • CI at 63a7311c839 (the final code d0b92d044c1 with main merged in; the merge changed only the brief's text, from main's fix(orchestration): stop minting and printing the dispatch capability #23994): 31 pass, 19 skipped. The three checks listed as failing (persistence, linux_glibc_floor, linux_musl) belong to a duplicate Bun profile persistence run that was cancelled; the same workflow passed on the same commit. GitHub reports the merge state as clean.

Not verified:

  • A live worker-start --on <host> start (unit tests only).
  • An end-to-end Windows worker start (Windows is covered by the capture only).
  • Git Bash, cmd, WSL, Linux, tmux and SSH panes (inferred).
  • The standalone server's Bun.Terminal spawn path.
  • mimo-code.
  • A user typing into a fresh OpenCode pane within the 2 s window: the retry would submit their partial text, as Codex's renderer retry already does.

Main: brief lost (empty box after a start that reported success)

main: OpenCode 2.0.18 input box empty after a start that reported success

Final head under heavy load: the task was submitted (the red line is the free model's own rate-limit reply)

final head: the TASK block submitted in OpenCode 2 under heavy load

This branch has not been deployed

No deployments
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.

[Bug]: Prompt Injection fails if there are delays with loading Opencode

1 participant