Skip to content

Reviewed guild application-command lifecycle

plan_guild_application_command_change, execute_guild_application_command_change, and review_guild_application_command_change belong only to the application-commands toolset. Enable capabilities.applicationCommandChanges, add each exact target to scopes.applicationCommandGuildIds, and keep that allowlist inside scopes.guildIds. The workflow uses the same operator-owned bot application whose public application and bot IDs are pinned in the policy and verified from the external bot credential. It manages only guild commands owned by that application; global commands, another application's commands, and the fixed native Interaction command workflow remain separate.

Every create request carries one complete canonical chat-input, user, or message command definition. Every update additionally targets one exact command ID and supplies the complete replacement definition with the existing type unchanged. Every deletion targets one exact command ID and requires acknowledgeDeletion: true. Definitions use named default member permissions or explicit null, explicit NSFW state, complete locale-keyed name and description localization arrays, and a strict typed option tree. The normalizer enforces Discord's naming, nesting, ordering, choice, autocomplete, numeric, string-length, channel-type, attachment-file-type, localization, and aggregate text constraints. It rejects unknown fields and incompatible option combinations instead of forwarding raw JSON.

Planning re-verifies the pinned identities and exact non-pending bot membership, fetches the complete guild command inventory with full localizations, projects every command into the same canonical definition, and fetches every guild command-permission entry for the application. The keyed plan binds both complete evidence digests, each command ID, version, type, transient name and definition digest, separate chat-input, user, and message capacities, the total capacity, the exact target's permission overwrites, collision and no-op decisions, the operation-key hash, privacy claims, risks, warnings, and the exact verification contract. A malformed, duplicated, unknown, incomplete, over-capacity, colliding, absent, type-mismatched, or changed observation blocks the write. An already-current update or already-absent deletion returns without confirmation, reservation, activity, or Discord mutation.

Discord's create route can return 200 after overwriting an existing same-name and same-type command. The connector accepts only 201 for create, so that upsert behavior can never silently turn creation into replacement. Update uses one non-retried exact-ID PATCH and treats the supplied definition as complete because Discord replaces aggregate fields rather than merging them. Delete uses one non-retried exact-ID DELETE. Rename and deletion permanently clear the target command's guild permission configuration under Discord's contract, so the plan displays the exact affected overwrites and treats that consequence as destructive. Command-permission mutation is excluded because Discord requires a user-authorized Bearer token for that route, outside this bot-token trust boundary.

Execution requires a fresh matching keyed plan, MCP host write approval, signed request state, explicit interactive confirmation, and another exact fresh-plan match. The production facade durably claims the guild's application-command collection before atomically reserving the one-shot operation key and appending pending content-free activity. It sends exactly one mutation with no automatic retry, validates the route-specific response, then rereads every localized command and every permission survivor. Create requires one new exact command and permits only an absent or empty new permission entry. An unchanged-name update requires the target permission entry to remain exact. A rename requires Discord's permission reset while preserving every unrelated entry. Delete requires exact target absence and exact unrelated command and permission survivors.

A deterministic Discord client refusal other than timeout or rate limiting may be recorded as failed. Rate limiting, transport ambiguity, Discord server failure, malformed success, response mismatch, unreadable or drifting full readback, or failed completion recording is uncertain and may have changed Discord. Every reserved key remains spent, the affected collection remains quarantined, and the connector never retries, rolls back, compensates, or guesses from a command name. Activity and operation records contain only exact application, bot, guild, and command IDs; command type; definition, inventory, permission, plan, and operation-key digests; timestamps; fixed status and verification values; and sanitized error categories. They never contain command, option, choice, or localization text, permission target IDs, Discord names, raw requests or responses, raw keys, or transport causes. Discord's application-command contract defines the route and replacement behavior.

Canonical source: docs/reference.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.