Witbitz docs HomeTrustAll docs

App-faced Spaces

A Space can wear an app: the full-screen surface is your app site, and the private room rides over it as a pull-up card — the input line sits exactly where a normal Space's does. The agent's tools execute against the app pane over an origin-pinned bridge, and the card's grab bar shows exactly the structured fields that crossed to your site — nothing else ever does. The reference is the Event Finder concierge: a Space whose "chat history area" is a live commercial events site.

Status: the app-site mode and the wire contract below are live (the Event Finder demo runs on them). The sign-in patterns in §3 are documented designs — the recommended shapes, not yet shipped primitives.

1. Declaring an app site

A branded deployment declares its app in the brand config:

json
{ "agentName": "Concierge", "persona": "…", "appSite": "https://your-app.example", "tools": [  ] }

Opening a Space on that origin renders appSite full-screen with the room as the card. Every Space on the origin gets the app face, the brand's tools, and per-room resume: the last search is stored in the room's own sealed state doc, so returning to a room (any device, any member) replays it.

Three gates for a new app-site origin, all fail-closed:

  1. the Spaces app's CSP must allow framing it (SPACE_VAULT_APP_ORIGINS at deploy);
  2. the app site's frame-ancestors must list the whole ancestor chain (the Spaces origin, and the vault origin if the app runs vaulted — browsers check every ancestor);
  3. the app site should origin-pin inbound messages to the Spaces origin(s).

2. The wire contract

The pane speaks two messages down, one up — all postMessage, origin-pinned both ways:

direction message meaning
Space → pane { type: "search", args } run a query; args are exactly the disclosure-strip fields
Space → pane { type: "focus", index } highlight the Nth already-shown result
pane → Space { type: "results", events: [...] } the public results — returned into the agent's turn, so it recommends from live data

The pane sees only these messages. It never receives the conversation, names, or reasons — the same-origin policy walls it off, and the bridge carries nothing but the structured arguments the strip displays.

3. Signing into the app pane

Three patterns, in ascending capability. A key browser fact shapes all of them: the pane is an iframe, so it cannot see your normal first-party login cookies (third-party cookies are blocked or partitioned), and most authenticated sites refuse framing entirely — an arbitrary site can't be pointed at and inherit your session. A cooperating app site, however, has clean options.

3a. No sign-in (public data) — what the demo ships

The pane serves public data keyed by nothing. Simplest, fully anonymous toward the site: it learns only the strip's fields per query. Right default for discovery-type apps.

3b. Personal account (per member)

The standard embedded-app pattern (the same shape Spaces' own central auth broker uses):

  1. the pane opens its login in a popup — top-level, so cookies are first-party and Google/password/passkeys work normally;
  2. the popup hands the session back to the pane, which keeps it in partitioned storage (a Partitioned cookie or a token in the iframe's storage). Partitioned storage is stable per embedding origin, so you sign in once per device and stay signed in across rooms and reloads.

What it buys: account prices, saved payment, a "buy" that completes. Disclosure honesty: the site can now join your queries to your identity — the strip should say so (shared → … · as you@example.com). Each member is signed into their own account, so panes may show member-specific views, and tool results come from whoever asked.

3c. Shared room account (a "party" account) — the room-native pattern

If all members use one stateful account, the site's own backend becomes the room's shared surface: one cart, one favorites list, one booking — every member's pane converges by definition, with no extra sync protocol.

The elegant part is how the account is shared: never a password. The site issues a scoped session token (a party token), and the token rides sealed inside the room — in the same encrypted per-room state doc that already carries the resume search:

Caveats: one identity for N people (right for a family or a trip crew, wrong where per-person accountability matters); concurrent edits are the site's job (carts handle this well); token rotation must accompany member removal, or a removed member's pane keeps working until expiry.

Choosing

site learns shared state best for
3a public queries only none (per-pane) discovery, demos
3b personal queries + who you are per member purchases, personal accounts
3c party token queries + one shared identity the site's own state, room-wide planning together: shared carts, group bookings

Next

Machine-readable source: app-spaces.md · Generated 2026-08-29T18:46:30Z · build f3ff88cc · every doc in one fetch: llms-full.txt (HTML) · ← concierge-app · api-reference