[DISCUSSION] file.top_k documents file count but actually bounds L2 segments
Description
RetrieveFileConfig.top_k is documented as "Total number of files to retrieve", but the current retrieve pipeline never uses it to bound files.
In AgenticMixin.progressive_retrieve:
_recall_segmentspassesfile.top_ktovector_search_segments, sotop_kactually bounds L2 segments, not L1 files._collect_filesthen rolls those ≤top_ksegments up to their files — the file list is a derived set, not a ranked, capped list.
Consequence: a single chatty recall file whose segments occupy all top_k slots yields exactly one file in the files layer, even though the config says "5 files". Diverse-but-weaker files are crowded out before they ever get a vote.
Motivation
The files layer is what the agent reads as "these are my relevant memory files". When one broad file (e.g. a long running-notes file with many lines) monopolizes the segment window, retrieval hides every other relevant file. This is user-visible: query the store, and the number of files returned is effectively unpredictable — it is distinct(recall_file_id) of whatever segments won, between 1 and top_k.
The file layer itself is intentionally not a second ranked search today (ADR 0007's roll-up design). The bug is that the only knob documented as file count instead silently means segment count.
Candidate directions (want input before implementing)
- Honest config, keep roll-up. Rename/redocument the knob to
segment.top_k(or addfile.enabledclarity) and accept thatfilescount is derived. Smallest change, no behavior shift, but the documented promise stays wrong-ish. - Enlarge the L2 window, keep roll-up. Search more segments than the file target (e.g.
file_count × segments_per_file_guess, or a newfile.candidatesmultiplier), then roll up and cut totop_kdistinct files. Keeps "no second ranked search"; a chatty file can still dominate only within its own file's segments once candidates are wider. Requires a per-file segment cap or re-slicing change to truly bound one file's share. - Rank files natively. Files already carry an embedding (
"{name}: {description}"on commit). Add a real file-level ranked search with its owntop_k, returning files first and segments as supporting evidence. Biggest change: new repo path (vector_search_files), possibly conflicts with ADR 0007's "L1 is not searched" stance, needs its own discussion.
No code yet — this is a semantics decision affecting the config contract and the inject result shape, so it should be settled here first.
Platform
Platform Independent
Priority
Minor (behavioral correctness of a documented knob, not a crash)
Out of scope
- Segment-layer ranking quality (covered elsewhere)
- Changing the roll-up scoring from
max(segment score)
Source: NevaMind-AI/memU