# TailMux - Research Sources And Findings

Date: 2026-05-05

This file records the sources and local findings that shape TailMux. Re-check external links before changing behavior that depends on Tailscale internals, macOS networking, or Apple entitlements.

## Tailscale Facts

### Fast User Switching

Source: https://tailscale.com/docs/features/client/fast-user-switching

Validated design points:

- Tailscale can remember multiple accounts on one device.
- Only one client account is active at a time.
- A device cannot transmit packets on multiple tailnets simultaneously through one official client identity.
- Tailnets remain separate through fast user switching.

TailMux implication:

- Do not build the product around official GUI account switching.
- Use separate profile identities when concurrent reachability is required.

### Userspace Networking

Source: https://tailscale.com/docs/concepts/userspace-networking

Validated design points:

- `tailscaled` can run with `--tun=userspace-networking`.
- Userspace mode can expose SOCKS5 and HTTP proxies.
- HTTP proxy is suitable for browser HTTP/HTTPS traffic.
- SOCKS5 domain connect is useful for non-HTTP clients.

TailMux implication:

- This remains the compatibility backend and a reference model.
- Hostname-preserving proxy protocols avoid DNS/IP ambiguity.

### `tailscaled` Daemon Flags

Source: https://tailscale.com/docs/reference/tailscaled

Validated design points:

- `--tun=userspace-networking` avoids kernel TUN routing.
- `--statedir=` and `--state=` control state location.
- `--socks5-server=[host]:port` exposes a SOCKS5 proxy.
- `--outbound-http-proxy-listen=[host]:port` exposes an HTTP proxy.
- `--port=N` controls the UDP port used for WireGuard/peer-to-peer traffic; `0` auto-selects.

TailMux implication:

- External `tailscaled` profiles can be isolated by state, socket, proxy ports, and UDP port.
- Fixed profile UDP ports make direct-vs-DERP diagnosis more stable.

### Tailscale CLI Socket Flag

Source: https://tailscale.com/docs/reference/tailscale-cli

Validated design point:

- The CLI supports profile-specific daemon access through `--socket=<path>`.

TailMux implication:

- External backend commands must always pass the selected profile socket.
- Plain `tailscale status` is only appropriate for official-client direct comparisons, not TailMux profile state.

### tsnet

Source: https://tailscale.com/docs/features/tsnet

Validated design points:

- `tsnet` embeds Tailscale inside a Go program.
- `tsnet` uses userspace networking.
- A Go process can create profile-specific Tailscale services and dialers.

TailMux implication:

- `tsnet` is now the recommended backend for new TailMux profiles.
- TailMux still needs PAC/proxy routing at the client boundary because apps must preserve the hostname.
- One `tsnet.Server` per profile keeps state and identity isolated inside one TailMux process.

### macOS Variants

Source: https://tailscale.com/docs/concepts/macos-variants

Validated design points:

- macOS has multiple Tailscale installation variants.
- GUI app networking is packaged differently from CLI-only daemon flows.
- The app-bundled CLI can be the authoritative binary for the installed official app.

TailMux implication:

- TailMux should not mutate the official GUI Network Extension.
- Local direct comparisons should use the same CLI version as the official app.
- On Claudio's Mac, the Homebrew `tailscale` symlink was replaced with a wrapper to `/Applications/Tailscale.app/Contents/MacOS/Tailscale` to remove a `1.96.4` CLI vs `1.96.5` server mismatch.

## Apple

### Network Extension

Source: https://developer.apple.com/documentation/networkextension

Validated design point:

- Network Extension is the Apple framework family for VPN/proxy-style extensions.

TailMux implication:

- Transparent routing is a separate route-manager phase, not an incremental tweak to the current router.
- Any Network Extension design must handle entitlements, signing, user consent, hostname-to-flow attribution, and cross-profile negative tests.

## Local Findings

### Official Client vs TailMux Measurements

After reconnecting the official Tailscale client to the personal tailnet and confirming direct MagicDNS worked, the comparison against:

```text
http://claudios-mac-mini-1.tail2c15f0.ts.net:13200/live-auctions
```

showed:

- official direct page fetch average: about `3.48s`
- TailMux router page fetch average: about `1.70s`
- official direct SSE first event average: about `199ms`
- TailMux router SSE first event average: about `152ms`

Interpretation:

- TailMux was not the bottleneck in that measurement.
- The previous slow SSE/browser behavior was consistent with proxy buffering of dynamic or unknown-length responses.
- The proxy was updated to stream dynamic, chunked, and unknown-length responses immediately.
- Re-measure before making new claims because Tailscale path, Wi-Fi/NAT, DERP/direct state, and app payload size can change.

### Safari vs In-App Browser

The Codex in-app browser may load a tailnet URL even when Safari fails because it is not proof that Safari is using the macOS PAC configuration. Safari must be checked through the active macOS network service PAC URL:

```text
http://127.0.0.1:43180/proxy.pac
```

TailMux documentation and diagnostics should always identify whether a test used:

- TailMux router
- embedded profile dialer
- external profile proxy
- official direct client

### TUN Recommendation Text

`diag path` can recommend:

```text
profile is in userspace networking mode: PAC/proxy routing is expected; TUN mode requires a separate route manager phase
```

Meaning:

- the selected non-`tsnet` profile is not installing kernel routes
- PAC/proxy routing is expected
- TUN/Network Extension routing is a separate architecture, not a switch to flip for current TailMux

For `backend: "tsnet"`, this recommendation should not appear.

## Assumptions To Revalidate

- Tailscale `tsnet` APIs remain compatible with the current embedded manager.
- Two embedded profile identities remain stable with separate `state_dir` values.
- Work tailnet approval policy permits the TailMux work profile device.
- Personal tailnet approval policy permits the TailMux personal profile device.
- Safari PAC behavior remains stable across macOS updates.
- `diag fetch` direct mode is only valid when the official client is connected to the same tailnet being compared.
