Provider manual live tests

Copy each prompt into T3 Code, wait for the outcome, then check the expectations. Prefer a fresh thread per section. Left nav is provider · commit theme. This published copy is static: select a prompt to copy it. The interactive version in the repository adds copy buttons and a light/dark toggle.

Grok · Background primitives

grok · grok-4.6

Grok ACP background primitives (PR #3578 C1 settlement / tools / continuation / images): monitors, spawn_subagent, post-settle wake, steer-during-hold, and image attach. Prefer a fresh thread per full pass.

01

Monitor baseline, in-turn

grok-subagent-monitor

Second turn is the multiturn settlement check.

First turn
send a sample response, and use a monitor that waits 10 seconds and does `ls` (show me the dirs the monitor found)
Second turn (same thread)
send another sample response which uses a monitor that waits 10 seconds and does `ls`  (show me the dirs the monitor found)

Expect

  • Monitor projects as a tool/command item, not a subagent row.
  • Each turn settles once the model replies; a late monitor complete must not corrupt the next turn.
  • No Waiting row or sidebar pill is expected for a persistent Grok monitor.
  • If Grok reports the listing in-turn, no extra Background task completed. wake afterward.
  • If Grok settles first and the CLI injects a monitor-event report, the listing still appears as a final assistant message.
02

Foreground spawn_subagent

grok-subagent-monitor
First turn
Send a short sample response, then use spawn_subagent (general-purpose) with a prompt that:
- sleeps about 5 seconds via shell
- prints exactly the token SUBAGENT_DONE

Do not poll. After starting the subagent, you may reply briefly. When it finishes, fetch output with get_command_or_subagent_output (timeout at least 20000ms) if needed so SUBAGENT_DONE is visible in the thread. End with a short confirmation that includes SUBAGENT_DONE.
Second turn (same thread)
Send another short sample response, and spawn_subagent (general-purpose) again with a prompt that sleeps about 5 seconds and prints exactly SUBAGENT_DONE_2. Fetch with get_command_or_subagent_output if needed, then confirm with SUBAGENT_DONE_2.

Expect

  • Subagent row completes with SUBAGENT_DONE / SUBAGENT_DONE_2; click-through opens the child thread.
  • Child prompt_complete must not terminalize the root turn; root settles after its own reply.
03

Post-settle monitor wake

grok-post-settle-continuation

Watch the thread go idle, then come back (~30s).

Prompt
Start a monitor with this exact command (do not rewrite the sleeps):

for i in 1 2 3 4 5 6 7 8 9 10; do echo STREAM_$i; sleep 3; done; echo STREAM_DONE

Do NOT wait for the monitor to finish. After it starts, reply with a short
message containing the token STARTED and stop. Do not start extra monitors
and do not poll the monitor output in this turn. The point is that your turn
ends while the monitor is still running.

Expect

  • First run settles with STARTED; monitor streams STREAM_N; thread shows idle.
  • No Waiting row or sidebar pill is expected because persistent Grok monitors are intentionally excluded.
  • After STREAM_DONE (~30s), exactly one Background task completed. wake with one concise reply.
  • Monitor card completed with STREAM_N output and exit 0 (not stuck spinning).
  • No burst of wake rows or progress chatter (Still running / monitor event received).
04

Post-settle subagent

grok-post-settle-subagent
Prompt
Live-test post-settle subagent completion.

1) Use spawn_subagent (general-purpose) exactly once, with this subagent prompt:
   Run the shell command: sleep 25 && echo SUB_SETTLE_DONE
   Then return exactly the token SUB_SETTLE_DONE as your final answer.

2) Do NOT wait for the subagent. Immediately after the spawn ACK, reply with a
   short root assistant message that contains the token STARTED and stop.

Do not poll get_command_or_subagent_output in this turn. Do not start monitors
or extra subagents. The point is that the root turn ends while the subagent is
still running.

Expect

  • Root settles with STARTED while subagent row spins; ~25-40s later row completes with SUB_SETTLE_DONE.
  • After root settlement, the timeline shows Waiting on the subagent and the sidebar shows Waiting until it completes.
  • At most one continuation run (no spam).
  • Thread-rendered subagent turn item also flips to completed (not a forever spinner).
05

Steer while run is held open

grok-steer-during-subagent-hold

Start prompt 4, then while still Working send the steer below.

Steer (while run active)
say test 2 now, without waiting on the subagent. When its result arrives later, report the subagent's final token too.

Expect

  • Steer row stays visible from send until committed.
  • Model replies with test 2 promptly (no blocking on the subagent) and the thread returns to idle.
  • After the steer run settles, Waiting remains visible until the carried-over subagent completes.
  • Subagent from prompt 4 still completes (row + turn item leave Running).
  • This-and-also-that: when the subagent finishes (~25-40s), at most one continuation reply reports SUB_SETTLE_DONE, so the thread ends showing both test 2 and the subagent result.
  • No duplicate Background task completed. spam after choosing Steer in a queue dialog.
06

Screenshot attach

manual only

Attach any screenshot to the Grok thread with the prompt below.

Prompt (with image attached)
describe this screenshot briefly

Expect

  • Run completes and the reply describes the image.
  • Pre-fix signature: run fails within ~500ms and no session/prompt is sent.

Grok · Interrupt / Stop

grok · grok-4.6

Grok interrupt / Stop UI pass (PR #3578 C1b process cleanup + settlement interrupt paths). Prefer a new thread per scenario. Headless packs grok-interrupt-fast / grok-interrupt-soak own process identity and ACP lineage; this section is UI-owned (spinner, Stop, queue vs steer, cards, held subagent). Markdown: grok-appimage-interrupt-prompts.md.

Grok can get confused after several interrupt tests in one thread. If you see repeated no-op `true` tool calls instead of an answer, duplicate copies of the same exact reply, a re-surfaced question card after Stop, or a recovery that never settles, Stop the turn and start a new thread with the remaining scenarios. Score the affected attempt model leakage / model-blocked, not a T3 bug (details in grok-appimage-interrupt-prompts.md).

01

Direct Stop during a long command

grok-interrupt-restart

As soon as the assistant says the command started, capture pre-Stop evidence (spinner + visible output), then Stop. Do not wait for a running command card.

Open prompt
Live-test direct Stop. Short preamble only. Then run this exact shell command and wait for it (do not background it): sleep 30 && echo SHOULD_NOT_FINISH_CMD. Keep the turn open until interrupted. Do not print INTERRUPTED_OK.
After Stop (idle)
Live-test after direct Stop. Reply with exactly INTERRUPTED_OK. No tools. Do not mention SHOULD_NOT_FINISH_CMD.

Expect

  • Stop ends the turn cleanly; thread accepts the follow-up.
  • Assistant final text is exactly (or clearly ends with) INTERRUPTED_OK.
  • You never see SHOULD_NOT_FINISH_CMD as command output after Stop.
  • No stuck Working spinner on the interrupted turn.
02

restart_active / steer while a command runs

grok-interrupt-restart

While Working, send the steer with plain Enter / send (steer), not Ctrl/⌘+Enter (queue).

Open prompt
Live-test steer via restart_active. Short preamble only. Remember the codeword BLUE_LANTERN for later; do not print it yet. Then run this exact shell command and wait for it (do not background it): sleep 30 && echo SHOULD_NOT_FINISH_RESTART. Keep the turn open. Do not print RESTART_ACTIVE_OK.
Steer (while Working)
Steer update: stop waiting on that command. Reply with one short line that contains exactly RESTART_ACTIVE_OK and also the codeword I gave you earlier. No tools. Do not mention SHOULD_NOT_FINISH_RESTART.

Expect

  • This-and-also-that: the settled reply contains both RESTART_ACTIVE_OK and BLUE_LANTERN in one message (steer landed and the original turn's context survived the same-session re-prompt).
  • Detach-and-continue: the cancelled command re-runs as a detached task and the model decides its fate. Killing it, ignoring it (output stays in the CLI task file), or polling and reporting it are all fine; SHOULD_NOT_FINISH_RESTART may legitimately appear in a completed command card or task report before the combined reply. Only a missing combined reply or a turn stuck waiting forever is a regression.
  • No permanent dual-Working stuck state.
03

Queue contrast while a command runs (no Stop)

manual only

Queue before the sleep finishes (Ctrl+Enter / ⌘+Enter only). If the command completes with no queued row, re-run.

Open prompt
Live-test queue contrast (no steer). Short preamble only. Then run this exact shell command and wait for it (do not background it): sleep 30 && echo SHOULD_NOT_FINISH_QUEUE_CONTRAST. Keep the turn open. Do not print QUEUE_CONTRAST_OK.
Queued follow-up (Ctrl/⌘+Enter only)
Live-test queued follow-up (queue contrast). Reply with exactly QUEUE_CONTRAST_OK. No tools. Do not mention SHOULD_NOT_FINISH_QUEUE_CONTRAST.

Expect

  • Queued message does not steal the turn mid-command.
  • Prior turn keeps running until it finishes or you explicitly Stop.
  • Not scenario 5 (queue then Stop); desktop hides Stop while queued.
  • Repeated QUEUE_CONTRAST_OK within the follow-up turn is the known no-op tool loop quirk, not a duplicate-run bug, as long as the projection has a single follow-up run.
04

Rapid duplicate Stop

grok-interrupt-duplicate-stop
Open prompt
Live-test direct Stop (stop spam edition). Short preamble only. Then run this exact shell command and wait for it (do not background it): sleep 30 && echo SHOULD_NOT_FINISH_CMD. Keep the turn open until interrupted. Do not print INTERRUPTED_OK.
After double-Stop (idle)
Reply with exactly DUPLICATE_STOP_OK. No tools.

Expect

  • One interrupted turn; no duplicate error card or phantom turn.
  • One settled DUPLICATE_STOP_OK response.
  • If the recovery spins on no-op tool calls and never answers, Stop it and record model-blocked (known quirk), not a T3 failure.
05

Queue a follow-up, then Stop (mobile)

grok-interrupt-queued-followup

Run on mobile. Desktop hides red Stop while anything is queued.

Open prompt
Live-test queue then Stop (mobile). Short preamble only. Then run this exact shell command and wait for it (do not background it): sleep 30 && echo SHOULD_NOT_FINISH_QUEUED_STOP. Keep the turn open until interrupted. Do not print QUEUED_STOP_OK.
Queued follow-up (do not steer)
Live-test after queue then Stop. Reply with exactly QUEUED_STOP_OK. No tools. Do not mention SHOULD_NOT_FINISH_QUEUED_STOP.

Expect

  • Original turn stops; queued message runs once as its own recovery turn.
  • Settles with QUEUED_STOP_OK; no SHOULD_NOT_FINISH_QUEUED_STOP command output after Stop.
  • If the queued recovery spins on no-op tool calls instead of answering, Stop it and record model-blocked (known quirk), not a T3 failure.
06

Stop while approval or question UI is visible (mobile)

manual only

Run on mobile. Desktop hides Stop while an approval/question card is open. Trailing mobile work-log tool rows after Stop are presentation-only if APPROVAL_STOP_OK settles.

Open prompt
Live-test Stop while approval or question is open (mobile). Enter Plan mode if needed, then ask me one trivial thing that surfaces either an approval card or a question card. Keep the turn open on that card. Do not print APPROVAL_STOP_OK yet.
After Stop (idle)
Live-test after approval/question Stop. Reply with exactly APPROVAL_STOP_OK. No tools or further questions.

Expect

  • Card dismisses or is no longer actionable; turn is not stuck Working.
  • Follow-up completes with APPROVAL_STOP_OK.
  • A plain 'No tools.' follow-up can make grok re-surface a fresh question card instead of answering (known quirk sibling); the extended 'or further questions' wording heads that off. If a recovery re-asks anyway, Stop and resend with the extended wording.
07

Stop while a subagent is running

grok-interrupt-subagent-hold
Open prompt
Live-test interrupt while a subagent holds the root prompt open.

1) Use spawn_subagent (general-purpose) exactly once, with this subagent prompt:
   Run the shell command: sleep 30 && echo HOLD_SHOULD_NOT_MATTER
   Then return exactly the token HOLD_SUB_DONE as your final answer.

2) Wait for that subagent and do not return a root answer before it finishes.

