Follow-up from the dual-interface refactor (ea2e57e on feat/enable-tunnel-flip-flag).
Current behaviour
After the dual-interface change, the tunnel TunnelTCPInterface mirror is created automatically for the first enabled foreground TCP entity whenever Background Transport's TunnelManager reaches .connected. The user has no per-relay control: every TCP relay either gets a background mirror (if BT is on) or doesn't (if BT is off).
What it should look like
When the user adds or edits a TCP relay in the wizard (TCPClientWizard / TCPClientWizardViewModel), surface a checkbox along the lines of:
☐ Keep this connection alive in the background
When enabled, the Network Extension maintains a parallel TCP path to this relay even when Columba is suspended. Lets you receive a notification when a message arrives while the app is closed.
Trade-off: an extra TCP socket per relay (one app-process, one extension-process) — minimal battery cost on Wi-Fi, slightly more on cellular. Requires Background Transport (Settings → Background Transport) to be on.
When unchecked, this TCP entry stays foreground-only — no TunnelTCPInterface mirror is created for it.
Implementation pointers
- Adds a new field on
TCPClientConfig (alsoTunneled: Bool, default true to match current behaviour) or on InterfaceEntity.
AppServices.registerTunnelInterface() filters foreground entities by that field instead of mirroring all of them — combines with the multi-relay issue (#TBD when filed) into a single pass.
- Plain reactive wiring: editing the toggle re-runs
reconcileTunnelInterface() (see related issue) so the change takes effect without a tunnel restart.
Why deferred
The architectural commit landed with a one-size-fits-all default. Per-relay control is a UX refinement, not a correctness gate.
Follow-up from the dual-interface refactor (
ea2e57eonfeat/enable-tunnel-flip-flag).Current behaviour
After the dual-interface change, the tunnel
TunnelTCPInterfacemirror is created automatically for the first enabled foreground TCP entity whenever Background Transport'sTunnelManagerreaches.connected. The user has no per-relay control: every TCP relay either gets a background mirror (if BT is on) or doesn't (if BT is off).What it should look like
When the user adds or edits a TCP relay in the wizard (
TCPClientWizard/TCPClientWizardViewModel), surface a checkbox along the lines of:When unchecked, this TCP entry stays foreground-only — no
TunnelTCPInterfacemirror is created for it.Implementation pointers
TCPClientConfig(alsoTunneled: Bool, defaulttrueto match current behaviour) or onInterfaceEntity.AppServices.registerTunnelInterface()filters foreground entities by that field instead of mirroring all of them — combines with the multi-relay issue (#TBD when filed) into a single pass.reconcileTunnelInterface()(see related issue) so the change takes effect without a tunnel restart.Why deferred
The architectural commit landed with a one-size-fits-all default. Per-relay control is a UX refinement, not a correctness gate.