Discord Strategy¶
Policy¶
Discord is controlled infrastructure, not product surface.
Discord provides authentication, notification delivery, and audio transport. It is not a community, social network, or peer-to-peer communication channel. Members interact with the platform through the bot and the relay app. Member-to-member interaction is an unintended side effect of the transport layer, not a feature.
Roles¶
Discord serves five roles for the platform:
| Role | Description |
|---|---|
| Authentication gateway | Discord identity = platform identity. Invite-based onboarding with auto-role assignment. |
| Broadcast channel | Bot posts game events, news, announcements. Members read. |
| Command interface | Slash commands for data queries. Responses are ephemeral or role-gated. |
| Audio transport | Stages for live calls during games. One-to-many broadcast. |
| Notification rail | Push notifications for game events via Discord's mobile app. |
Discord is not a community, peer network, support channel, chat room, or the product itself. The relay app is the product.
Channel Visibility by Role¶
Two live calls channels exist with different content and access levels.
| Channel | Minimum Role | Content |
|---|---|---|
| Primary Live Calls | Full Member+ | Real-time, undelayed game feed |
| Fantasy Live Calls | Fantasy Member + Admin | 5-second delayed game feed |
| Stage (Live Audio) | Full Member+ | Live audio broadcast |
| Announcements | @everyone | Read-only pre/post-game briefings |
| Forum / News | @everyone | Read-only RSS news threads |
| Bot Commands | @everyone | Slash command execution |
| Rules | @everyone | Read-only server rules |
| Team Preferences | @everyone | Read-only cross-team links |
| Moderator | Admin+ | Private admin channel |
Enforcement¶
| Restriction | Method | Script |
|---|---|---|
| Fantasy cannot see Primary Live Calls | view_channel=False overwrite |
fix_channel_permissions.py |
| Full Member/Scout cannot see Fantasy Live Calls | view_channel=False overwrite |
fix_channel_permissions.py |
| @everyone + Fantasy cannot connect to Stage | connect=False overwrite |
harden_permissions.py |
| @everyone cannot send in read-only channels | send_messages=False overwrite |
lock_channels.py |
| @everyone cannot reply in forum threads | send_messages_in_threads=False overwrite |
lock_channels.py |
Stage Access Policy¶
Stage listening is part of the premium (Full Member+) tier.
@everyone: deniedconnectandspeakfantasy_member: deniedconnectandspeakfull_member,scout,tester: grantedconnect, deniedspeakadmin: grantedconnectandspeak- Stage text chat: disabled
- Raise-hand: disabled where possible
Design Rules¶
These rules apply to all code changes across all leagues (NHL, MLB, MLS, FIFA):
- Never build features that facilitate member-to-member interaction
- Never expose member names, counts, or IDs in non-admin contexts
- Never create cosmetic or vanity roles
- All member-to-admin communication routes through bot commands (
/feedback) - Discussion channels are OFF by default (toggle:
discussion_channels) - Channel permissions default to deny; grant explicitly per-channel
- No
on_messagehandlers that respond to member content - Bot reacts only to slash commands and system events
Migration Trajectory¶
Over time, responsibilities shift from Discord to the relay app:
| Responsibility | Current | Target | Timeline |
|---|---|---|---|
| Game event feed | Discord + relay | Relay only | When app adoption is sufficient |
| Slash commands | Discord | Relay commands tab | Partially migrated |
| Live audio | Discord Stages | No change | Indefinite |
| Notifications | Discord push | App push | When push infra is ready |
| Auth | Discord invite | App-native auth | Long-term |
Discord Stages remain the audio layer indefinitely.