acpmux: agent messages steer a running turn by default again

Merged
TE
17d ago
+35-27

Summary

Takes back #22779: its queue default for agent messages. It was a precaution after the coordinator session claude-sr2 saw its tool calls cancelled, and the investigation shows steering was not the cause.

Steers don't cancel tool calls.

  • None of the 70 steered messages to claude-sr2 before 01:54 UTC was followed by a cancel.
  • Claude Code reads a steer at its next tool boundary. 11 steers sat unread for 193 s during one long Bash, then were read together, and no tool was rejected.
  • A live probe agrees: a steer into a steering Claude session running a 100 s foreground Bash left the tool call alone. It returned normally, and the steer was read right after.

What cancelled them was the queue's "Send now".

  • _acpmux/queue_edit send_now on a session with steering=false runs as "put next, then stop the turn" (hub/queue_edit.rs send_queued_now).
  • At 01:54:39 claude-sr2 was re-adopted after a daemon update and came back with steering=false. This is the first-upgrade gap named in #22736.
  • At 01:55:30, a send-now on a queued pane message gave the first cancel.
  • At 01:58:33โ€“39 came about 20 more, one per new turn, each a queue_order next:true on the current queue head.
  • Those fixes (recover steering at adoption, the queue row's โŒ˜โ†ฉ) are passed on to the queue lane (prompt-queue-edit).

This PR goes back to #22729's behavior:

  • acpmux send --no-wait steers into a running turn when the agent steers, and queues otherwise. --no-steer queues. A send that waits for its reply queues unless given --steer.
  • The cmux agent message pump sends steer: true.
  • chief tell sends steer: true.

A steer to an agent that doesn't steer, or whose steering is unknown, still only queues and never stops the turn. a_steer_without_interrupt_queues_behind_a_turn_its_agent_cannot_steer (steer_only.rs) pins this.

Testing

The tests are flipped back to the steer default: send_steers_messages_by_default_and_queues_waiting_sends (acpmux CLI), a_message_to_a_child_steers_its_running_turn (optchat-chief), and the_pump_delivers_a_queued_message_and_records_it (asserts steer: true). These assertions ran in #22729's CI. PR CI runs them here.

Observed / Not run

Observed:

  • claude-sr2's event log, read with acpmux session tail --json.
  • The live probe session steer-probe-ams (foreground 100 s Bash plus acpmux send --no-wait --steer): the tool result was PROBE_DONE, with no cancel.

Not run: local builds or the pre-push gate. Git is frozen on this Mac (cosmic-gray), so this was committed through the GitHub git data API.

Changelog

Changed: Messages between agent sessions reach a busy recipient at its next step when its agent supports steering, instead of waiting for the turn to end

Agent session: cosmic-gray

๐Ÿค– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Restores steering as the default for agent messages, after confirming steers never cancelled tool calls. #22779 queued messages out of caution; its cancelled calls came from queue "send now" operations, not from steers.

  • acpmux send --no-wait steers into a running turn by default; --no-steer queues. Sends that wait for a reply queue unless given --steer.
  • The cmux agent message pump and chief tell send steer: true again.
  • A message to an agent that does not steer still queues and never stops the turn.

Why steering is safe

  • The cancelled tool calls all followed queue "send now" operations on a session re-adopted with steering=false, not a steer.
  • A 100-second foreground Bash in a live probe carried a steered message to completion; the agent read it right after.
  • Eleven steers sat unread for 193 seconds during one long tool call and were read together with no tool rejected.