Inspiration

I kept thinking about what happens when a volunteer coordinator leaves a food bank. Two years of "how we do things" - intake procedures, vendor contacts, why Saturday pickups stopped - is sitting in old Slack threads. The new person can't find any of it, because they don't know the org's vocabulary yet. So knowledge that technically exists is functionally gone. Nonprofits lose roughly a third of their volunteers every year, and for most of them, Slack IS the institutional memory. Nobody backs it up into a wiki. I wanted the chat history itself to become the onboarding material.

What it does

Torch is a Slack agent you just talk to, in its agent pane or with @Torch in a channel.

  • Ask it anything about how the org works. It searches the workspace's own history through Slack's Real-Time Search API, reads the threads it finds, and answers with sources - every claim links to the actual discussion it came from.
  • It refuses honestly. If the history has no answer, it says "I couldn't find this in the workspace history yet" and logs the question to a Knowledge Gaps list. The org gets a live backlog of what it never wrote down. Failure becomes useful.
  • It generates onboarding guides. Say "onboard me as a food drive coordinator" and it builds a Canvas from real conversations: key channels, the people who actually answer things, how processes work, an FAQ - all source-linked.

How we built it

Node.js with Bolt for JavaScript over Socket Mode. Every question becomes at most two Real-Time Search calls (three for onboarding): one keyword, one semantic. The retrieved threads are the only context the LLM ever sees. It cites transcripts by index, and my code maps those indexes back to Slack permalinks - so a hallucinated source is literally unrepresentable. No sources means no answer.

Everything renders in native Slack surfaces: messages, a Canvas for role guides, a List for knowledge gaps. Every failure path degrades quietly (no Lists on the plan? Gaps go to a Canvas. Canvas fails? A formatted message. Search down? Honest refusal). No stack trace ever reaches the user.

Challenges we ran into

The biggest one nearly killed the demo: messages posted by a bot are never indexed by Slack search. I had seeded the demo workspace's "history" through the bot with custom usernames, and search returned nothing, for hours, with no error. Figuring that out took a whole evening. The fix was reseeding everything as a real user.

Other fun ones: the Real-Time Search action_token has to come from a real user interaction event; the semantic index lags hours behind the keyword index, so retrieval is keyword-first; and bot-created Lists and Canvases are invisible until you explicitly share them - which I only discovered when my own Knowledge Gaps list didn't show up in my sidebar.

Accomplishments that we're proud of

The grounding design. It would have been easy to prompt the model to "please cite sources" and hope. Instead the code enforces it: search results in, index-mapped permalinks out, refusal when evidence is thin. In testing, the wifi-password question never once produced a made-up answer. And the Knowledge Gaps list turned out better than planned - it reframes every miss as the org's documentation to-do.

What we learned

Slack's newer surfaces (agent pane, Lists, Canvas, Real-Time Search) compose into something that feels like a real product with surprisingly little code - but the sharp edges are all undocumented behaviors, not APIs. Verify everything against a live workspace before believing your own architecture diagram.

What's next for Torch

Scheduled digests of new knowledge gaps to org leads, letting leads mark a gap as "documented" with a link, and guides that refresh themselves when their source threads get new replies. And testing with a real volunteer org instead of my seeded food bank.

Built With

Share this project:

Updates