ADR-031: The User

Date: 2026-08-18

Statements

name

A User has a display_name, and it is a name rather than half a login. Not unique,

What identifies a User is a key they hold or an identity they control.

root

"display_name of root cannot be changed anymore when set"

"if display_name of root is unset, it becomes root"

"regardless of root_identity setting it or not, root is never an available display name except for the one root identity user, they dont need to set their display name as root"

So the ROOT User is root from the moment they exist, without choosing it, and root is the one name no other User may take.

You claim the ROOT User by proving you own a root identity. It happens once and cannot happen again, so it is attested as node:claimed. Recording never fails the thing it records (ADR-030), which makes this the one attestation whose loss cannot be made up later.

What is recorded

A User is one object per person under <location>/system/users/ on the parquet backend, holding an id, a display_name, any number of emails and phone numbers, the level, who switched it off, the keys it holds and the accounts that reach it. The record is auth.User, mirrored by UserRecord on the object. A sqlite deployment keeps none, the way it keeps no tokens.

POST /auth/user/arrive is where a person says a name, an email and a phone number, and requires none of them. The name is settled once; an email or a phone number that arrives later is added rather than refused, because a User has any number of each. A phone number is kept as its digits and the leading + the person typed, so one number is one string however it was spaced.

POST /auth/user/disable and POST /auth/user/enable are the switch, reached by the person's own session. Off, disabled_by names them, every gate refuses them as switched off, and the Self element offers to reawaken. Set by anyone else, enable is refused naming who, and the person stays off. The act is attested as identity:disabled and identity:enabled.

Not done

A User holds no first name and no last name. A Dutch name has three parts, and the middle one is the person's to write: van Doorn files under D, Van Doorn under V, and the string alone does not say which.

A User reaches namespaces through permission, and nothing records which yet.

A namespace's owner is a string, and so is a credential's admitted_as.

created_by is empty on ROOT. The node that signed the first admission is written down — node:claimed names it — but on the attestation rather than on the User, so the provenance is a record to go and find instead of a field to read.

root Element for User management and overview

GDPR delete, PR 911

Creating Users manually as root: an invitation ROOT sends to an address, with a cancel on ROOT's copy; a SUPER User made the moment the friend proves an account; the login reading SUPER off that User. The story is docs/stories.

ROOT switching a person off. The record and the gate are ready for it, and no route lets ROOT flip anyone but themselves yet.

reassignment of e-mail address