Repository navigation
feat(desktop): add client-only mode and guard backend ownership #28
Description
Problem
The desktop client currently starts a primary backend. On Windows, WSL-only
selects WSL as that primary; disabling WSL-only returns the primary to Windows.
There is no equivalent of the web app's client-only role for connecting only
to independently managed environments.
This is awkward when a user wants persistent Windows and WSL T3 services,
reachable from another desktop through private SSH forwards. If a service
already owns a T3 home, opening the ordinary desktop can attempt to start
another backend against that same data. Disabling desktop-managed WSL alone
is not enough when an independently managed Windows backend also uses the
desktop's normal Windows T3 home.
This is a fork tracking issue, not an upstream feature submission.
Observed behavior and evidence
- Fork Preview desktop on Windows with a WSL environment.
DesktopBackendConfiguration.describePrimaryselects a Windows or WSL
primary from the desktop settings.DesktopBackendManager.runBackendProcessspawns that backend.- The standalone CLI can also start a backend with an explicit
--base-dir. - We deliberately avoided starting competing servers against the same data.
This report does not claim observed database corruption.
Relevant implementation:
apps/desktop/src/backend/DesktopBackendConfiguration.tsapps/desktop/src/backend/DesktopBackendManager.tsapps/desktop/src/backend/DesktopBackendPool.tsapps/desktop/src/app/DesktopAppIdentity.ts
Desired behavior
Support an explicit desktop client-only mode, or a setting to disable
desktop-managed backend startup while retaining Connections, pairing, and
normal remote chat functionality. This should not require a second profile,
copying chats, changing the T3 home, or starting an empty local backend.
Separately, make backend ownership explicit enough that desktop and
independently managed startup cannot silently compete for one T3 data
directory. A port conflict or a PID number alone is not sufficient proof of
ownership, and arbitrary existing processes must never be adopted or stopped.
Acceptance criteria
- Default desktop behavior stays unchanged unless the user opts in.
- In client-only mode, opening the desktop starts neither a Windows nor a WSL
backend, but existing and newly paired external environments work normally. - The mode is visible and reversible through Settings, including when no
backend is reachable; an offline environment must not trap the user. - Windows and WSL remain independent environments. Direct and forwarded
connections to the same backend retain its existing identity and chats. - Starting a second backend for a T3 home with a verified live owner is
rejected clearly, or uses a deliberate authenticated attachment flow. - Stale-owner recovery is bounded and does not kill foreign processes or
bypass SSH/backend authentication. - Closing a client-only desktop does not stop independently managed servers.
- Cover local, remote/SSH-forwarded, multi-environment, and reconnect paths.
- Add focused tests for startup suppression, reversibility, verified-owner
conflicts, stale state, and preservation of existing pairing/data.
Temporary operational compromise
For now, the desktop owns and starts both its Windows and WSL backends. Only
the SSH tunnel supervisors remain persistent. Those environments are
available remotely only while the desktop on their host is open. Standalone
backend tasks/services are disabled to avoid competing ownership.
Validation boundaries
Transport, authenticated-backend boundaries (unauthenticated WebSocket
upgrades return 401), owned-process cleanup, SSH reconnect, and scheduled
tunnel recovery were exercised during the setup. Client-only mode does not
exist yet, and concurrent writers were not intentionally induced.
Prepared with GPT-6.1 Sol using GitHub Copilot CLI.
Activity
jdbencardinop commentedon Oct 29, 2026
Two useful findings from the v0.1.3 evaluation: (1) localEnvironmentEnabled is already present in the audited fork source as well as upstream, so first confirm the actual Windows desktop build and setting visibility before accepting the premise that client-only mode is absent. (2) Stable v0.1.3 adds serverOwnership.ts with a lifetime exclusive SQLite transaction on server-owner.sqlite, conservative pre-lock owner handling, and clear refusal without stopping a foreign server. This is stronger than a port/PID check. Treat as upstream reuse, not closure: require isolated Windows/WSL reproduction, startup/reversal, stale-owner and independent-service survival evidence on the deployed target. Never induce concurrent live-data writers.
jdbencardinop commentedon Oct 29, 2026
The packaged v0.1.4 Mac preview now passes local OFF → actual restart → remote retained → local ON → restart, with the original user backend unaffected. This does not qualify Windows/WSL behavior. The exact Windows candidate installer and pause-gated receiving-host procedure are ready: #1 (comment)
Reviewed report and visual evidence: #1 (comment)
Candidate only; no main promotion or live upgrade.