Skip to content

cmux vm token: one macOS lock per user; revoke removes an unreadable token - #29719

Merged
teamleaderleo merged 6 commits into
feat-cmux-nextfrom
lane/cloud-vm-29705
Nov 1, 2026
Merged

teamleaderleo merged 6 commits into
feat-cmux-nextfrom
lane/cloud-vm-29705

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Two follow-ups from the review of #27603, both in the cmux vm token store (workers/cmux-vm/cli/crates/cmux-vm/src/token.rs, dispatch in lib.rs).

#29705, one lock per user for the macOS Keychain item. The issue: "On macOS the token lives in one login Keychain item per user (fixed service and account), so two creates run with different XDG_CONFIG_HOME or HOME values take different locks, can both see an empty store, both mint, and one overwrites the other's stored key, leaving that key live with nothing able to revoke it." On macOS the store lock now follows the account: <home>/.config/cmux/vm-token.lock, with the home from the user database (getpwuid(geteuid()) through nix's safe User::from_uid; the crate forbids unsafe). In the usual environment (HOME is the account's home, no XDG_CONFIG_HOME) that is the same file as before, so an older cmux running at the same time still shares it. With no user-database entry (or a home that is not absolute) the macOS lock fails closed with an error instead of falling back to the environment, which would split the lock again. Linux and other platforms keep the lock beside the file store: that store's file itself follows XDG_CONFIG_HOME or HOME, so another environment is another store and nothing is overwritten.

#29706, an unreadable stored token names a recovery that works. The issue: "When the stored VM token's JSON cannot be read, the error recommends cmux vm token revoke. But token revoke loads the same stored token before it runs, so it fails with the same error." Now token revoke on a store holding something that is not a token (bad JSON, not text) removes that local copy, under the store lock and only while it is still unreadable, and says its key was not revoked and expires within its TTL (at most 24h), which deletes its VMs. --json prints {"id": null, "revoked": false, "removed": true}. The error now says exactly that. A store that cannot be read at all (Keychain refusal, a file other users can read) is still an error; the world-readable-file error no longer suggests a revoke that would fail, and says to chmod 600 it first.

Adds nix 0.31 (feature user, macOS only) to cmux-vm; cmux-tui's lock already has nix 0.31.3.

Fixes #29705
Fixes #29706

Changelog

  • Fixed: cmux vm token create takes one lock per macOS user, and cmux vm token revoke removes a stored token it cannot read instead of failing.

Tests

  • cargo test --locked -p cmux-vm --test lifecycle revoke_removes_an_unreadable_stored_token (in workers/cmux-vm/cli): fails at the test commit 5b12a6e, passes at the head.
  • cargo test --locked -p cmux-vm --lib the_lock_follows_the_account_not_the_environment: does not compile at the test commit (no account-keyed lock existed), passes at the head. two_environments_of_one_user_share_the_macos_lock runs on macOS only.

Observed / Not run

Observed on Linux CI (run 41245035670, head 70bcc7a): at the test commit the integration test FAILED (exit 101) and the unit test did not compile (exit 101); at the head both pass, cargo test --locked -p cmux-vm passes (45 unit, 83 lifecycle and the rest), cargo clippy --locked -p cmux-vm --all-targets -- -D warnings passes, and cargo test --locked -p cmux-tui cli::vm passes (25). The macOS code compiles in the PR's cmux-tui artifacts / build aarch64-apple-darwin and x86_64-apple-darwin jobs (green). Not run: the macOS-only test on a Mac, and a live Keychain (a cross-target cargo check on Linux had no macOS std installed).

No capture: CLI only, no UI change.

🤖 Generated with Claude Code
Agent session: agent session

teamleaderleo and others added 2 commits October 31, 2026 21:28
… unreadable token (#29705, #29706)

On macOS the token is one login Keychain item per user, so the store lock now
follows the account (its home from the user database), not HOME or
XDG_CONFIG_HOME. A stored token that cannot be read is removed by
`token revoke` (its key cannot be revoked without it and expires within its
TTL), and the error for it says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-75b7a03d1a2084cf16af
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 00dd1a0: 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=pr29719 -f ref=lane/cloud-vm-29705 -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 4510f25; does not block

Shipped in:

@teamleaderleo teamleaderleo added the risk:high Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:high Risk tier (docs/ci/risk-tiers.md) labels Oct 31, 2026
…s home

Review finding: falling back to HOME/XDG_CONFIG_HOME when the user database
has no home would split the lock again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-75b7a03d1a2084cf16af
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, next-review): BLOCK at 70bcc7a

BLOCK at 70bcc7a

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] lifecycle.rs:2610: The new test’s cfg(not(target_os = "macos")) includes Windows, where std::os::unix and Permissions::from_mode are unavailable. This breaks compilation of the lifecycle test target on Windows. Guard the Unix permission operations with cfg(unix) or restrict the test accordingly.

  2. [P2] [follow-up] token.rs:732: matches! discards errors from the locked re-read. If permissions change or Keychain access fails between reads, revoke returns success and claims the token was replaced, although recovery failed. Propagate the read error before checking whether the contents remain unreadable.

