Skip to content

feat(remote-connect): support targeted session rollback and edit-resend from remote control - #3137

Merged
bobleer merged 4 commits into
GCWing:mainfrom
BingCHuanJ:feat/remote-session-rollback-v1
Sep 21, 2026
Merged

bobleer merged 4 commits into
GCWing:mainfrom
BingCHuanJ:feat/remote-session-rollback-v1

Conversation

@BingCHuanJ

@BingCHuanJ BingCHuanJ commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Add real session rollback and "edit & resend" support to the mobile remote control surface, backed by the desktop's existing targeted-rollback transaction.

Rebased onto OpenBitFun 1.0.1 (upstream/main).

Motivation

Previously, the mobile interface only offered resend and delete. "Delete" only hid the bubble in the mobile browser without actually rolling back the turn or restoring modified files on the host desktop.

This PR connects the mobile web client to the host's actual rollback capability so users can:

  • Roll back to a message: withdraw that turn and subsequent turns, and restore files changed during those turns.
  • Edit and resend: roll back to that turn, load its original text into the mobile composer for editing, and send it as a new turn.

What Changed

  • Wire protocol (openbitfun-services-integrations):
    • Added RemoteCommand::RollbackSessionToTurn and RemoteResponse::SessionRolledBack.
    • User chat messages now carry turn_id and turn_index for turn-level addressing and optimistic concurrency checks.
  • Host runtime (openbitfun-core):
    • Implemented rollback_session_to_turn on RemoteSessionRuntimeHost, delegating to the desktop's rollback port while enforcing workspace ownership checks and rejecting remote SSH workspaces.
  • Mobile web (src/mobile-web):
    • Added "Roll back to here" and "Edit & resend" actions on user messages.
    • Confirmation sheet and input using @openbitfun/ui/mobile components (MobileConfirmSheet, MobileTextarea).
    • Disabled during active streaming to prevent conflicts.
    • If resending fails after a successful rollback, the edited draft is preserved in the composer so text is not lost.
    • Added i18n strings (11 keys each) across en-US, zh-CN, and zh-TW.

Verification

  • Rust tests:
    • cargo test -p openbitfun-services-integrations --features remote-connect --test remote_connect_contracts (73 passed)
    • cargo test -p openbitfun-services-integrations --features remote-connect --lib remote_connect::tests (18 passed)
    • cargo test -p openbitfun-core --features remote-connect --lib service_agent_runtime::tests (22 passed)
  • Frontend checks:
    • pnpm --dir src/mobile-web run test:ui-components (15 passed)
    • pnpm --dir src/mobile-web run type-check (passed, 0 errors)
    • pnpm --dir src/mobile-web run build (passed)
  • i18n: 11 new keys verified across all three supported locales (en-US, zh-CN, zh-TW).

Checklist

  • Code adheres to the repository's styling and component guidelines.
  • Scoped unit and contract tests pass.
  • All user-facing strings are localized in en-US, zh-CN, and zh-TW.
  • No unrelated changes or temporary files included.

Maintainer review and fixes

AI-assisted review and follow-up implementation by Codex. Fixed in fdad071ab:

  • Advertise and require session_rollback_v1; older hosts retain their existing actions without receiving an unknown rollback command.
  • Preserve the storage turn index through the production session-record stream, so rollback requests actually carry the concurrency guard.
  • Reject mismatched or malformed rollback acknowledgements before edit/resend can submit another turn.
  • Fence error and cleanup updates to the originating chat target, and retain the edited draft when rollback itself fails.
  • Add legacy-message round-trip coverage and mobile regressions for capability negotiation, streamed indices, invalid acknowledgements, and device switching.

A follow-up CI failure exposed an incomplete RemoteSessionManager mock in the Web UI-owned mobile integration suite. bf262c6e2 updates that mock and adds rendered-chat regressions for rollback failure and target-switch isolation (6 tests passed).

