Observability
Keep OTLP export disabled unless an operator has selected a trusted collector. Enabling export must remain a separate exact feature gate. Remote collectors require HTTPS; plaintext HTTP is permitted only for loopback. Collector URLs must remain credential-free and must not contain query strings or fragments. Treat OTLP header variables as secrets and percent-encode values according to the OpenTelemetry format. Reject unsupported certificate-file variables before constructing an exporter so upstream fallback configuration cannot read ambient files.
Telemetry must use only fixed operation, risk, outcome, and error categories plus numeric status, retry, duration, aggregate, trace, and span data. Continue an upstream MCP trace only from a strict W3C version 00 _meta.traceparent; retain _meta.tracestate only when its complete bounded normalized form validates without rewriting or loss. Ignore malformed carriers and all _meta.baggage without rejection, logging, persistence, metrics, or export. The REST boundary may reduce Discord's rate-limit scope header to a fixed shared-or-not boolean before observability, but no raw header value may cross that boundary. Never add tool arguments or results, Discord identifiers, raw routes or URLs, bodies, headers, bot tokens, error messages or stacks, plan digests, Gateway records, activity data, Discord content, or raw trace carriers to spans, metrics, stderr records, or local aggregates. Do not add automatic HTTP, logging, or exception instrumentation. Keep trace and metric providers private so process-global OpenTelemetry state cannot redirect connector telemetry or add unrelated data. Unknown operation names must collapse to a fixed value.
Track connector-observed 401, 403, and non-shared 429 responses in bounded monotonic rolling buckets, including intermediate responses that are retried. Exclude a 429 only when the transport proves X-RateLimit-Scope: shared. Treat the result as a lower bound on Discord's IP-wide invalid-request pressure because other processes and applications can share the egress IP. Report the documented reference limit and window but never infer remaining capacity, persist events, block a request, or change retry and uncertainty behavior from telemetry.
Exporter failure must never alter a Discord request or MCP tool result. Keep final flush bounded and keep exporter startup and shutdown under the stdio runner so construction, doctor, and setup cannot open collector connections. smoke launches the normal stdio runner, so configured exporters may start and must receive the same bounded shutdown. Status surfaces may report only aggregate operation health, bounded invalid-request pressure and its fixed coverage semantics, fixed privacy claims, exporter state and counters, and booleans indicating whether endpoint or header configuration exists.
Treat spawned smoke verification as a secret boundary. Give the child only the MCP SDK's safe process baseline, the exact non-secret policy selector, and environment values referenced by the selected policy. Never forward unrelated ambient variables. Retain only a bounded stderr tail, remove controls, and redact the bot token plus every referenced secret value before returning diagnostics. Smoke must use the current CLI entrypoint, normal serve startup, stable protocol negotiation, and read-only discovery and status calls so it proves the same startup path an MCP host uses without adding Discord write authority.
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.