kiro-discord-bot

Deployment #

Local Foreground Run #

Start with a foreground run before creating a service:

set -a
. ./.env
set +a
./kiro-discord-bot

Confirm the bot logs in, registers slash commands, and responds to /doctor. Review Environment Reference before turning the foreground command into a service.

Gateway Runtime Invariant #

Each Discord bot token/identity may have exactly one gateway runtime online at a time. Dual-engine deployment is one kiro-discord-bot process using Session.Engine to select the Kiro or OMP ACP dialect per channel/thread; it is not two bot processes sharing the same token.

During deploy or rollback, stop the old runtime before starting the replacement. Before reply smoke tests, confirm process/service metadata and, when comparing multiple hosts, compare only token hashes; never print token values. A healthy deployment has one bot identity, one gateway process, and one selected ACP child for the active scope.

macOS launchd #

For macOS, run the bot as a LaunchAgent with an explicit shell command that sources .env and executes the release binary. If private LAN MCP servers fail from launchd but work from an interactive shell, check proxy variables, Local Network permission, and the service identity. See macOS MCP Networking for the full runbook.

Linux systemd #

For Linux hosts, use a service unit with WorkingDirectory, EnvironmentFile, and an executable path pointing at the installed release binary. Build and test first, then stop the service, replace binaries, start it, and verify with /doctor.

The gateway watchdog is enabled by default. Keep the service manager restart policy enabled so unrecoverable Discord Gateway stalls become a clean process restart:

Type=notify
WatchdogSec=180s
Restart=on-failure
RestartSec=10s
StartLimitIntervalSec=300
StartLimitBurst=5

Type=notify / WatchdogSec is optional but recommended on systemd hosts. The bot sends READY=1 after Discord Gateway open succeeds and sends WATCHDOG=1 only while the Gateway is ready and heartbeat ACKs are fresh. Use /doctor after startup to confirm the Gateway watchdog status, heartbeat ACK age, reconnect attempts, and last reconnect error.

Docker #

The Compose setup uses host networking, mounts the selected engine authentication state and project roots, and keeps runtime MCP config isolated from global catalog sources. Catalog servers still must be enabled per channel through /mcp.

A2A NATS Deployment #

Use Enable A2A with NATS for first-time setup from NATS server through .env and Discord policy. Deploy NATS/JetStream before enabling bot A2A variables. The internal lightweight deployment uses one private JetStream node with TLS, token authentication, persistent storage, localhost-only monitoring, and host/network firewalling; hardened deployments may instead use NKey/JWT credentials through NATS_CREDS_FILE, optional TLS CA validation, one credential per stable bot/base identity with ACLs that authorize the derived runtime ID subjects, and A2A_PRODUCTION_SECURITY=true. Inject A2A variables through the service manager or container environment, restart or drain the bot, then verify /doctor plus the A2A rollout smokes. Keep NATS_URL empty until the setup and rollout gates are ready. For the identity, subject, task, policy, and delivery model, see A2A Protocol Model.

WebShare Relay Deployment #

WebShare adds a second process when enabled: the pure Go webshare-relay binary. The relay may sit behind nginx, Caddy, or Traefik and serves both the TypeScript web UI and WebSocket room endpoint. The bot connects outbound as the authenticated host, so do not open an inbound bot port for WebShare.

Production deployments should:

For nginx, systemd, Docker Compose, bot env, and relay env examples, see WebShare.

Release Updates #

Before tagging or deploying a release, run:

scripts/release-preflight.sh

When touching ACP, MCP policy, bot tools, cron, or deployment behavior, run the relevant smoke checks described in the Release Runbook.