oficina / meet Public

docs: README with the floor and relay paragraphs first; AGENTS.md deploying notes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CzvnuKhLzudvq7jZ7SvVt2
Paul Campbell pushed by paul@keymail.dev 93f1c2edba282932c17950daa35ca134f439ef5e parent fa875c7
2 files changed, +117 −0
  • AGENTS.md +11 −0
  • README.md +106 −0
diff --git a/AGENTS.md b/AGENTS.md
index 3bc2096..ad8a355 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -81,6 +81,17 @@ the golden deployment target, not a requirement: `./app -addr :8080`
serves anywhere. `GET /healthz` and `GET /api/version` are answered
by the framework, outside app middleware.
+## Deploying
+
+Meet deploys as a CARLOS unit route: `carlos deploy --app meet
+--account oficina`, checked against a build probe on `/api/version`.
+A migration applied under an earlier filename fails at boot;
+otherwise migrations never re-run. Every deploy, and every relay
+config change, restarts the instance and drops live calls. The wait
+can time out before hand-over — check `/api/version` before
+retrying. Canary: `carlos instances create` then `carlos deploy
+--channel` — `carlos canary` forms a two-label host (platform #124).
+
## UX conventions (seeded from profile: considered)
Accessible by construction, progressively enhanced, and never dependent on JavaScript to be usable, with the one exception named above: browser media participation, on the holding screen and in the room.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3d7d810
--- /dev/null
+++ b/README.md
@@ -0,0 +1,106 @@
+# Meet
+
+Meet is video calling for one team. A member makes a meeting, now or
+for later, and sends one link; anyone who follows it sets up their
+camera and microphone on a holding screen, waits to be let in if they
+are not on the team, and talks in a room of up to four, with chat
+beside the call and a screen to share. An agent can also create,
+list, relink and end meetings over an API. Every screen works with
+JavaScript disabled except browser media participation — the camera
+preview and join button on the holding screen, and the call itself in
+the room — and both pages still render their title, standing, floor
+notice and navigation with scripts off (spec §9).
+
+ICE servers come from the CARLOS platform relay, delivered as
+`CARLOS_RELAY` and minted fresh for each call at `GET /m/{sqid}/ice`;
+Meet names no STUN or TURN server of its own (suite ruling 6). With no
+relay configured, calls are direct only: two browsers connect when ICE
+can find a working path straight between them, and the holding screen
+says so. Enabling or changing the relay restarts the instance (spec
+§5.2, §5.5, §7.3, §15.13).
+
+## Sign-in
+
+Sign-in is a magic link to an address on the team's allowlist
+(`MEET_ALLOWED_ADDRESSES`). Following a meeting link gives an outsider
+a guest grant at sign-in — never a way into a room without a name —
+and the allowlist otherwise gates sign-in exactly as it does for a
+member (spec §3, §7.1). An operator can also enable Home sign-in with
+all four of `MEET_HOME_ISSUER`, `MEET_HOME_CONSUMER_ID`,
+`MEET_HOME_KEYS_BASE64` and `MEET_HOME_DEK_BASE64` — never a partial
+set — which links an existing member after a fresh, independent local
+sign-in and explicit confirmation; it never creates a person or grants
+membership on its own (spec §7.1.1).
+
+## The room
+
+The room is a peer-to-peer mesh of up to four admitted participants,
+negotiated with the W3C perfect-negotiation pattern over an SSE stream
+and a POST signal per peer. A guest waits in a queue until an admitted
+member lets them in; removing a participant and ending a meeting each
+go through their own confirm page — there is no in-room control that
+skips one (spec §3.5). Chat is fanned out live to admitted peers and
+never stored (spec §6). Screen share adds a second tile per sharer
+(spec §5.4). The room lives in one process's memory, so every deploy
+drops every live call (spec §15.11).
+
+## Agents
+
+A member mints an agent's bearer token from Settings; it is shown once
+and the row after it keeps only its hash. The token works on
+`/api/v1` only — never a cookie there, and never a bearer on an HTML
+route — for five operations: list meetings, create one, replace its
+link, end it, and read one meeting's detail. It cannot join a call
+(spec §8). An agent's reach is re-derived from its operator's current
+standing on every request, so an operator who leaves the team takes
+their agent's reach with them at once, with no separate revocation
+step. A limit of 60 requests a minute applies per agent (spec §8,
+§15.17).
+
+## Native apps
+
+The SwiftUI Mac and iPhone apps use this same server and a shared Go
+core (`meetcore/`, `protocol/`); there are no embedded webviews. Build
+the Mac app with `make native-mac`. See `native/README.md` and
+`native/ios/README.md` for setup, native sign-in and the native gates.
+
+## Building and gates
+
+`make ci` (vet, gofmt, tests, migration check) is the one gate a
+runner and a push share, and it stays `CGO_ENABLED=0` throughout.
+`make race` is the one exception, building a test binary under
+`CGO_ENABLED=1` for any change to `internal/meet/hub` or the
+signalling stream. `make browser` drives a real call across two real
+Chromium contexts, 31 scenarios in about nine minutes; it needs the
+Claude Code bash sandbox off, because the sandbox blocks UDP and every
+call then fails with `frames` stuck at 0. `make native-test` covers
+the shared Go core and the gomobile bridge. `make release
+VERSION=<sha>` stamps that version into `/api/version`, so a deploy
+can be checked against what it is meant to be running.
+
+## Deploying
+
+Meet deploys as a CARLOS unit route: `carlos deploy --app meet
+--account oficina`, checked against a build probe on `/api/version`.
+Secrets — `MEET_INSTANCE_KEY` and `MEET_DEK` (32 base64 bytes) — go
+through `carlos secrets`; mail reads `MEET_SMTP_*` with `CARLOS_SMTP_*`
+as a fallback, per variable; `MEET_ORIGIN`, `MEET_ALLOWED_ADDRESSES`
+and `MEET_ZONE` go through `carlos env`. `carlos relay enable --app
+meet` turns on the platform relay. Every deploy, and every relay
+change, restarts the instance and drops every live call, so deploy
+outside meeting hours. Migrations apply once each at boot (`msg=migrate`
+in the log) and are never re-run; a database that already applied a
+migration file under an earlier name fails at boot rather than
+silently diverging. The `carlos deploy` wait can time out before the
+instance hands over — check `/api/version` again before retrying. The
+canary recipe is `carlos instances create` then `carlos deploy
+--channel`, because `carlos canary` itself now forms a two-label host
+(platform #124).
+
+## Where things are written down
+
+The design lives in `docs/superpowers/specs/2026-09-07-meet-design.md`,
+the slice plans in `docs/superpowers/plans/`, and each slice's review
+in `docs/superpowers/reviews/`. `PRODUCT.md` covers what Meet is for
+and what it deliberately leaves out; `AGENTS.md` covers the
+conventions the code is held to.