Do not start another tool or subagent.
After Stop (idle)
Reply with exactly HOLD_FOLLOW_OK. No tools.

Expect

  • Follow-up yields HOLD_FOLLOW_OK (literal <|eos|> suffix is model leakage, not a fail).
  • No endless dual spinner with no way to send.
  • Subagent row interrupted; no HOLD_SUB_DONE or HOLD_SHOULD_NOT_MATTER.
08

Steer a settled held turn, then Stop (orphan containment)

manual only

Covers Stop after a soft steer already cleared the active turn while a subagent carried over (fix/grok-v2 review-round fixes): the runtime must die, the carried-over subagent must terminalize with its streamed text, and the thread must recover on a fresh session. Press Stop only after STEER_OK settles and the subagent row alone is still spinning.

Open prompt
Live-test Stop after steering a settled turn that still holds a subagent.

1) Use spawn_subagent (general-purpose) exactly once, with this subagent prompt:
   First print exactly the token SUB_PROGRESS_1 on its own line. Then run the shell command: sleep 60 && echo HOLD_SHOULD_NOT_MATTER
   Then return exactly the token HOLD_SUB_DONE as your final answer.

2) Reply immediately with exactly the token ROOT_SETTLED and do not wait for the subagent.

Do not start another tool or subagent.
Steer while held (plain Enter)
Reply with exactly STEER_OK. No tools.
After Stop (idle)
Reply with exactly ORPHAN_FOLLOW_OK. No tools.

Expect

  • Subagent row keeps spinning through the steer and STEER_OK lands (soft steer preserves the runtime).
  • On Stop, the subagent row becomes interrupted promptly; never a permanent spinner.
  • Interrupted subagent card still shows SUB_PROGRESS_1; never HOLD_SUB_DONE or HOLD_SHOULD_NOT_MATTER.
  • Composer stays unlocked; follow-up yields ORPHAN_FOLLOW_OK on a fresh session.

Claude · Background / resume

claudeAgent · claude-sonnet-5

Claude Agent SDK background Bash, Task/Agent subagents, Monitor, post-settle wake, and SendMessage resume. Claude/Codex C1 work is merged into t3code/codex-turn-mapping; these prompts still validate the stack in the UI.

01

Background Bash, settles in-turn

claude-background-bash-inturn
Prompt
Live-test background Bash that settles in-turn.

1) Run this command using the Bash tool with run_in_background set to true:
   sleep 8 && echo BG_INTURN_DONE
2) Poll the background task with TaskOutput (block: true, generous timeout)
   until it completes, then quote its output in your reply.
3) End your final assistant message with ALL_DONE.

Do not spawn subagents or monitors. Keep prose short.

Expect

  • One completed run; quotes BG_INTURN_DONE; ends ALL_DONE.
  • Bash is a normal command/tool item, not a subagent row.
  • No Waiting row or sidebar pill appears because the task completes before root settlement.
  • No Background task completed. message (finished in-turn).
02

Background Bash, post-settle wake

claude-background-bash-wake

Watch the root turn settle into Waiting, then wake (~20-45s).

Prompt
Live-test post-settle background Bash wake.

1) Run this command using the Bash tool with run_in_background set to true:
   sleep 20 && echo BG_WAKE_DONE
2) Immediately after starting it, reply with a short message containing the
   token STARTED and stop.

Do NOT poll TaskOutput. Do NOT wait for the task. Do not spawn subagents or
monitors. The point is that your turn ends while the command is still running.

Expect

  • First run settles with STARTED; the timeline shows Waiting on the Bash task and the sidebar shows Waiting.
  • One agent-authored wake user message for the completed background command.
  • Waiting clears when the task completes; the wake assistant reports BG_WAKE_DONE and the Bash turn item flips to completed.
  • No spam wakes, ghost history, or forever-spinning command item.
03

Foreground subagent

claude-subagent
Prompt
Live-test foreground subagent projection.

1) Spawn exactly one general-purpose subagent using the Task tool (also called
   Agent), in the foreground (do NOT set run_in_background), with this subagent
   prompt:
   Run the shell command: sleep 3 && echo SUBAGENT_DONE
   Then return exactly the token SUBAGENT_DONE as your final answer.
2) Wait for the subagent to finish.
3) End your final root assistant message with ALL_DONE.

Do not start background Bash tasks or monitors. Keep prose short.

Expect

  • Subagent row completes with SUBAGENT_DONE; click-through opens child thread.
  • No raw Agent tool-call item in the parent turn.
  • No Waiting row or sidebar pill appears because the root remains active until the foreground subagent completes.
04

Monitor tool

claude-monitor
Prompt
Live-test the Monitor tool projection.

1) Use the Monitor tool (persistent: false, timeout_ms at least 60000) with
   this command:
   for i in 1 2 3; do sleep 3; echo "MON_LINE_$i"; done; echo MON_DONE
2) Wait for the monitor to finish (use TaskOutput with block: true if needed)
   and quote the final line of its output in your reply.
3) End your final assistant message with ALL_DONE.

If the Monitor tool is not available to you, instead say exactly
MONITOR_TOOL_UNAVAILABLE and stop. Do not spawn subagents. Keep prose short.

Expect

  • Monitor projects as a completed dynamic tool (often after ToolSearch), not a subagent.
  • Assistant quotes MON_DONE and ends ALL_DONE.
  • No Waiting row or sidebar pill appears because the monitor completes before root settlement.
05

Background subagent, post-settle

claude-post-settle-subagent
Prompt
Live-test post-settle background subagent.

1) Spawn exactly one general-purpose subagent using the Task tool (also called
   Agent) with run_in_background set to true, with this subagent prompt:
   Run the shell command in the foreground and wait for it to finish:
   sleep 25 && echo SUB_SETTLE_DONE
   Do not use run_in_background for the shell command. Only after the command
   has printed SUB_SETTLE_DONE, return exactly the token SUB_SETTLE_DONE as
   your final answer, with no other text.
2) Do NOT wait for the subagent. Immediately after spawning it, reply with a
   short root assistant message containing the token STARTED and stop.

Do not poll TaskOutput in this turn. Do not start background Bash tasks or
monitors. The point is that the root turn ends while the subagent is still
running.

Expect

  • Root settles with STARTED; subagent row keeps spinning.
  • The timeline and sidebar show Waiting until the background subagent completes.
  • One continuation; trigger carries SUB_SETTLE_DONE (not only generic Background task completed.).
  • Waiting clears; the subagent row + turn item complete with the final answer (not ACK JSON).
06

Resume completed subagent (SendMessage)

claude-resume-subagent
Prompt
Live-test resuming a completed background subagent.

1) Spawn exactly one general-purpose subagent using the Task tool (also called
   Agent) with run_in_background set to true, with this subagent prompt:
   Reply with exactly the token FIRST_DONE and nothing else. If you later
   receive a follow-up message telling you to continue, run this shell command
   in the foreground and wait for it (do not background it):
   sleep 20 && echo RESUME_DONE
   and only after it prints RESUME_DONE, return exactly the token RESUME_DONE
   as your final answer, with no other text.
2) Wait for the subagent to complete its first answer (use TaskOutput with
   block: true if needed).
3) Send the subagent a follow-up using the SendMessage tool with the message:
   Continue: run the sleep command now and return the token.
   If the SendMessage tool is unavailable, reply with exactly
   SENDMESSAGE_UNAVAILABLE and stop.
4) Immediately after sending the follow-up, reply with a short root assistant
   message containing the token NUDGED and stop. Do NOT wait for the resumed
   subagent; the point is that your turn ends while it is running again.

Do not start background Bash tasks or monitors. Keep prose short.

Expect

  • Row completes FIRST_DONE, re-opens running on nudge; root settles with NUDGED.
  • After NUDGED settles, the timeline and sidebar show Waiting until the resumed subagent completes.
  • Later continuation carries RESUME_DONE; row + turn item complete.
  • Waiting clears after the resumed subagent reaches its terminal state.
  • An intermediate CLI autonomous turn with generic Background task completed. is OK if the final result is RESUME_DONE.
07

App-owned delegated child wakes the parent

claude-delegated-task-wake

App-owned delegation, not a provider-native subagent. This is the one path where the parent has no adapter-buffered wake output, so the wake text itself must reach the model.

Prompt
Live-test delegated child wake.

1) Use the t3-code delegate_task tool exactly once, with mode async and
   target providerInstanceId grok, delegating this exact task to the child:
   Reply with exactly CHILD_DONE and nothing else. Do not use any tools.
2) Immediately after delegate_task returns, reply with exactly STARTED and
   end your turn.
3) Do NOT call task_status in that first turn. Do NOT poll, wait, sleep, or
   spawn any watcher, Monitor, or background Bash task.
4) If you are later woken and told the delegated task completed, call
   task_status once for that taskId, then reply with exactly
   WOKE: followed by the child's result text, and end that turn.

Expect

  • Root settles with STARTED while the delegated child row is still running.
  • Timeline and sidebar show Waiting after the root settles, not Ready.
  • The thread wakes on its own: a later run appears with no user input.
  • That wake run must contain real model output, not just the injected message. A wake run that lasts well under a second and shows only the Delegated task ... completed line means the wake text never reached the provider.
  • The woken turn ends with WOKE: CHILD_DONE, proving the model read the child result.
  • Waiting clears and exactly one wake run appears, with no second wake.
  • The wake run reaches a terminal state on its own. A wake run that stays Working indefinitely after the model has clearly answered means its terminal result was discarded; the tell is that anything you send next queues behind it and never starts, needing one Stop per queued run.
08

Waiting on mobile, feed row and list pill (mobile)

claude-background-bash-wake

Run on the phone, against the same paired environment. The two mobile Waiting surfaces read different sources: the thread-list pill uses the server-derived shell roster, while the timeline row derives from the live projection. Checking only one of them will miss a disagreement between them, which is the failure mode worth catching here. A minute is long enough to look at both without rushing.

Prompt
Live-test mobile Waiting surfaces.

