cmux-tui tests: mint launch credentials over the verified app; acpmux agents start without one
Since dab1e80a0f8 ("fix(auth): require frontend credential authority"), only the verified cmux app may mint a launch credential: check_credential_owner refuses every other connection with credential_owner_only. That broke 32 of the 42 agent_message tests on feat-cmux-next. This PR fixes the callers and tests. check_credential_owner is unchanged.
- Harness mint.
Daemon::acp_credential(cmux-tuitests/agent_message_policy/harness.rs) minted over a plain connection, so everyagent_message_policyandagent_message_pumptest that needs a credential failed at setup. It now mints overDaemon::app(), the connection that proves itself with the install key.Appgets acallfor requests that aren't mutations, sincecredential.mintrefuses an idempotency key. The policy tests that mint now start an owner daemon (start_owner_with(name, env, acpmux)) so the app can prove itself. - acpmux's launch credential. acpmux mints in
acpmux/src/launch_credential.rsover its own plain connection toCMUX_TUI_SOCKET. dab1e80a0f8 removed itsLocalPeer::Acpmuxexception on purpose, and its doc says acpmux treats the refusal as non-fatal "until the frontend can delegate mint authority". So an acpmux agent now starts with no credential, and itscmux agent messagesends go out unverified. Making the app the minter for acpmux needs a new delegation path through Swift, the pane policy and acpmux, which is out of scope for a base-red fix.agent_message_launch_credential::an_acpmux_agent_sends_as_its_own_sessionasserted the old behavior. It is nowan_acpmux_agent_starts_without_a_credential_the_daemon_refuses: the daemon refuses acpmux's mint, the agent still starts with no credential, and the same holds with no daemon.the_sender_is_the_verified_actorstill checks that a credential the app mints sends as its ACP session. #23183 hits the same wall and has a proposal for the app-side design. - A red the setup failure was hiding. With setup fixed,
agent_message_pump::a_blank_acpmux_refusal_reason_reads_withdraw_refused(#21101) still failed.withdraw_refusaltrimmed the reason it parsed out of acpmux's message but not the one indata.reason, so a whitespace-only reason went out asacpmux_reason: " "instead ofwithdraw.refused. Both now get trimmed (cmux-tui-core/src/server/agent_message_acpmux.rs, separate commit).
Command: cmux-ci run --class isolated --script scripts/ci/cmux-tui-rust-check.sh --ref <sha> --arg test --arg agent_message
- Base e03e3f7299beb5d4c880e4845c1bad76ff44b17f, step
6f7445184dc71a402a54c316: 42 tests run: 10 passed, 32 failed. Every policy and pump test that mints failed onorigin.forbidden/credential_owner_onlyatharness.rs:418. The launch credential test failed with "the agent got no launch credential: CMUX_LAUNCH_CREDENTIAL=". - Head 9cb763481c82b11212344eabc0656386fd5e5fff, step
d507701927f31c5c4ed2c0e8: 42 tests run: 42 passed. - Intermediate head e8ca998174b (harness fix only), step
6e87d2bb4118d372a9110b23: 41 passed. The only failure wasa_blank_acpmux_refusal_reason_reads_withdraw_refused(acpmux_reasonwas" "), which the third bullet fixes.
Observed / Not run
Observed: the three fleet runs above, and --arg fmt green on the head (step 73cef9ebe3251a0f5e3366f3). python3 scripts/cmux-next/prepush-gate.py reported no new violations on both commits.
Not run to completion: --arg clippy on the head (step ba477ac5f9544a914cfb3b7f) failed in cmux-worktree-care/src/store.rs:97 (sort_by_key). This PR doesn't touch that crate, and #23183 reports the same failure on base. Because the build stops there, clippy never checked the crates this PR changes. Tests outside the agent_message filter were not run.
Risk: risk_tier.py classify gives normal (the agent_message_acpmux.rs change). The auth policy code is untouched.
Changelog
none
Agent session: cosmic-gray
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes the 32 agent_message tests broken when launch-credential minting became restricted to the verified cmux app, and normalizes blank acpmux withdraw-refusal reasons.
- The test harness now mints launch credentials over
Daemon::app(), the connection proven with the install key; policy tests that mint start an owner daemon. - acpmux's mint is still refused, so an acpmux agent starts without a credential;
agent_message_launch_credentialnow asserts that instead of the old minted behavior. withdraw_refusalnow trims the reason fromdata.reasontoo, so a whitespace-only acpmux refusal readswithdraw.refusedinstead of emitting the raw whitespace.