Project name
Cortex, the company brain for Slack
~ Cortex turns scattered Slack messages into permission-native institutional memory, and refuses to answer when it has no real evidence.
Elevator pitch
Institutional knowledge dies in Slack scroll. Cortex is a Slack agent that reconstructs decisions, SOPs, risks, and commitments from live workspace context, cites the exact messages, and writes durable memory to a Slack Canvas only after a human approves it. Unlike a generic chatbot, when there is no real evidence it says so instead of inventing an answer, which is what makes the memory it builds trustworthy.
What it does
Cortex lives in Slack and can be @mentioned, DMed, or triggered with an emoji reaction. For an institutional question it runs a deterministic pipeline: search live workspace context with Slack Real-Time Search, filter that evidence for signal, compute a confidence tier from the evidence alone, and only then answer with citations. If the answer is worth keeping, one click writes a real Slack Canvas and adds the decision, SOP, fact, risk, or commitment to a durable company brain. The next time someone asks a related question, Cortex cites that approved memory first. The brain compounds, and it never leaves Slack.
Workflows, all gated the same way (no evidence, no answer):
- Decision archaeology: "Why did we kill project Gizmo?" returns a structured Decision Record with owners, dissent, and confidence, built only from retrieved messages.
- SOP from reality: drafts the process the team actually follows, not the wiki version.
- Risk register, commitment tracker, action item extractor, change digest.
- People status without pinging: answers "what is this person working on" from public signals, never a DM.
- Multiplayer board: builds a shared status Canvas in the channel.
- Reaction capture: react with a brain or bookmark emoji to propose any message as memory.
- Every answer is labeled with its source mode (RTS live, channel-history fallback, or approved brain) and a confidence tier computed only from retrieved evidence.
How we built it
- Slack platform: Bolt for Python, Real-Time Search (
assistant.search.context), Canvas API (conversations.canvases.create), App Home, Block Kit interactivity, the Assistant and agent surfaces, and emoji reactions. - A deterministic pipeline (
agent/pipeline.py) is the primary, reliable path: classify the question, retrieve evidence, filter noise, compute a confidence tier and source mode strictly from the retrieved messages, then synthesize a structured answer. An LLM fallback lane (agent/agent.py, OpenAI Agents SDK) handles freeform questions the router does not classify, and degrades to a capabilities card instead of erroring. - Human-in-the-loop writes: every durable write is a Block Kit approval button. The handler creates the Canvas and updates the brain, and any cosmetic follow-up failure can never turn a successful write into a user-facing error.
- Canvas rendering: a converter normalizes Slack mrkdwn to standard Markdown so Canvas documents render with real headings, links, and bold.
- Persistence: a disk-backed JSON store (
agent/persist.py, override withCORTEX_STORE_PATH) so staged decisions and approved memory survive process reloads without an external database. - Model provider: OpenRouter through the OpenAI-compatible client, model configurable via
LEDGER_MODEL.
Inspiration
Every team re-debates decisions it already made, because the reasoning is buried in a thread nobody can find. Existing bots make it worse by answering confidently even when they have nothing to go on. We wanted an agent that treats Slack itself as the source of truth, cites its evidence, and is honest enough about what it does not know that a team can safely build durable memory on top of it.
Challenges I ran into
- Making the agent honest. The hardest and most important design choice was computing confidence and source mode from retrieved evidence only, never from the wording of the question, so the agent refuses to invent a decision when nothing matches.
- Keeping approvals trustworthy. A Canvas write that succeeded was reporting failure when a later cosmetic step failed. We restructured the handlers so the critical write path is isolated and only a genuine failure surfaces an error.
- Canvas fidelity. Slack chat mrkdwn does not render in Canvas, so we added a converter to standard Markdown.
- Enterprise Grid quirks. Search and user scoping behave differently on Grid, which we handled with workspace-scoped calls and graceful fallbacks.
My Accomplishments
- A full loop that works live: question, permission-scoped search, cited answer, human approval, real Canvas, App Home update, and a follow-up answer that cites the approved memory.
- The honesty gate, verified live: a question with real evidence gets a confident cited answer, and a question about something never discussed gets an explicit refusal with no fabricated content.
- Resilience: durable thread-post fallback when Canvas is unavailable, drafts that survive process reloads, and a capabilities card when the model lane fails.
- A clean, tested codebase with a green test suite covering the evidence gate, permalinks, workflows, view builders, action handlers, and the Canvas converter.
What we learned
Trust is the product. Retrieval and Canvas writes are table stakes; the feature that makes an institutional-memory agent usable is the discipline to refuse when the evidence is not there. Once the agent is honest about what it knows, everything downstream (compounding memory, approvals, citations) becomes safe to rely on.
What's next
- Deeper MCP integrations so answers can cite and act beyond Slack.
- Team-level analytics on what the brain knows and where the gaps are.
- A hosted multi-tenant store to replace the local JSON store.
- Adjacent verticals on the same engine: an incident commander, a verified analytics agent, and a meetings-to-memory agent.
Built with
python, slack-bolt, slack real-time search, slack canvas, slack app home, block kit, openai-agents, openrouter, socket-mode
Built With
- llm
- slack-mcp
- slack-real-time-search
Log in or sign up for Devpost to join the conversation.