Repository navigation
fix(acpmux): authenticate signed macOS update clones for handoff - #27377
Conversation
|
Found 9 test failures on Blacksmith runners: Failures
|
|
Bead |
|
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)
red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 8c5ab04 to compare; do not merge until green; see lane-rules |
teamleaderleo
left a comment
There was a problem hiding this comment.
Review (gpt-6-astra, high, fast; independent Codex reviewer): SHIP at d8c52ff
All four review passes ran in one session:
- Full-diff review at 291e88f: its only blocker was the missing
SecCodeCopyDesignatedRequirementexport inscripts/ci/macos-stubs/Security.tbd, and it found no security blocker. - Delta review 291e88f..79a3ced: SHIP. The fix adds exactly that stub export.
- SDK check at 79a3ced: SHIP. The declaration is at Xcode 26.6 SecCode.h:327, the export at Security.tbd:419, and no other exports were added.
- Delta review 79a3ced..d8c52ff: SHIP. Two De Morgan rewrites of the guards, same semantics.
Tests:
- Red: run 40856942331 shows the old refusal behaviour.
- Linux green at this head: run 40859608901 (12 exe_path tests, 41 cmux-link tests, clippy for acpmux and cmux-link).
- macOS fleet at this head: step 743bd914, nextest run 87710e22; all 4 sign_clone tests pass.
Remaining reds match base:
- test_ir
new-pane-right(inventory, protocol contract) - No-SwiftUI HomeChatColors
- release-notary test_digest on
tool-audio-discovery.md, which came from #27362
Risk: the reviewer noted that the tests mock signature verification and never exercise a real signed clone. A follow-up should add a macOS test against a real ad-hoc-signed copy.
|
The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40863444386 at e85bfbd failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files. |
|
Shipped in:
|
caller_macos.rs still resolves update clones through crate::sign_clone (#27377); the receiver port dropped its declaration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5
* Port root-owned Native guest receiver authority and lifecycle Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Include signed Native receiver interoperability fixture Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Preserve authenticated token issue times at the daemon boundary Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Attach the Native receiver to the root-owned daemon startup Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Keep guest-only parent channel gated to Linux Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Spawn the Native receiver through the descriptor-safe process wrapper Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Record the reviewed held-child identity check Independent review confirmed that supervised.rs reads only the pid from the retained Child after try_wait, compares captured start ticks, and never enumerates processes or accepts an external pid. Keep this exact single-pid authentication read as the PID-reuse fence; retain the child handle and process_start checks. Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Keep receiving service conversion non-panicking Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Exercise handshake capacity reclamation before valid admission Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Include the private Unix descriptor transfer dependency Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Accept the current Worker signed machine-role claim in Native tokens Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Bind Native owner gates to the authenticated connection role Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c * Preserve signed Native roles through the receiver handoff Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * Admit signed Native owners through the first-chat carrier Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c * Carry GUI terminal attachment operations for signed Native owners Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c * Limit Native terminal policy changes to the GUI latest mode Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c * Use the transfer host test fixture from its defining module Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4 * cmux-link: keep the macOS sign_clone module declaration caller_macos.rs still resolves update clones through crate::sign_clone (#27377); the receiver port dropped its declaration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * protocol: receiver ops use json-checks isPattern Schema.isPattern drops the pattern from the exported JSON Schema; the json-checks guard (json-checks.test.ts) requires the shared helper. Catalog regenerated; TS and Rust clients unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-host: keep the harness-login send path over the bounded Cloud transport The merge with feat-cmux-next brought harness_login's PlatformHttp, which calls JsonPoster::send (GET/PUT with a bearer). The receiver branch had replaced the blocking reqwest client with the bounded Transport; send and get now go through it with the method passed explicitly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-host: github_repos test token carries the enrollment the client now checks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-host, cmux-tui-core: keep team SSH auth and NEXT's team-VM creator policy Review at 99e6f0f (BLOCK, two P1s): - The typed token check pinned bound.grant, but team SSH bindings carry no grant, so CA/account sync could never authenticate. A grantless binding now pins user, install and team; the bounded original-authority path still requires and pins a grant. - Native role/dispatch/terminal tests expected a signed owner to be refused on a team VM, contradicting NEXT's creator policy (#28788). A signed owner is the creator and is admitted there; signed team and missing roles stay refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-host: name the grantless test client so it doesn't shadow client() Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-tui-core: native remote-entry tests pass clippy -D warnings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-cloud-wire: take feat-cmux-next's generated types_02 (drop merge markers) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 * cmux-cloud-wire: regenerate after the feat-cmux-next merge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
A NEXT update can relaunch the app from macOS's
code_sign_clonebundle. The daemon currently refuses its handoff as a temporary executable, leaving the old daemon running after its binary is deleted and every pane failing the server peer check.Leo: "30+ seconds just for the chat to come back"
Leo's standing rule: "OUR F***ING STUFF IS HARDLY EVER GOING TO GO IDLE... ACCEPT IT BREAKING AT SOME POINT BUT IT RESUMES WHATEVER IT INTERRUPTED."
Recognize update clones only after full Security.framework validation of the clone and installed
/Applicationsbundle and their executables. Their Apple-anchored Team IDs and signed identifiers must match this signed build. For handoff, the socket peer's audit-token-bound running code must also satisfy the installed executable's designated requirement. A copied unsigned or modified binary in a clone-shaped directory cannot pass. Missing/invalid signatures fail closed. Plain temporary executables and runner_workpaths stay refused.The app's
AcpmuxServerPeercheck remains unchanged: its unknown-peer error follows the deleted old executable. Allowing verified handoff lets that daemon stop normally. Starting at/Applicationsis deferred because the app enrolls only at its expected exact executable path; changing that independently would break enrollment.Validation:
6eb8110057c3d8069e93f88b41fbd0bbb97a1848: 11 existing executable-path tests pass;sign_clone_start_and_handoff_require_signature_prooffails with the old refusal behavior.79a3cedbc3a6c5929d0ff5b95665298643b7a98a: run 40858609739, all 12 executable-path tests and all 41 cmux-link tests pass.cargo check -p cmux-link --target aarch64-apple-darwinalso passes.d8c52ff2e884e5090a8082b2cc7388784ebb7f06simplifies two guard predicates to satisfy clippy without changing their behavior. Exact-head Linux regression/clippy is green: run 40859608901, including 12 executable-path tests, 41 cmux-link tests, and clippy for acpmux/cmux-link. Independent Astra high/fast review is SHIP at that exact head. Fleet macOS compile/tests also pass at this head: step743bd914d4c3a88e0409a72b, nextest run87710e22-ec12-4aee-b4a6-7993fd9b7004,scripts/ci/cmux-tui-rust-check.sh test sign_clone(profile ci), 4 selected tests passed, 0 failed, 12050 skipped. The tests cover clone signature matching, missing/mismatching signatures, temp/runner rejection, and start/handoff acceptance. The earlier overflow-routed step was cancelled before testing and supplies no evidence.SecCodeCopyDesignatedRequirementin Xcode 26.6's Security header and framework export stub. This PR adds only that symbol to its cross-build stub.Base CI warnings, compared by the coordinator: SDK generation fails
test_live_raw_v12_layout_and_history_contracts_are_exact(new-pane-right); the SwiftUI guard flagsHomeChatColorsPanel.swiftandHomeChatColorsView.swift. None of those files or behaviors changes here. The two clippynonminimal_boolerrors introduced here are fixed and clippy passes at the current head.Signature-decision unit tests use a fake reader of validated signature facts, so CI needs no signed app fixture. Production uses SecStaticCode and audit-bound SecCode validation; these tests do not claim a real signed-clone runtime reproduction.
Related app recovery work: #27283 (separate files).
pr-overlapwas attempted but its GraphQL read is unsupported by the lane broker; PR search found only that companion PR.Risk: changes an executable trust decision. The exception requires cryptographic proof, is macOS-only, preserves the runner guard and existing app authorization rules, and never trusts a folder name alone.
Agent session: agent session