memo · ADR 0045 · with 0021
45.The database answers the structured part. Retrieval answers the rest.!!
- The problem
- Two of the most common questions to a journal share no meaning with their answers. "What's on this week?" names only days, and the dentist note from three weeks ago is nowhere near it in vector space. "When did I last see Tunde?" matches every note that mentions Tunde, and the best match is whichever talks about seeing him most, not the latest. Both are structured questions sent down an unstructured path.
- The options
- Self-query, where a model turns the question into a query plus a metadata filter, the industry default; a deterministic parser over a closed set of time phrases; tool use, where the answer model calls a lookup mid-generation; or better-worded chunks and hope.
- The move
- Before searching, Ask reads what it can know exactly and pins it. A deterministic parser turns "this week", "last Friday", "6 October", "3 days ago" into a date span; the todos and events in that span are read from the same table the planner reads and pinned to the top. People named in the question are matched against the people table and their latest recorded contact is pinned with a line the model can quote. Then retrieval runs inside the window first, as exact distances over a materialised set rather than through the approximate index, and outside it to fill up to eight.
- What we accepted
- Phrasings outside the parser’s set get no window and fall back to plain retrieval. The answer is only as good as the review, since a confirmed wrong date is trusted over the note’s words. And the index is still a copy, so the companion decision reads each retrieved note's current, non-rejected items live at answer time rather than trusting what was embedded.
- When we would revisit
- When evals show date questions still missing after the parser, which is the trigger for a model-written filter measured against time to first token, or when retrieval inside a window is slow enough to matter.
The index decides which notes are relevant. The database decides what is true about them. That split is the whole answer to “your system extracted a fact, the user confirmed it, and the chatbot still answered from the raw text”: the embedding was a copy taken at processing time, and copies go stale. Keeping the index in sync means every write path enqueues a re-embed and you are eventually consistent. Reading the structured facts live, joined by the retrieved note’s id, is fresh by construction. memo does both, and trusts the live read.
The other half is latency. Citations are chosen by the system before generation, so the retrieval event fires before the first token and the model is never asked to invent a source. A parser costs nothing on that path. A second model round trip to write the filter would cost several hundred milliseconds on every question, which is why self-query lost.