acpmux: send --supersede KEY replaces your prompt still queued under KEY
What
acpmux send --supersede KEY: a prompt replaces the same sender's prompts still waiting in the queue under the same KEY.
session/prompttakes_meta.acpmux.supersede(a non-empty string of at most 256 bytes; anything else is refused withsupersede.invalid).- A replaced prompt leaves the queue the way an unsent agent message does (
remove_queued):- its
session/promptanswers withdrawn; - its
queue_removedrecord saysreason: "superseded"andsupersededBy; - a restart never runs it. The key is kept on the
queuedrecord, so a prompt restored after a restart can still be replaced.
- its
- Only a prompt that still waits is replaced. One whose turn started, or one being sent into the running turn, stays.
- "Same sender" is the queue's own notion of it (
digest.rsagent_sender): an agent's name (--from, or the session the connection runs in), or the person. - The new prompt's acceptance carries
replaced(a count) andreplacedPromptIds.acpmux sendprintsreplaced N queuedunderqueued/steered.--jsonaddsreplacedandreplacedPromptIds.- Without
--supersedethe output is unchanged.
- An edit of a waiting prompt drops its key, as it drops its provenance: the person rewrote it.
Why
acpmux prompts queue behind running turns, often 3 to 6 deep, so a lane reads a correction after the order it corrects. That is how one of today's tasks bounced between ci-speed and machine-mesh three times.
Tests
Written first:
- d8985588 adds the tests.
- 93581938 makes the tests count a prompt that went in with an agent-message turn as run, which also makes the "never ran" checks stricter.
- a661042d is the implementation.
tests/hub_integration/prompt_supersede.rs (end to end through the protocol handler with the fake agent):
- a same-key prompt is replaced and never runs, and its wait answers withdrawn;
- another sender's prompt, another key's prompt and an unkeyed prompt stay queued;
- a running turn under the key is never replaced;
- a prompt queued before a restart is still replaced;
- a bad key is refused.
Unit tests in cli/output.rs:
- through a real unix socket,
queue_promptwith a key replaces the earlier prompt, andsent_linesprintsreplaced N queued; - the key goes in
_meta.
Results on cmux16:
- Before the implementation, all 5 integration tests failed (the acceptance had no
replaced, and a bad key ran). - At the implementation:
cargo test -p acpmux: every binary is ok, including 518 unit and 362 hub_integration tests.cargo clippy -p acpmux --all-targets -- -D warningsis clean.cargo fmt --checkpasses after 4a3e141d.
No overlap with acpmux-unify's open PRs: #23027 and #23598 don't touch the queue or the prompt path.
Agent session: cosmic-gray
๐ค Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds acpmux send --supersede KEY so a correction replaces the same sender's prompts still queued under KEY instead of being read after the order it corrects.
Behavior
- Replaced prompts leave the queue like withdrawn ones: their
session/promptanswers withdrawn, thequeue_removedrecord saysreason: "superseded"andsupersededBy, and a restart never runs them; a key survives a restart, so a restored prompt can still be replaced. - Only prompts still waiting are replaced; one whose turn started stays. Replacement happens only where the new prompt is committed โ under the queue lock that puts it in, when its turn starts at once, or when it is steered in โ so a prompt refused while the chat moves replaces nothing and two sends under one key can't both stay.
- "Same sender" follows the queue's own notion (agent name via
--from, or the session the connection runs in); a forwarded keyed prompt names that session to the peer. Editing a waiting prompt drops its key. _meta.acpmux.supersedemust be a non-empty string of at most 256 bytes; anything else is refused withsupersede.invalid.acpmux sendprintsreplaced N queued(replaced ? queuedfrom a daemon that predates the key);--jsonaddsreplacedandreplacedPromptIds. Without--supersedethe output is unchanged.