Repository navigation
cmux link agent move: stop a running turn only where it goes on; never mid-compaction - #30567
Conversation
…r mid-compaction Follow-ups 2 and 3 of #30460 (review of #30280): - The daemon lists agent-transfer-continues-v1 (its acpmux continues a turn a move stops). The pump sends `interrupt` only to a source that lists it; an older source (an un-updated Cloud machine on Bring Back) would stop the turn for good, so there the move is refused while the turn runs, as before. - acpmux refuses a move with interrupt while the chat is compacting (transfer.busy): the Stop's compaction branch withdraws the person's queued prompts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-823b964b033ac6533d82
|
Review (subagent claude-opus-5-5 medium): SHIP at 588f353 Independent read of the commit: the capability is listed exactly where the transfer verbs are served; a failed or missing Follow-ups (in #30460):
|
There was a problem hiding this comment.
2 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="cmux-tui/crates/cmux-tui/src/link/agent_cli.rs">
<violation number="1" location="cmux-tui/crates/cmux-tui/src/link/agent_cli.rs:503">
P1: This capability check can describe a different daemon than the `source` connection that receives `agent-transfer-begin`. If the socket is replaced between the two connects, an older source can receive `interrupt: true` and permanently lose the running turn; probe capabilities on the same connection used for `begin`, or verify the peer identity before using the result.</violation>
</file>
<file name="cmux-tui/crates/acpmux/src/hub/transfer_out.rs">
<violation number="1" location="cmux-tui/crates/acpmux/src/hub/transfer_out.rs:239">
P1: This is only a snapshot, so compaction can begin after the check but before `log_continuation` and the eventual `SESSION_CANCEL`; the transfer can therefore log and stop a turn during compaction instead of refusing it. Couple the compaction transition and Stop through a shared fence, or revalidate immediately before stopping and abort before logging when compaction has begun.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| /// say so, or does not answer `identify`. | ||
| fn source_continues(socket: &std::path::Path) -> bool { | ||
| let capability = cmux_tui_core::server::agent_transfer::AGENT_TRANSFER_CONTINUES_CAPABILITY; | ||
| let identity = super::machine_gate::identify(socket); |
There was a problem hiding this comment.
P1: This capability check can describe a different daemon than the source connection that receives agent-transfer-begin. If the socket is replaced between the two connects, an older source can receive interrupt: true and permanently lose the running turn; probe capabilities on the same connection used for begin, or verify the peer identity before using the result.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/cmux-tui/src/link/agent_cli.rs, line 503:
<comment>This capability check can describe a different daemon than the `source` connection that receives `agent-transfer-begin`. If the socket is replaced between the two connects, an older source can receive `interrupt: true` and permanently lose the running turn; probe capabilities on the same connection used for `begin`, or verify the peer identity before using the result.</comment>
<file context>
@@ -489,6 +496,14 @@ fn sync_frozen(sync: &Sync) -> Result<(), Failed> {
+/// say so, or does not answer `identify`.
+fn source_continues(socket: &std::path::Path) -> bool {
+ let capability = cmux_tui_core::server::agent_transfer::AGENT_TRANSFER_CONTINUES_CAPABILITY;
+ let identity = super::machine_gate::identify(socket);
+ identity.as_ref().and_then(super::machine_gate::served).is_some_and(|s| s.contains(&capability))
+}
</file context>
| // A Stop while Claude compacts withdraws the person's queued prompts (`cancel.rs`): | ||
| // the move waits for the compaction instead of losing them. | ||
| let child = session.child.lock().await.clone(); | ||
| let compacting = session.compacting.load(std::sync::atomic::Ordering::SeqCst) |
There was a problem hiding this comment.
P1: This is only a snapshot, so compaction can begin after the check but before log_continuation and the eventual SESSION_CANCEL; the transfer can therefore log and stop a turn during compaction instead of refusing it. Couple the compaction transition and Stop through a shared fence, or revalidate immediately before stopping and abort before logging when compaction has begun.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/acpmux/src/hub/transfer_out.rs, line 239:
<comment>This is only a snapshot, so compaction can begin after the check but before `log_continuation` and the eventual `SESSION_CANCEL`; the transfer can therefore log and stop a turn during compaction instead of refusing it. Couple the compaction transition and Stop through a shared fence, or revalidate immediately before stopping and abort before logging when compaction has begun.</comment>
<file context>
@@ -233,6 +233,15 @@ impl Hub {
+ // A Stop while Claude compacts withdraws the person's queued prompts (`cancel.rs`):
+ // the move waits for the compaction instead of losing them.
+ let child = session.child.lock().await.clone();
+ let compacting = session.compacting.load(std::sync::atomic::Ordering::SeqCst)
+ || child.is_some_and(|c| c.translator.as_ref().is_some_and(|t| t.is_compacting()));
+ if compacting {
</file context>
|
CI at 588f353 (https://github.com/manaflow-ai/cmux/actions/runs/41292530431): clippy -D warnings shows no hits in this PR's files (CLIPPY_OURS=0; the hits are base's, in agent_tools.rs, cloud_repo_mcp.rs, remote_guard.rs, cloud_repos/*, agent_session_folders.rs, from #30361/#30363, fixed on base by #30528). link_agent_move 15 passed (the new gate test included), cloud_move_journey 3 and bring_back_journey 2 passed, cli agent_session_start 38 of 39 passed. The one failure, |
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
|
Found 7 test failures on Blacksmith runners: Failures
|
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Follow-ups 2 and 3 of #30460, from the review of #30280 (receipt #30280 (comment)). That work is for cmuxterm-hq#5846 item 1. Leo, 2026-11-01: "those all seem good".
What changes
Since #30280, Move to Cloud and Bring Back Local always pass
--interrupt, so a move stops a running turn and acpmux continues it where the chat lands. Two cases lost work:agent-transfer-continues-v1beside the transfer verbs. The pump (cmux link agent move) sendsinterruptonly to a source whoseidentifylists it. Any other source gets no Stop and refuses the move while the turn runs (transfer.busy), as before acpmux: a move that stops a running turn continues it where the chat lands #30280.cancel.rs) withdraws the person's queued prompts.transfer_beginwithinterruptnow refuses while the chat is compacting (transfer.busy: the chat is compacting; move it once that ends), before anything is logged or stopped. The check is the same onecancel.rsmakes.spec/commands.mdsays both.Tests
tests/link_agent_move.rsa_running_turn_is_stopped_only_on_a_source_that_continues_it: an older source's begin getsinterrupt: false, one that lists the capability getstrue, and with no flag it is never set.tests/cli/agent_session_start.rs: a daemon that serves transfer listsagent-transfer-continues-v1.cmux-ci receipt below.
Follow-ups (from its review, kept in #30460)
Changelog
none
🤖 Generated with Claude Code
Agent session: agent session
Summary by cubic
Fixes
cmux link agent moveso a move never stops a running turn unless the source's acpmux continues it where the chat lands, and never stops one mid-compaction.agent-transfer-continues-v1; the pump sendsinterruptonly to a source that lists it. An older source (an un-updated Cloud machine on Bring Back) would stop the turn for good, so there the move is refused while the turn runs, as before--interrupt.--interruptis refused (transfer.busy: the chat is compacting) while the chat compacts, since the Stop would withdraw the person's queued prompts.spec/commands.md.Written for commit 588f353. Summary will update on new commits.