What it is #
Quox Discord Pro is a loopback daemon that connects one Discord application to one or more QuoxCORE instances.
Each channel you bind gets a mode: mirror a message back for a liveness check, answer support questions from a grounded knowledge corpus, hand a question to the same brain behind the QuoxChat widget on quox.ai, route a private staff channel to the real platform agents as a named persona, convene several agent specialists at once for a synthesised answer, or simply receive outbound build and GitHub events.
Every inbound and outbound step is recorded as a WARD-witnessed AEE envelope, and channels marked staff-only stay silent to team members unless they @mention the bot or reply directly to one of its messages.
It ships as a repository, not (yet) a dashboard-installable plugin: see maturity and limits for exactly what that means today.
Binding modes #
Every channel is bound to exactly one mode, set with the qdp bind command described below. These are the six modes the daemon understands (manifest.json's bindingModes):
| Mode | What it does |
|---|---|
echo | Replies "echo: <message>" with the round-trip latency. A liveness check for the daemon and the binding, nothing more. |
support | Retrieval-grounded answers from a crawled knowledge corpus, cited by page, with a mention gate, per-channel HITL policy, cooldowns, staff-awareness, and a support-gap queue for questions the corpus could not answer. |
quoxchat | Routes a plain question to the same QuoxChat widget brain that answers on quox.ai, in a per-question thread. No infrastructure tools available in this mode, question-answering only. |
team | A private staff channel routed to the real platform agents via the collector chat pipeline, answering as a bound persona (for example CommanderQ, or a specialist like Security or Testing). |
roundtable | CommanderQ convenes two or three specialists, each replies as their own persona, then CommanderQ synthesises. Specialists can execute tools, not just advise. |
feed | Outbound only: build outcomes (from quox-build-daemon) and GitHub org events post into the channel under branded webhook personas. Not a message-handling mode; there is no inbound routing for it. |
A binding also carries per-channel settings depending on mode: persona(the display name and webhook avatar it answers under), agent_id (which platform agent a team channel talks to), instance (which QuoxCORE instance it targets, see Setup below), cooldown_s, and for support specifically hitl_policy and require_mention.
Setup #
This is the current, honest setup path, not an aspirational one. There is no install wizard yet.
1. Create a Discord application and bot
In the Discord Developer Portal, create an application, add a bot, and enable the privileged Message Content intent. That intent step is a manual click in the portal today; it is not automated by this daemon. Invite the bot to your server with the permissions it needs.
2. Provide credentials
Two secrets, read from files rather than environment variables baked into a build: a Discord bot token in a chmod-600 tokenFile, and the QuoxCORE collector's INTERNAL_SERVICE_KEY in a serviceKeyEnvFile pointing at the dashboard's .env. Neither is committed to the repository.
3. Edit config.json
The daemon's configuration is a single config.json: guildId, collectorBase and authBase (the QuoxCORE instance to talk to), orgId, and the bindings array (one entry per channel, each with its channel_id and mode plus that mode's settings). A daemon can also serve further QuoxCORE instances under config.instances, each scaffolded with its own collectorBase, orgId and serviceKeyEnvFile, and each toggled with its own enabled flag until its route is actually deployed.
4. Run the daemon
# start now, and keep it running across sessions and reboots
systemctl --user restart quox-discord-pro
# after editing config.json by hand (bindings edited via qdp bind/unbind
# take effect immediately, no restart needed)
systemctl --user restart quox-discord-proOne daemon per QuoxCORE instancePer manifest.json: this is one daemon per QuoxCORE instance, with a separate Discord application per instance. Dev and production never share bot credentials or a Discord application, by design.
The qdp CLI #
Every verb below is taken from bin/qdp.mjs's own usage output. Run it as node bin/qdp.mjs <verb> from the repository root.
| Verb | What it does |
|---|---|
status | Daemon liveness (systemd state, pid), configured instances, and the binding count |
instances | Every configured instance and the collector/org it targets, including disabled ones pending deploy |
bindings | Every channel binding: channel id, mode, instance, and mode-specific settings |
bind <channelId> <mode> [key=value ...] | Bind a channel to a mode via the daemon's control API. Live immediately and persisted to config.json, no restart |
unbind <channelId> | Remove a channel binding. Live immediately, no restart |
gaps | Support questions the corpus could not answer, awaiting an official answer from the dashboard inbox |
health | One-line OK / actionable summary; exits non-zero when the daemon is not healthy |
node bin/qdp.mjs status
node bin/qdp.mjs bind 123456789012345678 support hitl_policy=all require_mention=0
node bin/qdp.mjs bindings
node bin/qdp.mjs gapsThe bind and unbind verbs talk to the daemon's own loopback control API (controlPort/controlToken in config.json), so a live rebind never requires a restart. There is also a dashboard panel at /discord-pro inside quox-dashboard (src/components/discord-pro) for the same inspection surface without a terminal; check maturity and limits below for how current that panel is against this CLI.
Maturity and limits #
Compiled from quox-dashboard/docs/STATUS_AND_LIMITS_DISCORD_PRO.md, the authoritative maturity map for this surface. Nothing below is softened by omission; treat that file, not this page, as the source of truth if the two ever drift.
Beta Working, proven, with named caveats
- The gateway daemon connects, resumes, dedups replays, and backfills on boot so a restart window never silently drops a message.
- Governed support replies are live on the dev instance: a full inbound/draft/decision/outbound chain, WARD-witnessed, with both HITL-all (owner approves each draft) and policy-auto (answers without per-reply approval) proven. Answers are docs-grounded with citations, low-confidence escalation, and an auto-correction loop that files an official answer back into the corpus.
- QuoxSupport is live on production: a separate, scoped-permission bot bridges the public support channel to the same QuoxChat widget that answers on quox.ai, running under systemd with
Restart=always. - The agentic team roundtable convenes two or three specialists who answer as their own persona and get synthesised by CommanderQ; specialists execute real tools rather than only advising.
- Team-channel routing sends private staff channels to the real platform agents via the collector chat pipeline, each answering as its own persona.
- Build and GitHub feeds post via branded webhook personas, proven against real builds and real repository events.
Stub Not built yet, named plainly
- Dashboard settings surface and
.quoxpluginpackaging.Configuration is files on the dev and production boxes today (config.jsonplus a chmod-600 token file), not a settings UI a customer could self-serve.
Known gap Documented limitations, not softened
- Single guild, effectively one operator so far. Nothing here is multi-tenant today.
- The bot holds Administrator. A scoped permission set is a tracked follow-up, not done, by owner choice for the current build-out phase.
- The privileged Message Content intent is a manual step in the Discord Developer Portal; it is not automated by this daemon or its setup.
- Discord surfaces cannot be screenshotted headlessly without a real user session, so evidence for this surface is API readback with assertions, not pixels.
- Governed moderation (witnessed mod actions) is planned, not started.
- The publisher (changelog, news, proof-loop and QuoxPlan events posted to Discord) is planned: the webhook mechanics are proven by the build and GitHub feeds, but nothing beyond those two is wired yet.