Skip to content

fix: recover official-mix Mobile Remote Control sessions - #1789

Open
Rat0323 wants to merge 13 commits into
BigPizzaV3:mainfrom
Rat0323:agent/remote-control-session-normalization
Open

fix: recover official-mix Mobile Remote Control sessions#1789
Rat0323 wants to merge 13 commits into
BigPizzaV3:mainfrom
Rat0323:agent/remote-control-session-normalization

Conversation

@Rat0323

@Rat0323 Rat0323 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Follow up on merged PR fix: route Remote Control sessions through mixed relay #1666 by completing the persistence path for phone-created Mobile Remote Control sessions.
  • Scope automatic recovery to Codex++ official-mix profiles: relayMode = official with officialMixApiKey = true.
  • Repair a newly created thread's local catalog entry at runtime without rewriting its active rollout or changing threads.model_provider.
  • Keep startup recovery for inactive historical rollouts and partially committed recovery state.
  • Resolve the registered Codex provider from the active profile or live config instead of hardcoding custom.
  • Restrict catalog reads and writes to the explicit host_kind = local host so SSH host entries remain untouched.
  • Temporarily retain fix(ci): keep upstream theme assets LF-normalized #1735's .gitattributes LF normalization until that PR is merged.

Root cause

A phone-created Mobile Remote Control thread can be created inside the host app-server with modelProvider = openai while Codex++ official-mix routes model requests through a configured custom provider. This ingress path does not reliably pass through the desktop renderer's thread/start request client.

The active rollout and threads row can therefore remain openai, while the local thread catalog is initially missing or stale. Rewriting an active rollout in response to thread/started is unsafe because Codex may still be appending to that JSONL file. Updating SQLite before the rollout is safely normalized can also leave a partial state that the old candidate predicate no longer retries.

Implementation

Creation-event catalog recovery

The renderer observes app-server thread/started notifications across supported message envelopes and sends only the new thread id to the Codex++ bridge route.

Recovery requests are sequential over the existing bounded retry window. A successful catalog recovery stops later attempts. Early already up to date responses continue retrying because the Codex databases may be committed shortly after the notification.

The runtime route:

  • independently verifies that the exact active relay profile is official-mix;
  • repairs only the requested thread;
  • inserts, restores, or normalizes only its local catalog row;
  • leaves the active rollout and threads.model_provider unchanged;
  • does not touch other candidate threads or SSH/remote catalog hosts.

Startup recovery

Launcher startup performs the full normalization after rollouts are inactive. Candidates are derived from inconsistencies across rollout metadata, threads, and the local catalog, which keeps partial commits detectable and retryable.

Rollout updates use content comparison, an exclusive file lock, Windows deny-sharing where available, and write-back verification. A changed or locked rollout is deferred, and its database/catalog state is not advanced.

After a rollout is verified at the target provider, recovery repairs the catalog before updating thread provider rows. If a later database step fails, the already-normalized rollout is retained so the next startup can finish the remaining idempotent work.

Provider and request contracts

  • codex_model_provider is parsed from the active profile's root model_provider, with live config.toml as fallback.
  • An invalid activeRelayId no longer falls back to relayProfiles[0].
  • Desktop thread creation keeps its best-effort provider override for known thread-start methods.
  • Pure official, Pure API, Mixed API, aggregate, disabled relay profiles, and non-thread requests do not enable this recovery path.

Validation

  • node --check assets/inject/renderer-inject.js
  • cargo fmt --all -- --check
  • git diff --check
  • cargo test -p codex-plus-data --test provider_sync -- --test-threads=1 - 30 passed
  • cargo test -p codex-plus-core --test model_catalog -- --test-threads=1 - 7 passed
  • cargo test -p codex-plus-core --test cdp_bridge -- --test-threads=1 - 94 passed
  • cargo test -p codex-plus-core --test bridge_routes -- --test-threads=1 - 29 passed

The 160 targeted tests cover active-rollout concurrency, deferred recovery, retry after a partial database commit, local/SSH host isolation, exact active-profile selection, non-custom provider ids, pure authentication modes, and stop-after-success retry behavior.

A real phone-created Mobile Remote Control session was then validated end to end after installing commit f40141c: runtime recovery inserted the local catalog row as the configured provider, desktop resume preserved that mapping, and a subsequent turn reached the configured relay with HTTP 200.

Rat0323 added 4 commits August 6, 2026 13:40
Run Provider Sync during launcher startup for every non-pure-official relay profile even when the Provider Sync toggle is off, so mobile-created openai sessions are normalized to the active provider and recorded in local_thread_catalog.
@Rat0323 Rat0323 changed the title fix: normalize remote control sessions on launcher start fix: normalize Remote Control session providers at creation Aug 6, 2026
@Rat0323 Rat0323 changed the title fix: normalize Remote Control session providers at creation fix: recover Remote Control session providers on creation Aug 6, 2026
@Rat0323 Rat0323 changed the title fix: recover Remote Control session providers on creation fix: recover official-mix Mobile Remote Control sessions Aug 6, 2026
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.

1 participant