Skip to content

Gateway events

Keep the Gateway disabled unless real-time invalidation, channel-order layout evidence, exact-scope soundboard playback corroboration, or exact-scope native Interaction ingress is required. Enabling it requires expected application and bot IDs plus the exact scope required by the selected mode. READY must match both identities and identify a bot user before the feed accepts dispatches. The event feed may request only GUILDS, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, and GUILD_MESSAGE_POLLS; a layout-only channel-order connection requests only GUILDS; soundboard playback adds the standard GUILD_VOICE_STATES intent; and an Interaction-only connection requests zero intents. Do not add Message Content, presence, member, or other privileged intents.

Count every successful outbound Gateway event in one rolling budget private to its shard connection. Admit caller-triggered commands only below a conservative half-budget boundary so Heartbeat, Identify, and Resume retain priority capacity, but never let priority bypass the absolute Discord limit. Keep the command FIFO bounded by count and wait time, remove an aborted entry exactly, and cancel all retained commands on every connection boundary. Begin remote evidence freshness and response timing only after the command is written. A locally exhausted control budget must reconnect before another write and expose only a fixed error category. Never persist, log, export, or return a queued payload, its exact IDs, queue contents, or transport cause, and never add a configuration knob that can weaken the boundary.

Gateway dispatches must be reduced immediately to fixed event kinds, Discord identifiers, and receive times. Stage create, update, and delete dispatches may retain only exact guild, channel, and Stage-instance IDs; never retain their topics, speaker or audience state, scheduled-event objects, or unknown payload fields. A guild-updated event may hint that widget settings changed, but it must never carry settings fields, populate a widget cache, or replace a fresh authenticated REST read. Never retain raw payloads, message content, profile data, emoji, or URLs. Session IDs, Discord sequence numbers, and resume URLs may exist only as transient connection state needed for Resume; they must be cleared on stop or terminal failure and must never enter the event buffer, status, resources, logs, or persistent state. The bounded event buffer remains process-local and content-free, and resource notifications contain only an exact local resource URI.

A guild-updated event may also hint that named guild settings changed, but it must never populate a settings cache or substitute for the continuity-bracketed HTTP evidence used by audit and planning.

Complete direct-channel layout evidence may be retained only for the union of exact event-feed, channel-ordering, channel-cloning, Guild Template, guild-settings, onboarding, and member-role guild scopes. Any one of those evidence consumers may activate this projection without activating the public event feed. Never infer complete guild layout authority from channel-only read scope or from the visibility-bounded HTTP guild-channel endpoint. Retain only channel ID, documented direct-channel type, nonnegative raw position, nullable parent ID, and the explicit CHANNEL_OBFUSCATED flag. Never retain or trust an obfuscated channel's synthetic permission overwrite, name, topic, or any other metadata. Public status may expose aggregate layout counts and states, but not the retained guild or channel IDs.

Treat the independently enabled bulk member-role guild scope as another member-role layout-evidence consumer, without letting it widen the single-member scope or activate the public event feed.

Require one valid complete Guild Create channel array before marking a guild layout ready. Reject a partial array, duplicate or malformed ID, unknown or thread channel type, invalid position or flags value, category with a parent, missing category parent, or cross-guild channel. Apply direct Channel Create, Update, and Delete dispatches only to a ready or privately retained resuming snapshot and validate the complete topology after each change. A socket interruption must make the projection unreadable while replay proceeds; only successful Resume continuity may restore readiness. Clear affected evidence on guild unavailability or deletion, malformed relevant dispatches, and every connection gap or new Identify; never let transport READY alone imply layout readiness. Do not send Discord's temporary channel-obfuscation preview capability by default.

Gateway cursors are opaque and process-bound. Report malformed, foreign, expired, ahead-of-buffer, and connection-gap cursors as explicit continuity resets. Never expose a Discord sequence number as a cursor or imply uninterrupted delivery after overflow or a reconnect that cannot preserve Resume continuity.

Canonical source: SECURITY.md

Documentation generated for guildcontrol@0.0.0. Canonical source and edit history remain in the public repository. GuildControl is an independent project and is not affiliated with or endorsed by Discord Inc. Discord is used only to identify the platform that GuildControl connects to.