platform-and-people
Source path: knowledge-base/knowledge/vocabulary/platform-and-people.md
---
## Platform, instances & people (the roadmap vocabulary)
The platform (the shipped Hosted runtime + control-plane / desktop-app epics; see [Gateway](../operations/GATEWAY.md))
turns on a small set of words that are easy to overload. This is the canonical set — use exactly these;
the collisions below are resolved on purpose.
**People — four layers, two of them collide by name (resolve by layer + case):**
- **user** — a person. At the platform layer, one `auth.users` row (Supabase). The base unit; every other
word below is a *role a user plays*.
- **member** — a user's presence **inside one instance**: an `instanceMembers` identity record. It
carries sign-in details, not an editable access assignment. "A user is a *member* of an instance."
- **role** — the capability ladder (low→high): **guest** < **viewer** < **contributor** <
**manager** < **director**. Non-Director roles are assigned at constellation or domain scope and
enforced by `permissions.ts` plus the effective-role resolver.
These are **instance** roles, not platform roles. *(The manager role was renamed from "admin" so that
"admin" is free for the platform layer — see below. There is no in-instance "admin".)*
- **Director** *(capital-D — platform account)* vs **director** *(lowercase — in-instance role)*. The
**platform Director** is a user with a **gateway account** (`directors`, Supabase) that owns product
subscriptions. The **director role** is the top rung of the ladder — the sovereign of *that* instance.
They **coincide** (the account owner *is* their instance's director) but name **different systems**
(Supabase `directors` vs the master's `instanceMembers`). Disambiguate by case + "platform Director" /
"director role".
- **manager** *(in-instance role)* vs **Admin** *(platform operator — us)*. **manager** = the ladder role
just below director inside one instance (the director's deputy: manages people + edits the model, minus
hosting/sovereignty). **Admin** = the platform operator, a `platform_admins` row — the business admin
over **all** accounts (the gateway `/admin`). **Never conflate** — "Admin" is always the platform;
"manager" is always an in-instance role. (Under a director you have a **Manager**, not an "admin".)
**Instances — two orthogonal axes (never collapse them):**
- **instance** — one running Meridians host, sovereign over its own record.
- **Axis 1 · runtime authority** (`getSyncRole`; after E1, the *server-of-record*):
- **master** — the **authoritative record-holder**. *Shipped:* the Director's browser on
localhost/Electron. *After E1:* the **server daemon** (the forked Next server — local or on a VM). One
master per instance.
- **client** — a renderer that reads from a master over a transport: the **local renderer**, or a
**remote browser** that joined over the tunnel. **Retired synonyms — do not use for the sync role:
`clone`, `tributary`.** ("clone" survives *only* for *duplicating* a domain/scene, never the role.)
- **Axis 2 · product / where the master runs:**
- **License** — the master runs as an **Electron app on the user's own machine** (local; **BYOK** keys;
the cheap flat plan). The `electron/` roadmap.
- **Hosted (VM)** — the master runs on a **Fly VM we provision** (always-on; platform-supplied and metered provider services; pricier).
The `gateway/` roadmap. Avoid "Managed" as the product name (ambiguous) — say **Hosted**.
- **Orthogonality (the key unification):** *master/client* is **runtime authority**; *License/Hosted* is
**where the master runs + who pays/keys**. A master is the record-holder whether it's a local Electron
(License) or our VM (Hosted); collaborators are clients in **both**. A user can hold **License AND/OR
Hosted** — products are per-subscription (`hasLicense` / `hasHosted`), never a field on the account.
**Gateway & control plane (the C0–C2 vocabulary):**
One codebase, **two deployment modes** — the mode decides which surfaces exist (`src/proxy.ts` → the pure `routeForDeployment` policy is
the one enforcement point):
- **gateway** — the control-plane deployment (`meridians.global`, `MERIDIANS_GATEWAY=true`): central
auth (Supabase) + billing (Stripe) + the business consoles (Users / Devices) + Host + Explore. It
mounts **no store / IndexedDB / instance surface** (ThemeProvider only) and runs none of the
instance's sync/record machinery. Say **gateway**, not "the site" / "the portal".
- **instance** — a running Meridians app (the workspace): the Director's Electron app, a hosted VM, or
a plain web deploy. **Canonical word: instance.** *Retired synonym: `tenant`* — it survives only in
legacy filenames (`tenant-guard.ts`, `tenant-auth.ts`); never write "tenant" in new copy, docs, or
identifiers. Avoid "host instance" as a noun too — **host** is reserved for the *tunnel-hosting
role* (an instance that runs the broker + ngrok so clients can join); say "instance" and add the
role only when the tunnel is the point.
- **instance type** — `electron | hosted | web` (`detectInstanceType`). The product that unlocks each:
Electron ← **License**, hosted VM ← **Hosted**; platform owner/admin run either **free**. Say
"Electron instance (License)" / "hosted instance (Hosted)" — never "license instance".
- **control plane** — the gateway's API surface consumed by instances (`/api/account|admin|billing|
directory|entitlement`). Instances call it **only** when `controlPlaneEnabled()` (a gateway URL is
configured AND the build is production) — **never in development, and never during sign-in**. Auth
is local-first; the control plane is a separate, non-blocking layer (entitlement verdicts + device
telemetry) applied *after* a Director is signed in.
- **central auth** — Supabase authentication, **Directors only** (Google or email + password). Members
never touch it: they sign in with a **local PIN/password** and ride the Director's window. A local
Director record linked to its central account is **centrally linked** (`centralLinked`). The
Director's **email/mobile are owned by the gateway** — instances mirror them read-only and re-sync
on every auth event (`centralIdentityPatch`); the instance edits display names only.
- **platform roles** — `owner` > `admin` (the platform operators — free access to every product) ·
`Director` (a paying account) · `guest` (signed up, no plan). Resolved by `resolveRole` from
`platform_admins` + subscriptions. Distinct from **instance roles** (the guest→director ladder above)
— "Admin" is always the platform, never an in-instance role.
- **entitlement / the window rule** — entitled while actively subscribed **or** still inside the
paid-through period (`isEntitled`); canceling keeps access until the period ends, and every member
of the instance rides that same window. Offline, a cached verdict is trusted for the **grace**
ceiling (14 days), then the app must re-check.
- **device / access point** — one row in `access_devices`: a **host** (an instance that checked in) or
a **member seat** riding it, with server-observed IP + browser/region. Written by the heartbeat,
**admin-only** visibility (the gateway Devices console). Telemetry, never an auth factor.
- **hand-off** — the C2 §5 one-time token that lets an instance's "manage account" link land on the
gateway **already signed in** (same Supabase project, different origin). *Specced, not yet shipped* —
today the profile link opens `/account` and the user signs in there.
### Activity classification — category vs area (two axes, never conflate)
Every reducer action is classified on **two orthogonal axes** in `action-policy.ts`:
- **action category** — *who may do this*: the permission lattice (`view`/`sync`/`game`/`learn`/
`contribute`/`people`/`membership`/`extraction`/`extension`/`edit`/`delete`/`constellation`) that
`canDispatchAction` gates on. Authority only — never use it as an analytics lane.
- **activity area** — *what the person was doing*: the intent lane the activity log records and the
Usage page swimlanes on. Eleven areas: **world** (editing the domain artifact), **opinion** (streams,
priors, merges, projections, readings, notes, perspectives), **research** (Watch: loops, runs, the
source catalog, articles), **chat**, **extraction** (new-domain/extension jobs), **learning**,
**program** (the machine loop + auto mode), **game**, **constellation** (feed/newsletter/editorial),
**governance** (members, roles, boundary changes, deletion), **access** (sign-ins/outs, session
resumes, presence). Derived per action as category-default +
explicit override (`actionArea`); pre-area history re-lanes at read time from the entry's stored
Open on GitHubRaw Markdown source