What an account is in this product, who holds a seat in one, and what this account has done. An agency serving two drug companies buys two of these rather than one with a filter in it, and the reason is further down the page: there is no client column anywhere in this schema for a filter to read.
Live, from GET /api/measure/activity and GET /api/measure/outcomes, scoped to the bearer this deployment holds. Two families, reported separately, because FR-MEAS-03 asks for counts and asks for no target, no benchmark and no rating.
No identity provider is selected, so there is no user to make this request as. That is a statement about how this deployment is configured and not about your account: nothing here says you are signed out, because nothing here knows who you are.
Behind this: what this account has created and what came of it, counted two ways. No request was sent, so nothing on this screen is a guess about whether the service is up.
To see it on a development stack, run scripts/dev_up.sh and start the web application with AUTH_PROVIDER=e2e and SKEPSIS_DEMO_TOKEN_A set to the token that script mints. The harness refuses to load in a production build, or against an API that is not on this machine.
| What the question asked | OQ-04: can one agency account serve several pharma clients, and if so, how must each client’s data be kept apart inside that account. It is recorded against persona P-04 and ACC-01. |
|---|---|
| What was answered | That an external agency holds one account with a separate workspace per client, and that an in-house team holds its own account. The answer sits in skepsis_core.decisions, beside the question it settled. |
| What this schema has | Not that. There is no client column and no workspace column on any table, and skepsis_db.models.tenancy says in its own opening paragraph that adding one would answer OQ-04 in the schema. So in this build a client is an account: stricter separation than the answer describes, and not the shape it describes. Three requirements still carry OQ-04 on their gate, which is the honest reading of a question answered in prose and unbuilt in tables. OQ-04 |
| What keeps them apart | tenant_session sets app.tenant_id for the request and a tenant_isolation policy on every tenant-scoped table compares it. A route that forgets its WHERE clause returns nothing rather than returning a rival’s target list. That is also why this screen carries no control that shows both accounts at once: there is no query that could. |
| What does not change | The Article 14 register and the objection records at Compliance. Those tables carry no tenant_id by decision, because a duty owed to a profiled person cannot differ per customer, so switching accounts leaves them identical. A screen claiming the register belonged to this workspace would be wrong, and a sceptic who switches notices within a second. |
This deployment holds a bearer for no account at all. No bearer is configured, so no account is selected.
SampleNothing below is a measurement.
No route in this API serves a user, a seat or a role. The seats themselves exist: scripts/demo_seed.py writes one organisations row per account and six users under it with a membership each, and the CHECK constraint on memberships refuses any role outside the five below. Nothing reads them back out over HTTP, so the table is typed into components/RoleTable.tsx to match the seed rather than fetched from it.
Check it: GET /openapi.json on this deployment lists every path the API serves, and not one of them is a user, a seat or a role. The rows this table stands in for are in the demo database, in users and memberships, where psql can count them.
| Seat | Role, as this API spells it | As the requirements document names it | Where the role comes from |
|---|---|---|---|
user_admin | customer_admin | customer administrator (P-05), and ACC-03 calls the same person an administrator | Persona P-05, basis inference, so rule 0.3 blocked ACC-03 until somebody confirmed it. Somebody did, on 18/09/2026, which is what the requirement table below answers with. |
user_kol | kol_lead | KOL lead (P-01) | Basis stated. The reader this product was described for, and the only persona whose seat nobody has ever had to argue about. |
user_fml | field_medical_lead | field medical lead (P-02) | Basis stated, beside the KOL lead, and for the same reason. |
user_msl | msl | Medical Science Liaison (P-03) | Basis research. OQ-03 asked whether an MSL holds a seat of their own or only reads over a field medical lead's shoulder, and it has been answered: they hold their own. |
user_viewer | viewer | named by no persona and no requirement | The floor. `map_provider_role` answers viewer for any role key it does not recognise, so a token carrying an unknown claim lands on the role that reads nothing rather than on one that reads something. |
Each account holds a sixth row, user_dev, with role kol_lead: the subject the demo bearer signs in as. scripts/demo_seed.py seeds it so that GET /api/alerts returns that caller’s own subscriptions rather than an empty list. It is a sixth seat and not a sixth role.
Two words do not survive the crossing, and both deserve a customer administrator’s attention. The requirements document names a commercial user and this API holds no such role: ACC-02 asks for a separate commercial view, OQ-35 asks whether pharma commercial users are in scope at all, and a constraint that admitted commercial would be answering OQ-35 in the schema. The commercial surface in this demo is therefore a route, the commercial view, and not a role. In the other direction, viewer is a role this API holds and no requirement asked for, which is also deliberate: it is where an unrecognised role claim lands, and it reads nothing a gate has not opened. OQ-35
Adding a user, removing a user and assigning a role are the three things ACC-03 asks for. None of the three is here.
There is no route to press them against, and no question is holding one. This is the third of the four refusals this product tells apart: permitted, decided, and unwritten. Nobody to chase, only work to do.
The requirement table on this deployment answers for ACC-03: verdict BUILD, basis inference, released by the confirmation of 18/09/2026, OQ-03, OQ-35, and carrying no open question. So the decision to let an administrator add users, remove users and assign roles has been taken. What is missing is the path, which is a different sentence from the one this screen would have carried before that confirmation, and the ledger is what changed it.
What an account will never hold