Repository navigation
acpmux: a question answered in the pane counts on another machine under the person's proof (re-cut of #23869, daemon side) - #25424
Conversation
|
Owned by hb-acpmux on big-red · session |
…et cover exactly what the person picked (fails: annotations are refused without the person, the daemon verb refuses them, the ticket names no answers) Codex review of #25424: the remote wire dropped a question's annotations (the chosen preview, #24356), and the gesture ticket named no answers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… under the person's proof, and its ticket binds the answers Codex review of #25424: - The remote wire, the session daemon's client and agent-session-permission now carry a question's annotations (Claude Code's chosen preview and notes, #24356) beside its answers. acpmux counts annotations from a connection that is not the person only under the person's decision proof over them: the answers proof gains a seventh part, the annotations' digest, when the answer has annotations. A phone's signed answer still never carries them. - A permission answer's gesture ticket now names the question's answers and annotations, compared by their canonical JSON, so a ticket the page took for one answer never redeems or gets signed for another. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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)
Stale: these images are of Gallery before/after for
States
Pick other states with a |
…er the person proof over its answers and annotations Re-cut of #23869 (cosmic-gray lane), daemon side; the pane side is its own PR. A relayed AskUserQuestion answer was refused because the person decision proof (cx-0q7o) never covered answers. acpmux-person-decision-answers-v1 covers the answers digest, and the annotations digest when there are any; annotations from a connection that is not the person count only under it. cmux-tui agent-session-permission carries answers and annotations to acpmux unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b7ab635 to
a7c004b
Compare
a7c004b to
fd848fb
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review (codex gpt-6-astra xhigh, hb-stale-pane-review): SHIP at 40cba81 |
|
|
|
Shipped in:
|
Re-cut of #23869 (by the cosmic-gray lane 01a15bdd, now gone), rebased onto feat-cmux-next. The stale-pr-reconciler gave it to hb-acpmux; Leo, 2026-10-25: "these should never have been this stale for this long". Credit for the work goes to #23869. It is split in two to stay under 800 lines: this PR is the daemon side (acpmux, cmux-tui), and #25440 is the pane side (Swift, web). Each lands on its own: until both are in, an answer relayed from the pane is still refused, the same as today.
Answering an agent's question in the Mac app's chat pane failed for a chat on an ssh peer (Leo hit it live on huge-blue). The peer's acpmux refused it with "approve this on the Mac app: allowing a permission is accepted only from the cmux app".
Cause
A chat on another machine gets its answers over a connection that is never the person, so the peer counts an allow only when it carries the person's decision proof (cx-0q7o). That proof never covered question answers:
person_decidedandrespond_permissionrefused any proof whenanswerswas present.Fix
acpmux-person-decision-answers-v1(hub/person/decision_answers.rs), signs the allow's five parts plus the sha256 of the canonical answers JSON (approvers::answers_digest). When the answer has annotations (Claude Code's chosen preview and notes, Send a question's chosen preview back to Claude Code (annotations) #24356), the sha256 of the canonical annotations is a seventh part.agent-session-permissioncarriesanswersandannotations(objects of at most 64 KiB each, annotations only beside answers) to acpmux unchanged (spec/commands.md).Tests
cargo test -p acpmux --test person_allow:a_relayed_answer_counts_with_the_persons_proof_over_exactly_its_answers, red at 2f32042 (a compile error: the proof does not exist yet).a_relayed_answers_annotations_count_only_under_the_persons_proof_over_them, red at 9aab5bf (run: the annotated answer is refused).the_answers_decision_proof_matches_the_apps_vector, with annotations and a character outside the BMP. The vectors were computed independently in Python, and the Swift side checks the same vectors in agent pane: a question answered in the pane for a chat on another machine carries the person's proof (re-cut of #23869, pane side) #25440.cargo test -p cmux-tui-core:a_question_answer_carries_its_answers_and_proof_to_acpmux_unchanged, red at e621126.a_question_answers_annotations_go_to_acpmux_unchanged, red at 9aab5bf.cargo test -p acpmux --test hub_integration questions: 8 of 8 pass. clippy-D warningsis clean, and rustfmt is clean at this head.agent_tools::tests::own_servers_run_under_the_daemon_prefixalso fails on base 41e4d6b (run). It is not this PR's.Review
Codex gpt-6-astra xhigh, through the bare mirror. Round 1 BLOCKed with two findings: the ticket did not bind the answers, and the remote wire dropped annotations. Both are fixed with tests. Round 2 BLOCKed on Unicode equality in the Swift ticket, which is fixed in #25440. Round 2 confirmed the daemon side by inspection. The final verdict at this head is in a comment.
No new timers or observers.
No capture: the change is in the proof and the daemon verb, and nothing in the UI changes.
Changelog
Fixed: Answering an agent's question in a chat on another machine no longer fails with "accepted only from the cmux app" (with #25440).
risk:high: this changes what the person's decision proof covers (auth).
Agent session: big-red
🤖 Generated with Claude Code