Skip to content

Reviewed exact role configuration

Role configuration has no immediate-call path and is independent of role reads, creation, assignment, scaffolds, and channel overwrites. Set capabilities.roleConfiguration: true and list every eligible standard role by its exact ID in scopes.roleConfigurationIds. The configured list is an explicit role boundary inside the existing exact guild read scope. @everyone and managed roles are always rejected even if their IDs are configured. Grant Manage Roles only in the selected guilds, keep the connector's highest role strictly above every selected role, and do not grant Administrator.

The partial surface accepts at least one explicit name, primary color, nullable secondary or tertiary color, hoist setting, mentionability setting, exact known permissions set, named permission-grant list, named permission-revocation list, or tagged roleIcon intent, plus an audit reason and unique one-shot operation key. Exact permissions and grant or revoke deltas are mutually exclusive. An exact set may be empty, replaces only Discord permissions known to this release, preserves every unknown future bit observed on the role, and cannot include ADMINISTRATOR. Grant and revoke lists must be disjoint; they preserve all permissions outside the named deltas, and ADMINISTRATOR can be revoked but never granted. Omitted properties remain unchanged. Role deletion, reordering, assignment, creation, name-based targeting, and raw permission bitfields are unavailable.

roleIcon accepts exactly { "kind": "clear" }, { "kind": "unicode", "value": "..." }, or { "kind": "local-image", "filePath": "/absolute/path" }. Unicode input must be one valid NFC emoji grapheme. A new Unicode or image icon requires fresh ROLE_ICONS guild-feature evidence. Local images reuse storage.guildExpressionRoots, so no additional environment variable or policy key is needed. The file must be one exact canonical absolute path beneath a configured root, owned by the connector user, regular, single-linked, stable while read, nonanimated PNG or JPEG, exactly 64 by 64 pixels, and no larger than 256 KiB. URLs, transported base64, custom emoji IDs, symlinks, hardlinked files, and other formats are rejected. Metadata changes plus clear or Unicode intents remain available when the shared roots are empty; local-image intent does not.

  1. Call plan_role_configuration with the exact guild and role IDs, explicit partial changes, audit reason, and one-shot operation key.
  2. Review the verified application and bot IDs, exact guild and role, untrusted names, affected-member count, requested and changed fields, complete current and desired role projections, tagged current and desired icon state, local-file review and verification mode when present, requested exact known permission set or named deltas, effective permission changes, high-risk grants and revocations, modern colors, logical-name collisions, bot hierarchy and grantability evidence, post-change connector authority, privacy boundary, risks, warnings, operation-key hash, and keyed digest.
  3. If the status is already-current, no confirmation, receipt, activity entry, or write is needed.
  4. Call execute_role_configuration with identical inputs plus the digest.
  5. Approve the signed MCP confirmation only if every exact ID, field, icon intent, reviewed local path and file evidence, permission delta, color, impact count, risk, warning, reason, operation-key hash, verification mode, and digest remains intended.
  6. Review the complete response, exact role readback, full inventory match, role-holder-count match, activity ID, verification, and outcome before any follow-up. For a local image, confirm that response-bound hash verification matched.

Planning fetches the exact guild, connector member, complete role inventory, and role-holder-count map in one evidence pass. It rejects an absent or managed target, @everyone, unknown target fields, invalid modern-color combinations, insufficient MANAGE_ROLES, a target at or above the connector, an ungrantable complete desired permission set when the permission bitfield would change, delta permission changes when unknown permission bits exist, and any change that would remove the connector's own MANAGE_ROLES authority. Exact known permissions remain safe with unknown future bits because the desired bitfield explicitly preserves those bits rather than interpreting or clearing them. Metadata-only plans report whether the unchanged desired permission set is a subset without requiring it. Exact-ID targeting keeps logical-name collisions unambiguous, but the plan and confirmation surface every collision as a warning. The affected-member count is aggregate only; member identities are never fetched.

The process-keyed digest binds the normalized request without the raw operation key, its domain-separated hash, verified identities, exact guild features and owner, connector membership and permissions, complete normalized role inventory, complete role-holder counts, current and desired target state, tagged icon intent, actual permission delta, name collisions, impact count, risks, and warnings. For a local image it additionally binds the canonical path, stable file identity and metadata, structural image review, and an HMAC content digest of the exact bytes. A connector restart invalidates the digest. The MCP adapter rebuilds the plan before approval, and the service rebuilds it immediately before reservation. Both reread any local image and require the exact same digest, so a replaced or changed file blocks the write.

A real change atomically reserves the one-shot key, appends a pending content-free activity entry, and issues one non-retried PATCH containing only changed fields and an encoded Discord audit reason. Clear and Unicode icon intents have exact pre-known desired values. For a local image, Discord assigns the icon hash and does not expose byte-level role-icon readback, so any local-image request is deliberately write-required even when the current role already has an image. The connector requires the successful response to contain one image hash and no Unicode emoji, then binds that exact response role as the target for the exact role GET and full role inventory. It also performs a fresh role-holder-count GET. A matching result is completed; safe observed divergence is completed-with-drift. A known pre-response Discord 4xx is failed. Transport errors, Discord 5xx responses, malformed responses, post-response failures, or failed readback are uncertain and may represent a completed write. The connector never fetches the Discord CDN to guess byte equality, retries, compensates, rolls back, or spends a second mutation under the same key.

Activity and operation records contain only the exact guild and role IDs, requested field names, plan digest, operation-key hash, timestamps, fixed verification and outcome values, activity ID, and sanitized error category. They never contain role names, colors, permissions, member counts or identities, audit reasons, raw operation keys, local paths, file content or file digests, Discord icon hashes, Unicode emoji, or raw Discord responses. Direct service instances retain same-role serialization as defense in depth. The production facade additionally acquires durable exact role and guild roles-collection claims, so connector processes sharing the activity-state root exclude overlapping role configuration and retain the claims after uncertainty. See Discord's modify guild role reference and role member-count reference.

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.