1) Run this command using the Bash tool with run_in_background set to true:
   sleep 60 && echo MOBILE_WAITING_DONE
2) Immediately after starting it, reply with a short message containing the
   token STARTED and stop.

Do NOT poll TaskOutput. Do NOT wait for the task. Do not spawn subagents or
monitors. The point is that your turn ends while the command is still running.

Expect

  • The turn settles with STARTED, and a Waiting row appears under that reply naming the background command. It must not read Ready.
  • The label is clamped to two lines. A subagent description is the whole child prompt, so an unclamped label would fill the screen.
  • Back on the thread list, the same thread shows a muted Waiting pill. The two surfaces must agree; a pill with no row, or a row with no pill, is the finding.
  • Both clear once the command completes and the wake lands.
  • Check whether Stop is still offered while Waiting. The roster parks the runtime at idle, so Stop can disappear even though background work is outstanding. Record what you see either way; this is the mobile consequence of idle parking and it has no mobile test.
  • Force-quit the app while Waiting is showing, reopen, and go straight to the thread. The row must not reappear from cache before the detail is live again, because a cached projection can outlive the task it describes.
09

Delegated child follow-up exposes pending work

manual only

App-owned child follow-up, not a provider-native subagent resume. The first task_status call must happen before the 25-second child command finishes. If it does not, retry in a fresh thread.

Prompt
Live-test delegated follow-up status. Do exactly this in order.

1) Load the t3-code delegate_task, t3_thread_send, and task_status tools.
2) Call delegate_task exactly once with mode wait, timeoutMs 60000, target providerInstanceId grok, and this exact child task:
   Reply with exactly STATUS_FIRST_DONE and nothing else. Do not use tools.
3) After it completes, use its childThreadId with t3_thread_send mode queue. Send this exact follow-up:
   Run this exact foreground shell command and wait for it: sleep 25. After it finishes, reply with exactly STATUS_SECOND_DONE and nothing else.
4) Immediately call task_status exactly once with the original taskId. Do not wait for the follow-up first.
5) Reply with STATUS_OBSERVED followed by the exact task_status JSON, then end the turn.
6) If you are later woken for this child, call task_status exactly once again and reply with STATUS_FINAL followed by the exact JSON. Do not start other work.

Expect

  • The STATUS_OBSERVED JSON keeps childRunId, status, summary, and resultContextTransferId tied to completed ordinal 1 with STATUS_FIRST_DONE.
  • hasPendingChildRuns is true while ordinal 2 is queued, running, or waiting.
  • latestTerminal* selects completed ordinal 1 with STATUS_FIRST_DONE while ordinal 2 is still pending.
  • The later wake ends with STATUS_FINAL. Primary fields still select completed ordinal 1, hasPendingChildRuns is false, and latestTerminal* selects completed ordinal 2 with STATUS_SECOND_DONE.
  • Pre-fix failure: STATUS_OBSERVED has no field distinguishing the completed original task from a child thread that is still working.

Claude · Interrupt / Stop

claudeAgent · claude-sonnet-5

Claude direct Stop and post-Stop recovery coverage from PR #4229, plus mid-turn steer coverage. The first scenario mirrors claude-interrupt-fast. The second recreates the pending task-notification race that previously made the first recovery request disappear from T3 Code. Scenarios 4 and 5 cover steering a turn while a command runs, and stopping work a steer introduced. Use a fresh thread per scenario. Markdown: claude-appimage-interrupt-prompts.md.

01

Direct Stop with two sequential recoveries

claude-interrupt-direct-stop

Stop only after the foreground command is visibly running. Send recovery 1 after the thread returns to idle, then send recovery 2 only after recovery 1 settles.

Open prompt
Live-test Claude direct Stop dual recovery. Short preamble only. Then call Bash exactly once with run_in_background false and wait for this exact command: bash -c 'sleep 30 & child=$!; wait "$child"; echo SHOULD_NOT_FINISH_CLAUDE_STOP'. Do not retry or background it. Keep the turn open until interrupted. Do not print either recovery token.
Recovery 1 (after Stop and idle)
Reply with exactly CLAUDE_RECOVERY_ONE_OK. No tools.
Recovery 2 (after recovery 1 settles)
Reply with exactly CLAUDE_RECOVERY_TWO_OK. No tools.

Expect

  • The original turn becomes interrupted and its command card stops spinning.
  • Recovery 1 remains visible and receives its own CLAUDE_RECOVERY_ONE_OK assistant response; it must not disappear or complete blank.
  • Recovery 2 remains visible and receives a later, separate CLAUDE_RECOVERY_TWO_OK response.
  • SHOULD_NOT_FINISH_CLAUDE_STOP never appears as command output after Stop.
  • The thread ends idle with no ghost assistant row or stuck Working state.
02

Pending task notification crosses Stop

manual only

Regression-specific manual race. Stop while the background subagent and foreground command are both still running, then send recovery 1 immediately.

Open prompt
Live-test Claude task notification crossing Stop.

1) Spawn exactly one general-purpose subagent using the Task tool (also called Agent) with run_in_background set to true. Give it this prompt:
   Run the foreground shell command: sleep 12 && echo PRESTOP_TASK_DONE
   Then return exactly PRESTOP_TASK_DONE.
2) Do not wait for or poll the subagent. Immediately call Bash exactly once with run_in_background false and wait for this exact command:
   bash -c 'sleep 30 & child=$!; wait "$child"; echo SHOULD_NOT_FINISH_CLAUDE_RACE'
   Do not retry or background it.
3) Keep the root turn open until interrupted. Do not print either recovery token.
Recovery 1 (immediately after Stop)
Reply with exactly CLAUDE_RACE_RECOVERY_ONE_OK. No tools.
Recovery 2 (after recovery 1 settles)
Reply with exactly CLAUDE_RACE_RECOVERY_TWO_OK. No tools.

Expect

  • Recovery 1 stays visible and settles with CLAUDE_RACE_RECOVERY_ONE_OK even if PRESTOP_TASK_DONE arrives before or during it.
  • A task notification may update the interrupted subagent row or produce a provider continuation, but it must not terminalize recovery 1 blank.
  • Recovery 2 settles separately with CLAUDE_RACE_RECOVERY_TWO_OK.
  • SHOULD_NOT_FINISH_CLAUDE_RACE never appears as command output after Stop.
  • No permanently spinning subagent, command card, or Working state remains.
03

Stop while a foreground subagent is running

manual only

Stop only after the foreground Task row is visibly running. This isolates subagent terminalization from the background task-notification race in scenario 2.

Open prompt
Live-test Claude Stop while a foreground subagent holds the root turn.

1) Spawn exactly one general-purpose subagent using the Task tool (also called Agent), in the foreground, with this prompt:
   Call Bash exactly once with run_in_background false and wait for this exact command: bash -c 'sleep 30 & child=$!; wait "$child"; echo SHOULD_NOT_FINISH_CLAUDE_SUBAGENT_STOP'. Do not retry or background it.
   Then return exactly CLAUDE_SUBAGENT_HOLD_DONE.
2) Wait for that subagent. Do not start other tools or return a root answer before it finishes.
Recovery (after Stop and idle)
Reply with exactly CLAUDE_SUBAGENT_STOP_RECOVERY_OK. No tools or further questions.

Expect

  • The root turn becomes interrupted and the foreground subagent row becomes terminal, never permanently running.
  • Neither CLAUDE_SUBAGENT_HOLD_DONE nor SHOULD_NOT_FINISH_CLAUDE_SUBAGENT_STOP appears after Stop.
  • Recovery settles on a distinct run with CLAUDE_SUBAGENT_STOP_RECOVERY_OK and does not complete blank.
  • The thread ends idle with no ghost assistant row or stuck Working state.
04

Steer a long turn twice

manual only

Timing is the whole scenario: each steer must be sent while a command is actually running, not between commands. Send steer 1 while the first command runs, then steer 2 while a later command runs. Watch the sidebar status and the run count, not just the final text. A steer delivered at the moment a reply was already due can supersede that reply; that is the model choosing, not a lost message, so judge by run count and status rather than by one missing token.

Open prompt
Live-test mid-turn steer output retention.

Do exactly this, in order, all in this one turn:

1) Run this foreground shell command and wait for it:
   sleep 10 && echo STEER_A
   Then reply with a short line containing exactly STEER_A.
2) Run this foreground shell command and wait for it:
   sleep 10 && echo STEER_B
   Then reply with a short line containing exactly STEER_B.
3) Run this foreground shell command and wait for it:
   sleep 10 && echo STEER_C
   Then reply with a short line containing exactly STEER_C.
4) Finally reply with exactly STEER_BASE_DONE.

Do not use run_in_background, Monitor, or subagents.
If you receive extra instructions while working, honor them at the end.
Steer 1 (send right after STEER_A appears)
Also, at the very end after STEER_BASE_DONE, reply with exactly STEER_EXTRA_1.
Steer 2 (send once steer 1 looks unanswered)
And after STEER_EXTRA_1, reply with exactly STEER_EXTRA_2 as your final line.

Expect

  • One run carries the whole turn. Both steers are accepted and every token the steers asked for appears under that one run.
  • The sidebar row stays Working from the first command through the last reply. It must never go blank mid-turn.
  • The second steer is accepted while the agent is visibly working. A refusal saying the thread has no running turn that can be steered is a failure.
  • No extra Background task completed. run appears. A continuation run carrying the steer's answer means the run settled early and the answer had to be rescued.
  • The turn ends only after the last steered reply, not moments after a steer is delivered.
  • Diagnostic: compare the assistant text in the thread against what the agent actually did (commits pushed, files written). Output present in the world but absent from the thread is the failure this scenario exists to catch.
  • Before the mid-turn steer fix this failed reliably: the run went terminal within about 75ms of the steer being delivered, the sidebar went blank while work continued, and the second steer was refused. Tracked in tasks/fix-orphaned-output-after-early-settle.
05

Stop while steered work is running

manual only

Covers Stop landing on work that a steer introduced, rather than on the turn's original command. Steer while the first command runs, wait for the steered command to start, then press Stop.

Open prompt
Live-test Stop during steered work. Short preamble only. Then call Bash exactly once with run_in_background false and wait for this exact command: bash -c 'sleep 20 & child=$!; wait "$child"; echo CLAUDE_STEER_STOP_A'. Then reply with exactly CLAUDE_STEER_STOP_A_OK. Do not retry or background the command. Do not spawn subagents.
Steer (send while the first command runs)
Additional instruction. After the current command finishes, call Bash once more with run_in_background false and wait for this exact command: bash -c 'sleep 40 & child=$!; wait "$child"; echo SHOULD_NOT_FINISH_CLAUDE_STEER_STOP'. Then reply with exactly CLAUDE_STEER_STOP_B_OK.
Recovery (after Stop and idle)
Reply with exactly CLAUDE_STEER_STOP_RECOVERY_OK. No tools.

