docs: establish canonical documentation architecture (#1210)
ci/woodpecker/push/publish Pipeline failed
ci/woodpecker/push/publish Pipeline failed
This commit was merged in pull request #1210.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# User Guide
|
||||
|
||||
> **Status:** Partially migrated. The quickstart, web-dashboard reference, and Discord conversation workflow are current.
|
||||
|
||||
This book is the canonical home for end-user workflows, user-visible behavior, product concepts, and user troubleshooting. Keep installation, deployment, security controls, and recovery procedures in [`ADMIN-GUIDE/`](../ADMIN-GUIDE/); keep implementation detail in [`DEVELOPER-GUIDE/`](../DEVELOPER-GUIDE/).
|
||||
|
||||
## Start here
|
||||
|
||||
- [Documentation atlas](../README.md) — placement rules and source-of-truth boundaries.
|
||||
- [Documentation sitemap](../SITEMAP.md) — resolvable current navigation and authority-gated migration summary.
|
||||
- [Quickstart](getting-started/quickstart.md) — install Mosaic, complete setup, and launch a session.
|
||||
- [Web dashboard](product/web-dashboard.md) — current routes, navigation, chat persistence, projects/tasks views, settings, and admin behavior.
|
||||
- [Discord conversations](workflows/discord-conversations.md) — current authorized parent-channel, thread, attachment, and control workflow.
|
||||
|
||||
## Chapter map
|
||||
|
||||
| Chapter | Scope | Status |
|
||||
| ------------------ | ------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| `getting-started/` | First-use setup, orientation, and quickstarts. | Quickstart is current; additional pages are planned. |
|
||||
| `concepts/` | User-facing terminology, product concepts, and mental models. | Scaffold only. |
|
||||
| `workflows/` | Task-oriented procedures for using Mosaic Stack. | Discord conversation workflow is current. |
|
||||
| `product/` | Current product surfaces and visible behavior. | Web dashboard reference is current. |
|
||||
| `troubleshooting/` | User-visible failures, diagnostics, and fixes. | Scaffold only. |
|
||||
|
||||
### Current pages
|
||||
|
||||
- [Quickstart](getting-started/quickstart.md) — the verified installed-CLI first-use path.
|
||||
- [Web dashboard](product/web-dashboard.md) — verified current Next.js dashboard behavior and limitations.
|
||||
- [Discord conversations](workflows/discord-conversations.md) — verified current Discord user workflow.
|
||||
|
||||
Every promoted page must be added to this index and to [`SITEMAP.md`](../SITEMAP.md) in the same migration slice.
|
||||
|
||||
## Migration backlog — not current navigation
|
||||
|
||||
These are source candidates, not current user guidance:
|
||||
|
||||
- `_old_structure/guides/user-guide.md` — quarantined historical source; verify every claim before promotion. See the [documentation catalog](../reports/documentation/2026-08-10-docs-catalog-audit.md) for its disposition.
|
||||
- The former root `QUICKSTART.md` was an empty placeholder and has been replaced by the current page above.
|
||||
|
||||
Do not link to the quarantine as a current user path. Create a new page only after classifying its audience, status, and evidence in the migration report.
|
||||
|
||||
## Authoring boundary
|
||||
|
||||
New user-facing documentation belongs under one of the chapter directories above. Use a lowercase kebab-case page name, state whether commands are current or held, and link back to this index plus related canonical sources.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[PRD|Product requirements]]
|
||||
@@ -0,0 +1,129 @@
|
||||
---
|
||||
title: Mosaic Stack Quickstart
|
||||
type: guide
|
||||
audience: user
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# Mosaic Stack Quickstart
|
||||
|
||||
Verify and install the versioned Mosaic CLI package, complete first-run setup, connect to a gateway, and launch an agent session. This page covers the installed-CLI path with the default local storage tier.
|
||||
|
||||
> **Scope:** This is an end-user installation route. It does not authorize PostgreSQL setup, production deployment, or starting Gateway/Web directly from a source checkout. Use the [administrator guide](../../ADMIN-GUIDE/README.md) for deployment and the [developer guide](../../DEVELOPER-GUIDE/README.md) for contributor setup.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 20 or newer.
|
||||
- npm, for the global Mosaic CLI installation.
|
||||
- At least one supported agent runtime:
|
||||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
||||
- [Codex](https://github.com/openai/codex)
|
||||
- [OpenCode](https://opencode.ai)
|
||||
- [Pi](https://pi.dev)
|
||||
- Credentials for the runtime or model provider you plan to use.
|
||||
|
||||
## 1. Install Mosaic
|
||||
|
||||
> **Installation hold:** Do not execute the website installer or a script fetched from a mutable repository branch. The current release tooling does not publish an independently verified immutable dependency closure or a signed installer. If your policy requires either property, stop until a release provides it.
|
||||
|
||||
The currently published CLI/framework package is `@mosaicstack/[email protected]`. Pin the exact package version and verify its published artifact integrity before installation:
|
||||
|
||||
```bash
|
||||
registry='https://git.mosaicstack.dev/api/packages/mosaicstack/npm/'
|
||||
package='@mosaicstack/[email protected]'
|
||||
expected_integrity='sha512-/Zsjdf8Ln2QchQTG9lirpqSxhDbNyBjOvGkWrDWRugxCuqUWP5V0rUNVDivmPvro+Vyq3hxDyA9i4hDfkEFmMg=='
|
||||
actual_integrity="$(npm view --registry="$registry" "$package" dist.integrity)"
|
||||
test "$actual_integrity" = "$expected_integrity"
|
||||
npm install --global --registry="$registry" "$package"
|
||||
```
|
||||
|
||||
The explicit comparison pins the reviewed top-level package artifact; npm also checks the downloaded tarball against registry integrity metadata. It does **not** make the package's transitive dependency graph independently immutable. Review the [package release](https://git.mosaicstack.dev/mosaicstack/-/packages/npm/%40mosaicstack%2Fmosaic/0.0.49) before proceeding, and stop if the integrity comparison fails.
|
||||
|
||||
The versioned package includes the Mosaic framework and CLI. npm installs it under your configured global prefix. Ensure that prefix's `bin` directory is on `PATH` if your shell cannot find `mosaic`.
|
||||
|
||||
## 2. Complete first-run setup
|
||||
|
||||
The versioned package install does not launch the wizard. Run it manually:
|
||||
|
||||
```bash
|
||||
mosaic wizard
|
||||
```
|
||||
|
||||
The wizard guides framework setup and gateway installation. It can collect your agent identity, preferences, provider configuration, and gateway administrator details interactively.
|
||||
|
||||
For a separately installed or existing gateway, skip local gateway installation and use its URL in the login step below.
|
||||
|
||||
## 3. Verify and sign in
|
||||
|
||||
For a gateway installed on this machine, check its health and setup state:
|
||||
|
||||
```bash
|
||||
mosaic gateway status
|
||||
mosaic gateway verify
|
||||
```
|
||||
|
||||
Sign in without putting your password in shell history or process listings:
|
||||
|
||||
```bash
|
||||
mosaic gateway login
|
||||
```
|
||||
|
||||
The command prompts for the gateway URL, email, and password as needed. Do not pass passwords with `--password`.
|
||||
|
||||
For a remote gateway, provide its URL explicitly:
|
||||
|
||||
```bash
|
||||
mosaic gateway login --gateway https://gateway.example.com
|
||||
```
|
||||
|
||||
## 4. Launch Mosaic
|
||||
|
||||
Open the interactive terminal interface:
|
||||
|
||||
```bash
|
||||
mosaic tui
|
||||
```
|
||||
|
||||
The TUI defaults to `http://localhost:14242` and can prompt for login if no valid session is saved. To connect it to another gateway:
|
||||
|
||||
```bash
|
||||
mosaic tui --gateway https://gateway.example.com
|
||||
```
|
||||
|
||||
You can also launch a supported runtime through Mosaic:
|
||||
|
||||
```bash
|
||||
mosaic pi
|
||||
mosaic claude
|
||||
mosaic codex
|
||||
mosaic opencode
|
||||
```
|
||||
|
||||
Use the launcher matching the runtime you installed and authenticated.
|
||||
|
||||
## 5. Inspect configuration and health
|
||||
|
||||
These commands are safe diagnostics and do not change the product requirements or active task ledger:
|
||||
|
||||
```bash
|
||||
mosaic config show
|
||||
mosaic doctor
|
||||
mosaic gateway logs
|
||||
```
|
||||
|
||||
If the gateway is unhealthy, run `mosaic gateway status` and `mosaic gateway logs` before attempting a reinstall. If your session expires, run `mosaic gateway login` again.
|
||||
|
||||
## Storage and deployment boundary
|
||||
|
||||
The default local gateway tier uses embedded PGlite and does not require an external PostgreSQL or Valkey service. This quickstart intentionally does not configure `DATABASE_URL`, PostgreSQL, pgvector, or a federated deployment.
|
||||
|
||||
For standalone or federated storage, deployment topology, secrets, SSO, backups, or recovery, stop here and use the [administrator guide](../../ADMIN-GUIDE/README.md). For work from a repository checkout, keep `DATABASE_URL` unset and follow the [developer guide](../../DEVELOPER-GUIDE/README.md); do not use root `pnpm dev` as a local PGlite route while the current dotenv safety hold remains active.
|
||||
|
||||
## Related
|
||||
|
||||
- [User Guide](../README.md)
|
||||
- [Documentation atlas](../../README.md)
|
||||
- [Administrator Guide](../../ADMIN-GUIDE/README.md)
|
||||
- [Developer Guide](../../DEVELOPER-GUIDE/README.md)
|
||||
- [Repository README](../../../README.md)
|
||||
@@ -0,0 +1,276 @@
|
||||
---
|
||||
title: Mosaic web dashboard
|
||||
type: guide
|
||||
audience: user
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# Mosaic Web Dashboard
|
||||
|
||||
This page documents the current Next.js dashboard: its routes, navigation, visible
|
||||
views, and the chat persistence behavior supported by the checked-in web and gateway
|
||||
implementation.
|
||||
|
||||
> **Current UI boundary:** Projects and tasks can be displayed in the dashboard, but
|
||||
> the current dashboard does not provide **New Project** or **New Task** controls.
|
||||
> Those entities can be created through authenticated gateway API clients; that API
|
||||
> surface is separate from the views described here.
|
||||
|
||||
## Access and routes
|
||||
|
||||
The dashboard uses the gateway session. Dashboard routes are protected by the web
|
||||
`AuthGuard`; the admin route also requires the `admin` role.
|
||||
|
||||
| Path | Access | Current behavior |
|
||||
| --------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/` | Any | Redirects to `/chat`. A signed-out visitor is then redirected to `/login`. |
|
||||
| `/login` | Signed out | Email/password sign-in, plus buttons for configured SSO providers. Successful sign-in returns to `/chat`. |
|
||||
| `/register` | Signed out | Creates an account with name, email, and password, then returns to `/chat`. |
|
||||
| `/auth/provider/[provider]` | SSO handoff | Looks up the requested provider and starts an OIDC sign-in when that provider is configured and supports OIDC. Unknown, disabled, or incompatible providers show an error and a link back to login. |
|
||||
| `/chat` | Signed in | Conversation list and streamed assistant chat. |
|
||||
| `/projects` | Signed in | Project cards and the Active Mission status section. |
|
||||
| `/projects/[id]` | Signed in | Project detail view with overview, tasks, missions, and an optional read-only PRD tab. |
|
||||
| `/tasks` | Signed in | Task data in Kanban or list view. |
|
||||
| `/settings` | Signed in | Profile, appearance, notifications, and provider tabs. |
|
||||
| `/admin` | Signed-in admin | User Management and System Health tabs. Non-admin users are redirected away from the admin page. |
|
||||
|
||||
Settings and admin tabs are client-side tabs; changing a tab does not change the URL.
|
||||
|
||||
## Dashboard navigation
|
||||
|
||||
The **Workspace** sidebar contains these links, in order:
|
||||
|
||||
1. **Chat** — `/chat`
|
||||
2. **Tasks** — `/tasks`
|
||||
3. **Projects** — `/projects`
|
||||
4. **Settings** — `/settings`
|
||||
5. **Admin** — `/admin`
|
||||
|
||||
The active link is highlighted, including the parent link when viewing a project
|
||||
such as `/projects/<id>`. The Admin link is rendered in the shared sidebar, but the
|
||||
page itself is still restricted to administrators.
|
||||
|
||||
The top bar provides:
|
||||
|
||||
- a sidebar toggle (collapse/expand on desktop; open/close an overlay on mobile),
|
||||
- the light/dark theme toggle,
|
||||
- the signed-in user's name, and
|
||||
- **Sign out**, which returns to `/login`.
|
||||
|
||||
The applied global theme is stored in browser local storage under `mosaic-theme`.
|
||||
|
||||
## Chat
|
||||
|
||||
### Starting and managing conversations
|
||||
|
||||
Open `/chat` and either select a conversation or choose **Start new conversation**
|
||||
in the empty state. The conversation sidebar also has **New conversation**. Creating
|
||||
one calls the gateway and gives the conversation a server-side ID before the first
|
||||
message is sent.
|
||||
|
||||
The sidebar currently supports:
|
||||
|
||||
- searching conversation titles,
|
||||
- selecting a conversation,
|
||||
- renaming a conversation inline (Enter or leaving the field commits the new title),
|
||||
- deleting a conversation after confirmation, and
|
||||
- grouping conversations by project when project data is available.
|
||||
|
||||
Archived conversations are filtered out of the sidebar. The current dashboard does
|
||||
not expose archive/restore controls.
|
||||
|
||||
If no conversation is selected when a message is sent, the dashboard creates one
|
||||
automatically. A new conversation is titled from the first 60 characters of the
|
||||
first message; an empty placeholder conversation is similarly retitled after its
|
||||
first message. The active conversation is held in page state, not in the URL: the
|
||||
route remains `/chat` rather than changing to `/chat/<id>`. After a refresh, select
|
||||
the stored conversation again from the sidebar.
|
||||
|
||||
### Sending and streaming
|
||||
|
||||
The chat composer provides:
|
||||
|
||||
- a model selector populated from available gateway providers and models,
|
||||
- a multiline message field,
|
||||
- character and approximate token counts, and
|
||||
- a **Send** button.
|
||||
|
||||
Use **Cmd/Ctrl+Enter** to send. The composer is disabled while a response is
|
||||
streaming. The interface displays a **Stop** control during streaming, but the
|
||||
current `ChatPage` does not pass a stop handler, so cancellation is not a reliable
|
||||
current dashboard action.
|
||||
|
||||
Assistant and user messages render Markdown. Assistant messages can show model and
|
||||
token metadata when it is present in the returned message, and rendered user/assistant
|
||||
messages have a copy control.
|
||||
|
||||
### What is persisted
|
||||
|
||||
Assistant replies are not page-only or memory-only. The current flow is:
|
||||
|
||||
1. The browser creates or selects a conversation and optimistically displays the
|
||||
user's message.
|
||||
2. The browser submits the user message to the gateway conversation-message API and
|
||||
sends the turn over the authenticated `/chat` WebSocket namespace.
|
||||
3. The gateway streams the assistant response to the page. At `agent_end`, it saves
|
||||
non-empty assistant text to the conversation with model, provider, tool-call, and
|
||||
token-usage metadata when available.
|
||||
4. Selecting the conversation later loads `/api/conversations/<id>/messages`, so
|
||||
stored user and assistant messages are shown again. When the gateway has to create
|
||||
or resume the agent session for that conversation, it also loads stored conversation
|
||||
history as context.
|
||||
|
||||
The live page appends the completed response as soon as the stream ends; the gateway
|
||||
persistence write is asynchronous. Therefore a persistence error can leave a reply
|
||||
visible in the current page while it is unavailable after a later reload. The gateway
|
||||
redacts sensitive content before emitting and storing assistant text.
|
||||
|
||||
## Projects and missions
|
||||
|
||||
### Project list: `/projects`
|
||||
|
||||
The project page loads the signed-in user's projects and shows either:
|
||||
|
||||
- project cards with name, status, description, and creation date, or
|
||||
- **No projects yet** with the message that projects appear when created through the
|
||||
gateway API.
|
||||
|
||||
The page also shows **Active Mission**. It reports the mission ID, phase, task
|
||||
completion count, and status when coordination data is available; otherwise it
|
||||
shows **No active mission detected**.
|
||||
|
||||
There is no New Project button or project form on this page. The gateway has
|
||||
project CRUD endpoints, but this dashboard page currently reads project data only.
|
||||
|
||||
### Project detail: `/projects/<id>`
|
||||
|
||||
A project detail page shows its name, status, description, created/updated dates,
|
||||
and task summary counts for total, done, in progress, and blocked tasks. Its tabs
|
||||
are:
|
||||
|
||||
- **Overview** — up to five recently updated tasks, a mission summary, and non-empty
|
||||
project metadata.
|
||||
- **Tasks (`n`)** — task status filters and clickable task rows.
|
||||
- **Missions (`n`)** — a status-ordered mission timeline.
|
||||
- **PRD** — present only when project metadata contains non-empty `prd` or
|
||||
`prdContent` text; the content is displayed read-only.
|
||||
|
||||
Selecting a task from the project detail Tasks tab opens a detail dialog with its
|
||||
status, priority, description, assignee, due date, timestamps, tags, pull-request
|
||||
links, and notes when those fields exist. The dialog can be closed with its close
|
||||
button, the backdrop, or Escape. The dashboard does not provide project or task
|
||||
edit controls in this view.
|
||||
|
||||
## Tasks
|
||||
|
||||
Open `/tasks` to load the tasks visible to the signed-in user. The default view is
|
||||
**Kanban**; a toggle switches to **List**.
|
||||
|
||||
- Kanban columns are **Not Started**, **In Progress**, **Blocked**, and **Done**.
|
||||
- Kanban cards show title, priority, optional description, status, and due date.
|
||||
- List view shows title, status, priority, and due date.
|
||||
- The supported task status set also includes `cancelled`; it is not a Kanban
|
||||
column, but a returned cancelled task can appear in List view.
|
||||
|
||||
The top-level Tasks page has no New Task button, form, or working task edit dialog.
|
||||
Clicking a task in that page does not open the project-detail dialog. The gateway
|
||||
supports authenticated task CRUD separately, while this dashboard page currently
|
||||
reads and presents task data.
|
||||
|
||||
## Settings
|
||||
|
||||
Open `/settings`. The page has four tabs and opens on **Profile**.
|
||||
|
||||
### Profile
|
||||
|
||||
- **Display Name** can be edited.
|
||||
- **Email** is displayed but disabled; the page says it cannot be changed there.
|
||||
- **Avatar URL** can be edited.
|
||||
- **Save changes** sends the profile update through BetterAuth and reports saving,
|
||||
saved, or an error state.
|
||||
|
||||
### Appearance
|
||||
|
||||
The tab presents **System**, **Light**, and **Dark** theme choices, a **Collapse
|
||||
sidebar by default** switch, and a **Default Model** text field. **Save changes**
|
||||
saves these as user preferences.
|
||||
|
||||
Current implementation limits are worth noting: the shared sidebar provider starts
|
||||
expanded and does not read `ui.sidebar_collapsed` on page load; the global applied
|
||||
theme is controlled by the top-bar theme toggle; and the chat page initially selects
|
||||
the first available provider model rather than reading `ui.default_model` itself.
|
||||
Do not treat these preference fields as proof that those defaults are applied across
|
||||
all dashboard sessions.
|
||||
|
||||
### Notifications
|
||||
|
||||
The tab presents and saves three email preferences:
|
||||
|
||||
- **Agent task completed** — initially off,
|
||||
- **Mentions** — initially on, and
|
||||
- **Weekly digest** — initially off.
|
||||
|
||||
### Providers
|
||||
|
||||
The Providers tab contains SSO discovery and LLM provider discovery/testing areas:
|
||||
|
||||
- **SSO Providers** shows configured providers and their protocols, callback path,
|
||||
team-sync claim, SAML fallback, and warnings when supplied by the gateway. It does
|
||||
not configure SSO from the dashboard.
|
||||
- **LLM Providers** shows configured providers as Active or Inactive. A provider can
|
||||
be tested for reachability; the result may include latency, an error, and the
|
||||
number of discovered models. Expanding a provider shows model capabilities,
|
||||
context size, cost, and the default-model marker.
|
||||
|
||||
When no LLM providers are configured, the page displays setup guidance mentioning
|
||||
`OLLAMA_BASE_URL` and `MOSAIC_CUSTOM_PROVIDERS`. Provider credentials and provider
|
||||
configuration are not editable in this dashboard tab.
|
||||
|
||||
## Admin panel
|
||||
|
||||
The `/admin` page is wrapped in an admin-role guard. It opens on **User Management**
|
||||
and provides **System Health** as the second tab.
|
||||
|
||||
### User Management
|
||||
|
||||
The page loads the user list and provides:
|
||||
|
||||
- a user count,
|
||||
- **+ New User**, with name, email, password, and `member`/`admin` role fields,
|
||||
- role promotion/demotion,
|
||||
- ban/unban,
|
||||
- deletion after confirmation, and
|
||||
- a retry action when loading fails.
|
||||
|
||||
The table shows name/email, role, active or banned status, creation date, and
|
||||
available actions.
|
||||
|
||||
### System Health
|
||||
|
||||
The health tab loads the gateway's overall `ok` or `degraded` status and provides a
|
||||
**Refresh** action. Its cards cover:
|
||||
|
||||
- PostgreSQL database status and latency/error,
|
||||
- Valkey cache status and latency/error,
|
||||
- active agent-session count, and
|
||||
- configured LLM providers and model counts.
|
||||
|
||||
## Evidence used for this page
|
||||
|
||||
The behavior above was checked against the current implementation and focused tests,
|
||||
not copied forward as-is from the historical mixed guide. The main evidence files
|
||||
are:
|
||||
|
||||
- `apps/web/src/app/(dashboard)/` route pages and `apps/web/src/app/page.tsx`,
|
||||
- `apps/web/src/components/layout/`, `apps/web/src/components/chat/`,
|
||||
`apps/web/src/components/projects/`, and `apps/web/src/components/tasks/`,
|
||||
- `apps/web/e2e/navigation.spec.ts`, `chat.spec.ts`, `projects.spec.ts`,
|
||||
`settings.spec.ts`, and `admin.spec.ts`,
|
||||
- `apps/gateway/src/chat/chat.gateway.ts` and
|
||||
`apps/gateway/src/__tests__/conversation-persistence.test.ts`,
|
||||
- `apps/gateway/src/chat/chat.gateway-redaction.spec.ts`, and
|
||||
- the authenticated gateway controllers under `apps/gateway/src/conversations/`,
|
||||
`projects/`, `tasks/`, and `admin/`.
|
||||
|
||||
Related: [User Guide index](../README.md) and [SSO provider runbook](../../ADMIN-GUIDE/security/sso-providers.md).
|
||||
@@ -0,0 +1,128 @@
|
||||
# Discord conversations
|
||||
|
||||
> **Status:** Current Discord workflow for an administrator-provisioned, authorized guild channel.
|
||||
>
|
||||
> Telegram shared-contract parity, Matrix channel conversations, and a gateway-wide shared adapter registry are not current features. See [Current versus planned](#current-versus-planned) before using any older channel instructions.
|
||||
>
|
||||
> **Audience:** People conversing with an agent through Discord.
|
||||
|
||||
This workflow assumes an administrator has configured the Discord bot, gateway connection, allowlists, and a logical-agent binding. Users cannot create a binding or authorize themselves from Discord.
|
||||
|
||||
## Current versus planned
|
||||
|
||||
| Surface | Status | What you can rely on |
|
||||
| ----------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Discord guild messages | **Current live routing** | Authorized messages route to the configured logical agent; parent/thread delivery is tested, but ordinary durable history is not guaranteed. |
|
||||
| Telegram | **Not shared-contract parity** | A raw legacy plugin exists, but its current source has no equivalent documented authorization, pairing, route, or focused package tests. |
|
||||
| Matrix | **Not implemented as a channel workflow** | No current gateway channel adapter and test boundary establishes a Matrix conversation workflow. |
|
||||
| Shared channel registry | **Not implemented** | The gateway's current registry hosts lifecycle wrappers; it does not provide universal channel routing or health. |
|
||||
|
||||
## Start in a configured parent channel
|
||||
|
||||
Send a normal message in the administrator-configured parent text channel. You do **not** need to mention the bot for an ordinary turn.
|
||||
|
||||
For an authorized user, Mosaic:
|
||||
|
||||
1. checks the guild, parent channel, user allowlist, pairing, role, and rate limit;
|
||||
2. keeps the response target in the parent channel; and
|
||||
3. routes the turn to the binding's logical agent using a stable conversation address.
|
||||
|
||||
No Discord thread is created for this untagged parent-channel case. The response is sent back to that same channel.
|
||||
|
||||
Messages from an unconfigured guild/channel, an unallowlisted user, an unpaired user, or a user without a role that can send are ignored without creating a thread or dispatching to the gateway. Bot-authored messages are ignored. Direct messages are not handled by the current guild ingress path.
|
||||
|
||||
## Start a threaded topic with a mention
|
||||
|
||||
Mention the bot in a parent channel when you want a separate topic:
|
||||
|
||||
```text
|
||||
@Mosaic investigate the deployment failure
|
||||
```
|
||||
|
||||
The current Discord adapter creates a public thread for the message, removes the bot mention from the content sent to the agent, and targets the response to that thread. If the message already has a Discord thread attached, the adapter reuses it instead of creating another one.
|
||||
|
||||
Authorization happens before thread creation. If the user, guild, parent channel, pairing, role, or rate check fails, no thread is created. If Discord cannot create or fetch the requested thread, the message is not dispatched because Mosaic cannot guarantee the requested response destination.
|
||||
|
||||
## Continue inside a thread
|
||||
|
||||
Reply in the existing authorized thread without mentioning the bot again. The adapter:
|
||||
|
||||
- authorizes the message against the configured parent text channel;
|
||||
- keeps the thread as the response target; and
|
||||
- never attempts to create a nested thread.
|
||||
|
||||
A category above the text channel is not used as the authorization parent. Only the actual configured text-channel parent grants thread inheritance.
|
||||
|
||||
The stable conversation address is formed from the configured logical agent, channel name, and response channel/thread, for example:
|
||||
|
||||
```text
|
||||
<logical-agent-id>:discord:<response-channel-id>
|
||||
```
|
||||
|
||||
It does not contain Claude, Codex, Pi, OpenCode, a model, a provider, a process, or a native runtime-session ID. The gateway owns runtime selection behind that route, so changing the runtime/provider does not require a new Discord address.
|
||||
|
||||
### Durability limitation
|
||||
|
||||
Treat the current Discord path as **live routing and delivery**, not guaranteed durable conversation history. The Discord conversation address above is an external route string, while persisted conversation/message rows use UUID conversation IDs. No current external-route-to-UUID mapping was found. The gateway can continue dispatching after a persistence/binding failure, so a reply may appear in Discord without durable history or restart/resume continuity.
|
||||
|
||||
Do not rely on Discord as the sole record of a conversation. Durable history requires an implementation that maps the external route to a UUID, surfaces persistence failure, and proves fresh-message persistence and restart recovery in an integration test.
|
||||
|
||||
## Attachments
|
||||
|
||||
An authorized message may contain text, attachments, or an attachment without text. The current adapter maps attachments into the shared message shape and preserves the native attachment ID, name, URL, content type, and optional size.
|
||||
|
||||
The gateway accepts only bounded attachment metadata: at most 10 attachments, HTTPS URLs without credentials, query strings, or fragments, and bounded ID, name, URL, MIME-type, size, and total metadata values. An unsafe or malformed attachment is rejected before the message is acknowledged or dispatched. Binary content is not embedded in the gateway message; the attachment remains a validated external reference.
|
||||
|
||||
## Runtime controls
|
||||
|
||||
The current Discord text controls are:
|
||||
|
||||
```text
|
||||
/approve
|
||||
/stop <approval>
|
||||
```
|
||||
|
||||
They remain on the current parent/thread route and do not create a new topic. Approval and stop require an already enrolled durable session; ordinary Discord chat does not prove that enrollment occurred. These are privileged operations: the paired user must have the `admin` role and a provisioned `mosaicUserId`, the gateway must have a tenant configured for the control path, and the enrolled durable session must still belong to the bound logical agent. A stop must present the exact approval reference created for that target; approval consumption is one-time.
|
||||
|
||||
If these checks fail, the control operation is denied or produces no successful control result. Do not assume that being able to read a channel grants control authority.
|
||||
|
||||
## Response and delivery behavior
|
||||
|
||||
The gateway emits raw stream events to the current Discord compatibility path. The plugin buffers `agent:start`/`agent:text` output and sends the completed response on `agent:end`; this is not a claim of token-by-token Discord rendering.
|
||||
|
||||
Outbound Discord text is split at a 1,900-character boundary. Transient rate-limit, server, and network failures are retried up to three attempts with one deterministic nonce per correlation/chunk; permanent delivery failures are not retried. A response route is checked against the configured logical-agent/channel binding before Discord is contacted.
|
||||
|
||||
## If a message gets no response
|
||||
|
||||
Check these possibilities with the administrator:
|
||||
|
||||
1. You are in a direct message, an unconfigured guild/channel, or a thread whose parent is not configured.
|
||||
2. Your Discord user ID is missing from the user allowlist or `pairedUsers`.
|
||||
3. Your pairing is `viewer`, which cannot send ordinary agent turns.
|
||||
4. The per-user/channel message or mention-thread limit was reached.
|
||||
5. The bot is not connected to Discord or the gateway Socket.IO `/chat` namespace.
|
||||
6. A mentioned topic could not create/fetch its thread.
|
||||
7. The gateway rejected the signed envelope, route, attachment, or replayed native message ID.
|
||||
8. `/approve` or `/stop <approval>` was attempted without the required admin pairing, tenant, pre-enrolled durable session, or exact approval.
|
||||
|
||||
These failures are intentionally fail-closed; an unauthorized or unverifiable message should not create a thread or agent side effect.
|
||||
|
||||
## Not current: Telegram and Matrix
|
||||
|
||||
Do not substitute Telegram or Matrix instructions for this workflow:
|
||||
|
||||
- The current Telegram plugin uses raw Telegraf and Socket.IO messages, maps a chat to `telegram-<chatId>`, accepts text only, and does not establish the Discord-style service-token, allowlist, pairing, shared-route, or attachment boundary.
|
||||
- No current Matrix gateway channel adapter, channel binding, user authorization flow, or focused channel tests establish a Matrix conversation workflow.
|
||||
- The current gateway plugin list is lifecycle-only; it is not proof that every channel shares this Discord behavior.
|
||||
|
||||
Those are parity/design gaps, not alternate user workflows.
|
||||
|
||||
## Evidence and related pages
|
||||
|
||||
- [Channel protocol architecture](../../DEVELOPER-GUIDE/architecture/channel-protocol.md) — current shared types, Discord compatibility path, and explicit parity boundary.
|
||||
- [Discord ingress security](../../ADMIN-GUIDE/security/discord-ingress.md) — administrator configuration, authentication, authorization, and failure controls.
|
||||
- [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) — native Discord routing and delivery implementation.
|
||||
- [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) — parent, mention, existing-thread, authorization, attachment, rate, egress, and health tests.
|
||||
- [`apps/gateway/src/plugin/discord-ingress.security.spec.ts`](../../../apps/gateway/src/plugin/discord-ingress.security.spec.ts) — gateway signature, replay, binding, attachment, approval, and stop tests.
|
||||
- [`apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts`](../../../apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts) — Discord control-flow test with explicit durable-session pre-enrollment; it is not fresh-message persistence evidence.
|
||||
- [User Guide](../README.md)
|
||||
Reference in New Issue
Block a user