AlphOne 0.15.0
Nothing changes for the accounts you already have. Every one keeps the role it holds, and a stock install still names admin and member. An account that held no role becomes a member.
What changes is that the list is no longer fixed. A plugin can declare a role of its own, or add a capability to a role that already exists, so a deployment can name roles the core knows nothing about.
A role is now a set of named capabilities rather than a rank. The core knows one capability, manage_users, and createUser, setUserDisabled and setUserRole need it. Ask me for capabilities and grantable rather than reading the role name, because a plugin role holding manage_users passes the same check an admin does.
An admin can only give a role it holds itself, and can only touch an account whose role it holds. So an admin cannot grant a role reaching further than admin, and cannot demote or disable an account that already holds one. The Users screen offers only the roles you may actually give.
An account holding no role still works contacts and tasks, because no field of the product asks for a capability. It only loses user management. alphone grantrole -role member gives a role to every account holding none.
Plugin screens can now read the signed-in session and ask what the account may do, rather than comparing a role name.
Changes that may affect existing integrations
Refusals now carry a capability extension naming what the role fell short of. The message still reads admin required, so anything matching on it keeps working, but read the extension instead of the message.
createUser takes an optional role and starts an account at the narrowest role the deployment names, which is member in a stock install.
Upgrading
This is a normal migration and runs on container start. Migration 00014 moves each role onto the account row and drops core.user_roles. Rolling it back restores the table with every role intact, including any a plugin declared, but take a backup first anyway. See Updates and backups.