Expect

  • The steered second command starts, proving the steer was taken and the turn stayed alive across it.
  • Stop terminalizes the turn promptly as interrupted; the command card stops spinning and no Working state persists.
  • SHOULD_NOT_FINISH_CLAUDE_STEER_STOP and CLAUDE_STEER_STOP_B_OK never appear after Stop.
  • No continuation run opens after Stop; interrupt closes the query, so there is no late wake.
  • Recovery settles on its own run with CLAUDE_STEER_STOP_RECOVERY_OK and does not complete blank.

Codex · Background / resume

codex · gpt-5.6-terra medium

Codex app-server settlement, collab subagents, background exec wake, and resume. Codex C1 is merged into t3code/codex-turn-mapping. If the model daemonizes with nohup/& despite instructions, retry (model miss).

01

Baseline settlement + second turn

codex-settlement
First turn
Live-test baseline settlement.

1) Run this shell command and quote its output in your reply:
   echo CODEX_SETTLE_MARK
2) End your final assistant message with SETTLE_DONE.

Do not spawn sub-agents or collaborator agents. Do not start background or
long-running commands. Keep prose short.
Follow-up
Reply with exactly SECOND_DONE and nothing else.

Expect

  • Quotes CODEX_SETTLE_MARK, ends SETTLE_DONE, then SECOND_DONE.
  • Shell is a normal command item, not a subagent row.
02

Foreground collab subagent

codex-subagent
Prompt
Live-test foreground sub-agent projection.

1) Spawn exactly one collaborator sub-agent (your agent-spawning tool), with
   this task:
   Run the shell command: sleep 3 && echo CODEX_SUB_DONE
   Then return exactly the token CODEX_SUB_DONE as your final answer.
2) Wait for the sub-agent to finish and quote its result in your reply.
3) End your final root assistant message with ALL_DONE.

If you have no tool for spawning sub-agents or collaborator agents, reply with
exactly SUBAGENT_TOOL_UNAVAILABLE and stop. Do not start background or
long-running commands yourself. Keep prose short.

Expect

  • Subagent row completes with CODEX_SUB_DONE; child thread opens on click.
  • Root ends ALL_DONE; no raw collab tool item in parent turn.
03

Fire-and-forget subagent, post-settle

codex-post-settle-subagent
Prompt
Live-test post-settle sub-agent completion.

1) Spawn exactly one collaborator sub-agent (your agent-spawning tool), with
   this task:
   Run the shell command in the foreground and wait for it to finish:
   sleep 25 && echo CODEX_SUB_SETTLE_DONE
   Only after it prints CODEX_SUB_SETTLE_DONE, return exactly the token
   CODEX_SUB_SETTLE_DONE as your final answer, with no other text.
2) Do NOT wait for the sub-agent. Do not call any wait tool. Immediately after
   spawning it, reply with a short root assistant message containing the token
   STARTED and stop.

If you have no tool for spawning sub-agents or collaborator agents, reply with
exactly SUBAGENT_TOOL_UNAVAILABLE and stop. The point is that your root turn
ends while the sub-agent is still running. Keep prose short.

Expect

  • Root settles with STARTED; subagent keeps spinning.
  • The timeline and sidebar show Waiting until the subagent completes.
  • ~25-40s later row + turn item complete with CODEX_SUB_SETTLE_DONE (no wake required for subagents).
04

Background command, post-settle wake

codex-background-exec-wake

Main Codex wake path. Watch the root settle into Waiting, then wake.

Prompt
Live-test background command wake.

1) Start this command as a background / long-running process that you do NOT
   wait for, using your own built-in background execution facility (run the
   command itself and let it keep running past your turn):
   sleep 20 && echo CODEX_BG_WAKE_DONE
2) Immediately after starting it, reply with a short message containing the
   token STARTED and stop.
3) Later, if you are woken with the result of the background command, reply
   with a short message that quotes the command output verbatim (it contains
   a token) and stop.

Do NOT wait for the command to finish. Do not poll its output. Do not spawn
sub-agents. Do not daemonize it yourself with nohup, setsid, disown, "&", or
output redirection to a file; the command must stay tracked by you as a
running command. The point is that your turn ends while the command is still
running. If you have no way to keep a command running in the background after
your turn ends, reply with exactly BG_UNSUPPORTED and stop. Keep prose short.

Expect

  • First run settles with STARTED; the command item keeps spinning and the timeline and sidebar show Waiting.
  • Waiting clears when one wake run quotes CODEX_BG_WAKE_DONE and the command item flips to completed.
  • The wake is a work-log row (Background task finished), not a right-aligned user bubble.
  • Exactly one wake; no forever spinner after wake.
05

Two background commands, two wakes

manual only

Manual only.

Prompt
Live-test two background command wakes.

1) Start these two commands as background / long-running processes that you
   do NOT wait for, using your own built-in background execution facility
   (run the commands themselves and let them keep running past your turn):
   sleep 20 && echo CODEX_BG_TWO_FIRST_DONE
   sleep 40 && echo CODEX_BG_TWO_SECOND_DONE
2) Immediately after starting both, reply with a short message containing the
   token STARTED and stop.
3) Later, each time you are woken with the result of a background command,
   reply with a short message that quotes that command's output verbatim (it
   contains a token) and stop.

Do NOT wait for the commands to finish. Do not poll their output. Do not
spawn sub-agents. Do not daemonize them with nohup, setsid, disown, "&", or
output redirection to a file; both commands must stay tracked by you as
running commands. The point is that your turn ends while both commands are
still running. If you have no way to keep a command running in the background
after your turn ends, reply with exactly BG_UNSUPPORTED and stop. Keep prose
short.

Expect

  • After root settlement, Waiting reports two background tasks.
  • Two wakes in order: FIRST then SECOND tokens.
  • After the first completion, Waiting remains for the second task, then clears after the second completion.
  • Both command items end completed; second does not stick running after first wake.
06

Background command + fire-and-forget subagent

manual only

Manual only.

Prompt
Live-test a background command plus a fire-and-forget sub-agent in one turn.

1) Start this command as a background / long-running process that you do NOT
   wait for, using your own built-in background execution facility:
   sleep 20 && echo CODEX_BG_MIX_CMD_DONE
2) Spawn exactly one collaborator sub-agent (your agent-spawning tool), with
   this task:
   Run the shell command in the foreground and wait for it to finish:
   sleep 35 && echo CODEX_BG_MIX_SUB_DONE
   Only after it prints CODEX_BG_MIX_SUB_DONE, return exactly the token
   CODEX_BG_MIX_SUB_DONE as your final answer, with no other text.
3) Do NOT wait for either of them. Do not call any wait tool. Immediately
   after starting both, reply with a short root assistant message containing
   the token STARTED and stop.
4) Later, if you are woken with the result of the background command, reply
   with a short message that quotes the command output verbatim and stop.

Do not daemonize the command with nohup, setsid, disown, "&", or output
redirection to a file. If you have no way to keep a command running in the
background after your turn ends, reply with exactly BG_UNSUPPORTED and stop.
If you have no tool for spawning sub-agents, reply with exactly
SUBAGENT_TOOL_UNAVAILABLE and stop. The point is that your turn ends while
both are still outstanding. Keep prose short.

Expect

  • After root settlement, Waiting reports two background tasks.
  • Exactly one wake (for the command) quoting CODEX_BG_MIX_CMD_DONE.
  • Waiting remains for the subagent after the command completes, then clears when the subagent completes in place with CODEX_BG_MIX_SUB_DONE (no second wake).
07

Resume a completed subagent

codex-resume-subagent
Prompt
Live-test resuming a completed sub-agent.

1) Spawn exactly one collaborator sub-agent (your agent-spawning tool), with
   this task:
   Reply with exactly the token CODEX_FIRST_DONE and nothing else. If you
   later receive a follow-up message telling you to continue, run this shell
   command in the foreground and wait for it to finish:
   sleep 20 && echo CODEX_RESUME_DONE
   and only after it prints CODEX_RESUME_DONE, return exactly the token
   CODEX_RESUME_DONE as your final answer, with no other text.
2) Wait for the sub-agent to return its first answer.
3) Send the sub-agent this follow-up message:
   Continue: run the sleep command now and return the token.
4) Do NOT wait for the resumed sub-agent. Immediately after sending the
   follow-up, reply with a short root assistant message containing the token
   NUDGED and stop.

If you have no tool for spawning sub-agents, reply with exactly
SUBAGENT_TOOL_UNAVAILABLE and stop. If you cannot send a follow-up message to
a finished sub-agent, reply with exactly RESUME_UNSUPPORTED and stop. The
point is that your root turn ends while the sub-agent is working again. Keep
prose short.

Expect

  • Row completes CODEX_FIRST_DONE, root NUDGED, row re-opens then completes CODEX_RESUME_DONE.
  • After NUDGED settles, Waiting appears for the resumed subagent and clears when CODEX_RESUME_DONE arrives.
  • No wake required for subagent completion (row updates in place).
08

Background command completes in-turn (no wake)

manual only

Negative control: manual only.

Prompt
Live-test a background command that finishes before your turn ends.

1) Start this command as a background / long-running process using your own
   built-in background execution facility (no nohup, no "&"):
   sleep 5 && echo CODEX_BG_INTURN_DONE
2) After starting it, wait for it to finish and quote its output in your
   reply.
3) End your final assistant message with ALL_DONE.

Do not spawn sub-agents. Keep prose short.

Expect

  • One completed run; quotes CODEX_BG_INTURN_DONE; ends ALL_DONE.
  • No Waiting row or sidebar pill appears because the command completes before root settlement.
  • After idle, no spontaneous second run for ~30s.
09

Queue while foreground tools continue

manual only

After ACTIVE_TURN_STARTED appears and the first command is running, send the follow-up with Ctrl+Enter / ⌘+Enter so it queues.

Open prompt
Live-test active timeline visibility while a follow-up is queued.

1) Before using tools, send a short progress update containing exactly
   ACTIVE_TURN_STARTED.
2) Run this exact command in the foreground and wait for it:
   sleep 20 && echo ACTIVE_TOOL_ONE_DONE
3) Then run this exact command in the foreground and wait for it:
   sleep 10 && echo ACTIVE_TOOL_TWO_DONE
4) Then run this exact command in the foreground and wait for it:
   sleep 15 && echo ACTIVE_TOOL_THREE_DONE
5) End your final answer with exactly ACTIVE_TURN_FINISHED.

Do not background either command. Do not skip the progress update. Keep
all other prose short.
Queued follow-up (Ctrl/⌘+Enter only)
Reply with exactly QUEUED_FOLLOWUP_DONE and nothing else. No tools.

Expect

  • The queue panel shows one queued follow-up while the original turn remains active.
  • ACTIVE_TURN_STARTED and completed foreground command rows remain visible; the original turn must not collapse into a Worked for row before ACTIVE_TURN_FINISHED.
  • The second command row appears normally after the follow-up was queued, while the third command keeps the original turn active.
  • QUEUED_FOLLOWUP_DONE starts only after ACTIVE_TURN_FINISHED and runs exactly once.
  • After the original turn settles, its normal Worked for fold may appear.
10

Background wake stays off the Queued chip

manual only

Send the follow-up with ordinary Send as soon as STARTED is visible and the first run is idle. Do not wait extra. If a wake already started while idle, abort and use a fresh thread. The wake should queue behind the live sleep 45.