Cargo tests could not run because the box has no Rust toolchain.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high fast): SHIP at 70bcc7a

SHIP
Visual verdict: n/a (CLI only)

Findings

No [blocking] or [follow-up] findings.

The earlier fallback issue is fixed: macOS lock creation fails closed when the user database has no absolute home and never consults HOME or XDG_CONFIG_HOME. Non-macOS locking mirrors the environment-based file store.

Unreadable-token removal rechecks under the shared store lock, while readable-token revocation rechecks the key before deleting local state. nix uses the user feature, and both lockfiles pass cargo metadata --locked. Formatting and diff checks pass. The focused fleet test could not dispatch because the broker socket was unavailable.

An earlier review at 257bad7 blocked on the macOS lock falling back to HOME/XDG_CONFIG_HOME without a user-database home; 70bcc7a makes it fail closed, and this review is at that head. Green compile: Linux CI run 41245035670 (cmux-vm tests and clippy, cmux-tui cli::vm) and cmux-tui artifacts aarch64/x86_64-apple-darwin builds at the head.

lifecycle.rs: both sides added tests at the end (revoke_removes_an_unreadable_stored_token
here, #29722's kept-run archive tests on base); both are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-75b7a03d1a2084cf16af
@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Found 8 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp5a43kfce/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpu25f4abf/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
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)/
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)
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

Review (codex gpt-6-astra high, next-review): SHIP at 00dd1a0

SHIP at 00dd1a0

Visual verdict: no images; Leo tries the build

No findings.

Follow-ups: none

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high fast): SHIP at 00dd1a0

SHIP
Visual verdict: n/a (CLI only)

Findings: No verified blocking or follow-up defects. The macOS lock fails closed without an account home, unreadable-token removal is lock-protected and revalidated, readable revocation remains server-first, callers and base archive/CLI changes integrate correctly, and both locked workspaces resolve metadata successfully.

Verification: reviewed both merge diffs and callers; cargo metadata --locked --no-deps passed for both workspaces.

This head merges feat-cmux-next into 70bcc7a (SHIP, no findings); the one conflict, tests/lifecycle.rs, keeps both sides' new tests. Tests at this head (cmux-ci run 41260858997): cargo test --locked -p cmux-vm 49 unit + 86 lifecycle + 3 + 1 pass; cargo clippy --locked -p cmux-vm --all-targets -- -D warnings clean; cargo test --locked -p cmux-tui cli::vm 27 pass. The red/green for the new tests is at 5b12a6e (earlier receipt).

Not this PR's red: clippy (changed cmux-tui packages) fails at this head only on the panic ratchet's cmux-chat-index: clippy::indexing_slicing 33 > baseline 32. This PR changes neither cmux-chat-index nor scripts/cmux-next/rust-panic-baseline.json against its base 2fbbb12, and unrelated open PRs #29967 and #29943 fail the same check with the same cmux-chat-index 33 > 32 line, so it is base's (cmux-chat-index last changed on base in #28771 / #28755).

cmux-bot[bot]
cmux-bot Bot previously approved these changes Nov 1, 2026

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

cmux-bot approves 00dd1a0: an independent review passed this exact head (next-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot 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-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 02:23 Inactive
@cmux-bot
cmux-bot Bot dismissed their stale review November 1, 2026 02:25

A newer verdict blocks 9d9c1cc (no independent SHIP at the head).

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high fast; carried by patch-id): SHIP at 9d9c1cc

This head is cmux-bot's base merge of 00dd1a0, reviewed SHIP there (issuecomment-6552119419). The PR's change against its base has the same git patch-id --stable at both heads (04a1df21ba28e84078b1bcc0488dd75b192e1122), so the review carries. Reds at this head are base's: clippy (changed cmux-tui packages) fails only on acpmux/src/hub/processes.rs:256 (redundant closure), a crate this PR does not change.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high fast; carried by patch-id): SHIP at ca989b5

This head is cmux-bot's base merge of 9d9c1cc (itself a base merge of the SHIP-reviewed 00dd1a0, issuecomment-6552119419). The PR's change against its base still has git patch-id --stable 04a1df21ba28e84078b1bcc0488dd75b192e1122, so the review carries. The release-notary red is base's: this PR changes nothing under release-notes/, scripts/whats-new/ or scripts/ci/, and the same job fails on unrelated open PRs.

@teamleaderleo
teamleaderleo merged commit b13c08d into feat-cmux-next Nov 1, 2026
222 of 227 checks passed
@teamleaderleo
teamleaderleo deleted the lane/cloud-vm-29705 branch November 1, 2026 06:33

This branch was previously deployed

3 inactive deployments
artifacts — ca989b57 Deployed Nov 1, 2026 by cmux-bot[bot] via add the Windows daemon to the tree #93745
sentry-dsyms — ca989b57 Deployed Nov 1, 2026 by cmux-bot[bot] via upload cmux-tui dSYMs to Sentry #93745
ci-routing-agent — ca989b57 Deployed Nov 1, 2026 by cmux-bot[bot] via cmux-tui tree preflight #93745
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