<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Beever AI</title>
    <description>The latest articles on Forem by Beever AI (@beeverai).</description>
    <link>https://forem.com/beeverai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3896513%2Fcd0981f2-139a-4b83-be53-fa2aa95a5faf.png</url>
      <title>Forem: Beever AI</title>
      <link>https://forem.com/beeverai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/beeverai"/>
    <language>en</language>
    <item>
      <title>Day 1: Your Team’s Chat Is a Wiki Waiting to Happen — A New Kind of RAG</title>
      <dc:creator>Beever AI</dc:creator>
      <pubDate>Tue, 28 Apr 2026 08:01:32 +0000</pubDate>
      <link>https://forem.com/beeverai/day-1-your-teams-chat-is-a-wiki-waiting-to-happen-a-new-kind-of-rag-3fg6</link>
      <guid>https://forem.com/beeverai/day-1-your-teams-chat-is-a-wiki-waiting-to-happen-a-new-kind-of-rag-3fg6</guid>
      <description>&lt;p&gt;Why we built Beever Atlas — and why “distill first, retrieve second” works where vanilla RAG falls apart.&lt;br&gt;
By Alan Yang &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8aajkhtrme1qedaiohhl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8aajkhtrme1qedaiohhl.webp" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your team already documents everything — in chat. Beever Atlas distills those conversations into a wiki that the LLM can actually reason over. Across Slack, Discord, Microsoft Teams, and Mattermost (More platforms will be integrated).&lt;/p&gt;

&lt;p&gt;5-Day Beever Atlas Series — start here.&lt;/p&gt;

&lt;p&gt;This is Day 1 of a five-part deep dive into Beever Atlas — the open-source, wiki-first RAG system that turns your team’s chat into a self-writing knowledge base.&lt;/p&gt;

&lt;p&gt;Day 1: Why Beever Atlas exists — concept, comparison with other tools, real use cases&lt;/p&gt;

&lt;p&gt;If any of this lands for you, the single best thing you can do is ⭐ the GitHub repo — it makes a real difference for an OSS launch.&lt;/p&gt;

&lt;p&gt;The Karpathy Insight&lt;br&gt;
Andrej Karpathy put it plainly in a post on X:&lt;/p&gt;

&lt;p&gt;LLMs are “far better at reasoning over curated, encyclopedic content (books, docs, wikis) than over raw conversational transcripts.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43nhza6wt48st66hkuxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43nhza6wt48st66hkuxz.png" alt=" " width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chat history is noisy, redundant, temporally scattered, and packed with implicit context that only the people who were there can resolve. A wiki is the already-distilled form of that knowledge — deduplicated, structured, citation-bearing, organized by topic rather than by timestamp.&lt;/p&gt;

&lt;p&gt;Most RAG systems retrieve from the messy left-hand side. We distill into the right-hand side first. That’s the entire idea.&lt;/p&gt;

&lt;p&gt;Feed an LLM a raw Slack export and ask it to reason about your auth strategy. Then feed it a two-page wiki summarizing the same conversation. The second version produces better answers, fewer hallucinations, and traceable citations. Every time. This isn’t a subtle distinction — it’s a structural one.&lt;/p&gt;

&lt;p&gt;The quality of LLM reasoning is bounded by the quality of its input.&lt;/p&gt;

&lt;p&gt;What Beever Atlas Does&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2iqkmjjgfc7q3vrrh7ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2iqkmjjgfc7q3vrrh7ca.png" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wiki-preview above is real output. That page — concept map, topic clusters, FAQ section, glossary, decision log — was produced entirely from 246 Slack messages. Nobody scheduled a documentation sprint. Nobody opened Confluence.&lt;/p&gt;

&lt;p&gt;Beever Atlas connects to your team’s chat platforms and continuously distills conversations into a structured, queryable wiki. Three things it does:&lt;/p&gt;

&lt;p&gt;Reads from Slack, Discord, Microsoft Teams, Telegram, Mattermost — all five, on a schedule or on demand (README.md:31)&lt;br&gt;
Continuously distills into a structured wiki with seven page types per channel: overview, topics, decisions, people, FAQ, glossary, activity (docs/mcp-server.md:139–149)&lt;br&gt;
Answers questions with citations — through the dashboard or via MCP directly into Claude Code and Cursor&lt;/p&gt;

