Brokentooth.io / 06 Writing / How SessionMunch finds useful project memory

How SessionMunch finds useful project memory

Exact words, entities, links, and optional vectors each get a vote. The result still needs judgment.

Keeping project history is only half the job. The other half is finding the useful bit before I give up and explain the whole damned project again.

A pile of accurate notes can still be a bad memory system. Twelve pages containing “migration,” ordered by an opaque confidence number, can technically answer a question while making the filing cabinet everybody else's problem.

I want retrieval that can cope with the different ways I remember things. Sometimes I remember the exact error. Sometimes I remember a component. Sometimes I only remember the idea. Those aren't equivalent queries, and I don't expect one ranking method to handle all of them well.

Four ways into the same knowledge

SessionMunch's knowledge search uses several signals.

FTS5 handles the words. Exact error strings, command names, filenames, and terminology are good reasons to keep lexical retrieval. If I know the identifier, I want the system to respect that advantage.

Entity matching uses the page's canonical frontmatter entity list. It gives named components and concepts another route into the candidate set. It also has an honest limitation: an empty entity index contributes nothing. Writing “graph” on an architecture diagram does not cause relationships to appear by administrative decree.

Link-neighbor retrieval follows relationships between pages. A decision may link to the gotcha that explains it, which may link to the component being discussed. Connections help related material surface even when each page doesn't repeat the full vocabulary.

Optional vector retrieval adds semantic similarity. With embeddings configured, differently worded accounts of the same idea can meet in the candidate set. That helps when my query says “login token” and the useful note says “authentication credential.” It also gives us another fallible ranking, rather than an oracle.

Let the rankings disagree

These signals produce different rankings. Their raw scores aren't naturally comparable: an FTS score and a vector similarity aren't two temperatures measured on the same scale.

SessionMunch combines the ranked lists with Reciprocal Rank Fusion, or RRF. The useful intuition is simple: a candidate earns credit for placing well in a list. Appearing prominently in several lists can strengthen its position.

That means an exact match can matter without requiring every query to be an exact match. A semantically close page can surface without automatically outranking an exact match.

Invented records illustrate narrowing scope and inspecting evidence. This is not live search or an RRF simulation. Open the explainer on its own.

The interactive example shows a different part of retrieval: choosing a scope and opening the evidence behind a snippet. It uses invented records; it does not implement RRF, display real rankings, or benchmark SessionMunch.

A search result is a route to evidence. It is not permission to stop thinking.

The implementation also applies a bounded authority adjustment before final truncation. Maintained rules, decisions, procedures, and gotchas can win close contests against episodic material, using page metadata. Historical evidence remains searchable. That is useful because the latest transcript and the current rule may both mention the same subsystem while answering different questions.

An optional judge after retrieval

The current runtime can apply an optional LLM reranker to project or scoped searches. This happens after retrieval has already assembled a shortlist.

The distinction matters. The provider gets a bounded query and bounded titles and snippets, up to thirty candidates. It gets one call per query, with limited concurrency. It is judging candidates rather than roaming the archive and inventing a new answer.

Failure preserves the local order. Timeout, invalid output, an unavailable provider, or saturation should leave normal retrieval usable. I don't want “the relevance assistant is unavailable” to become a reason I cannot search my own notes.

JEV belongs in the future-work paragraph. The abstraction and evaluation scaffolding exist, but the live runtime option here is llm. JEV is planned for the same post-retrieval role. Calling it an available backend now would make the roadmap more exciting and the documentation less useful.

Ask the right archive

There is another distinction I find more important than any ranking formula: compiled knowledge and raw event history answer different questions.

“What convention did we settle on?” belongs with maintained knowledge. “When did we run this command on that machine?” often belongs in event search, with scope, harness, machine, and time filters.

SessionMunch exposes both. Knowledge search can also return a bounded raw-observation fallback when compiled pages miss in supported scoped modes. That fallback is not identical to an exhaustive search of the separate event ledger, and global knowledge search has its own boundaries.

My working approach is to start small: a specific question, a few snippets, then the relevant page or event. I check dates, origin, and the current repository before treating retrieved history as current truth.

The goal isn't to stuff every remembered thing into the next context window. That would just automate the paperwork. I want enough well-founded context to continue the work, and a clear route back when I need to know what actually happened.

Back to the SessionMunch series.

Sources and setup

These links pin the v0.1.0 release-candidate implementation discussed here: retrieval architecture, hybrid reader, event reader, and README model and reranking guide. For setup, use the public quick start.