The setup subcommand → Step 2 → Discord bullet in SKILL.md (line 92) states:
Important: At least one of Allowed User IDs or Allowed Channel IDs must be set, otherwise the bot will reject all messages (default-deny).
The Telegram branch (line 91) enforces an analogous postcondition by prompt-ordering: Chat ID is collected without an (optional) tag and has its own confirm step, so the at-least-one-of-(Chat ID, Allowed User IDs) constraint reduces to "Chat ID is required" and is structurally guaranteed.
The Discord branch lists Allowed User IDs → Allowed Channel IDs (optional) → Allowed Guild IDs (optional). Allowed User IDs has no (optional) tag but also no validation: the wizard does not re-prompt on empty input, and Step 4 (Write config and validate) validates only the bot token. A user who:
- Pastes the bot token,
- Presses Enter on
Allowed User IDs (empty),
- Presses Enter on
Allowed Channel IDs (optional),
- Presses Enter on
Allowed Guild IDs (optional),
walks the wizard to a successful Step 4 token validation, the wizard reports "Setup complete!", and the bot ends up in the exact default-deny state the Important: clause warned against.
The same gap exists in the QQ and WeChat branches — their at-least-one postconditions are stated similarly in prose but not enforced by either the prompt sequence or the Step 4 validator.
Suggested fix
Add a post-collection validator step inside the Discord branch (and analogously in QQ / WeChat), and re-run it inside Step 4 (Write config and validate):
if allowed_user_ids == '' AND allowed_channel_ids == '':
print "ERROR: Discord requires at least one of Allowed User IDs or Allowed Channel IDs."
re-ask both fields
refuse to write config.env until at least one is set
The Telegram branch's structural enforcement is a good model — making Chat ID non-optional makes the postcondition trivially true. Discord doesn't have a single equivalent required ID, so an explicit validator is the cleanest fix.
The
setupsubcommand → Step 2 → Discord bullet inSKILL.md(line 92) states:The Telegram branch (line 91) enforces an analogous postcondition by prompt-ordering:
Chat IDis collected without an(optional)tag and has its ownconfirmstep, so the at-least-one-of-(Chat ID, Allowed User IDs) constraint reduces to "Chat ID is required" and is structurally guaranteed.The Discord branch lists
Allowed User IDs → Allowed Channel IDs (optional) → Allowed Guild IDs (optional).Allowed User IDshas no(optional)tag but also no validation: the wizard does not re-prompt on empty input, and Step 4 (Write config and validate) validates only the bot token. A user who:Allowed User IDs(empty),Allowed Channel IDs (optional),Allowed Guild IDs (optional),walks the wizard to a successful Step 4 token validation, the wizard reports "Setup complete!", and the bot ends up in the exact default-deny state the
Important:clause warned against.The same gap exists in the QQ and WeChat branches — their at-least-one postconditions are stated similarly in prose but not enforced by either the prompt sequence or the Step 4 validator.
Suggested fix
Add a post-collection validator step inside the Discord branch (and analogously in QQ / WeChat), and re-run it inside Step 4 (
Write config and validate):The Telegram branch's structural enforcement is a good model — making
Chat IDnon-optional makes the postcondition trivially true. Discord doesn't have a single equivalent required ID, so an explicit validator is the cleanest fix.