Skip to content

Resolve restore targets from live process identity - #9384

Merged
austinywang merged 37 commits into
mainfrom
issue-9380-pi-restore-nothing-to-restore
Aug 1, 2026
Merged

austinywang merged 37 commits into
mainfrom
issue-9380-pi-restore-nothing-to-restore

Conversation

@austinywang

@austinywang austinywang commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Resolve implicit local cmux restore targets from the CLI process's live controlling TTY instead of inherited CMUX_SURFACE_ID state.
  • Resolve relay-backed restores from fresh TTY reports scoped to the authenticated remote workspace.
  • Preserve authoritative routing through ordinary workspace moves, Dock transfers, persistent PTY bridge retries, remote lifecycle end, and nonpersistent reconnects.
  • Cache each Ghostty PTY device for its terminal lifecycle and fail closed when no live target exists.

Investigation

Hypothesis 2 was confirmed. A controlled stale CMUX_SURFACE_ID reproduced the exact false nothing to restore result: the old restore path queried the inherited surface even though the terminal running the command belonged to another surface with a valid Pi binding. Issue #8672 corrected Pi hook dispatch and its stale-target circuit breaker, but it did not change restore-command routing. Conda activation, cd, and nested shells did not independently make the variable stale during current testing.

Hypothesis 1 did not explain the report. Pi discovery runs on the 8 second autosave cadence after a 0.65 second typing quiet period. A fresh local Pi launch bound after about 8.5 seconds. For the reported session, the checkpoint was persisted at 04:10:35, the app quit at 04:10:49, and it relaunched at 04:10:51. The restore binding therefore existed before the reported command.

Review exposed additional routing-boundary defects. Ended remote terminals retained current-runtime TTY provenance. Disconnect also left authenticated relay provenance live, and a delayed report_tty could recreate proof for an ended terminal. Nonpersistent reconnects did not retire the previous remote PTY's report. PID routing repeatedly allocated TTY strings and called stat. Workspace transfer restored TTY proof before destination lifecycle initialization cleared it. Persistent PTY bridge retries were mistaken for new remote shells even though the report-once shell hook does not run again. A relay-authenticated remote terminal moved into a new ordinary workspace fell outside the original workspace's candidate scan. A second ordinary-workspace move dropped its remote classification, and a persistent retry after the first move consulted the ordinary workspace instead of the configuration attached to the transferred terminal.

Final review found three trust-boundary gaps. The relay did not stamp its authenticated owner onto surface.report_tty, so that method could retain a caller-supplied owner marker. Remote registration checked the live origin but not the current terminal lifecycle and attach attempt. Local and transferred TTY proof was not scoped to the Ghostty runtime generation, so proof could outlive runtime replacement.

A follow-up concern about local detached report_tty ordering did not reproduce. A worst-case harness invoked the real zsh integration and built restore CLI immediately after _cmux_report_tty_once. The report connection arrived first in 200 of 200 runs, with a 1.668 ms minimum lead. Interactive use adds the prompt-to-command interval. No polling was restored without contrary evidence.

A later review found two remote readiness gaps. Existing tmux shells kept stale lifecycle and attach-attempt values after a new cmux attach, so the server correctly rejected their TTY reports. Fish and the initial remote bootstrap also launched work before surface.report_tty completed. These were distinct from Pi local discovery cadence and did not change the confirmed root cause for #9380.

Fix

Local implicit restore calls agent.resolve_delivery_target with the CLI PID and pid_resolution: controlling_tty. The app matches the kernel controlling-device identifier against live local terminals. It ignores ambient CMUX_SURFACE_ID, TTY, and SSH_TTY claims for this decision.

TerminalSurface captures its Ghostty TTY name and device identifier once per runtime lifecycle. Ghostty starts the PTY asynchronously, so a missed eager lookup retries lazily only until the PTY exists. Later probes use the in-memory device identifier. The cache is cleared whenever the runtime pointer changes.

