Inspiration
Teams commit to ideas fast — and most tools built to help you decide are designed to agree with you. I wanted the opposite: a Slack agent whose entire job is to be the dissenting voice in the room, armed with real evidence instead of just an opinion. Not a "helpful assistant" — a red team.
What it does
GoNoGo is a Slack agent that argues against your team's ideas before you ship them, using real evidence — both from the open web and from your own team's Slack history.
Three commands, one workflow:
/gonogo <idea>— searches the open web for prior attempts at this idea (competitor products, funding history, market signals) and searches your workspace's Slack history at the same time. Both sets of evidence are merged into a one-page risk memo with a clear verdict, posted directly in the channel./gonogo redteam— simulates how four different critical parties would react: a Competitor, a Customer, an Investor, and a Security reviewer, each grounded in the same evidence already gathered — no repeat search, no extra cost./gonogo approve(orreject) — once the team has debated, reads the entire thread and freezes it into a one-page decision record — summary, key risks discussed, who decided, when — posted as a downloadable file for the whole team.
How I built it
The stack is a TypeScript monorepo: a core package with no Slack dependency (pure business logic — search, memo generation, red-teaming, decision summarization), a slack package (Bolt, Socket Mode) that wires that logic into actual Slack commands, and a cli package for testing the core logic in isolation.
Two evidence sources feed Stage 1 in parallel: Claude (Anthropic API), using a capped web-search tool, searches the open web; Slack's own Real-Time Search API (assistant.search.context) searches the workspace's own message history for anything the team already discussed. Neither source writes anything — they only retrieve facts. A single Claude call then turns the combined evidence into the actual risk memo, and that same pattern repeats for the red-team and decision-record stages.
Challenges I ran into
Credit usage. My first version asked Claude to search and write a full memo in one enormous call, with no cap on how many searches it could run — token usage spiraled fast. I split it into small, focused steps (search → write) and capped the search tool's max_uses, which cut cost dramatically without losing quality.
Silent JSON failures. Several stages ask Claude to return structured JSON, and models occasionally wrap that in markdown fences or add a stray sentence despite instructions not to — which silently broke parsing and fell back to garbled output. I built a shared, forgiving JSON extractor used across every stage, plus real truncation detection (checking the API's actual stop_reason rather than guessing from a broken parse).
Getting the real Real-Time Search API working. This was the hardest part. My first attempt called Slack's RTS API with a bot token — which technically has the right scope, but every bot-token call requires an action_token tied to Slack's dedicated AI Assistant-thread surface, which a slash-command-based app doesn't have. After confirming that was a genuine dead end, I discovered a user token with the same search:read.public scope works cleanly with no such restriction — no OAuth rebuild, no architecture change, just a different token type. That one discovery is what let me keep the existing command-based design while still genuinely using Slack's named Real-Time Search API.
What I learned
Slack's "Real-Time Search API" is a specific, named Slack platform product — not a generic technical category. It's worth confirming that distinction early rather than assuming a generic implementation (like calling any web-search API) satisfies a requirement that's actually asking for a specific, named integration.
Accomplishments that I'm proud of
Getting the Real-Time Search API working without rebuilding GoNoGo as a different kind of app. My first assumption was that using it would mean pivoting to Slack's dedicated AI Assistant surface — a real architecture change this close to a deadline. Finding that a user token sidesteps that entirely meant I kept the exact product I set out to build, while still genuinely satisfying the requirement rather than working around it.
I'm also proud of how much the credit-usage fixes improved output quality, not just cost — tighter, more focused prompts at each stage produced sharper risk memos and red-team critiques than my original single-giant-call version did.
What's next for GoNoGo
Persisting state beyond a single in-memory map (so multiple ideas can be tracked per channel concurrently), and letting /gonogo redteam optionally pull a fresh Slack search of its own rather than only reusing Stage 1's evidence.
Built With
- anthropic
- bun
- claude
- node.js
- real-time-search-api
- slack
- slack-api
- slack-bolt
- socket-mode
- typescript
Log in or sign up for Devpost to join the conversation.