# Roles

> The Roles root of the Users page, the role list with its reach strips, and the role panel where a role's name, description and permission switches are set, including the two fixed roles.

The **Roles** root holds one node per role. A role is a named set of permission switches;
users bind to it, and editing it changes every user who holds it at once. The station ships
six roles. Two are fixed: **Not signed in** (the role in force before anyone signs in) and
**Admin** (full access). Four are ordinary editable, deletable suggestions: **Viewer**,
**Operator**, **Maintainer** and **Developer**.

Like the Users root, this root and its children belong to an administrator on this circuit
(Manage local users). Anyone else sees the root without children and, behind it, the notice
that says to sign in as an administrator. On a station with no users yet the notice reads
instead: "Roles are already seeded, but changing one takes an administrator, and this station
has none yet. Set up local users first: the primary administrator is the first one."

## The role list {#the-role-list}

Opening the root shows the card **ROLES**, with the line "Each role reaches these areas, at
the depth its strip shows. Editing a role changes every user who holds it, and editing the
first one changes what any screen may do before someone signs in." and one row per role, in
a fixed order:

| Row | Marks | Sub-line |
| --- | --- | --- |
| Not signed in | A walking-person glyph and the chip **In force before a sign-in**. | Its description, "What anyone can do at this station without signing in." |
| Admin | A lock glyph and the chip **Full access · locked**. | Its description, "Full access to every area, plus managing users." |
| Every other role | | Its description when one is set; otherwise a live summary of its reach ("Can change {n} of 6 areas", "View-only" or "No access"), so an empty description never leaves the row blank and a stale one never lingers. |

Every row trails its compact reach strip, six pips in the same order everywhere, so the roles
read as a ladder rather than a list of names. With no editable roles left, the card says "Not
signed in and Admin are the only roles on this station. New role builds one for the work the
bench actually does."

Clicking a row opens that role's node. In the column, each role node trails the same compact
strip; the Not signed in node wears the walking-person glyph among the keys.

## The factory roles {#the-factory-roles}

| Role | Description as shipped | What it holds |
| --- | --- | --- |
| Not signed in | What anyone can do at this station without signing in. | Everything except Manage local users and Remote access (LAN). |
| Admin | Full access to every area, plus managing users. | Every permission; fixed. |
| Viewer | Read-only across the station. | View dashboards, View connector, Look at models, View histories, View logic, View validation, View events, Remote access (LAN). |
| Operator | Runs the line day to day. Operates dashboards and logic, runs procedures. | Viewer plus Operate dashboards, Operate logic, Run procedures. |
| Maintainer | Operator, plus calibrating and configuring the connector, exporting data and managing recorded runs. | Operator plus Calibrate tags, Configure connector, Export/import histories, Manage histories. |
| Developer | Builds screens, logic and procedures: everything except station administration. | Maintainer plus Edit dashboards, Configure logic, Manage process (which brings Edit recipes & evaluations with it). |

The ladder is a suggestion, not a contract: Viewer, Operator, Maintainer and Developer can be
renamed, edited and deleted. The seed runs once, on a station whose roles table is empty; a
deleted seed does not come back. Not signed in is permissive by design, so a fresh station
works fully with nobody signed in and tightening it is a deliberate act.

## The role panel {#the-role-panel}

A role's panel saves as you work: the name and the description when the field is left, a
switch the moment it is flipped. While the runtime is stopped the panel is inert under a
"Runtime stopped" note. While a role another screen has just deleted is selected, the panel
says "That role is no longer on this station. Pick another in the column."

### Head, name and description {#head-name-and-description}

The head names the role and, for the fixed pair, what it is. Admin carries the chip **Full
access · locked**. Not signed in carries a chip that reads how open the station stands to
anyone who has not signed in, followed by one sentence:

| Chip | When | Sentence |
| --- | --- | --- |
| Open | Three or more areas at Operate or Manage. | "Without signing in, anyone at this station can operate or configure {n} of 6 areas. Turn switches off below to tighten it." |
| Restricted | One or two areas at Operate or Manage. | "Without signing in, anyone at this station can change {n} of 6 areas; the rest is view-only or off." |
| View-only | No area above View. | "Without signing in, anyone at this station can view what the strip below shows, and change nothing." |

| Field | What it is | Values / default | Effect |
| --- | --- | --- | --- |
| Role name | The name the column, the list and the user picker use. | Up to 60 characters; a new role starts as **New role**; a blank name keeps the previous one. Locked on Not signed in and Admin. | Commits when the field is left; the feed reports "Renamed the role to '{name}'." |
| Description | The role's sub-line in the list. | Up to 200 characters, placeholder "What this role is for". Hidden on Not signed in; read-only on Admin. | Commits when the field is left; the feed reports "Saved the description of '{name}'." |

