Skip to content

acpmux: _acpmux/queue_get reads a held prompt whole for the owner - #26855

Closed
teamleaderleo wants to merge 18 commits into
feat-cmux-nextfrom
lane/mp-queue-get
Closed

teamleaderleo wants to merge 18 commits into
feat-cmux-nextfrom
lane/mp-queue-get

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

HOLD: stacked on #26747; rebase and drop this line once it lands.

Leo (2026-10-28), on T3 Code's "Share with guest": "we want to be having, be able to do this kind of flow for CMux multiplayer ... we can work on the agent chat multiplayer." In that flow each message a guest sends waits for the owner, who approves or declines it. Before approving, the owner's pane needs the whole prompt: its words, its images and files, and the revision the approval names. This PR adds that read. Plan: manaflow-ai/cmuxterm-hq#4766.

Only the last commit is this PR's. Everything below it is #26747.

What it does

  • New method. _acpmux/queue_get {sessionId, promptId} returns {sessionId, promptId, turnId, revision, text, prompt, inlineParts, author, provenance, awaitingOwner} for a prompt that is still in the queue:
    • prompt is the full content blocks as the prompt would run now, including the author's edits: images with their data, resource links, audio and files.
    • revision is the value _acpmux/queue_approve expects.
  • Once the prompt has left the queue (approved and run, declined or removed): queue.not_found (-32002), with data.decided set the same way queue_approve sets it.
  • Caller rules, the same as queue_approve:
    • Owner only: a caller with an author gets queue.owner_only.
    • A Web caller has to pass the Web-control check.
    • The Full-access hold applies.
  • Peer forwarding: forwarded only to a peer that lists the new feature queueGet, and sent on the link that listed it (Peer::lists_on). Otherwise it fails with queue.approval_unsupported and nothing is forwarded.
  • New capability: queue-get-v1.
  • Updated: docs/acpmux-schema.json, the README method list, spec/acpmux-protocol.json, and the TS types regenerated with bun scripts/acpmux-protocol-codegen.ts.
  • What a peer gets: a peer's caller receives the prompt unmasked. That matches the queued and queue_updated records peers already receive (peer_text.rs masks only summaries).

Risk

risk:low. A new read-only method that sits behind the same checks as queue_approve. Nothing that exists changes behavior.

Tests

  • hub_integration prompt_approval::the_owner_reads_a_held_prompt_whole_at_its_revision. After the guest edits a held prompt that had an image and a file link, queue_get returns the new text, the kept blocks, revision 1, its author and provenance. A caller with an author gets queue.owner_only. After a decline, the prompt is queue.not_found with decided: "declined".
  • peer_queue_approval:
    • A peer without queueApproval refuses get, approve and decline.
    • A peer that lists queueApproval but not queueGet refuses get, and nothing is forwarded.
    • A peer that lists queueGet is forwarded the get.
  • The cmux-ci receipt is in a comment.

Changelog

none

Agent session: agent session

🤖 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

Adds owner approval for queued guest prompts in chatbot mode: a person's prompt waits for the owner, who approves or declines it, and can read the prompt whole before answering. Previously the owner only saw the queued preview; now they get full content blocks (including images and files), the current revision, and author/provenance info. Also blocks the prompt from reaching an older daemon that would run it unapproved.

Approval flow

  • _acpmux/queue_approve runs the prompt in its queue place at the revision the owner saw; a stale revision is refused queue.stale. _acpmux/queue_decline drops it and its session/prompt answers queue.declined.
  • Owner-only (queue.owner_only), under the Web-control check and Full-access hold; the guest can edit (new revision, still waiting) or remove it.
  • Approvals and declines bind to their queued prompt under the queue lock, so a restart or a concurrent removal can't apply them to the wrong prompt.

Access and forwarding

  • _acpmux/queue_get returns the full blocks, revision, author, and provenance; once the prompt leaves the queue it returns queue.not_found with the same decided value as queue_approve.
  • Held prompts and owner answers are forwarded only to a peer listing queueApproval, on the link that listed it; queue_get requires queueGet. Otherwise queue.approval_unsupported and nothing is forwarded.
  • Moves refuse transfer.held_prompts while any prompt waits for the owner, since an older build would run it unapproved.
  • Adds capabilities queue-approval-v1 and queue-get-v1.

Written for commit 68ac4b4. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 17 commits October 28, 2026 10:05
Chat multiplayer, Share with guest (manaflow-ai/cmuxterm-hq#4766, first PR). A
person's prompt whose author carries `approval: "owner"` (a link guest,
`guest:<id>`) is queued, never steered in nor stopping the running turn, and
the queue runs past it until the owner answers:

- `_acpmux/queue_approve {sessionId, promptId, revision}` runs it in its place
  as a queued prompt; a stale revision is refused `queue.stale`.
- `_acpmux/queue_decline {sessionId, promptId}` drops it; its session/prompt
  answers `queue.declined`.

Both are owner-only (`queue.owner_only`) and held to Web control and the
Full-access machine like a prompt. The guest may edit (a new revision, still
waiting) or remove it; move, send now and interrupt are refused
`queue.awaiting_owner`, and an edit after approval `queue.approved`. At most
16 wait per author (`queue.too_many_held`). Records: `queued` gains
`awaitingOwner`/`revision`, new `queue_approved` and `queue_declined`; the
queue summary exposes `awaitingOwner` and `revision`; a restart rebuilds it
all from the log. Capability `queue-approval-v1`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…ed in order

