docs/design/2026-08-09-bounded-memory-recall-candidates.md
The project and user memory scanners enumerate, read, and parse every topic, then return only the 200 most recent documents. Recall uses those shared scanner APIs, so an older relevant document outside either 200-document window cannot reach the heuristic or model selector even though the expensive scan work has already happened. The truncation key is recency, applied per scope and before anything has looked at the query.
The same capped APIs are also used by Forget, Indexer, Status, and Extraction. Removing their limit globally would widen unrelated behavior.
Keep the existing scanner APIs and their 200-document limit unchanged. Add explicit all-topic variants used only by recall.
Recall ranks the combined project and user pool before model selection:
The heuristic fallback continues to score the complete recall pool and still returns at most five documents. Existing body and prompt limits remain unchanged.
"Removes the 200-document cap" is the wrong summary, and reviewers should read the effect per pool size rather than as a uniform widening. What the change actually does is replace a per-scope, query-blind recency truncation with a global, query-aware one:
MAX_MODEL_MANIFEST_BYTES, not the document capMAX_MODEL_CANDIDATE_DOCS = 200 reads like the limit but rarely is one. Each
manifest line carries an absolute file path and an ISO-8601 timestamp before
the description, so its fixed overhead is on the order of 150–250 bytes for an
ordinary project path. Against a 25,000-byte budget that binds somewhere around
90–150 documents, which is why both measurements above land in the nineties
rather than at 200.
Two things follow. Deployments should read the byte budget, not the document cap, as the real candidate ceiling. And the recency reserve only survives truncation because it is interleaved with the lexical candidates rather than appended after them — at a cut in the nineties, an appended reserve would be discarded in full.
The manifest byte budget also packs rather than prefixes: a document whose line does not fit is skipped and later, shorter lines are still considered. A long-description document can therefore be dropped while a lower-ranked one is kept.
Forget, Indexer, Status, and Extraction keep the capped scanner. That preserves their current behavior but means an older document can become recallable before it becomes manageable by those non-recall flows.
Project scanning remains required. User scanning remains best-effort. Invalid or unreadable files keep the existing skip behavior. Empty candidate manifests return no model selection rather than sending an unbounded request.
There is no public setting, persistent index, new dependency, provider API, or
second selection pathway. Each recall enumerates, reads, and parses the full
project and user memory trees once, then performs O(n) local ranking and
active-tool filtering over the parsed documents. The deterministic fast path
described in 2026-08-08-native-memory-recall-reliability.md reuses the
candidates produced by that single pass, so it adds no scan, no ranking work,
and no state machine — only an earlier delivery point for results already
computed. The model candidate count and manifest are
bounded, but the local I/O and filtering work grow with the memory tree; a
persistent catalog requires separate measurement and evidence.