Remote reports remain scoped to the authenticated relay workspace and follow a terminal into its current Workspace or Dock owner. The relay overwrites surface.report_tty provenance with its authenticated workspace. Every remote TTY report carries the terminal lifecycle and attach attempt through bootstrap, zsh, bash, and fish paths, and registration requires all three identities to match the live terminal. Mosh creates the attempt before staging its bootstrap and registers it before launch. Authenticated origin and attempt identity are preserved across detach and attach, including repeated moves through ordinary workspaces. Destination lifecycle tracking initializes before transferred proof is restored. The transfer remains classified as remote while live relay provenance exists, and retry policy reads the configuration attached to that transferred terminal. New terminal lifecycles, disconnect, lifecycle end, and nonpersistent attach attempts retire old proof. Local and transferred TTY proof is also tied to the current Ghostty runtime generation. Persistent transport retries retain proof because they reattach the same remote PTY and shell.

Existing tmux sessions now receive current CMUX_TERMINAL_LIFECYCLE_ID and CMUX_SSH_ATTEMPT_ID values on attach, and zsh, bash, and fish pull those keys from tmux. Fish waits for relay acknowledgement before latching its one-time TTY report, and the remote bootstrap completes surface.report_tty before starting the interactive shell. surface.ports_kick remains asynchronous, and no polling was added.

A complete not_found delivery-target reply is authoritative and fails closed immediately. The CLI does not poll for shell registration. Older apps still use the unique, workspace-scoped legacy match after method_not_found or unrecognized_method. Ambiguous, malformed, timed-out, or unscoped results fail closed.

Red and green proof

  • 942469d093 adds a failing regression through the real moveSurfaceToNewWorkspace path. Relay resolution returned not_found after the move.
  • ca95cc4185 preserves authenticated report provenance and resolves the terminal at its current live owner. The new regression passes.
  • 2c625bde77 adds failing tests for workspace transfer and persistent Workspace and Dock bridge retries. All three returned no delivery target before the fix.
  • 413d5a487d restores transferred proof after destination lifecycle setup and distinguishes persistent bridge attempts from new remote PTYs.
  • d2759b3b24 adds failing tests for single-reply local and relay failure plus Workspace and Dock reconnect provenance.
  • 0a9d22111e removes readiness polling and makes the first complete not_found authoritative.
  • 5db73900a1 adds failing tests for ended Workspace and Dock TTY reuse plus repeated native TTY reads.
  • c32a53fcf1 invalidates ended-lifecycle runtime proof and caches the PTY device.
  • 13f3b1e7a2 adds failing tests showing disconnect leaves the old TTY resolvable and a delayed report revives an ended terminal.
  • b1d61ad219 clears authenticated relay provenance on disconnect and terminal end, then requires that live provenance for remote TTY registration.
  • f85da04bf5 adds failing regressions for a second ordinary-workspace move and a persistent retry after the first move.
  • 01494812d6 keeps remote classification tied to live relay provenance and reads retry policy from the terminal's transferred configuration.
  • d78041b2f7 adds failing regressions for relay owner spoofing, stale attach attempts, and local TTY proof surviving runtime replacement.
  • c482c7a54a stamps relay ownership, validates lifecycle and attempt identity, propagates that identity through every remote report path, and scopes proof to the runtime generation.
  • 1dd6ab0944 extends the shared live-process target regression to Grok without changing Grok discovery code.
  • 48157de9f1 adds failing regressions for stale tmux lifecycle identity, unacknowledged fish registration, and bootstrap ordering. Before the fix, zsh, bash, and fish retained stale IDs, fish latched after an unsuccessful call, and bootstrap returned raced.
  • e693ac2cfa rebinds lifecycle identity through tmux and waits for TTY registration acknowledgement before readiness.
  • Earlier commits retain the same test-first split for stale ambient routing, ambiguity, PID resolution, relay scoping, and Dock ownership.

