---
title: Cross-Org Connections (Team Chat Lane C)
---

# Cross-Org Connections (Team Chat Lane C)

## What it is

Connect with any Omniscio user by email — a coworker in the same workspace OR someone in a completely different organization — to start a 1:1 DM. The connection forms ONLY when the recipient approves.

## Where to find it

Everything starts in **Team Chat**, which has a **Connections** section in its sidebar; the **Connect by Email** dialog opens from there. A request you receive shows up in that same sidebar section and as a card in your **Inbox**, where you accept or decline it. Once a connection exists, its conversation sits in the Team Chat sidebar with your other chats. Your own discoverability switch is on your **Team Chat** self-profile popover — the avatar strip in the sidebar — so you can stop receiving connection requests without leaving Team Chat.

## How it behaves

### How it works

1. **Request** — type a person's exact sign-in email in the **Connect by Email** dialog (opened from the Team Chat sidebar's Connections section). The request is sent via the `globalAuthProfile` Cloud Function (`requestConnection` action).
2. **Approval** — the recipient sees a pending request in their **Team Chat sidebar** (Connections section) AND as an **Inbox item** (see [connection-request-inbox.md](connection-request-inbox.md)). They can **Accept** (creates the connection and opens the DM) or **Decline** (deletes the pending doc so a future re-request starts clean).
3. **Messaging** — once accepted, both users can message each other in a 1:1 DM that lives in a top-level `connections/{connId}` collection, separate from any org's channels. Messages use the same frozen schema as org channels. Reactions, pins, and threads all work on connection DMs (parity with org channels).

## For agents

### Key design decisions

- **Separate top-level collection** — connections can't nest under any one org (they cross tenant boundaries), so `connections/{connId}` is a new top-level Firestore surface gated purely on participation. It never weakens the org tenant wall.
- **Deterministic ID** — `connId = conn_<uidA>__<uidB>` with sorted uids, so A→B and B→A resolve to the same doc. Mutual requests auto-accept.
- **Anti-enumeration** — a request for a non-existent email, an opted-out user, or a disabled account ALL return `{ status: 'requested' }` so callers can't probe which emails are real accounts (invariant C1).
- **Server-only lookups** — the email→uid resolution and privacy check happen server-side in the Cloud Function (Admin SDK). A client never sees a uid it doesn't already have a relationship with (invariant C2).

### Privacy controls

Each user has an **`acceptsConnections`** field on their `users/{uid}` doc — **default-on** (absent = accepts; only an explicit `false` opts out). The toggle lives in the user's **Team Chat self-profile popover** (the avatar strip in the sidebar). It is NOT an AppSettings field and is NOT in the admin-only Workspace settings dialog — every member can control their own discoverability.

### CLI routes

- `POST /team-chat/connections` — request a connection by email.
- `POST /team-chat/connections/:id/respond` — accept or decline a pending request.

### Renderer components

- `ConnectByEmailDialog` — the email input + request dialog.
- `ConnectionsSection` — the sidebar list of accepted + pending connections.
- `ConnectionMessageView` — the DM conversation view for a connection.
- `ConnectionPrivacyToggle` — the opt-in/opt-out toggle (optimistic, identity-gated interactivity).
- `ConnectionRequestDetailPane` — the inbox approval pane with Accept/Decline buttons.

### Agent message attribution

Agent-sent connection DMs use the same `authoredByAgent` flag as org channel messages. The cross-org connection DM relay stamps this unconditionally, so an agent DM always renders as "<Name>'s agent" (parity reached 2026-08-11).

## Related

The parent feature — the org channels and the sidebar this lane lives in — is on the [Team Chat](team-chat.md) page. How a pending request is presented in the unified queue is on [Connection Request Inbox Items](connection-request-inbox.md), and the queue itself is described on the [Inbox Overview](inbox-overview.md) page.

### Related pages

- [Team Chat](team-chat.md) — the parent feature.
- [Connection Request Inbox Items](connection-request-inbox.md) — how requests surface in the unified Inbox.

Contract: [team-chat-connections-contract.md](../../.claude/memory/contracts/team-chat-connections-contract.md) (C1-C13).
