Sohay owns five capabilities, registered on the administrator role at
activation. WordPress’s manage_options is layered on top so existing
administrators keep working with no migration.
The five
| Capability | Persona |
|---|---|
sohaychat_manage |
Plugin admin |
sohaychat_view_conversations |
Read-only support viewer |
sohaychat_reply_conversations |
Support agent |
sohaychat_manage_kb |
Knowledge-base editor |
sohaychat_view_logs |
SRE / observability |
The implications
manage_options (WordPress core)
└─ sohaychat_manage
├─ sohaychat_view_conversations
├─ sohaychat_reply_conversations ──┐
├─ sohaychat_manage_kb ├─ (reply also implies view)
└─ sohaychat_view_logs ┘
Three edges:
manage_optionsimplies all five — backwards compatibility.sohaychat_manageimplies the other four — the top of Sohay’s own hierarchy.sohaychat_reply_conversationsimpliessohaychat_view_conversations— you cannot reply to what you cannot see.
The consequence that catches people out
The implications are dynamic, not stored.
They run through WordPress’s user_has_cap filter, so
current_user_can( 'sohaychat_view_logs' ) returns true for any administrator
even though wp role get administrator will not list it.
That works fine until somebody trims a role. Remove manage_options from a
custom role and every dynamic grant for that role disappears with it — the
user keeps whatever is explicitly stored and loses the rest, usually without
an obvious error.
If you build a custom role by removing capabilities from administrator, grant Sohay’s capabilities explicitly rather than relying on the chain.
Two deliberate asymmetries
Knowledge Base authoring rides core post capabilities. Writing an
article is content work — any Author or Editor can do it. sohaychat_manage_kb
gates the sync and AI-management surfaces, not the writing. Those are
different jobs and they are separated on purpose.
Clearing the log requires more than reading it. sohaychat_view_logs gets
you Diagnostics read-only; clearing the buffer escalates to
sohaychat_manage. Somebody with read access cannot erase the evidence.
Conversation scoping
A non-administrator holding only sohaychat_view_conversations is scoped to
conversations assigned to them or unassigned rather than the whole inbox.
This is a genuine access control, not a UI nicety. To change it, the
sohaychat_admin_conversation_scope filter narrows or widens what a given
operator can reach.
Granting them
Any role editor, or WP-CLI:
wp cap add editor sohaychat_reply_conversations
Activation and uninstall
Capabilities are added to administrator at activation and removed at uninstall. Capabilities you granted to other roles are yours to manage — removing the plugin cleans up its own grants, not your role design.
Where to go next
Giving your team access without making them admins for the practical arrangements, and The REST API surface for what each capability gates.