&lt;p&gt;One limitation worth naming up front: very recent messages (last few minutes) may not yet appear in the wiki. The QA agent falls back to raw messages for facts that haven’t been distilled yet. You trade a small recency window for dramatically better reasoning quality on the bulk of your history.&lt;/p&gt;

&lt;p&gt;How It Compares&lt;br&gt;
The tools below all touch “AI + knowledge.” None of them do the same thing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k8c2wfap9zo6ev2x17v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k8c2wfap9zo6ev2x17v.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The honest version: Mem0 is good for personal memory. Notion AI is good if your team already writes the docs themselves. Obsidian with an LLM plugin is good for individual researchers who curate their own notes. Beever Atlas is good if your team’s knowledge already lives in chat and you want it to organize itself — without anyone touching a wiki editor.&lt;/p&gt;

&lt;p&gt;What Teams Actually Do With This&lt;br&gt;
These aren’t hypothetical. They’re four questions that surfaced in our own team chat the week we started building Beever Atlas.&lt;/p&gt;

&lt;p&gt;1 The new hire who doesn’t DM Alice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdc04flzfub8ce4cg04ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdc04flzfub8ce4cg04ys.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s day three at a new company. Instead of pinging Alice on Slack (“hey, why are we using Stripe and not Adyen?”), The new hire opens the #payments wiki and clicks Decisions. The Stripe-vs-Adyen entry is right there — extracted from the original thread, with citations linking back to the source messages. No DM. No interruption. Onboarding scales without putting anyone on call.&lt;/p&gt;

&lt;p&gt;2 The decision archaeologist&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezxx8rexpzix30ibqcjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezxx8rexpzix30ibqcjn.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Six months after the JWT-vs-OAuth debate, you ask: ”Why did we pick JWT?” The QA agent traces the decision through the entity graph and returns a chronological timeline — who proposed each option, what was rejected and why, when the final call landed, and a link back to the original Slack thread. It’s the institutional memory your team’s chat already had, now searchable.&lt;/p&gt;

&lt;p&gt;3 The expert finder&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m6zcm4c7goj1wcjzgdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m6zcm4c7goj1wcjzgdn.png" alt=" " width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You ask: ” Does anyone know about database indexing?” Most teams answer this with @channel and hope. Atlas ranks teammates by message frequency on the topic, citation count from other facts, and graph weight — quietly, without putting anyone on the spot. The person who’s been answering indexing questions for three years bubbles to the top.&lt;/p&gt;

&lt;p&gt;4 The Claude Code power-up&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpo6vdptzgczt9r4xhku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpo6vdptzgczt9r4xhku.png" alt=" " width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside Cursor (or Claude Code), your AI assistant calls ask_channel() over MCP. The response comes back with citations from your team’s actual decisions — not from training data, not made up. The same agent that powers the dashboard is now sitting next to your code editor, reading from the same brain.&lt;/p&gt;

&lt;p&gt;Try It&lt;br&gt;
Apache-2.0. Two free keys — Google AI Studio for Gemini, Jina for embeddings. Docker Compose. Runs on a laptop. About 15 minutes including Docker pulls.&lt;/p&gt;