Review of #26747: a restart applied an approval to a later prompt reusing the
id, and an approval logged after the author's removal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…e queue lock

Restore applies queue_approved to the queued record with the same turn id,
never to a later prompt that reuses a client-chosen prompt id. Approve and
decline append their records under the queue lock that changes the queue, so
the author's concurrent removal is always logged after them, and a late
answer's decided reads the last decision for the prompt's latest incarnation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…gent

Review of #26747: a Send now racing the guest's prompt could set its steer
flag, and nothing checked the hold where a steer is let out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
Send now, move and put_next check the hold under the queue lock that changes
the prompt, not before it. queue_turn lets out no steer of a prompt that waits
for the owner, take_queued leaves such a prompt in the queue (and clears its
steer flag), and approval clears the steer flag, so an approved prompt runs in
its place, never as a steer, whatever flag a race left on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…t gone

The queue_moved wake can reach the waiting task before its withdrawal; it then
finds the prompt gone (take_queued) and answered withdrawn. It now answers
queue.declined when the owner declined it. Seen flaking in
a_declined_prompt_answers_declined_and_never_runs (3 of 8 runs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…t stays the answer

Review of #26747.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
The owner's decline of a restored prompt settles its cached outcome
(queue.declined); the restored task that then finds it gone answered
withdrawn and overwrote it. Both writes now settle the outcome once: the
first settled answer stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
Review of #26747: an older peer ignores author.approval and would run the
prompt unapproved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
…g queueApproval

The forwarder refuses a prompt whose author carries approval, and
_acpmux/queue_approve and _acpmux/queue_decline, with
queue.approval_unsupported when the peer did not list queueApproval at its
handshake: nothing is forwarded. Peer keeps the features it listed as one list
(Peer::lists), which the attachment, upload and resume checks now read too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
So peer.rs, over its size budget, does not grow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
A forwarded prompt also attaches the peer's session first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
Review of #26747: a move to an older build would restore the held prompt as an
ordinary queued one and run it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
- A move (transfer_begin) is refused transfer.held_prompts while any prompt
  waits for the owner, checked once the bundle is made, in the daemon: the
  destination may be an older build. Approve or decline it first.
- A held prompt, and the owner's answer to one, forwarded to a peer go on the
  link that listed queueApproval (Peer::lists_on), never on one a reconnect
  brought since; a link's end clears its feature list before its epoch moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
{sessionId, promptId} -> {promptId, turnId, revision, text, prompt (the full
blocks as it would run now), inlineParts, author, provenance, awaitingOwner};
queue.not_found with decided once it left the queue. Owner only
(queue.owner_only), under the Web-control check, and forwarded to a peer only
when it lists queueGet, on the link that listed it. Capability queue-get-v1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Oct 28, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-8va9lp created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-ci receipt at 68ac4b4f6296176283a9f3ca1d5469eeca6742b0 (job 48777ed6f91d4b98a80b66f14617d175, passed):

Suite Result
peer_queue_approval 1/1
peer_integration 50/50
hub_integration -- prompt_approval prompt_provenance queue steer (includes the_owner_reads_a_held_prompt_whole_at_its_revision) 63/63
lib author queue peer capabilities protocol (includes protocol_ir_is_current and initialize_status_and_the_cli_name_the_same_capabilities) 198/198

The generated TS is current (bun scripts/acpmux-protocol-codegen.ts --check).

initialize adds _acpmux/queue_get and queueGet to its lists in requests/queued.rs::advertised. They are not inside the reply's own json!, which is at the macro's recursion limit.

@teamleaderleo

teamleaderleo commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Carried on #29003 (same commits, authorship kept, on the current base). It lands after #28859, the carry of #26747.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Superseded by its carry #29003 (same commits, on the current base, after #28859). Closing this copy.

teamleaderleo added a commit that referenced this pull request Nov 1, 2026
…rries #26855) (#29003)

* acpmux: _acpmux/queue_get reads a queued prompt whole for the owner

{sessionId, promptId} -> {promptId, turnId, revision, text, prompt (the full
blocks as it would run now), inlineParts, author, provenance, awaitingOwner};
queue.not_found with decided once it left the queue. Owner only
(queue.owner_only), under the Web-control check, and forwarded to a peer only
when it lists queueGet, on the link that listed it. Capability queue-get-v1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
(cherry picked from commit 868904c)

* acpmux: initialize advertises queue_get outside its json! (recursion limit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-c3300437b0af7f1bba36
(cherry picked from commit 68ac4b4)

* acpmux: queue_get names a prompt's images with their sources (base renamed named to named_sourced)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-049fca947e3297e5ccd3

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch had an error being deployed

1 failed and 2 inactive deployments
sentry-dsyms — 68ac4b4f Deployed Oct 28, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #71649
artifacts — 68ac4b4f Deployed Oct 28, 2026 by teamleaderleo via publish to R2 #71649
ci-routing-agent — 68ac4b4f Deployed Oct 28, 2026 by teamleaderleo via wait for same-key tree publisher #71649
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:high Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant