# The Bridge — governed collaboration between sovereign Spaces

The Bridge is Witbitz's forward-looking frontier: a **governed relationship between two or more sovereign Spaces**
— *not* another shared room. Each side keeps its own identity, data, policies, and authority; the Bridge defines
what may flow, who participates, and how it's audited. The other side need not even be Witbitz — an external agent
and its humans can join over signed HTTPS. **The protocol is the product.**

> Status: an **early protocol preview**, live at `https://api.witbitz.chat/v1/bridge`. Normative spec:
> [bridge-protocol.md](https://docs.witbitz.chat/bridge-protocol.md); wire contract:
> [bridge.openapi.yaml](https://docs.witbitz.chat/bridge.openapi.yaml).

---

## 1. The shape — three spaces

Two parties each keep a **private prep room** (their people + their agent, sealed under their own key — raw work
never leaves), and they meet in **one shared space** — the Bridge — where approved content is placed and humans can
talk directly. There is **no neutral host**; the parties co-host. A party is *native* (a Witbitz Space) or
*external* (someone else's agent + humans, on their own system) — the two are just implementations of the same
wire contract. It generalises to N parties (the shared space is a first-class Space with its own id).

## 2. The five invariants

The semantics are stated invariants-first; the ops are just mechanism.

1. **Confinement is structural.** The shared space's epoch key opens *only* the shared space. Private rooms are
   under different keys — an external or hostile party **can't reach them because it holds no key**, not because a
   policy says no.
2. **Attribution by signature.** Every entry is signed by the submitting party's key and verified against its
   public key in the membership record — on the ciphertext.
3. **The platform is content-blind.** Bodies are sealed under a key the platform never holds. It checks
   membership, capability, epoch, and the hash chain — never the content.
4. **Source-side egress.** Each party approves what it contributes *before* it is sealed into the shared space.
   Nothing crosses un-reviewed; the platform never reads content to police it.
5. **Governed, revocable membership + trustless audit.** Every join or revoke mints a fresh epoch key; a joiner
   gets no back-history by default; a revoke gives real forward-secrecy. Server-signed **checkpoints** that parties
   pin + gossip make equivocation detectable.

## 3. Key epochs

The shared space is a sequence of **epochs**, each with its own key sealed per-member (to each party's box key).
Every **join OR revoke** is an epoch boundary: the new key is sealed only to the new member set. So a **removed**
party can't open the next epoch (forward secrecy), and a **joiner** gets no transcript unless policy explicitly
seals past epochs to it (invited into a conversation, not handed its history).

## 4. Capabilities

Each member carries `caps ⊆ {read, submit, admit, revoke}` → observer (read-only auditor) / party (read+submit) /
admitter (+admit/revoke). SUBMIT/ADMIT/REVOKE are capability-gated.

## 5. The ops (live)

At `https://api.witbitz.chat/v1/bridge`:

| op | what it does | auth |
|----|--------------|------|
| `POST /spaces` | found a shared Space (JOIN, first party) | entry signature |
| `GET /spaces/{s}/members` | the public membership record + sealed key grants | public |
| `PUT /spaces/{s}/members` | admit / revoke — a re-key, an epoch boundary | capability |
| `POST /spaces/{s}/entries` | submit a signed, sealed entry (a load or a post) | entry signature |
| `GET /spaces/{s}/entries` | read the shared thread since a cursor (ciphertext) | public |
| `GET /spaces/{s}/checkpoint` | the latest server-signed head, to pin + gossip | public |

**Deployed auth is thin-but-sound:** SUBMIT is authenticated by the entry's own signature (verified against the
membership pubkey); reads/members/checkpoint are content-blind or public. Per-request `partySignature`
(RFC-9421-style) is the documented hardening (`x-status: proposed`) — the guarantees already hold from the key
boundary + entry signatures.

## 6. Native or external — the interop boundary

The whole point is that the *other side isn't necessarily Witbitz*. A native party and an external party (identity
+ the protocol crypto only, zero Witbitz-Space code) are two implementations of one contract; the interop was
proven end-to-end (a native + an external party co-inhabit one shared space, content-blind). That interop boundary
— *own the governance; let the wire be MCP/A2A/signed-HTTPS* — is why the protocol, not any one app, is the
product.

## 7. Code map

| Concern | Where |
|---|---|
| Membership + capabilities + key epochs | `agent/bridgeMembership.mjs` |
| Signed, hash-chained log + checkpoints | `agent/bridgeLog.mjs` |
| Service + party client (native = external) | `agent/bridgeSpace.mjs` |
| HTTP binding | `agent/bridgeHandler.mjs`; infra `infra/prod-bridge.tf` |
| Normative spec / wire contract | `docs/bridge-protocol.md` · `docs/bridge.openapi.yaml` |

## 8. Status

Live over HTTP + verified end-to-end (found → admit an external party → signed+sealed submit → content-blind read →
checkpoint; governance rejects a stranger/tamper). It is an **early preview** — the frontier of the platform, not
a beta-stable API. The wider vision (org-to-org negotiation, delegated authority across the boundary, a public
transparency log) builds on this.
