Decisions captured from product direction
- Dedicated channel for organizer triage (new, separate from general organizers chat)
- Role-gated access based on a configurable set of Discord role IDs
- Finalize button lives in the cardβs thread (fallback: on the card if thread canβt be created)
- Default recommendation threshold = 3 votes, configurable
FOR IMMEDIATE RELEASE
A Discord-native triage inbox with role-gated voting, threaded discussion, and one-click final decisions.
New York, NY β Rust NYC today announced TalkTriage, a Discord-native review pipeline that replaces ad-hoc spreadsheets and scattered DMs with a dedicated organizer inbox channel inside Discord. When a speaker submits a talk, TalkTriage posts a structured βreview cardβ into a private triage channel where organizers can vote with one click, open a focused discussion thread, and finalize a decisionβwithout leaving the place they already coordinate.
Volunteer organizing teams are often limited not by the quality of their communities, but by the overhead of triaging submissions. TalkTriage reduces that overhead by turning every submission into a single source of truth: the abstract, links to the speaker discussion channel, the live vote tally, and decision history.
TalkTriage is role-gated so only authorized reviewers can vote or finalize decisions. Once a decision is finalized, the bot automatically posts a clear status update into the speakerβs submission channelβreducing uncertainty and ensuring speakers get timely feedback.
βWe wanted a workflow that felt native to Discord. TalkTriage doesnβt add another toolβit turns Discord into the tool.β β Rust NYC organizers
Availability: TalkTriage will roll out first to Rust NYCβs organizer team. The initial release focuses on the triage inbox, voting + tallying, and thread-based decision finalization. Scheduling handoff and analytics will follow as separate phases.
Job to be done: βKeep the queue moving, align as a team, and make decisions quicklyβwith minimal overhead.β
Pain today:
- Review state lives in a spreadsheet or someoneβs memory
- Votes are unstructured (hard to tally, hard to audit)
- Discussion fragments across channels and DMs
- Submissions stall because urgency isnβt visible
Job to be done: βKnow my talk was seen, understand what happens next, and get a timely answer.β
TalkTriage is a dedicated, role-gated Discord triage inbox where submissions become review cards with one-click voting, a linked discussion thread, and a finalize button that turns consensus into action.
- New channel:
#talk-triage(dedicated inbox) - Review card message in
#talk-triagewith interactive controls - Thread per card for deliberation (created on-demand)
- Action panel message inside the thread (contains Finalize buttons)
- Slash commands (MVP):
/triageβ show queue (grouped by status + aging)/talk <id>β view details + jump links (optional MVP; can be phase 1.5)
- Existing: speaker submission channel (already created today)
- New: status update messages posted into the speaker channel when finalized (and optionally when moved into βUnder reviewβ)
- New route:
POST /api/discord/interactions(Discord Interactions webhook) - New internal API endpoints (optional; for debugging/backfills)
- New tables for votes/status/history + mapping submission β review card message β thread
- New env vars for triage channel + reviewer roles + thresholds
Existing flow remains:
- DB insert
- speaker channel created
- welcome message posted
New addition: also create a TalkTriage review card in #talk-triage.
A single message containing:
- Submission ID
- Speaker + on-behalf info
- Abstract excerpt
- Link to speaker discussion channel
- Status badge
- Live vote tally
Controls on the card:
- Vote buttons: β Accept, π€ Maybe, β Pass
- βDiscussβ button: π¬ creates/opens thread
- Each vote is per-reviewer (updatable)
- Card edits to show live tally
- When tally meets the configurable threshold (default: β₯3 Accept votes), card shows βRecommendation: Accept (threshold met)β
- Clicking Discuss creates a thread (if possible) and posts an Action Panel message
- The action panel contains Finalize buttons (see below)
The action panel includes:
- Finalize: Accept
- Finalize: Waitlist
- Finalize: Decline
Finalizing:
- Updates DB status
- Edits review card status badge + pins final state in thread
- Posts a status update into the speaker channel
Fallback: if thread creation fails, the finalize buttons are posted directly on the review card message.
/triage returns an organizer-only view:
- Grouped by status (Pending / Under Review / Accepted / Waitlist / Declined)
- Sorted by aging and/or score
- Each row: ID, speaker, age, tally summary, links
Message content (example):
π€ Talk Submission #42 \ Status: Pending
Speaker: Jane Doe
Submission: Submitted by speaker (or βon behalf of β¦β)
Abstract (excerpt):
Rust lifetimes are hardβthis talk explainsβ¦ (first 400β800 chars)
Speaker channel: <#123456789012345678>
Votes: β
2 Β· π€ 1 Β· β 0
Recommendation: (not yet)
Components (buttons):
- Row 1: β Accept | π€ Maybe | β Pass
- Row 2: π¬ Discuss
Notes:
- We intentionally keep βFinalizeβ out of the main card in the happy path to reduce accidental clicks; finalization lives in the thread action panel.
Header: βDecision panel for Talk #42β
Shows:
- Current tally + recommendation
- Current status
- A reminder: βFinalizing will notify the speaker channel.β
Buttons:
- Finalize: β Accept
- Finalize: π¨ Waitlist
- Finalize: β Decline
Optional (later): βRequest more infoβ button that posts a template in speaker channel.
Only users with at least one of the configured roles may:
- vote
- open a discussion thread (optional gating)
- finalize decisions
- view
/triageoutput
DISCORD_REVIEWER_ROLE_IDSβ comma-separated list of role IDsDISCORD_TRIAGE_CHANNEL_IDβ where review cards are posted
Discord interaction payloads include member.roles for guild interactions. We check:
- is request valid (signature verification)
- is in expected guild
- is user role-authorized
If unauthorized:
- respond ephemerally: βYou donβt have permission to use TalkTriage actions.β
- βRecommendation: Acceptβ when Accept votes β₯ 3
TALKTRIAGE_MIN_ACCEPT_VOTES(default3)- Optional additional constraints (future):
- require N total votes
- block recommendation if any β votes exist
Important: thresholds should influence recommendation and/or enabling finalize buttons, but finalization is always explicit and role-gated.
Maps a submission to its review card message/thread.
submission_id(PK)triage_channel_idreview_message_idreview_thread_id(nullable)created_at
One vote per reviewer per submission.
submission_idreviewer_discord_idvoteenum:accept | maybe | passupdated_at- UNIQUE(
submission_id,reviewer_discord_id)
Current status.
submission_id(PK)statusenum:pending | reviewing | accepted | waitlist | declinedupdated_atupdated_by_discord_id
Append-only audit trail.
idsubmission_idfrom_status,to_statuschanged_by_discord_idnote(nullable)created_at
pending(default)reviewingacceptedwaitlistdeclined
pending β reviewing(optional automatic when first vote arrives)pending/reviewing β accepted | waitlist | declined(finalize)accepted/waitlist/declined β reviewing(admin override only; logs history)
When finalizing, post into the speaker channel:
-
Accepted: βπ Your talk has been accepted! Next weβll coordinate scheduling in this channel.β
-
Waitlist: βπ¨ Your talk is on the waitlist. We loved itβtiming and slots are the only constraint. Weβll update you as soon as we can.β
-
Declined: βThank you for submitting. This one isnβt the right fit for our upcoming slots, but weβd love to see you submit again. If youβd like feedback, reply here.β
(Exact tone TBD by Rust NYC.)
It separates high-signal review activity from general organizer chat, and gives an always-up-to-date βinboxβ view. It also makes permissioning and automation simpler.
Role-gating protects against accidental permissions drift, makes it safe to share the triage channel with non-review organizers (e.g., logistics), and enables consistent enforcement on all interactive actions.
Final decisions are the highest-risk action. Putting finalize controls in the thread reduces accidental clicks, encourages discussion, and gives a clear audit trail next to the rationale.
If Discord thread creation fails (permissions or configuration), TalkTriage falls back to placing finalize buttons directly on the review card.
Noβthresholds are configurable. The system uses thresholds to inform recommendations and (optionally) to enable finalize buttons, but humans can still finalize explicitly.
This design intentionally uses Discord Interactions (HTTP callbacks) rather than emoji reaction events that typically require a persistent Gateway connection.
Net-new capabilities needed in code:
- Add a Discord interactions endpoint and signature verification (
DISCORD_PUBLIC_KEY) - Extend
DiscordService.sendMessage()to support embeds + components (buttons), not just plain text - Add DB tables listed above
- Add handlers for:
- button clicks (vote, discuss, finalize)
/triagecommand
- Do we want βRequest more infoβ as a standardized workflow (templates, SLA timers)?
- Do we want consensus rules beyond simple thresholds (e.g., require no β votes)?
- Should finalization require a confirmation modal?
- Should we show βreview participationβ nudges (e.g., ping reviewers if no votes after 48h)?