Verification

  • cmux-unit: the two disconnect and delayed-report regressions failed before b1d61ad219 and passed afterward.
  • cmux-unit: the three trust-boundary regressions failed before c482c7a54a and passed afterward.
  • cmux-unit: the complete 22-case transfer, repeated-move, lifecycle, reconnect, retry, restore, relay-scoping, and trust-boundary matrix passed on final HEAD.
  • cmux-unit: three focused zsh and bash relay payload tests passed.
  • cmux-unit: testTerminalEndClearsReadinessPendingRemoteConfiguration passed on final HEAD.
  • cmux-unit: 27 targeted restore and routing tests passed before the final lifecycle review fix.
  • CmuxFoundation: 14 focused Mosh and remote bootstrap staging tests passed.
  • CmuxControlSocket: 17 focused surface coordinator tests passed.
  • CmuxTerminalTests: controllingTTYNameIsReadOncePerRuntimeLifecycle passed with one native read.
  • cmux-unit: 27 focused shell integration and remote bootstrap tests passed on final HEAD.
  • CmuxFoundation: four focused remote tmux session tests passed under arm64.
  • zsh -n, bash -n, and fish -n: all three shell integration files passed syntax validation.
  • ./scripts/lint-pbxproj-test-wiring.sh: passed for 648 test files.
  • ./scripts/check-pbxproj.sh: passed.
  • python3 scripts/check-workspace-package-groups.py --check: passed.
  • python3 scripts/check-package-resolved-policy.py: passed.
  • git diff --check origin/main...HEAD: passed.
  • python3 scripts/swift_warning_budget.py --log /tmp/cmux-app-host-xcodebuild-untagged-attempt-1.log: passed with zero cmux-owned Swift warnings.
  • scripts/swift_file_length_budget.py and .github/swift-file-length-budget.tsv are absent from this checkout and origin/main. No budget TSV was changed, and all newly added or previously untracked Swift files remain below 500 lines.
  • No local XCUITests were run. The tagged Debug build completed and launched from e693ac2cfa; its isolated socket responded.

Closes #9380

@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Restore now resolves the caller’s terminal binding before selecting a surface. It validates delivery targets, retries transient failures, and applies protocol and TTY fallbacks. TTY metadata restoration clears stale device identity. Tests cover routing, failure, timeout, and ordered socket responses.

Changes

Restore surface resolution

