2. Copies the message text (stripped of any prior "react to advance" hint) into the next channel. When advancing out of **Submitted**, the copy also gets a permalink back to the user's original message.
3. Depending on where we're advancing *from*:
- **From Submitted:** keeps the user's original message in place and posts a threaded `➡️ Advanced to {Stage}` reply. The Submitted channel is the permanent audit trail.
- **From Processed or Authorized:** deletes the old copy so each intermediate channel stays a clean "current work" queue.
Channel chain: Submitted → Processed → Authorized → Matched. The bot can only delete its own posts, which is why the Submitted original (a real user message) is preserved by design.
- **Receiver Lambda** (`src/receiver/`) — fronted by API Gateway HTTP API. Verifies the Slack request signature, handles the URL-verification handshake, and async-invokes the processor. Returns 200 within Slack's 3-second window to prevent retries.
- **Processor Lambda** (`src/processor/`) — does the 5-step sequence of Slack API calls. No inbound HTTP; invoked only by the receiver.
- **Secrets** — Slack bot token and signing secret each stored as separate AWS Secrets Manager secrets. Each Lambda only has IAM access to the secret it needs.
4. After the first deploy, take the `SlackEventsUrl` output and paste it into the Slack app's **Event Subscriptions → Request URL**. Subscribe the bot to the `reaction_added` event.