Stage instances
Keep Stage-instance inventory behind its own audit toggle and exact Stage-channel allowlist. Do not derive Stage scope from a guild, parent, category, or thread. Verify the pinned identities, exact guild ownership, exact Stage channel type, connector membership, complete roles and overwrites, and effective VIEW_CHANNEL before returning one active or inactive privacy projection. Within one inventory call, guild, connector-member, and role evidence may be shared per guild, but each channel and Stage instance must be read exactly and no evidence cache may survive the call. Never enumerate speakers or listeners, inspect voice state, return scheduled-event objects, forward unknown raw fields, or cache or persist a Stage read.
Keep every start, topic update, and end behind the independent change toggle, process-keyed planning, signed interactive confirmation, write-aware host approval, final fresh-plan match, atomic one-shot operation-key reservation, pending content-free operation and activity records, one non-retried mutation, and exact active-state or absence readback. Require guild-only privacy, no scheduled-event association, zero unknown fields, and complete VIEW_CHANNEL, CONNECT, MANAGE_CHANNELS, MUTE_MEMBERS, and MOVE_MEMBERS evidence. Deprecated public and scheduled-event-linked instances are read-only. Do not add an immediate-call path, fuzzy channel lookup, bulk mutation, automatic retry, rollback, reconciliation, or scheduled-event association mutation.
Keep Discord's guild-wide Stage start notification behind a third independent toggle. Require fresh MENTION_EVERYONE evidence, bind the choice into the plan and signed state, and consume the shared interaction rate budget before mutation. Never permit notification on update or end. A no-op must reserve nothing, journal nothing, request no confirmation, and issue no write.
Bind the normalized action-specific request, verified identities, exact guild and Stage channel, complete role and overwrite evidence, effective permissions, active or inactive current state, desired state, guild-only privacy, scheduled-event isolation, schema-drift count, notification choice, warnings, and domain-separated operation-key hash into the plan. Exclude the raw operation key from plan material, signed request state, records, results, and errors. Any identity, state, topic, privacy, association, schema, or permission drift must invalidate the reviewed plan. Check the shared interaction rate guard immediately before any notification reservation or durable write state.
Treat a known pre-write Discord client error as failed. Treat transport errors, malformed mutation responses, Discord server errors, and failures after mutation or during exact readback as uncertain and potentially completed. Never retry, compensate, or roll back automatically. Permanently spend every reserved key after any outcome.
Serialize changes per exact Stage channel inside one process as defense in depth. The production facade also acquires a durable exact channel claim, so connector processes sharing the activity-state root exclude overlapping changes and retain the claim after uncertainty. Never persist topics, guild or channel names, speaker or audience identities, scheduled-event objects, role names, permission evidence, audit reasons, raw operation keys, or raw Discord responses. Activity and operation records may contain only exact guild, channel, and optional Stage-instance IDs, action, plan digest, operation-key hash, timestamps, fixed verification and outcome values, activity ID, and sanitized error category.
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.