Focused validation of the updated head:

  • Rust remote-connect contracts: 73 passed; remote-connect unit tests: 19 passed; Core service_agent_runtime::tests: 22 passed.
  • Mobile workspace/rollback tests: 21 passed; UI component contracts: 15 passed; Chrome session-stream browser suite passed.
  • Mobile TypeScript and production build passed; all 23 theme audit surfaces and i18n audit passed.
  • Disposable Chrome visual checks at 375, 768, and 1200 pixels confirmed action-sheet layout, streaming-disabled rollback, and legacy-host gating.

Remote coverage: simulated remote-control protocol/Chrome stream tests, including control-device switching and old-host compatibility. Real phone-to-desktop file restoration, SSH workspace rejection, Peer Device Mode, and Detached Dispatch were not exercised end to end. The host continues to reject rollback for remote workspaces explicitly. No CI checks were bypassed; merge waits for the updated head's CI.

Queue integration review

Follow-up review in e087a2230 fixes a stale-controller race: remote rollback now requires idle at the host, checked under the same session-operation lock used for submission, before queue retirement or cancellation. A concurrent submission causes a clear rejection and leaves accepted work intact. The additive runtime request field defaults to the legacy maintenance policy for existing callers.

Edit/resend failures now restore image attachments alongside the edited text. Rollback responses reject malformed composer text and array elements.

Validation: 42 focused scheduler tests (including lock contention and retained queued work), 22 service runtime tests, legacy rollback DTO round trip, 21 mobile workspace/protocol tests, 7 rendered chat submission/rollback tests, and mobile TypeScript passed. A pre-existing lineage DTO test fixture was supplied its missing optional workspace ID so the contract suite compiles. These are simulated remote-control and runtime tests, not physical-phone or live SSH/peer E2E evidence.

PR #3180 will additionally test this rollback guard against the host-owned queue, including blocked/unconsumed steering entries and preservation of the queue epoch and receipts.

@BingCHuanJ
BingCHuanJ force-pushed the feat/remote-session-rollback-v1 branch from 68b026d to 63f67ee Compare September 20, 2026 04:12
…nd from remote control

The remote control surface previously offered only resend and delete, where
delete was a local hide that left the turn and file mutations intact on the
desktop.

Port the targeted rollback and edit-and-resend capability to OpenBitFun 1.0.1:

- Project the owning turn identity onto user `ChatMessage`s (`turn_id` +
  `turn_index`). Targeted rollback addresses turns rather than messages, and
  `turn_index` carries the same optimistic-concurrency guard the desktop sends
  so a stale transcript cannot retire the wrong turn.
- Add `RemoteCommand::RollbackSessionToTurn` and
  `RemoteResponse::SessionRolledBack` to the owner contract in
  `openbitfun-services-integrations`, routed through the session command group.
- Implement `RemoteSessionRuntimeHost::rollback_session_to_turn` in core on
  top of `AgentRuntime::rollback_session_to_turn`, passing the workspace
  ownership gate (`ensure_remote_binding_runtime_ownership`) and rejecting
  remote workspaces.
- Mobile web gains "edit & resend" and "roll back to here" on user messages,
  using `MobileConfirmSheet` and `MobileTextarea` to conform to
  `@openbitfun/ui/mobile` component boundaries.
- Disable rollback mutations while a turn is active to preserve consistency
  with desktop `assertSessionIdleForHistoryMutation`.
- Nudge the stream poller immediately upon rollback completion to pull the
  authoritative message snapshot from the host.
- Provide full i18n support across en-US, zh-CN, and zh-TW.
@BingCHuanJ
BingCHuanJ force-pushed the feat/remote-session-rollback-v1 branch from 63f67ee to 9f16efb Compare September 20, 2026 07:16
@GCWing
GCWing requested a review from bobleer September 21, 2026 13:32
@bobleer
bobleer merged commit ab4f798 into GCWing:main Sep 21, 2026
13 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.

2 participants