Under the name field the fixed roles carry a note: "The Admin role is fixed. It always has
full access and can manage local users." and "Not signed in is the role in effect when nobody
is signed in. Its permissions are editable; the role itself cannot be renamed, deleted or
assigned to a user." The description's hint reads "Shown under the role's name. Update it when
you change what the role can do."

Below the fields the card reads the role's reach live: the summary, the words **follows the
switches below**, and the labeled strip. It re-forms on every flip, before the write comes
back. It never edits: the System area mixes independent switches, so a pip cannot map back to
one of them.

### Permissions {#permissions}

The **PERMISSIONS** card opens with one of three leads:

- Admin: "The Admin role always has full access, so its switches are fixed. It is the role
  that can manage users, and the station keeps one."
- Not signed in: "Each switch applies as soon as you change it, to every screen where nobody
  has signed in."
- Every other role: "Each switch applies as soon as you change it, to this role and to every
  user holding it."

Then one group per area, headed by the area's glyph, its name and a counter, "{on} of
{total}": Dashboard (3), Connector (3), Process (4), Histories (3), Logic (3), Validation (1)
and System (5). Each row is a label, a description and a switch. The full catalog, with every
label and description exactly as it reads, is on the [Permissions](users-permissions) page.

A switch is locked, and cannot be flipped, in four cases:

| Locked switch | Why | How it reads |
| --- | --- | --- |
| Every switch on Admin | The Admin mask is fixed. | On, greyed, no tag. |
| Manage local users on every other role | Exclusive to Admin. | Off, greyed. |
| View dashboards | The floor; it can never be revoked. | On, greyed, tagged **Required**. |
| A prerequisite whose dependent is on | Turning the dependent on turned it on and holds it there. | On, greyed, tagged **Required**. |

Flipping a switch on also turns on what it requires (Operate dashboards turns on View
dashboards; Manage process turns on Edit recipes & evaluations, Run procedures and Look at
models). Flipping a switch off also turns off everything that required it (View connector off
takes Calibrate tags and Configure connector with it). The rules are listed on the
[Permissions](users-permissions#implication-rules) page. Every flip writes the whole role at
once and the feed reports "{Label}: on for '{role}'." or "{Label}: off for '{role}'."; a write
the station refuses puts the switches back to what it actually holds and reports "Could not
save the role: {reason}".

The station also normalizes what it stores: a non-Admin role never keeps Manage local users,
and every stored mask carries its prerequisites, so a role is always self-consistent.

### In force for, or Held by {#in-force-for-or-held-by}

The last card differs between the walk-up role and every other:

- On Not signed in, **IN FORCE FOR** reads "Every screen where nobody has signed in, this
  station's own and any device viewing it. Nobody is given this role; it is what applies
  until someone signs in, and signing in swaps it for that user's own role." and "Because the
  station depends on it being here, this role stays: its permissions are yours to set, its
  name and its existence are not."
- On every other role, **HELD BY** lists the display names of the users holding it, with
  "Every switch you change here changes what all of them may do." With nobody on it, it reads
  "No user holds this role yet. Assign it on a user's own page, under Users."

## Creating and deleting a role {#creating-and-deleting-a-role}

**New role** in the column footer creates a role that starts at the floor: View dashboards
on, everything else off, empty description. Add reach deliberately; note that a blank role
does not hold View events, which every factory role has. **Delete role** on the detail bar
asks "Delete the role '{name}'? This cannot be undone." and is refused, greyed with the
reason, while the runtime is stopped, on either fixed role ("{Name} is a fixed role: the
station depends on it being here."), and while any user still holds it ("This role is held by
users. Move them to another role first.").

## How a change reaches everyone {#how-a-change-reaches-everyone}

The roles live in one service the whole station reads. A flipped switch reaches every user
holding the role on every connection at once: the station window, every browser, every
signed-in operator. A screen re-checks the role at every press, so an operator whose role just
lost a permission has the command refused on the next press even if the screen was already
drawn. A user whose role is deleted from under them falls to the floor. A dashboard whose
**Visible to** checklist named the deleted role treats that entry as inert, so the dashboard
never becomes unreachable.

## What the panel does not do {#what-the-panel-does-not-do}

- It does not assign users. That is the Role picker on each user's page under
  [Users](users-local-users#role).
- It does not change Admin: not its switches, not its name, not its existence.
- It does not rename or delete Not signed in, and it does not offer it in any user's Role
  picker.
- It refuses every write while the runtime is stopped: name, description, switches, creation
  and deletion all answer "Runtime stopped".
- It cannot grant Manage local users to any role but Admin, and it cannot revoke View
  dashboards from any role.