Open prompt
Live-test Codex queued-chip hide.

Do exactly this, in order, no extra steps.

1) Start this command as a background / long-running process that you do NOT
   wait for, using your own built-in background execution facility:
   sleep 30; echo CODEX_BG_FAIL; exit 1
2) Immediately after starting it, reply with a short message containing the
   token STARTED and stop.
3) Later, if you are woken with the result of the background command, reply
   with a short message that quotes the command output verbatim (it contains
   CODEX_BG_FAIL) and stop.

Do NOT wait for the command to finish. Do not poll its output. Do not spawn
sub-agents. Do not daemonize it with nohup, setsid, disown, "&", or output
redirection to a file. If you have no way to keep a command running after
your turn ends, reply with exactly BG_UNSUPPORTED and stop. Keep prose short.
Follow-up (ordinary Send after STARTED)
Run this in the foreground and wait until it finishes:
sleep 45 && echo CODEX_FG_DONE
When it finishes, reply with a short message containing FG_DONE and the
CODEX_FG_DONE token. Do not mention, fetch, or wait on any background
command unless this prompt itself includes that command output.

Expect

  • First run settles with STARTED; the background command is still running.
  • The follow-up sleep 45 starts immediately and keeps a live turn.
  • When the background command finishes, a wake may sit queued. The composer Queued chip stays empty: no Steer, reorder, or X for that wake.
  • After the sleep, one continuation quotes CODEX_BG_FAIL.
  • The wake is a work-log row (Background task finished), not a right-aligned user bubble.
11

Two background commands coalesce into one wake

manual only

Send the follow-up with ordinary Send as soon as STARTED is visible. Do not wait extra. If either command already woke while idle, abort and use a fresh thread. Idle sequential completions (scenario 5) can still produce two wakes.

Open prompt
Live-test Codex wake coalesce.

Do exactly this, in order, no extra steps.

1) Start BOTH of these as background / long-running processes that you do NOT
   wait for, using your own built-in background execution facility:
   sleep 25; echo CODEX_BG_A; exit 1
   sleep 35; echo CODEX_BG_B
2) Immediately after starting both, reply with a short message containing the
   token STARTED and stop.
3) Later, if you are woken with background-command results, reply with a short
   message that quotes every token you were given (CODEX_BG_A and/or
   CODEX_BG_B) and stop.

Do NOT wait for either command to finish. Do not poll. Do not spawn
sub-agents. Do not daemonize with nohup, setsid, disown, "&", or file
redirection. If you cannot background them, reply BG_UNSUPPORTED and stop.
Keep prose short.
Follow-up (ordinary Send after STARTED)
Run this in the foreground and wait until it finishes:
sleep 50 && echo CODEX_FG_DONE
When it finishes, reply with a short message containing FG_DONE and the
CODEX_FG_DONE token. Do not mention, fetch, or wait on any background
command unless this prompt itself includes that command output.

Expect

  • First run settles with STARTED; both background commands are still running.
  • The follow-up sleep 50 starts immediately and keeps a live turn.
  • Both command completions fold into one queued wake. The composer Queued chip stays empty.
  • After the sleep, one continuation quotes both CODEX_BG_A and CODEX_BG_B.
  • The wake is a work-log row (2 background tasks finished), not two user bubbles.

Codex · Interrupt / Stop

codex · gpt-5.6-terra low

Codex direct Stop and two-message recovery coverage from PR #4229. This mirrors codex-interrupt-fast and provides a provider comparison for the Claude missing-first-recovery regression. Use a fresh thread. This manual scenario validates recovery and visible projection only; use the headless pack for process-containment proof. Markdown: codex-appimage-interrupt-prompts.md.

01

Direct Stop with two sequential recoveries

codex-interrupt-direct-stop

Stop only after the foreground command is visibly running. Send recovery 1 after the thread returns to idle, then send recovery 2 only after recovery 1 settles. This UI check does not prove the provider shell process exited.

Open prompt
Live-test Codex direct Stop dual recovery. Short preamble only. Then run this exact foreground shell command and wait for it: sleep 30 && echo SHOULD_NOT_FINISH_CODEX_STOP. Keep the turn open until interrupted. Do not print either recovery token.
Recovery 1 (after Stop and idle)
Reply with exactly CODEX_RECOVERY_ONE_OK. No tools.
Recovery 2 (after recovery 1 settles)
Reply with exactly CODEX_RECOVERY_TWO_OK. No tools.

Expect

  • The original turn becomes interrupted and its command card stops spinning.
  • Recovery 1 remains visible and receives its own CODEX_RECOVERY_ONE_OK assistant response.
  • Recovery 2 remains visible and receives a later, separate CODEX_RECOVERY_TWO_OK response.
  • SHOULD_NOT_FINISH_CODEX_STOP never appears as command output after Stop.
  • The thread ends idle with no ghost assistant row or stuck Working state.
02

Stop while a collaborator subagent is running

manual only

Stop only after the collaborator row is visibly running. This validates subagent and parent-turn terminalization. The manual UI does not prove provider process containment.

Open prompt
Live-test Codex Stop while a collaborator subagent holds the root turn.

1) Spawn exactly one collaborator subagent with this task:
   Run the foreground shell command: sleep 30 && echo SHOULD_NOT_FINISH_CODEX_SUBAGENT_STOP
   Then return exactly CODEX_SUBAGENT_HOLD_DONE.
2) Wait for that collaborator. Do not start other tools or return a root answer before it finishes.
Recovery (after Stop and idle)
Reply with exactly CODEX_SUBAGENT_STOP_RECOVERY_OK. No tools or further questions.

Expect

  • The root turn becomes interrupted and the collaborator row becomes terminal, never permanently running.
  • Neither CODEX_SUBAGENT_HOLD_DONE nor SHOULD_NOT_FINISH_CODEX_SUBAGENT_STOP appears in the thread after Stop.
  • Recovery settles on a distinct run with CODEX_SUBAGENT_STOP_RECOVERY_OK.
  • No command or collaborator card returns to running after the thread reaches idle.

OpenCode · Interrupt / Stop

opencode · opencode/glm-5.2

OpenCode 1.x direct Stop and sequential recovery for #4759 opencode-interrupt-tool-items: the interrupted turn must close its in-flight tool items, and each recovery must land on its own run. Covered by the opencode-interrupt-direct-stop pack, which reuses the shared provider-neutral interrupt body. Use a fresh thread per pass. Markdown: opencode-appimage-interrupt-prompts.md.

01

Stop while a command is running

opencode-interrupt-direct-stop

Stop only after the command card is visibly running. This is the scenario #4759 opencode-interrupt-tool-items changes; the other two passed before and after it.

Open prompt
Live-test direct Stop dual recovery. Short preamble only. Run this exact foreground command and wait for it: bash -c 'sleep 30 & child=$!; wait "$child"; echo SHOULD_NOT_FINISH_CMD' Keep the turn open until interrupted.

Expect

  • The run becomes interrupted.
  • Every tool item in flight at Stop closes with the turn. Before #4759 opencode-interrupt-tool-items, the command card kept its last observed running state and spun forever.
  • SHOULD_NOT_FINISH_CMD never appears as command output.
  • The thread returns to idle with no stuck Working state.
02

Send after Stop lands on a new run

opencode-interrupt-direct-stop

Send only after the thread returns to idle.

Recovery 1
Live-test after direct Stop, recovery 1. Reply with exactly RECOVERY_ONE_OK. No tools.

Expect

  • The message is accepted; the provider thread remains reusable after the abort.
  • It lands on a run distinct from the interrupted one.
  • The run completes with RECOVERY_ONE_OK and must not complete blank.
03

Second send lands on its own run

opencode-interrupt-direct-stop

Send only after recovery 1 settles.

Recovery 2
Live-test after direct Stop, recovery 2. Reply with exactly RECOVERY_TWO_OK. No tools.

Expect

  • It lands on a run distinct from both the interrupted run and recovery 1.
  • Three runs total project as interrupted, completed, completed.
  • The thread ends idle with no ghost assistant row or resumed spinner.

OpenCode 2 · Baseline settlement

opencode2 · opencode-go/glm-5.3

OpenCode 2 instance and projection smoke test. The first turn must project a completed shell card and assistant marker; the second must settle as a distinct run on the same provider thread; the third forks that history and continues on the child; the fourth archives that child and verifies a clean new provider thread. Covered by the instance-bound opencode2-settlement pack for turns 1-2; fork is manual UI. Use a fresh thread per pass. Markdown: opencode2-appimage-live-prompts.md.

The experimental Background subagents setting is separate from provider-native shell backgrounding. The prompt-driven Background contract and its automatic post-settle wake have their own section.

01

Tool turn settles with its output

opencode2-settlement

This is the first check after installing a new v2.1 AppImage. Confirm the thread is using the opencode2 instance before sending.

Open prompt
Live-test OpenCode 2 baseline settlement.

1) Run this shell command and quote its output in your reply:
   echo OPENCODE2_SETTLE_MARK
2) End your final assistant message with OPENCODE2_SETTLE_DONE.

Do not spawn subagents. Do not start background or long-running commands. Keep prose short.

Expect

  • A shell command card appears, completes, and contains OPENCODE2_SETTLE_MARK.
  • The assistant reply contains OPENCODE2_SETTLE_MARK and ends with OPENCODE2_SETTLE_DONE.
  • The run and every tool card settle; no Working state or spinner remains.
  • No subagent row or duplicate assistant response appears.
02

Follow-up settles on a distinct run

opencode2-settlement

Send only after scenario 1 is fully idle.

Follow-up
Reply with exactly OPENCODE2_SECOND_DONE and nothing else. No tools.

Expect

  • The message is accepted on the same thread.
  • A second run completes with exactly OPENCODE2_SECOND_DONE.
  • The first run remains unchanged and the second response does not merge into it.
  • The thread ends idle with no ghost assistant row.
03

Fork preserves history and accepts a new turn

manual only

Requires a v2.1 AppImage that includes the #5251 opencode2-provider fork wire-up (raw session fork with boundary body). After scenario 2 is idle, use the thread Fork control (not a new empty thread). Then send the child prompt on the forked thread only.

On the forked thread
Live-test OpenCode 2 thread fork.

1) Confirm you can still see OPENCODE2_SETTLE_MARK and OPENCODE2_SECOND_DONE from the source history.
2) Reply with exactly OPENCODE2_FORK_CHILD_OK and nothing else. No tools.

Do not message the source thread after forking.

Expect

  • Fork creates a separate app thread without failing the fork action.
  • The forked thread shows the source history (OPENCODE2_SETTLE_MARK and OPENCODE2_SECOND_DONE).
  • The forked thread accepts OPENCODE2_FORK_CHILD_OK and settles idle.
  • The source thread is unchanged and does not receive the fork child reply.
04

Archive cleanup leaves the provider reusable

manual only

After scenario 3 is fully idle, archive the forked child thread from the UI. Then create a fresh OpenCode 2 thread and send the prompt below. Automated coverage owns the native storage assertion; this scenario owns visible cleanup and immediate provider reuse.

