Ctrl K
ComunidadGuías…

CONTEXT.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Synara

A multi-provider web GUI for coding agents. One account, many hosts: clients reach any of the user's hosts directly (LAN, SSH, Tailscale) or through a cloud relay.

## Language

### Hosts & Environments

**Host**:
A user's machine running a Synara server, registered on their account. Host = Environment, 1:1 — the environment id is the host's stable identity; one machine runs one Synara environment.
_Avoid_: device (that's a client), remote host (all hosts are the same entity, reachable or not)

**Environment**:
The running Synara server instance a host is. Not modeled separately from Host; there is deliberately no multi-environment-per-machine concept.

**Owner**:
The user who registered a host. Hosts are user-owned; the org is tenancy, not automatic shared ownership.

**Discoverability**:
A per-host toggle controlled by its owner, on by default. Off: only the owner sees the host. On: the entire org sees and can use it — visibility and usability are the same switch; there is no finer-grained grant.
_Avoid_: sharing, visibility (as separate concepts from usability)

**Reachability**:
Whether a client can currently reach a host — learned by attempting (the probe race), never stored or pushed. There is no live presence state; host lists show reachability as of the last probe, and `lastSeenAt` is historical metadata.
_Avoid_: presence, heartbeat, online/offline (as stored state)

### Reaching a host

**Transport**:
One of the ways a client reaches a host: loopback, LAN, Tailscale, SSH (desktop-only), or Relay. SSH direct and the relay coexist; SSH is not merely a bootstrap mechanism.

**Relay**:
The cloud rendezvous: a dumb WebSocket pipe that pairs one client socket with one host socket and forwards opaque frames. Hosts dial out; nothing listens on the user's network. There is one relay per deployment — relay reachability is derived from presence, not stored as an endpoint.

**Relay Grant**:
A short-lived (~60s), single-use, host-scoped signed token the API issues to an authorized client; the relay verifies it statelessly and splices exactly one session. The API owns the splice authorization; the host mints the actual session credential (see Host Keypair).

**Splice**:
The relay pairing one client data socket with one host data socket, 1:1 per session — no multiplexing. The host dials a fresh data socket per session, signaled over its control socket.

**Endpoint**:
A URL a host self-reports to the directory for a direct transport (LAN, Tailscale), reported at startup and on address change (latest set replaces, no TTL). Probe candidates, not guarantees — stale entries are harmless because clients race them. Hosts also advertise on the local network via mDNS so same-network clients find them without the directory. The relay is not an endpoint.

**Control Socket**:
A host's supervisor-kept persistent connection to the relay, used for splice signaling. Hosts hold one; clients hold none — a client only contacts the relay to open a session. Distinct from a spliced data socket, which stays opaque end-to-end.

**Host Keypair**:
The Ed25519 keypair a host generates at registration; its public key lives in the directory. It is the host's _only_ credential: it proves link challenges, authenticates the host to the API, and mints session credentials — the cloud can authorize a splice but can never fabricate access to a host. Revocation = deleting the public key.

**Directory**:
The cloud's role with respect to hosts: identity, endpoints, presence, display metadata. Cloud is a directory + pipe; hosts own all state.

### Sync

**Host Secrets**:
Per-host configuration synced across the owner's devices end-to-end encrypted (SSH destination, launcher config, key-verification policy). The cloud stores ciphertext only, versioned whole-blob with last-write-wins (small version history kept for recovery). Secrets never cross user boundaries — SSH is therefore an owner-only transport; org members reach a discoverable host via relay, LAN, or Tailscale.

**Session Credential**:
The credential a client uses against a host, minted by the host itself: DPoP-bound to the client device's key thumbprint (a leaked credential is useless without the device key), ~1h TTL, re-minted via a fresh grant on expiry or reconnect.
_Avoid_: host token (replaced by the Host Keypair as the host's credential)

**Sync Key**:
The random master key that encrypts Host Secrets. Generated by the owner's first device, handed to each new device during device pairing; the cloud never sees it. Losing all devices loses Host Secrets (re-enter them), never the hosts. Removing a device rotates the Sync Key: a surviving device re-encrypts Host Secrets so the removed device cannot decrypt future ciphertext.

**Device**:
A client the user signs in from (desktop app, iOS app). A device's identity is its **Device Key** — a non-exportable keypair in the platform keystore, registered on the account at pairing; session credentials are DPoP-bound to it. Devices hold the Sync Key; hosts do not need it to operate.