Skip to content

fix(acpmux): authenticate signed macOS update clones for handoff - #27377

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/hb-signclone
Oct 29, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/hb-signclone

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

A NEXT update can relaunch the app from macOS's code_sign_clone bundle. 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 /Applications bundle 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 _work paths stay refused.

The app's AcpmuxServerPeer check remains unchanged: its unknown-peer error follows the deleted old executable. Allowing verified handoff lets that daemon stop normally. Starting at /Applications is deferred because the app enrolls only at its expected exact executable path; changing that independently would break enrollment.

Validation:

  • Red: run 40856942331, 6eb8110057c3d8069e93f88b41fbd0bbb97a1848: 11 existing executable-path tests pass; sign_clone_start_and_handoff_require_signature_proof fails with the old refusal behavior.
  • Green at 79a3cedbc3a6c5929d0ff5b95665298643b7a98a: run 40858609739, all 12 executable-path tests and all 41 cmux-link tests pass. cargo check -p cmux-link --target aarch64-apple-darwin also passes.
  • Current head d8c52ff2e884e5090a8082b2cc7388784ebb7f06 simplifies 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: step 743bd914d4c3a88e0409a72b, nextest run 87710e22-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.
  • The review also verified SecCodeCopyDesignatedRequirement in 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 flags HomeChatColorsPanel.swift and HomeChatColorsView.swift. None of those files or behaviors changes here. The two clippy nonminimal_bool errors 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-overlap was 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

@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Found 9 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpdv68ds0h/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpf47xtkl5/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')/
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')
View Logs
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')/
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')
View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review d8c52ff: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr27377 -f ref=lane/hb-signclone -f platform=macos -f backend_mode=local

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
teamleaderleo marked this pull request as ready for review October 29, 2026 11:00

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 SecCodeCopyDesignatedRequirement export in scripts/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.

@teamleaderleo
teamleaderleo merged commit 89b99d5 into feat-cmux-next Oct 29, 2026
181 of 188 checks passed
@teamleaderleo
teamleaderleo deleted the lane/hb-signclone branch October 29, 2026 11:02
@github-actions

Copy link
Copy Markdown
Contributor

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.
Those jobs last passed at 3aae968. This pull request is one of 4 merged since: #27377, #27390, #27379, #27220.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Nov 1, 2026
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
teamleaderleo added a commit that referenced this pull request Nov 1, 2026
* 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>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — d8c52ff2 Deployed Oct 29, 2026 by teamleaderleo via cmux-tui tree preflight #76423
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant