platform-and-people
From the Meridians Wiki · Public · Maintained · joint
Platform, instances & people (the roadmap vocabulary)
The platform (the shipped Hosted runtime + control-plane / desktop-app epics; see Gateway 🔒) 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.usersrow (Supabase). The base unit; every other word below is a role a user plays. - member — a user's presence inside one instance: an
instanceMembersidentity 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.tsplus 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 (Supabasedirectorsvs the master'sinstanceMembers). 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_adminsrow — 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.
- License — the master runs as an Electron app on the user's own machine (local; BYOK keys;
the cheap flat plan). The
- 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 whencontrolPlaneEnabled()(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 byresolveRolefromplatform_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
/accountand 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) thatcanDispatchActiongates 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