&lt;p&gt;Please Star Us on GitHub ⭐⭐⭐ (&lt;a href="https://github.com/Beever-AI/beever-atlas" rel="noopener noreferrer"&gt;https://github.com/Beever-AI/beever-atlas&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5hpciexs8mf0z3vn473.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5hpciexs8mf0z3vn473.png" alt=" " width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One Line Installation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone &amp;amp;&amp;amp; ./atlas&lt;/code&gt; — running in a few minutes.&lt;/p&gt;

&lt;p&gt;⭐ Star us on GitHub · 💬 Join the Discord · 🐦 Follow on X&lt;/p&gt;

&lt;p&gt;Next — Day 2: Why Beever Atlas Uses Two Databases — and the 6-Stage Pipeline That Feeds Them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>rag</category>
    </item>
    <item>
      <title>LLM Wiki vs RAG: a different approach to team-chat memory</title>
      <dc:creator>Beever AI</dc:creator>
      <pubDate>Fri, 24 Apr 2026 18:12:18 +0000</pubDate>
      <link>https://forem.com/beeverai/llm-wiki-vs-rag-a-different-approach-to-team-chat-memory-4m91</link>
      <guid>https://forem.com/beeverai/llm-wiki-vs-rag-a-different-approach-to-team-chat-memory-4m91</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpo5xehuqn2ppdy2z798.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpo5xehuqn2ppdy2z798.png" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Retrieval-augmented generation became the reflex answer for &lt;em&gt;"my LLM needs to know about my data."&lt;/em&gt; Chunk it, embed it, retrieve top-k on query, stuff it in the prompt. It works so well on documents that engineers now apply it to everything — PDFs, wikis, code, support tickets, and, increasingly, team chat.&lt;/p&gt;

&lt;p&gt;RAG is the wrong tool for chat.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://beever.ai" rel="noopener noreferrer"&gt;Beever AI&lt;/a&gt; we spent the last months building an alternative and just released it as open source. &lt;a href="https://github.com/Beever-AI/beever-atlas" rel="noopener noreferrer"&gt;Beever Atlas&lt;/a&gt; is an &lt;strong&gt;LLM Wiki&lt;/strong&gt; — not a RAG system — that ingests Slack, Discord, Microsoft Teams, Mattermost, and Telegram conversations into a structured, browsable, auto-maintained wiki and knowledge graph. This post explains what an LLM Wiki is, what it can answer that RAG cannot, and the design decisions behind our implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an LLM Wiki?
&lt;/h2&gt;

&lt;p&gt;An LLM Wiki is a structured, LLM-maintained knowledge artefact derived from a conversational corpus. It is &lt;em&gt;not&lt;/em&gt; a retrieval preprocessing step. It is the artefact itself — browsable by humans, queryable by agents, versioned, and cited back to its sources.&lt;/p&gt;

&lt;p&gt;Seven differences worth naming:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary output.&lt;/strong&gt; RAG surfaces prompt-time retrieval results. An LLM Wiki produces a standing artefact (the wiki and the knowledge graph).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What breaks when retrieval breaks.&lt;/strong&gt; RAG hallucinates. An LLM Wiki is still readable as-is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumed by.&lt;/strong&gt; RAG: LLMs, mostly. LLM Wiki: humans &lt;em&gt;and&lt;/em&gt; LLMs both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness cost.&lt;/strong&gt; RAG re-indexes on every write. An LLM Wiki re-consolidates affected topics only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedup.&lt;/strong&gt; RAG does it per-query, ranking-dependent. An LLM Wiki does it at extraction time, structurally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Citations.&lt;/strong&gt; RAG reconciles sources post-hoc and can drift. An LLM Wiki carries citations forward from extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-hop questions.&lt;/strong&gt; RAG is poor at them. An LLM Wiki makes them first-class via the graph.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Karpathy outlined the idea in a widely-shared thread earlier this year. We took it seriously and built a production implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why RAG falls down on conversations
&lt;/h2&gt;

&lt;p&gt;Chat isn't documents. Four specific failure modes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Same fact, said dozens of times.&lt;/strong&gt; Someone announces &lt;em&gt;"we're moving to Postgres on March 15"&lt;/em&gt; in &lt;code&gt;#engineering&lt;/code&gt;. Twelve people ack. Four people quote it in later threads. Three retrospectives cite it. The same fact now exists as 20+ near-duplicate chunks. Chunk-based retrieval surfaces one somewhat arbitrarily, or several near-duplicates that crowd out unrelated relevant context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time-ordered, not topic-grouped.&lt;/strong&gt; In a document, related content sits adjacent. In chat, a feature decision, a bug report, and a lunch plan can be interleaved across five minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure lives outside the text.&lt;/strong&gt; Meaningful metadata is not in the message body: author, thread parent, reactions, platform, mentions, attachments. Embedding the body only throws away half the signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer instability.&lt;/strong&gt; Ask the same question a week apart. Different chunks rank highest depending on recent message volume and minor embedding perturbations. You get subtly different answers — corrosive to user trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an LLM Wiki can answer that RAG can't
&lt;/h2&gt;

&lt;p&gt;This is the part of the design that most people miss when they first see the architecture. A good vector retriever can handle &lt;em&gt;"what did we decide about onboarding?"&lt;/em&gt; just fine. The capabilities that separate an LLM Wiki from RAG show up when the question is &lt;strong&gt;relational, temporal, or multi-hop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Who decided we're moving to Postgres, and did anything supersede that decision?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Which projects does the billing service block, and who owns them?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Show me every decision Alan announced in Q1 that was later reversed."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Which technologies are members of team A working with that are still flagged experimental?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"What got decided in threads that mention the SOC2 audit?"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these requires walking a relationship — decision supersession, team membership, thread mentions, status attributes — that chunk-based retrieval fundamentally can't express. In Beever Atlas the knowledge graph in Neo4j holds those relationships. The Cypher traversal used in the codebase for decision-chain queries looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;type:&lt;/span&gt; &lt;span class="s1"&gt;'Decision'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d.channel_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;$channel_id&lt;/span&gt;
   &lt;span class="ow"&gt;OR&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:MENTIONED_IN&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;ev:&lt;/span&gt;&lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ev.channel_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;$channel_id&lt;/span&gt;
      &lt;span class="ss"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;OPTIONAL&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;person:&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DECIDED&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;OPTIONAL&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:SUPERSEDES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;old:&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;OPTIONAL&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;newer:&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:SUPERSEDES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
     &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;person.name&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;decided_by&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
     &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;old.name&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;    &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;supersedes&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
     &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;newer.name&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;superseded_by&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decided_by&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;supersedes&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;superseded_by&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="n"&gt;$limit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the kind of query a Q&amp;amp;A agent's router hands off to the graph path when a question's shape demands it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of a fact and an entity
&lt;/h2&gt;

&lt;p&gt;Before showing the pipeline, the data shapes that hold everything together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomic fact&lt;/strong&gt; — a single self-contained claim with a source message, author, timestamp, and thread context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The team is migrating from MySQL to Postgres on March 15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_message_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"slack:C08TX:1712500000001100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alan5543"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-01T14:22:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"thread_parent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MySQL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Technology"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Technology"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Team"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIGRATING_TO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"valid_from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-01T14:22:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"valid_until"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source_message_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"slack:C08TX:1712500000001100"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details to flag:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every relationship has temporal props&lt;/strong&gt; — &lt;code&gt;confidence&lt;/code&gt;, &lt;code&gt;valid_from&lt;/code&gt;, &lt;code&gt;valid_until&lt;/code&gt;, &lt;code&gt;source_message_id&lt;/code&gt;. This is how we answer &lt;em&gt;"as of when"&lt;/em&gt; questions and how later decisions supersede earlier ones without destroying history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entity scope&lt;/strong&gt; — some entity types (Person, Technology, Project, Team) merge globally across channels. Others (Decision, Meeting, Artifact) merge only within a channel scope. Scope-aware MERGE prevents two different channels' "Q1 planning decisions" from collapsing into each other, while still letting "Alan" mean the same person everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;String-level dedup is done with Jaro-Winkler similarity (via APOC) inside the scope; semantic dedup is done with embedding cosine on &lt;code&gt;Entity.name_vector&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the wiki gets built — six ADK stages
&lt;/h2&gt;

&lt;p&gt;Ingestion runs as a pipeline of Google ADK &lt;code&gt;LlmAgent&lt;/code&gt; steps, using Gemini 2.5 Flash for extraction. Six stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Preprocessor&lt;/strong&gt; — normalises platform-specific message shapes into a single &lt;code&gt;NormalizedMessage&lt;/code&gt; with author, timestamp, thread context, attachments, platform metadata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fact Extractor&lt;/strong&gt; — pulls atomic facts with channel + author + timestamp attached. Bounded output via &lt;code&gt;MAX_FACTS_PER_MESSAGE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entity Extractor&lt;/strong&gt; — LLM-driven with a flexible type schema (Person / Decision / Project / Technology / Team / Meeting / Artifact / …). Type vocabulary isn't frozen; new types can be added without a migration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-batch Validator&lt;/strong&gt; — dedupes entities and relationships across batch boundaries. This is where scope-aware MERGE and Jaro-Winkler similarity live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationship Graph&lt;/strong&gt; — materialises bidirectional relationships (&lt;code&gt;DECIDED ↔ DECIDED_BY&lt;/code&gt;, &lt;code&gt;BLOCKED_BY ↔ BLOCKS&lt;/code&gt;, and so on) with the temporal props above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persister&lt;/strong&gt; — transactional-outbox write to Weaviate + Neo4j + MongoDB, with media attribution preserved. The outbox pattern means a partial failure doesn't leave the stores inconsistent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Periodically, a separate &lt;strong&gt;consolidation agent&lt;/strong&gt; clusters related facts and synthesises them into topic pages — the "wiki" users browse in the dashboard. Consolidation is idempotent and checkpointed: you re-run it on a subset without rebuilding from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dual memory: why Weaviate &lt;em&gt;and&lt;/em&gt; Neo4j
&lt;/h2&gt;

&lt;p&gt;Facts live in two stores because no single store wins both query shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weaviate&lt;/strong&gt; — 3-tier semantic memory (channel-level summaries, topic-level synopses, fact-level detail). Hybrid BM25 + vector retrieval. Good for &lt;em&gt;"what did we decide about X?"&lt;/em&gt; — any question whose answer is a semantic lookup over fact text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neo4j&lt;/strong&gt; — entities, decisions, episodic links, media attributions. Good for &lt;em&gt;"who decided this and why?"&lt;/em&gt; — any question that requires walking a relationship.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;query router&lt;/strong&gt; picks semantic, graph, or both per question. The router is a small LLM classifier, not a rule engine. Rule engines fail on novel phrasings; a classifier trades a few milliseconds of routing latency for resilience to queries we haven't seen before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    Q[Question] --&amp;gt; R[Query Router&amp;lt;br/&amp;gt;LLM classifier]
    R --&amp;gt;|semantic| W[Weaviate&amp;lt;br/&amp;gt;channel / topic / fact]
    R --&amp;gt;|graph| N[Neo4j&amp;lt;br/&amp;gt;entity + rel traversal]
    R --&amp;gt;|both| W
    R --&amp;gt;|both| N
    W --&amp;gt; M[Merge + dedup by fact_id]
    N --&amp;gt; M
    M --&amp;gt; A[Answer agent&amp;lt;br/&amp;gt;ADK SkillToolset]
    A --&amp;gt; S[SSE stream&amp;lt;br/&amp;gt;response + citations]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB holds the wiki page cache, ingestion state, and the transactional outbox. Redis holds sessions. Nothing interesting happens in either — they're operational plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP surface: same memory, two audiences
&lt;/h2&gt;

&lt;p&gt;The dashboard is one surface. The &lt;strong&gt;MCP (Model Context Protocol) server&lt;/strong&gt; is the other. Sixteen tools are exposed to external agents like Claude Code, Cursor, or any MCP-capable client:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;search_by_topic&lt;/code&gt;, &lt;code&gt;search_channel_facts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_decision_timeline&lt;/code&gt;, &lt;code&gt;find_supersessions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;graph_traverse&lt;/code&gt;, &lt;code&gt;resolve_entity&lt;/code&gt;, &lt;code&gt;find_mentions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_channels&lt;/code&gt;, &lt;code&gt;read_wiki_section&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;…and more for ingestion status, media lookup, and policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The meaningful shift here is that the team memory becomes &lt;strong&gt;reusable context&lt;/strong&gt;, not a siloed app. An IDE-resident coding agent can ask &lt;em&gt;"what did the team decide about the auth library?"&lt;/em&gt; with the same guarantees the dashboard gives a human — citations back to source messages, scope-aware resolution, permission-aware access (roadmap, below).&lt;/p&gt;

&lt;h2&gt;
  
  
  What this costs
&lt;/h2&gt;

&lt;p&gt;Honest accounting: ingestion is slower and more expensive than RAG. You pay the LLM twice — once for extraction, once for consolidation. Using Gemini Flash keeps both bounded. Consolidation runs sparsely (once per topic cluster) and amortises across many messages.&lt;/p&gt;

&lt;p&gt;The tradeoff is explicit: &lt;strong&gt;you pay more ingestion cost to get a standing artefact instead of ephemeral retrieval results.&lt;/strong&gt; For team-chat corpora with heavy repetition, high conversational noise, and relational/temporal queries, an LLM Wiki reliably wins on answer quality, citation fidelity, browsability, and the types of question it can even entertain. For already-structured documents, classic RAG is still the right tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete query path
&lt;/h2&gt;

&lt;p&gt;Someone asks &lt;em&gt;"who decided we're moving to Postgres, and has anything superseded that decision?"&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The router classifies this as &lt;strong&gt;both&lt;/strong&gt; — it needs fact retrieval &lt;em&gt;and&lt;/em&gt; graph traversal, since there's a decider and a supersession chain.&lt;/li&gt;
&lt;li&gt;Weaviate retrieves the top facts about Postgres migration from the fact tier.&lt;/li&gt;
&lt;li&gt;Neo4j runs the decision-chain traversal shown earlier, returning &lt;code&gt;decided_by&lt;/code&gt;, &lt;code&gt;supersedes&lt;/code&gt;, and &lt;code&gt;superseded_by&lt;/code&gt; collections.&lt;/li&gt;
&lt;li&gt;Results merge, dedup by &lt;code&gt;fact_id&lt;/code&gt;, and pass to the answer agent.&lt;/li&gt;
&lt;li&gt;The agent streams back via SSE:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Alan announced the migration from MySQL to Postgres on March 1, 2026 [1], with cutover scheduled for March 15 [1]. The decision was ratified in the March 3 engineering sync [2] and has not been superseded since.&lt;/p&gt;

&lt;p&gt;[1] alan5543 in #engineering, 2026-03-01 14:22&lt;br&gt;
[2] alan5543 in #engineering-sync, 2026-03-03 10:00&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The citations come straight from the fact records surfaced in steps 2 and 3. There's no separate "find the source" step that can drift from what the agent actually retrieved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where we sit, and what's defensible
&lt;/h2&gt;

&lt;p&gt;Most team-memory products are &lt;strong&gt;vector-only&lt;/strong&gt; — Glean, Notion AI, various OSS "LLM wiki" clones built on a single embedding store. Beever Atlas is the first OSS product we're aware of putting a real knowledge graph under team-chat memory.&lt;/p&gt;

&lt;p&gt;The graph isn't cosmetic. It's load-bearing for a specific class of query — multi-hop, temporal, scope-aware — that vector retrieval fundamentally can't serve. It's also the substrate on which a &lt;strong&gt;permission spine&lt;/strong&gt; can be built: mirroring Slack Enterprise Grid ACLs as graph-level access rules means permissions get enforced at query time, not papered over with app-tier filters. That's on our roadmap and we think it's the right shape for enterprise deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the stack
&lt;/h2&gt;

&lt;p&gt;The full system runs locally via &lt;code&gt;docker compose&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python backend — FastAPI + Google ADK agents&lt;/li&gt;
&lt;li&gt;TypeScript bot bridge — Slack / Discord / Teams / Mattermost / Telegram webhooks with platform-specific signature verification&lt;/li&gt;
&lt;li&gt;React dashboard — wiki view, interactive Cytoscape knowledge graph, streaming Q&amp;amp;A with live citations&lt;/li&gt;
&lt;li&gt;Weaviate, Neo4j, MongoDB, Redis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Platform credentials (bot tokens) are encrypted at rest with AES-256-GCM. All data stays in databases you control. The app sends no telemetry anywhere — LLM calls go through API keys you configure in your own &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;make demo&lt;/code&gt; target brings up the full stack pre-loaded with a public Wikipedia corpus (Ada Lovelace + Python history, CC-BY-SA 3.0). Pre-computed fixtures ship in the repo, so seeding runs without any API keys. Asking questions via the Q&amp;amp;A agent needs a free-tier Gemini API key — Ollama support for fully-local inference is on the roadmap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Beever-AI/beever-atlas
&lt;span class="nb"&gt;cd &lt;/span&gt;beever-atlas
make demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8000/api/channels/demo-wikipedia/ask &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer dev-key-change-me"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"question":"Who was Ada Lovelace?"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see a streaming SSE response with six citations linking back to the source Wikipedia articles.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/Beever-AI/beever-atlas" rel="noopener noreferrer"&gt;github.com/Beever-AI/beever-atlas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://docs.beever.ai/atlas" rel="noopener noreferrer"&gt;docs.beever.ai/atlas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo video: &lt;a href="https://youtu.be/VJ81Uxyjxb0" rel="noopener noreferrer"&gt;youtu.be/VJ81Uxyjxb0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beever Atlas is developed by Beever AI Limited in Toronto, Ontario, and released under the Apache 2.0 license. The LLM Wiki concept was inspired by Andrej Karpathy's earlier-2026 thread on LLM Knowledge Bases; we took the idea seriously and built the implementation.&lt;/p&gt;

&lt;p&gt;Contributions welcome. Issues especially — we want to hear the edge cases where a vector-only system would have worked and our graph overhead turned out not to pay for itself.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>llmwiki</category>
    </item>
  </channel>
</rss>