On a fresh thread after archiving the fork
Reply with exactly OPENCODE2_POST_ARCHIVE_OK and nothing else. No tools.

Expect

  • The archived fork leaves the active thread list without an error toast.
  • A fresh OpenCode 2 thread starts normally and completes with exactly OPENCODE2_POST_ARCHIVE_OK.
  • The original source thread remains available and unchanged.
  • No stale Working state, deleted child row, or provider-start failure appears.

OpenCode 2 · Queue

opencode2 · opencode-go/glm-5.3

OpenCode 2 uses T3's app-owned queue. A queued message must remain durable while the provider turn is active, start once after that turn settles or is stopped, and reach OpenCode 2 only when promoted. Natural promotion, multi-item controls, and promote-to-steer have deterministic or live-provider proof. Markdown: opencode2-appimage-live-prompts.md.

While Working, plain Enter or Send steers. Use Ctrl+Enter or Cmd+Enter to queue. Desktop currently hides red Stop while a message is queued, so queue then Stop is a mobile UI case. The headless OpenCode 2 queue then Stop contract is already green. Queue rows also support edit, reorder, remove, and Steer controls.

01

Queued follow-up waits for natural settlement

manual only

Queue before the sleep finishes with Ctrl+Enter or Cmd+Enter. Do not use plain Send.

Open prompt
Live-test OpenCode 2 queue ordering. Run this exact foreground command and wait for it: sleep 30 && echo OPENCODE2_QUEUE_FIRST_DONE. Then reply with exactly OPENCODE2_QUEUE_FIRST_DONE. Do not background the command.
Queued follow-up (Ctrl/Cmd+Enter only)
Reply with exactly OPENCODE2_QUEUE_SECOND_DONE and nothing else. No tools.

Expect

  • The second message appears as queued and does not steer or interrupt the first turn.
  • The first command and run complete with OPENCODE2_QUEUE_FIRST_DONE.
  • The queued message then starts exactly once as a distinct run and completes with exactly OPENCODE2_QUEUE_SECOND_DONE.
  • The thread ends idle with no queued row, ghost assistant, or stale spinner.
02

Queue a follow-up, then Stop (mobile)

manual only

Run on mobile. Desktop hides red Stop while anything is queued. Queue the follow-up before stopping the running command.

Open prompt
Live-test OpenCode 2 queue then Stop. Run this exact foreground command and wait for it: sleep 45 && echo OPENCODE2_QUEUE_STOP_SHOULD_NOT_FINISH. Keep the turn open until interrupted.
Queued follow-up
Reply with exactly OPENCODE2_QUEUE_STOP_RECOVERY_OK. No tools. Do not mention OPENCODE2_QUEUE_STOP_SHOULD_NOT_FINISH.

Expect

  • Stop interrupts the first run and command row; the forbidden command output never appears.
  • The queued message promotes exactly once after the interrupted run.
  • The recovery run completes with exactly OPENCODE2_QUEUE_STOP_RECOVERY_OK.
  • The thread ends idle with an interrupted, completed run sequence.
03

Manage and reorder multiple queued messages

opencode2-queue-controls

Use desktop or web so every Queue row control is visible. Queue all three follow-ups before editing, moving, or removing any row.

Open prompt
Live-test OpenCode 2 multi-item Queue controls. Run this exact foreground command and wait for it: sleep 45 && echo OPENCODE2_QUEUE_CONTROLS_ACTIVE. Then reply with exactly OPENCODE2_QUEUE_CONTROLS_ACTIVE. Do not background the command.
Queue first (remove later)
Reply with exactly OPENCODE2_QUEUE_REMOVE_ME and nothing else. No tools.
Queue second (edit later)
Reply with exactly OPENCODE2_QUEUE_EDIT_ORIGINAL and nothing else. No tools.
Queue third (move to front)
Reply with exactly OPENCODE2_QUEUE_FRONT and nothing else. No tools.
Replace the second row through Edit
Reply with exactly OPENCODE2_QUEUE_EDITED and nothing else. No tools.

Expect

  • All three follow-ups first appear as distinct queued rows while the active command keeps running.
  • Edit the second row to the replacement text, move the third row to position 1, then remove the original first row.
  • After the active run settles, OPENCODE2_QUEUE_FRONT completes first and OPENCODE2_QUEUE_EDITED completes second, each on one distinct run.
  • Neither OPENCODE2_QUEUE_REMOVE_ME nor OPENCODE2_QUEUE_EDIT_ORIGINAL appears in assistant or tool output.
  • The thread ends idle with no queued residue, duplicate response, ghost assistant, or stale spinner.
04

Promote a queued message to Steer

opencode2-queue-promote-steer

Queue the follow-up first. Once its Queue row is durable, click that row's Steer control instead of sending another message.

Open prompt
Live-test OpenCode 2 Queue promotion. Remember the codeword MARBLE_LANTERN. Run this exact foreground command and wait for it: sleep 45. Keep the turn open, and do not mention the codeword until I send another instruction.
Queued follow-up
Stop waiting and reply with exactly OPENCODE2_QUEUE_PROMOTED MARBLE_LANTERN. No tools.

Expect

  • The follow-up first appears as one queued row and does not reach the active turn before Steer is clicked.
  • Clicking Steer removes that Queue row and attaches the same message to the existing active run rather than starting another run.
  • The active run completes with OPENCODE2_QUEUE_PROMOTED and MARBLE_LANTERN in one response.
  • Exactly one user-visible promoted message and one matching assistant response appear, with no queued residue or duplicate run.

OpenCode 2 · Subagents and background

opencode2 · opencode-go/glm-5.3

OpenCode 2 foreground and background subagents. Enable Background subagents (experimental) in the OpenCode 2 provider settings before testing scenarios 1, 2, 7, 8, and 9. T3-owned servers receive the explicit OpenCode environment flag; external servers must set it themselves. Use a fresh thread per scenario. Markdown: opencode2-appimage-live-prompts.md.

The OpenCode 2 adapter maps both native permission generations and session.created parentID into the parent runtime policy, child thread, and Lineage. OpenCode owns native child concurrency; T3 must not imply that it serializes provider-created children. A provider-buffered continuation projects OpenCode's automatic post-settle parent wake without sending a duplicate prompt. Scenarios 6 through 10 cover foreground, settled-parent, direct-child, sibling-exclusion, and nested-child Stop. Scenario 10 requires the private depth-2 harness because OpenCode defaults subagent depth to 1. Native background-shell pinning, projection, and Stop remain covered by the headless opencode2-background-pin, opencode2-shell-projection, and opencode2-interrupt-backgrounded-stop packs because the required session.background control is not exposed in the UI. An ordinary Waiting root with no provider-native target keeps the generic run Stop path and is covered by the routing contract rather than another OpenCode-specific prompt.

01

Background subagent launch and post-settle wake

manual only

The root must release immediately after the background task acknowledgement. Wait up to 60 seconds for child completion.

Prompt
Live-test OpenCode 2 background subagent wake. Use the subagent tool exactly once with background=true. Give it this task: Run the shell command sleep 25 && echo OPENCODE2_BG_CHILD_DONE, then return exactly OPENCODE2_BG_CHILD_DONE. Do not wait for or poll the subagent. Immediately after the task acknowledgement, reply with exactly OPENCODE2_BG_STARTED and end the turn.

Expect

  • A T3 subagent row appears with a child present in Lineage.
  • The root assistant response lands with exactly OPENCODE2_BG_STARTED without waiting for the child result.
  • After the child finishes, its row completes and its child thread contains OPENCODE2_BG_CHILD_DONE.
  • Exactly one later assistant wake reply contains OPENCODE2_BG_CHILD_DONE.
  • No ghost row, duplicate child or wake, or permanent Running state remains.
02

Queued follow-up overlaps background work

manual only

Queue the follow-up with Ctrl+Enter or Cmd+Enter while the foreground sleep is visibly running.

Open prompt
Live-test OpenCode 2 background and queue overlap. Use the subagent tool exactly once with background=true. Give it this task: Run the shell command sleep 35 && echo OPENCODE2_BG_QUEUE_CHILD_DONE, then return exactly OPENCODE2_BG_QUEUE_CHILD_DONE. Do not wait for or poll the subagent. After the task acknowledgement, run this foreground command and wait for it: sleep 15. Then reply with exactly OPENCODE2_BG_QUEUE_STARTED and end the turn.
Queued follow-up (Ctrl/Cmd+Enter only)
Reply with exactly OPENCODE2_BG_QUEUE_FOLLOWUP_OK and nothing else. No tools.

Expect

  • The follow-up remains queued through OPENCODE2_BG_QUEUE_STARTED while the child is active.
  • After the child settles, the queued run starts exactly once and completes with exactly OPENCODE2_BG_QUEUE_FOLLOWUP_OK.
  • The child row and child thread retain OPENCODE2_BG_QUEUE_CHILD_DONE.
  • Exactly one later assistant wake reply contains OPENCODE2_BG_QUEUE_CHILD_DONE, even if OpenCode's synthetic wake races the queued user execution.
  • All runs and cards settle with no lost output, duplicate wake, queued residue, or stale spinner.
03

Foreground subagent honors Full access

manual only

Select Full access before sending. The child intentionally bursts several read tools before a command so both preview legacy permission normalization and repeated replies are exercised.