Layer / File(s) Summary
Caller terminal lookup
CLI/CMUXCLI+ClaudeHookWorkspaceRouting.swift
Caller TTY resolution now delegates to an overload that accepts an explicit TTY name before requesting terminal data.
Restore target resolution
CLI/CMUXCLI+Restore.swift
Current-surface restoration validates PID delivery targets, retries transient not-found responses, handles unsupported methods, uses legacy TTY discovery, closes failed clients, and shares unknown-surface error construction.
TTY metadata lifecycle
Sources/AgentDeliveryTargetResolution.swift, Sources/Workspace.swift, cmuxTests/AgentNotificationMutationBoundaryTests.swift
Runtime TTY changes refresh device identities. Persisted TTY metadata clears cached device identity until fresh runtime registration.
Restore fixtures and ordered socket coverage
cmuxTests/CMUXCLIErrorOutputRegressionTests.swift
Fixtures include PID, workspace, and surface metadata. Tests cover routing, malformed or unavailable targets, retries, fallbacks, timeouts, and ordered socket responses. UnixSocketResponder supports response sequences and SO_NOSIGPIPE.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RestoreCommand
  participant TerminalBindingResolver
  participant UnixSocketResponder
  RestoreCommand->>TerminalBindingResolver: resolve current restore surface
  TerminalBindingResolver->>UnixSocketResponder: request PID delivery target
  UnixSocketResponder-->>TerminalBindingResolver: return target metadata
  TerminalBindingResolver-->>RestoreCommand: return validated surface or fallback
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers: lawrencecchen, azooz2003-bit


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (3 errors, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Cmux Swift Blocking Runtime ❌ Error CLI/CMUXCLI+Restore.swift adds production usleep retry backoff (25–400 ms) while polling not_found from agent.resolve_delivery_target. Replace usleep polling with a cancellation-aware real registration signal, callback, notification, async sequence, or explicit completion point before retrying.
Cmux Swift Package Boundaries ❌ Error CMUXCLI+Restore.swift adds protocol-heavy target validation, retry, fallback, and TTY discovery in the app CLI; socket-fixture tests show this is independently testable domain logic. Extract restore target resolution and the TTY-binding contract into a small CmuxAgentDeliveryRouting SwiftPM target exposing RestoreSurfaceResolver; keep SocketClient and CLIError adapters in CLI.
Cmux Architecture Rethink ❌ Error CLI/CMUXCLI+Restore.swift adds a production usleep backoff loop after not_found, explicitly waiting for background TTY registration; this is the timing repair prohibited by rule 7. Make TTY registration and PID target resolution share an atomic readiness transition owned by the app, or return authoritative unavailable; remove the sleep/retry loop.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift @Concurrent ❓ Inconclusive Investigation is still in progress; no verdict submitted yet. Inspect changed declarations, actor isolation, and async call sites before deciding.
✅ Passed checks (20 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #9380 by using live process and TTY routing, failing closed, preserving fallbacks, and adding regression coverage.
Out of Scope Changes check ✅ Passed All code and test changes support restore-target resolution, TTY registration, socket synchronization, or related regression coverage.
Cmux Swift Actor Isolation ✅ Passed Production additions are synchronous CLI helpers and a Workspace method inside an explicit @MainActor extension; no new implicit models, async protocols, Sendable references, or background UI acces...
Cmux Browser Automation Off-Main ✅ Passed The PR changes restore and agent-delivery routing only; it adds no browser.* commands and does not modify TerminalController, socketWorkerMethods, worker routing, or WebKit automation.
Cmux Expensive Synchronous Load ✅ Passed The production diff adds no agent-history loader, transcript/JSONL read, or broad scan; the existing close-path RestorableAgentSessionIndex.load() remains unchanged, and new code resolves live TTY...
Cmux Cache Substitution Correctness ✅ Passed The diff uses live PID/TTY RPCs for restore and clears the cached TTY device on snapshot restore; runtime report_tty updates repopulate it, so no fresh read was replaced by an unhandled cache.
Cmux No Hacky Sleeps ✅ Passed The diff changes only Swift source and Swift tests; it introduces no TypeScript, JavaScript, shell, or build/runtime-script sleeps covered by this check.
Cmux Algorithmic Complexity ✅ Passed The changed production paths use linear scans only; restore retries are bounded to five delays, and TTY cache updates remain linear. No nested scalable scan or repeated sort/filter was introduced.
Cmux Swift Concurrency ✅ Passed The production diff adds no DispatchQueue, Task, Combine, or completion-handler pattern; it only adds a bounded synchronous usleep retry, while test synchronization remains existing test-only infra...
Cmux Swiftpm Lockfiles ✅ Passed The diff changes only six Swift source/test files; it contains no Package.swift, Package.resolved, .gitignore, workflow, or Xcode package-reference changes requiring lockfile updates.
Cmux Swift Logging ✅ Passed The changed runtime Swift files add no print, debugPrint, dump, NSLog, Logger, or ad hoc diagnostic logging; stdout references are test assertions, and existing NSLog calls remain DEBUG-only.
Cmux User-Facing Error Privacy ✅ Passed The production diff adds only generic restore recovery text; routing and UUID/TTY details stay internal, and logged diagnostics are private hashed values. Test fixtures are allowed.
Cmux Full Internationalization ✅ Passed Production diff adds no new user-facing copy or catalog files; the moved current-surface error already used the localized key on origin/main and has a Localizable.xcstrings entry. Other additions a...
Cmux Swiftui State Layout ✅ Passed The PR changes CLI, delivery-resolution, workspace metadata, and tests; no new SwiftUI state, layout measurement, lazy-row store reference, or render-time mutation appears in the diff.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The diff adds no standalone NSWindow, NSPanel, NSWindowController, Window, or WindowGroup code; changes are routing, metadata, and tests. scripts/lint_auxiliary_window_close_shortcuts.py passed.
Cmux Source Artifacts ✅ Passed All six changed paths are hand-written Swift source or regression tests; no artifact directories, logs, screenshots, caches, build output, or copied artifacts enter the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The Sources diff adds no test/debug guards or seam-named members. restorePersistedSurfaceTTYName is used by production session restoration, and existing CLI callers use the new TTY overload.
Cmux No Ambient Global State ✅ Passed Production additions are methods on CMUXCLI or Workspace; the file-scope helpers in AgentDeliveryTargetResolution.swift predate the diff, and no new mutable global, static namespace, or singleton w...
Title check ✅ Passed The title clearly identifies the primary change: resolving restore targets from the live process identity.
Description check ✅ Passed The description gives a detailed summary, investigation, fix, testing evidence, and issue reference, but omits the template checklist and demo-video section.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-9380-pi-restore-nothing-to-restore

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@austinywang austinywang changed the title Prefer live TTY routing for agent restore Resolve restore targets from live process identity Aug 1, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmuxTests/CMUXCLIErrorOutputRegressionTests.swift`:
- Around line 646-656: The test fixture in the caller-target response does not
exercise duplicate-TTY handling because currentRestoreSurfaceID only uses the
top-level source, pid_resolution, workspace_id, and surface_id fields. Either
remove the unused terminals row and rename the assertion to reflect top-level
surface precedence, or change the mocked response to an actual
ambiguity/not_found case and assert that currentRestoreSurfaceID falls back to
CMUX_SURFACE_ID.
- Line 657: Rename the local String constants named restoreResponse in the
affected test cases to a distinct name, and update each corresponding responder
initializer to use the renamed constant while preserving the
restoreResponse(result:) helper method calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ac624011-0161-419d-8184-1ceb205eeed9

📥 Commits

Reviewing files that changed from the base of the PR and between fec1cb0 and 0f1a9f3.

📒 Files selected for processing (2)
  • CLI/CMUXCLI+Restore.swift
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

Comment thread cmuxTests/CMUXCLIErrorOutputRegressionTests.swift
Comment thread cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CLI/CMUXCLI+Restore.swift (1)

182-225: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Malformed-success handling relies on incidental catch routing.

The guard at Lines 199-206 throws currentRestoreSurfaceUnknownError() from inside the do block. That error is then caught by catch let error as CLIError at Line 208 and reaches default: only because the helper's v2Code is nil. The result is correct today, but the mechanism is indirect: a later change that assigns a v2Code to currentRestoreSurfaceUnknownError(), or a new case added to the switch, can silently redirect this path (for example into the method_not_found legacy fallback) instead of failing closed.

Close and throw directly at the guard site instead of routing the local error back through the switch.

♻️ Proposed fix to close and throw directly on malformed success
             guard payload["source"] as? String == "pid",
                   payload["pid_resolution"] as? String == resolution,
                   let workspaceID = normalizedHandleValue(payload["workspace_id"] as? String),
                   isUUID(workspaceID),
                   let surfaceID = normalizedHandleValue(payload["surface_id"] as? String),
                   isUUID(surfaceID) else {
-                throw currentRestoreSurfaceUnknownError()
+                client.close()
+                throw currentRestoreSurfaceUnknownError()
             }
             return surfaceID
         } catch let error as CLIError {
             switch error.v2Code {
             case "not_found":
                 client.close()
                 throw currentRestoreSurfaceUnknownError()
             case "method_not_found", "unrecognized_method":
                 // These protocol replies were consumed in full, so the socket
                 // remains synchronized for the legacy discovery request.
                 return legacyRestoreSurfaceID(client: client)
             default:
                 client.close()
                 throw error
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+Restore.swift around lines 182 - 225, Update the
malformed-success guard in currentRestoreSurfaceID so it closes the client and
throws currentRestoreSurfaceUnknownError() directly when the response fields are
invalid. Keep protocol-error handling through the existing CLIError switch
unchanged, ensuring malformed successful responses cannot reach
legacyRestoreSurfaceID through catch routing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@CLI/CMUXCLI`+Restore.swift:
- Around line 182-225: Update the malformed-success guard in
currentRestoreSurfaceID so it closes the client and throws
currentRestoreSurfaceUnknownError() directly when the response fields are
invalid. Keep protocol-error handling through the existing CLIError switch
unchanged, ensuring malformed successful responses cannot reach
legacyRestoreSurfaceID through catch routing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7d2ac8e3-e17c-41f8-b95e-b19a29c81842

📥 Commits

Reviewing files that changed from the base of the PR and between 0f1a9f3 and 381670c.

📒 Files selected for processing (3)
  • CLI/CMUXCLI+ClaudeHookWorkspaceRouting.swift
  • CLI/CMUXCLI+Restore.swift
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/CMUXCLI`+Restore.swift:
- Around line 191-231: Remove the retryDelays/retryIndex loop and make the
resolve_delivery_target path fail closed on the first not_found response. Move
the readiness ordering guarantee into the server handler or ensure shell
integration completes registration before returning control to the caller, while
preserving legacy fallback for method_not_found/unrecognized_method and closing
the client for other failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6aeacd6d-0932-40a5-bfa9-7173bdab56f6

📥 Commits

Reviewing files that changed from the base of the PR and between 381670c and be1b8bd.

📒 Files selected for processing (5)
  • CLI/CMUXCLI+Restore.swift
  • Sources/AgentDeliveryTargetResolution.swift
  • Sources/Workspace.swift
  • cmuxTests/AgentNotificationMutationBoundaryTests.swift
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

Comment thread CLI/CMUXCLI+Restore.swift Outdated
@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@austinywang
austinywang merged commit 6d47bf3 into main Aug 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pi restore says 'nothing to restore' for a real, current session

1 participant