MeridiansMeridians

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 GitHub

Raw Markdown source