Skip to content

feat(desktop): add client-only mode and guard backend ownership #28

Open

Description

@jdbencardinop

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.describePrimary selects a Windows or WSL
    primary from the desktop settings.
  • DesktopBackendManager.runBackendProcess spawns 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.ts
  • apps/desktop/src/backend/DesktopBackendManager.ts
  • apps/desktop/src/backend/DesktopBackendPool.ts
  • apps/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

  1. jdbencardinop commented on Oct 29, 2026

    @jdbencardinop
    Author

    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.

  2. jdbencardinop commented on Oct 29, 2026

    @jdbencardinop
    Author

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions