Platform Surfaces
Threads implemented as channels. Bots are first-class service principals with capability-row grants and webhook-first events. Elysia OpenAPI generates MCP and CLI clients from the same contract. bojastack is the admin-API-first operator CLI.
Threads as Channels
A thread is a channel with parent_channel_id and root_message_id set. Thread permissions inherit from the parent, then apply thread-local channel permission layers on top. This design means threads reuse all message history, unread tracking, permission evaluation, pin, and pagination code without duplication.
A valid reply auto-reopens an archived thread. Threads are not a special case — they are channels with a parent reference. All channel code works identically for threads.
channels (
id text PRIMARY KEY,
type text CHECK (type IN ('text', 'thread', 'dm', 'group', 'live', 'saved')),
server_id text REFERENCES servers(id),
parent_channel_id text REFERENCES channels(id), -- non-null for threads
root_message_id text, -- thread anchor
position integer,
...
)
Bots / Service Principals
Bots are not second-class users with special-cased auth. They are first-class user identities with is_bot = true, operating through the same infrastructure as human users.
| Aspect | Design |
|---|---|
| Identity | First-class user_id with is_bot = true; uses same auth and session infrastructure as human users |
| Installation | bot_installations: (bot_id, server_id, installed_by); installation scopes capability rows to that server |
| Capability grants | capability_key/effect rows identical to any role; limited to the declared manifest subset |
| Message content grant | Separate explicit grant required — not inherited from installation. Reading message content is opt-in. |
| Webhook events | Webhook-first delivery; bots receive events at their registered endpoint |
| Rate limiting | Explicit per-bot rate limits enforced server-side, independent of human user limits |
| Visibility | Server-owned and private bots visible in V1 UI |
OpenAPI Surface
Elysia generates the versioned OpenAPI schema from day one. All client surfaces — the MCP server, bojastack CLI, and any future SDKs — are generated from the same schema definition. There is no separate client maintenance burden.
MCP (Model Context Protocol) enables AI tools to call Boja APIs as structured tool invocations. Because the schema is auto-generated from Elysia routes, any new API endpoint is immediately available as an MCP tool and CLI command with no extra maintenance.
bojastack CLI
bojastack is the operator CLI for administrative and diagnostic tasks. Every destructive operation produces a mandatory audit record. The CLI communicates with the admin API — it never bypasses authorization.
| Command Category | Description |
|---|---|
access explain |
Show full permission evaluation trace for a user/channel pair — which rules matched, which capability rows applied |
audit |
Query the immutable audit log with structured filters by actor, resource, time range, or event type |
redact |
Apply tombstone or legal-hold to content by ID; creates auditable redaction record |
break-glass |
Controlled emergency access with mandatory audit record — no silent impersonation |
server inspect |
View server state, membership list, roles, channel tree |
billing inspect |
View subscription and entitlement state — never raw ledger rows |
Zero inspect |
View sync publication state, client staleness metrics, replica health |
API Invariants
A search engine hit is a candidate, never authorization evidence. External API callers receive the same capability-checked responses as the product UI — no search result ever bypasses the capability row check.
- Webhook retries: 7 attempts over 24 hours with exponential backoff
- CLI auth: Device/interactive auth flow for humans; expiring CI keys for automation
- Production impersonation: Explicit audit record required. No two-person approval at V1 launch (planned post-launch)
- External API parity: No privileged internal-only API surfaces — external callers get the same authorization as product UI
Platform Capability Scoping
Bot capabilities are scoped strictly to their installation context. A bot installed in Server A cannot see Server B's channels, regardless of its declared capabilities.
A bot cannot read channels it was not installed with access to. Message content is a separate explicit grant. Server admins control which bots are installed and what capabilities each bot receives within that server.