Repository navigation
agent-pane-policy: the gesture pick is the Swift host's: hand-off prompt ids, answer digests, Double numbers - #31915
lawrencecchen wants to merge 12 commits into
Conversation
The Swift host's AgentPaneGesturePick binds a ticket to a hand-off prompt's own id (AgentPaneHandoffPrompt.ownID, 07efced), to a question's answers and annotations by the sha256 of their canonical JSON (AcpmuxSecretKey.canonicalDigest, 8c3e829; the same bytes as acpmux approvers::canonical_json), skips a null answers, and compares numbers as Double. The crate uses the raw prompt id and picks nothing for a frame with answers, so a ticket for a question answer or a hand-off prompt never redeems. tests/cases/picks.json (24 cases; the expected values from a line-for-line Python copy of the Swift code, which also asserts Swift's AgentPaneRelayedAllowTests canonical JSON vectors and acpmux's the_wire_payload_is_fixed digest) and parity.rs gesture_picks; check.json's ticketed question answer now expects its answers digest. Co-Authored-By: Claude <noreply@anthropic.com>
…at it now expects Co-Authored-By: Claude <noreply@anthropic.com>
…f prompt ids, answer digests, Double numbers GesturePick now matches Swift AgentPaneGesturePick: - a session/prompt picks its own id (own_prompt_id, a port of AgentPaneHandoffPrompt.ownID: one handoff-<turn>- label stripped); - a permission answer's answers and annotations are picked by the sha256 of their canonical JSON (src/canonical.rs, a port of AcpmuxSecretKey.canonicalJSON/canonicalDigest, the same bytes as acpmux approvers::canonical_json); a null one is no key; one that is not an object or has no canonical form picks nothing; - a number param is held as a Double, so 1 and 1.0 pick the same. sha2 is the workspace's 0.10.9, already in the app FFI lock (cmux-tasks-core): no new package. Co-Authored-By: Claude <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)
web and size checks: green |
|
Review (subagent, correctness first): SHIP at f0ff04d |
|
Evidence for ready-to-land at f0ff04d: SHIP receipt #31915 (comment); red at 491bc30 (4a1391d28e534741c122f80c: gesture_picks fails); green at this head: gesture_picks 22bc82b833861f1df34047de 1/1, full_check_order 36bfbb518b62f980b218a08f 1/1, panic 6565cf92c3ddee37fb2eb093 green; clippy green at the scratch ref 87e158b = this head + #31907 (3ae3fde409656c44d0833217), since feat's clippy is red until #31907 lands. No FFI input; no Swift change, so no Mac Swift suite applies. |
|
Review (independent review subagent): SHIP at 9f5bc0f Re-review after the cmux-bot merge of feat-cmux-next (previous SHIP at f0ff04d). Read-only; I ran no build or test.
|
This comment has been minimized.
This comment has been minimized.
|
Review (codex gpt-6.1-sol xhigh, next-review): SHIP at 6e6efc5 SHIP at 6e6efc5 Compared the changed paths with Swift and independently verified all 24 pick fixtures and existing full-check picks. Rust tests could not run because the box has no Rust toolchain. Follow-ups: none |
|
Found 1 test failure on Blacksmith runners: Failure
|
|
Review (codex gpt-6.1-sol xhigh, next-review): SHIP at 0a313a3 SHIP at 0a313a3 Compared against Swift and independently verified all 24 pick fixtures and canonical digest vectors. Cargo tests were not run because the box has no Rust toolchain. Follow-ups: none |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
A gesture ticket is bound to a pick: the method and the params it was taken for. The Swift agent pane host builds that pick three ways that the crate does not, so a host that runs the crate would never redeem these tickets:
handoff-<turn>-label (AgentPaneHandoffPrompt.ownID, 07efced). The crate used the raw id, so the ticket of a Cloud hand-off prompt never redeemed.answersandannotationsare picked by the sha256 of their canonical JSON (AcpmuxSecretKey.canonicalDigest, 8c3e829). The crate picked nothing for a frame with answers, so the ticket of a question answer never redeemed.1and1.0give the same pick.What changes in the crate:
src/canonical.rsportscanonicalJSON/canonicalDigest. These are the same bytes as acpmux'sapprovers::canonical_json: keys in UTF-8 byte order, no whitespace, only",\and control characters escaped, and an integral float below 1e15 written as an integer. A value with no canonical form has no digest, and its frame picks nothing.GesturePick::new(src/check.rs) follows SwiftAgentPaneGesturePick:own_prompt_id, the digests, a null answers is no key, andas_double.tests/gesture_pick.rs, with 24 cases intests/cases/picks.json. The expected values come from a line-for-line Python copy of the Swift code. That copy asserts Swift's own canonical JSON vectors (AgentPaneRelayedAllowTests) and acpmux's fixed digest (the_wire_payload_is_fixed,44ba30ad…), so the digests match Swift byte for byte.tests/cases/check.jsoncase now expects the answers digest, as Swift gives it, not "no pick". I renamed it to say so.sha2is the workspace's 0.10.9.cmux-tasks-corealready brings it into the app FFI lock, so no new package goes into the app.cmux-tui/Cargo.lockgains one dependency line.This is the last of the Swift-only drifts that would break features if the app called the crate (rm-pane-policy, layer-ownership V-23). The app does not call the crate yet, and cmux-app-ffi does not link it, so nothing changes in the app and this PR is no FFI input.
Security
A ticket binds a question answer to exactly those answers and annotations, by digest, as in the running Swift host. Before, Rust picked nothing for such a frame, so the ticket could not redeem it at all. No method or param is newly allowed, and the default stays deny.
Changelog
none
Observed / Not run
Observed (fleet, Linux,
scripts/ci/cmux-tui-rust-check.sh):gesture_picks: job 4a1391d28e534741c122f80c, FAIL.gesture_picks9d7d7a9962d481ba6d74a97e PASS;full_check_orderba855a870a310f1410dc80cd PASS.gesture_picks22bc82b833861f1df34047de PASS,full_check_order36bfbb518b62f980b218a08f PASS,panic6565cf92c3ddee37fb2eb093 green.Known differences, all fail closed (a ticket does not redeem; none reachable through check_frame today, because the answers rule refuses numbers in answers):
-0in answers digests as-0here and0in Swift; acpmux's canonical_json writes2.0where Swift and this crate write2; a hand-off idhandoff-12-followed by a combining mark loses its label here and not in Swift (Character vs scalar split).Not run: no Swift compile (no Swift change).