Prompt
Live-test OpenCode 2 foreground subagent permissions. Use the subagent tool exactly once without background=true. Give it this task: In one assistant response, issue two grep calls for .pnpm and orchestrator, plus two glob calls for **/*.md and **/trees/**. Then run the exact shell command printf OPENCODE2_FG_CHILD_DONE and return exactly OPENCODE2_FG_CHILD_DONE. Wait for the subagent to finish. Then reply with exactly OPENCODE2_FG_ROOT_DONE.

Expect

  • Full access auto-approves every child permission; no permission card or undefined-length provider error appears.
  • All five child tools execute despite the burst of legacy permission events.
  • A T3 subagent row appears as Running, then Completed, and opens a child present in Lineage.
  • The child result contains exactly OPENCODE2_FG_CHILD_DONE.
  • The root completes with exactly OPENCODE2_FG_ROOT_DONE and leaves no running card.
04

Supervised subagent permission resumes once

manual only

Select Supervised before sending. Approve the child command with Allow once when prompted.

Prompt
Live-test OpenCode 2 supervised subagent permissions. Use the subagent tool exactly once without background=true. Give it this task: Run the exact shell command printf OPENCODE2_SUPERVISED_CHILD_DONE, then return exactly OPENCODE2_SUPERVISED_CHILD_DONE. Wait for the subagent to finish. Then reply with exactly OPENCODE2_SUPERVISED_ROOT_DONE.

Expect

  • One actionable permission request appears for the child command.
  • Allow once resumes that child without spawning a duplicate run or child.
  • The child appears in Lineage and its row completes with OPENCODE2_SUPERVISED_CHILD_DONE.
  • The root completes with OPENCODE2_SUPERVISED_ROOT_DONE and the thread returns idle.
05

Concurrent children isolate lifecycle and rate limits

manual only

Select Full access. OpenCode owns native child concurrency, so this scenario observes rather than prescribes launch order.

Prompt
Live-test OpenCode 2 concurrent native subagents. Use the subagent tool twice without waiting between launches. Child A must run sleep 10 and return exactly OPENCODE2_CHILD_A_OK. Child B must run sleep 10 and return exactly OPENCODE2_CHILD_B_OK. After both native subagent calls settle, report each result exactly once.

Expect

  • Two distinct child rows and Lineage entries appear; one child's events never update the other row.
  • T3 does not claim to queue or serialize provider-native child launches.
  • If both children succeed, both rows complete and both tokens appear exactly once.
  • If OpenCode returns HTTP 429, that child becomes a prominent Failed card with the rate-limit detail and retry attempt instead of silently hanging.
  • A child failure does not poison the surviving child or prevent the parent from reporting the outcome.
06

Stop while a foreground subagent command runs

manual only

Select Full access. Stop only after the child command row is visibly running, then send the recovery after the parent returns idle.

Open prompt
Live-test OpenCode 2 foreground subagent Stop. Use the subagent tool exactly once without background=true. Give it this task: Run the exact shell command sleep 45 && echo OPENCODE2_FG_STOP_SHOULD_NOT_FINISH, then return exactly OPENCODE2_FG_STOP_SHOULD_NOT_FINISH. Wait for the subagent to finish. Then reply with exactly OPENCODE2_FG_STOP_ROOT_SHOULD_NOT_FINISH. Do not do anything else.
Recovery after Stop
Reply with exactly OPENCODE2_FG_STOP_RECOVERY_OK. No tools. Do not mention any forbidden completion marker.

Expect

  • Stop interrupts the parent run, foreground subagent row, and child command rather than leaving the child active.
  • Neither OPENCODE2_FG_STOP_SHOULD_NOT_FINISH nor OPENCODE2_FG_STOP_ROOT_SHOULD_NOT_FINISH appears as completed output.
  • The child command shows Tool execution interrupted without a red Failed state.
  • The recovery lands exactly once on a distinct completed run with OPENCODE2_FG_STOP_RECOVERY_OK.
  • Neither parent nor child retains a stale Working, Waiting, or Running state.
07

Stop a detached child from the settled parent

manual only

Select Full access. After the root releases with the start marker and displays Waiting, press Stop on the root without opening the child.

Open prompt
Live-test OpenCode 2 detached background subagent Stop. Use the subagent tool exactly once with background=true. Give it this task: Run the exact shell command sleep 90 && echo OPENCODE2_PARENT_STOP_SHOULD_NOT_FINISH, then return exactly OPENCODE2_PARENT_STOP_SHOULD_NOT_FINISH. Do not wait for or poll the subagent. Immediately after the task acknowledgement, reply with exactly OPENCODE2_PARENT_STOP_STARTED and end the turn.
Recovery after Stop
Reply with exactly OPENCODE2_PARENT_STOP_RECOVERY_OK. No tools. Do not mention any forbidden completion marker.

Expect

  • After OPENCODE2_PARENT_STOP_STARTED, the settled root keeps a clear Stop action while the direct child remains active.
  • Root Stop interrupts the exact owned child and command; OPENCODE2_PARENT_STOP_SHOULD_NOT_FINISH never appears as completed output.
  • The parent receives at most one terminal wake for the interrupted child.
  • The recovery completes exactly once with OPENCODE2_PARENT_STOP_RECOVERY_OK on a distinct run.
  • No child row, parent thread, or provider shell remains active.
08

Stop a detached child from its own thread

manual only

Select Full access. After the root releases, open the direct child from its row or Lineage and press Stop there while its command is visibly running.

Open prompt
Live-test OpenCode 2 direct provider-child Stop. Use the subagent tool exactly once with background=true. Give it this task: Run the exact shell command sleep 90 && echo OPENCODE2_CHILD_STOP_SHOULD_NOT_FINISH, then return exactly OPENCODE2_CHILD_STOP_SHOULD_NOT_FINISH. Do not wait for or poll the subagent. Immediately after the task acknowledgement, reply with exactly OPENCODE2_CHILD_STOP_STARTED and end the turn.
Root recovery after child Stop
Reply with exactly OPENCODE2_CHILD_STOP_RECOVERY_OK. No tools. Do not mention any forbidden completion marker.

Expect

  • The projected provider child exposes Stop without owning an ordinary T3 root run.
  • Child Stop interrupts that child's own native turn and command; OPENCODE2_CHILD_STOP_SHOULD_NOT_FINISH never appears as completed output.
  • The parent receives at most one terminal wake for the interrupted child.
  • The root recovery completes exactly once with OPENCODE2_CHILD_STOP_RECOVERY_OK on a distinct run.
  • The child, root, and provider shell all finish without stale Working, Waiting, or Running state.
09

Stop one detached child without stopping its sibling

manual only

Select Full access. Open child A from Lineage and press Stop only after both child rows exist and A's command is visibly running. Do not Stop child B.

Open prompt
Live-test OpenCode 2 exact child Stop with a sibling. Use the subagent tool twice with background=true and do not wait between launches. Child A must run sleep 90 && echo OPENCODE2_SIBLING_A_SHOULD_NOT_FINISH, then return exactly OPENCODE2_SIBLING_A_SHOULD_NOT_FINISH. Child B must run sleep 25 && echo OPENCODE2_SIBLING_B_OK, then return exactly OPENCODE2_SIBLING_B_OK. Do not wait for or poll either child. Immediately after both task acknowledgements, reply with exactly OPENCODE2_SIBLINGS_STARTED and end the turn.
Root recovery after child B settles
Reply with exactly OPENCODE2_SIBLING_RECOVERY_OK. No tools. Do not mention the forbidden child A marker.

Expect

  • Child A and child B project as distinct rows and Lineage entries.
  • Stopping child A interrupts only A; OPENCODE2_SIBLING_A_SHOULD_NOT_FINISH never appears as completed output.
  • Child B remains active, then completes normally with OPENCODE2_SIBLING_B_OK exactly once.
  • The parent receives no duplicate terminal wake for A or B, and the explicit recovery completes once with OPENCODE2_SIBLING_RECOVERY_OK.
  • All child rows, commands, runs, and provider shells end terminal with no stale activity.
10

Stop a nested child from its direct parent

opencode2-interrupt-nested-child-stop

Harness-only unless private serve supplies experimental.subagent_depth=2 through inline configuration. OpenCode's default depth 1 rejects this topology; do not change global OpenCode configuration for the test.

Depth-2 prompt
Live-test OpenCode 2 nested-child Stop. Use the subagent tool exactly once with background=true. Give the middle child this task: Use the subagent tool exactly once with background=true. Give the grandchild this task: Run sleep 90 && echo OPENCODE2_NESTED_SHOULD_NOT_FINISH, then return exactly OPENCODE2_NESTED_SHOULD_NOT_FINISH. Do not wait for or poll the grandchild. Immediately reply with exactly OPENCODE2_NESTED_MIDDLE_STARTED and end. In the root, do not wait for or poll the middle child. Immediately reply with exactly OPENCODE2_NESTED_ROOT_STARTED and end.
Root recovery after nested Stop
Reply with exactly OPENCODE2_NESTED_RECOVERY_OK. No tools. Do not mention any forbidden completion marker.

Expect

  • The root, middle child, and grandchild form three distinct Lineage levels.
  • Stop on the settled middle child targets only its direct active grandchild.
  • The grandchild command becomes interrupted and OPENCODE2_NESTED_SHOULD_NOT_FINISH never appears as completed output.
  • Root recovery completes exactly once with OPENCODE2_NESTED_RECOVERY_OK.
  • The harness stops its private server and descendants without changing the running AppImage or global OpenCode configuration.

OpenCode 2 · Interrupt / Stop

opencode2 · opencode-go/glm-5.3

OpenCode 2 direct Stop and sequential recovery. The interrupted command must close as interrupted, not failed, and both later messages must settle on distinct runs. Covered by the opencode2-interrupt-direct-stop pack. Use a fresh thread. Markdown: opencode2-appimage-live-prompts.md.

01

Stop while a command is running

opencode2-interrupt-direct-stop

Stop only after the command card is visibly running.

Open prompt
Live-test OpenCode 2 direct Stop dual recovery. Short preamble only. Run this exact foreground command and wait for it: sleep 30 && echo SHOULD_NOT_FINISH_OPENCODE2_STOP. Keep the turn open until interrupted.

Expect

  • The run and in-flight command item become interrupted, not failed.
  • Tool execution interrupted may appear as the command terminal marker without a red failed row.
  • SHOULD_NOT_FINISH_OPENCODE2_STOP never appears as command output.
  • The thread returns to idle with no stuck Working state.
02

First recovery lands on a new run

opencode2-interrupt-direct-stop

Send only after scenario 1 returns to idle.

Recovery 1
Reply with exactly OPENCODE2_RECOVERY_ONE_OK. No tools. Do not mention SHOULD_NOT_FINISH_OPENCODE2_STOP.

Expect

  • The message is accepted on the same provider thread.
  • It lands on a run distinct from the interrupted run.
  • The run completes with exactly OPENCODE2_RECOVERY_ONE_OK.
03

Second recovery remains distinct

opencode2-interrupt-direct-stop

Send only after recovery 1 settles.

Recovery 2
Reply with exactly OPENCODE2_RECOVERY_TWO_OK. No tools.

Expect

  • It lands on a run distinct from the interrupted run and recovery 1.
  • Three runs total project as interrupted, completed, completed.
  • The thread ends idle with no ghost assistant row or resumed spinner.

Pi · Long work and steer

pi · default

Pi (#7211 pi-provider) has no native subagents, monitors, or post-settle Waiting. These scenarios cover the applicable long-work surface: a tool turn that settles, a long foreground command, native steer, and a queued follow-up. Enable Pi in provider settings first (Early Access, disabled by default). Use instance pi and model default so Pi keeps the user's own defaultProvider/defaultModel. Requires a tree or AppImage that includes #7211. Markdown: pi-appimage-live-prompts.md.

A long foreground command may show Working while the turn is open. It must not leave a Waiting row or sidebar pill after the turn settles. Isolated live-serve points Pi at a run-scoped session dir so the user's Pi session store stays untouched. Pi must have at least one available model (`pi --list-models`); an empty catalog fails every turn with No API key found for the selected model.

01

Tool turn settles with its output

pi-settlement

Confirm the thread is using the pi instance and the default inherit model before sending.

Open prompt
Live-test Pi baseline settlement.

1) Run this shell command and quote its output in your reply:
   echo PI_SETTLE_MARK
2) End your final assistant message with SETTLE_DONE.

Do not spawn subagents. Do not start background or long-running commands. Keep prose short.

Expect

  • A shell command card appears, completes, and contains PI_SETTLE_MARK.
  • The assistant reply contains PI_SETTLE_MARK and ends with SETTLE_DONE.
  • The run and every tool card settle; no Working state or spinner remains.
  • No subagent row, Waiting pill, or duplicate assistant response appears.
02

Follow-up settles on a distinct run

pi-settlement

Send only after scenario 1 is fully idle.

Follow-up
Reply with exactly SECOND_DONE and nothing else. No tools.

Expect

  • The message is accepted on the same thread.
  • A second run completes with exactly SECOND_DONE.
  • The first run remains unchanged and the second response does not merge into it.
  • The thread ends idle with no ghost assistant row.
03

Long foreground command stays on the same turn

manual only

This is the applicable long-work case. Pi has no native background shell or post-settle wake.

Open prompt
Live-test Pi long foreground work. Run this exact command and wait for it: sleep 20 && echo PI_LONG_DONE. Then reply with exactly PI_LONG_DONE. Do not background the command.

Expect

  • A command card stays running for about 20 seconds, then completes with PI_LONG_DONE.
  • The assistant reply contains PI_LONG_DONE and the run settles once.
  • Working may show while the command runs; no Waiting row or sidebar pill remains after settle.
  • No subagent row or Background task completed. wake appears.
04

Native steer during a running command

pi-steer

Send the steer only after the sleep command card is visibly running. Use ordinary Send so it steers the active turn.

Open prompt
Live-test Pi native steer. Run this exact foreground command and wait for it: sleep 45. Keep the turn open, and do not mention PI_STEER_OK until I send another instruction.
Steer (while the command is running)
Stop waiting on the sleep. Reply with exactly PI_STEER_OK and nothing else. No tools.

Expect

  • The steer attaches to the same active run rather than starting another run.
  • The assistant reply contains exactly PI_STEER_OK.
  • The thread returns to idle with one run for the original prompt plus steer.
  • No subagent row, queued residue, or second completed run appears.
05

Queued follow-up waits for the long command

manual only

Queue before the sleep finishes with Ctrl+Enter or Cmd+Enter. Do not use plain Send.

Open prompt
Live-test Pi queue ordering. Run this exact foreground command and wait for it: sleep 30 && echo PI_QUEUE_FIRST_DONE. Then reply with exactly PI_QUEUE_FIRST_DONE. Do not background the command.
Queued follow-up (Ctrl/Cmd+Enter only)
Reply with exactly PI_QUEUE_SECOND_DONE and nothing else. No tools.

Expect

  • The second message appears as queued and does not steer or interrupt the first turn.
  • The first command and run complete with PI_QUEUE_FIRST_DONE.
  • The queued message then starts exactly once as a distinct run and completes with exactly PI_QUEUE_SECOND_DONE.
  • The thread ends idle with no queued row, ghost assistant, or stale spinner.

Pi · Manual compact

pi · default

Pi TUI `/compact` is not in RPC `get_commands`. T3 advertises it and sends RPC `compact` instead of a prompt. Auto-compact still runs on its own. Isolated packs: pi-compact-empty, pi-compact, pi-compact-queued. Markdown: pi-appimage-live-prompts.md.

Typing `/compact` must show a compaction card, not an assistant reply that pretends to compact. A fresh thread is too small and should fail that card (or the run) with Nothing to compact. Queued `/compact` waits for a long command. Steer `/compact` aborts the current agent first, matching Pi TUI.

01

Fresh thread /compact is not chat

pi-compact-empty

Use a new thread. Type `/compact` from the slash menu or by hand. Do not add extra text.

Open prompt
/compact

Expect

  • A compaction card appears. A fresh session is too small, so the card may fail with Nothing to compact.
  • The model does not treat `/compact` as a user request or invent a summary in chat.
  • The thread returns to idle. A failed compact card is fine; a chat reply without a card is not.
02

/compact after a fat turn

pi-compact

Send `/compact` only after the open prompt is idle. Optional instructions are allowed.

Open prompt
Live-test Pi manual compact.

1) Run this exact shell command and wait for it:
   python3 -c "from hashlib import sha256; from pathlib import Path; Path('compact-pad.txt').write_text(''.join(f'token-{i:04d} {sha256(str(i).encode()).hexdigest()} unique compact-pad line.\n' for i in range(4000)))" && cat compact-pad.txt
2) End your final assistant message with PAD_DONE.

Do not spawn subagents. Do not start background commands. Keep prose short.
Follow-up
/compact

Expect

  • The first turn settles with PAD_DONE.
  • `/compact` shows Compacting context..., then Context compacted (or a failed too-small card if the pad was skipped).
  • No second assistant essay that only talks about compacting.
  • The context meter may drop after a successful compact.
03

Queued /compact waits for a long command

pi-compact-queued

Queue `/compact` with Ctrl+Enter or Cmd+Enter while the sleep is running. Do not use plain Send (that steers).

Open prompt
Live-test queued Pi compact. Run this exact foreground command and wait for it: sleep 20 && echo PI_QUEUE_COMPACT_FIRST. Then reply with exactly PI_QUEUE_COMPACT_FIRST. Do not background the command.
Queued follow-up (Ctrl/Cmd+Enter only)
/compact

Expect

  • The sleep command finishes and the first run completes with PI_QUEUE_COMPACT_FIRST.
  • `/compact` does not abort or steer the sleep.
  • A later run shows a compaction card (completed, or failed too-small).
  • The thread ends idle.

Pi · T3 MCP orchestration

pi · default

Pi core has no MCP client. A trial build that injects T3's per-session HTTP MCP server through a T3-owned extension should expose the same t3-code tools as Claude, Codex, Grok, and OpenCode. These scenarios prove the tools are real (not invented), that the model does not fall back to grok -p, and that an idle Pi parent wakes for each finished delegated sibling. Requires a v2.1 trial AppImage that includes the Pi T3 MCP layer, not only #7211 pi-provider. Isolated packs: pi-t3-mcp, pi-delegated-sibling-idle-wake. Markdown: pi-appimage-orchestration-prompts.md.

Look for dynamic_tool cards named orchestrator_capabilities, t3_thread_list, and delegate_task. MCP_MISSING in the assistant reply means the tools never reached the model. Do not run this on a #7211-only build.

01

T3 MCP tools are callable

pi-t3-mcp

Confirm the thread is using the pi instance and the default inherit model before sending.

Open prompt
Live-test T3 MCP injection on Pi.

Do exactly this, in order, no extra steps:

1) Call the t3-code tool orchestrator_capabilities exactly once. Do not invent the tool. If it is missing, say MCP_MISSING and stop.
2) Call the t3-code tool t3_thread_list exactly once.
3) In your final reply, quote one providerInstanceId from the capabilities result and end with PI_MCP_OK.

Do not call delegate_task. Do not run grok -p or any other CLI. Do not spawn Pi subagents. Do not start background or long-running commands.

Expect

  • A dynamic_tool card named orchestrator_capabilities completes.
  • A dynamic_tool card named t3_thread_list completes.
  • The assistant reply quotes a real providerInstanceId and ends with PI_MCP_OK.
  • MCP_MISSING does not appear.
  • No delegate_task card and no grok -p command appear.
  • The run and every tool card settle; no Working state or spinner remains.
02

Three async siblings wake an idle parent

pi-delegated-sibling-idle-wake

App-owned delegate_task children, not Pi-native subagents. Watch Waiting after STARTED. The MID wake must start while SLOW is still running.

Open prompt
Live-test idle-parent delegated sibling wakes.

Do exactly this, in order:

1) Call the t3-code tool orchestrator_capabilities exactly once. If it is missing, say MCP_MISSING and stop.
2) Start three async delegate_task children on the pi instance, in this order. Do not target grok or codex provider instances. Each child must run the given shell command, then reply with only the token. No T3 tools.

   FAST: sleep 15; echo FAST_DONE
   MID:  sleep 50; echo MID_DONE
   SLOW: sleep 110; echo SLOW_DONE

3) After all three delegate_task calls return, reply with exactly STARTED and end the turn.
4) Do not call task_status, poll, wait, or spawn a watcher in that first turn.
5) Each time you are woken that a delegated task reached a terminal state, call task_status once for that taskId, quote the child's token, and end that turn. Do not wait for the other children.

Do not use Pi-native subagents. Do not run grok -p.

Expect

  • First run settles with STARTED while at least SLOW is still running. The thread goes Waiting.
  • Three server wake prompts appear with no user input between them.
  • After the FAST wake settles, the MID wake starts while SLOW is still running. That is the regression: the old hold waited for SLOW.
  • Wake assistant text includes FAST_DONE, then MID_DONE, then SLOW_DONE.
  • Waiting clears after the last wake. The Queued chip does not show those wake prompts.
  • MCP_MISSING does not appear. No grok -p command appears.

Pi · Interrupt / Stop

pi · default

Pi direct Stop and sequential recovery. Stop is a session abort; requestRuntimeRestart degrades to the same abort and does not respawn the process. The interrupted command must close as interrupted, and both later messages must settle on distinct runs. Covered by the pi-interrupt-direct-stop pack. Use a fresh thread. Markdown: pi-appimage-interrupt-prompts.md.

The recovery proof is two later messages on the same provider thread, not a new Pi process identity.

01

Stop while a command is running

pi-interrupt-direct-stop

Stop only after the command card is visibly running.

Open prompt
Live-test Pi direct Stop dual recovery. Short preamble only. Run this exact foreground command and wait for it: sleep 30 && echo SHOULD_NOT_FINISH_PI_STOP. Keep the turn open until interrupted.

Expect

  • The run and in-flight command item become interrupted, not failed.
  • SHOULD_NOT_FINISH_PI_STOP never appears as command output.
  • The thread returns to idle with no stuck Working state.
02

First recovery lands on a new run

pi-interrupt-direct-stop

Send only after scenario 1 returns to idle.

Recovery 1
Reply with exactly PI_RECOVERY_ONE_OK. No tools. Do not mention SHOULD_NOT_FINISH_PI_STOP.

Expect

  • The message is accepted on the same provider thread.
  • It lands on a run distinct from the interrupted run.
  • The run completes with exactly PI_RECOVERY_ONE_OK.
03

Second recovery remains distinct

pi-interrupt-direct-stop

Send only after recovery 1 settles.

Recovery 2
Reply with exactly PI_RECOVERY_TWO_OK. No tools.

Expect

  • It lands on a run distinct from the interrupted run and recovery 1.
  • Three runs total project as interrupted, completed, completed.
  • The thread ends idle with no ghost assistant row or resumed spinner.
04

Stop during /compact

pi-compact-interrupt

Load enough context first, send `/compact`, then Stop while Compacting context... is visible. Pi abort does not cancel manual compact; T3 must tear the process down.

Open prompt
Live-test Pi compact then Stop.

1) Run this exact shell command and wait for it:
   python3 -c "from hashlib import sha256; from pathlib import Path; Path('compact-pad.txt').write_text(''.join(f'token-{i:04d} {sha256(str(i).encode()).hexdigest()} unique compact-pad line.\n' for i in range(4000)))" && cat compact-pad.txt
2) End your final assistant message with PAD_DONE.

Do not spawn subagents. Do not start background commands. Keep prose short.
Follow-up
/compact
Recovery (after Stop)
Reply with exactly PI_COMPACT_RECOVERY_OK and nothing else. No tools.

Expect

  • A compaction card appears, then Stop interrupts that run.
  • The thread returns to idle. The compact run is interrupted, not left spinning.
  • Recovery completes with exactly PI_COMPACT_RECOVERY_OK on a later run.