Repository navigation
base red: pty_reclaim takes poisoned locks instead of unwrapping (9e23760ae80; unwrap 1148 -> 1150) - #28853
Conversation
…ping (9e23760) 9e23760 (owner parks idle unwatched shells) added two `.lock().unwrap()` in mux/pty_reclaim.rs reclaim_candidates, raising the crash ratchet's rust cmux-tui-core unwrap row 1148 -> 1150. Use the crate's pattern, `.unwrap_or_else(PoisonError::into_inner)`, as the other mux readers of workspace_registry and state do. No behavior change unless a holder panicked; then the reaper reads the state instead of panicking.
…ing (045f9e0) 045f9e0 (feat(apps): install = deploy + pin) added seven `.lock().unwrap()` in the non-test code of apps/deploy.rs, raising the crash ratchet's rust cmux-tui-core unwrap row by 7. Use the pattern the same file already uses for instances (line 352) and apps/cancel.rs uses: `.unwrap_or_else(PoisonError::into_inner)`. No behavior change unless a holder panicked.
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. |
|
Review (claude-review-subagent): SHIP at 39614fe Correctness first. The review was read-only, in a fresh worktree at the head. I did not compile it: the fleet compile is a separate step.
Not run: cargo build and test. The fleet compile result is still necessary. |
…ne runs out of PTYs
macOS gives the machine 511 PTYs (kern.tty.ptmx_max). Every terminal host holds
one for life, so a session with hundreds of agent workspaces, each with a shell
tab nobody opened, used them all. On Lawrence's Mac (2026-10-30) the owner held
480 of 511, and 431 of those were shells idle at a prompt for a median 148 h with
no client. Every new workspace then failed with 'PTY capacity exhausted (os
error 6)'.
When fewer than 64 PTYs are free, the terminal reaper thread now parks shells
(park-tabs, tab-park-v1) until 128 are free. The tab stays and shows
'relaunch: {cwd}', and the app starts it again when it is shown. A shell is
parked only when all of these are true: it has sat at its prompt (OSC 133 A)
and printed nothing for 30 min or more, no client is attached to any of its views, no program reports an OSC 7501 status
in it, and it is not kept. The oldest prompt goes first. A launch that fails
for lack of PTYs wakes the pass at once. Nothing happens while PTYs are
plentiful.
Live, on the same rules through park-tabs: 511 -> 351 PTYs in use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ud VM
Manifest v2 gains deploy {server: {kind: container, image, port, health},
tenancy, targets} and implements[cmux.pane/1].remote = instance; billing
{model} is free only (Lawrence 2026-10-30). The validator refuses a remote
pane without deploy and a local target for a third-party app; the schema
refuses shell characters in image and health.
cmux.apps.install takes deploy {target}: self-hosted:<ssh host> (the
customer's own machine over SSH or Tailscale SSH, no cmux Cloud call) or
cloud-vm:<machine> (cmux cloud exec). One POSIX runner for both: docker or
podman run bound to the tailnet address (else 127.0.0.1, never every
interface), wait for the health path, print the URL. The install commits and
answers with the instance deploying; a worker records running + URL, or rolls
the install back (container removed) with the reason in the app log. Remove
removes the container. Instances persist in <state>/apps-instances.json and
show in apps-list and installed.list.
|
Found 9 test failures on Blacksmith runners: Failures
|
|
Fleet compile on head 39614fe: |
…y-reclaim-unwraps # Conflicts: # cmux-tui/crates/cmux-tui-core/src/apps/deploy.rs
|
Review (claude-review-subagent): SHIP at 61fa3cb Checked on a fresh detached worktree at the head (origin/feat-cmux-next = dff3196, the merge's second parent, so no newer tip to re-merge).
Not run here: cargo build/test (fleet compile runs separately). |
|
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); base red: the same failure on the base dff3196; does not block Shipped in:
|
|
Fleet compile on head 61fa3cb: |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Base red on
feat-cmux-next: the "Crash safety" step ofcmux-next checksreportscrash-ratchet: rust cmux-tui-core: unwrap 1148 -> 1150.9e23760 ("the owner parks idle unwatched shells before the machine runs out of PTYs") was a direct push by lawrencecchen, with no PR. It added two non-test
.lock().unwrap()calls inmux/pty_reclaim.rsreclaim_candidates. It is a 335-line fix for PTY exhaustion on a real machine, so a revert is not small.This PR uses the crate's pattern,
.lock().unwrap_or_else(PoisonError::into_inner), as the other mux readers ofworkspace_registryandstatedo (detached_terminals.rs,command_history.rs). The behavior changes only if a lock holder panicked; then the reaper reads the state instead of panicking. No waiver is recorded and the baseline does not change.History: the first head also fixed 7 unwraps in
apps/deploy.rsfrom 045f9e0 (1150 -> 1157). #28847 fixed those on the tip in the meantime. A merge oforigin/feat-cmux-nexttakes the tip'sdeploy.rs, so this PR now changes onlypty_reclaim.rs.Testing
Check:
scripts/cmux-next/check-crash-safety.sh "$PWD/Packages/macOS/CmuxNext"(the step's command). For the exports I usedcrash_ratchet.py --repo DIR --exported-tree.9e23760ae80^: ok.9e23760ae80:unwrap 1148 -> 1150(the first red sha).unwrap 1148 -> 1150(red).check-crash-safety: ok,crash-ratchet: ok, exit 0.rustfmt --edition 2024withcmux-tui/rustfmt.toml: clean.python3 scripts/cmux-next/prepush-gate.py: no new violations.Observed / Not run
Observed: I ran the checks above on a Linux VM and saw the results above. Fleet compile-check of the first head 39614fe, job c36db17abdc290f6f3efefaa: passed (CmuxNext, app, cmux-tui). The compile of this head comes in a comment below.
Not run:
cargo test -p cmux-tui-core.Changelog
none
Proof
Crash-safety change in Rust; no UI.