fix(searcher): scope _expand_with_neighbors by parent_drawer_id (#1580) - #1792
fix(searcher): scope _expand_with_neighbors by parent_drawer_id (#1580)#1792ggettert wants to merge 1 commit into
Conversation
…alace#1580) Implements Option B from MemPalace#1580: when the matched chunk carries a parent_drawer_id, narrow both the neighbor query and the total_drawers count query by it so cross-drawer chunk leakage cannot happen even when multiple drawers share a non-empty source_file. Also relaxes the early-return so neighbor expansion runs for the MCP oversized-content path (where source_file="" but parent_drawer_id is always present). Bails only when both keys are missing. Adds two regression tests pinning the MemPalace#1580 repro shape and the unchanged legacy source_file-only path. Fixes MemPalace#1580
There was a problem hiding this comment.
Code Review
This pull request addresses issue #1580 by scoping neighbor expansion in _expand_with_neighbors using parent_drawer_id when source_file is empty or missing. This prevents chunks from unrelated drawers with empty source files from leaking into the neighbor query. The PR also updates the total drawers lookup to use the same scoped filter and adds corresponding unit tests to verify the new scoping behavior and ensure no regression on the legacy source-file-only path. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Closing — I missed PR #1628 when scoping this work. #1628 also closes #1580 and implements the same |
Fixes #1580.
Summary
Implements Option B from the issue: scope
_expand_with_neighborsby
parent_drawer_id(in addition tosource_file) when the matchedchunk carries one.
Why this is bigger than the one-line guard relaxation
Pre-fix, the helper bailed early when
source_filewas empty:That guard masked the bug on the MCP-chunked path (where every chunk
has
source_file="") by silently disabling neighbor expansion for it.So the user-visible symptom on
developtoday is "neighbor expansionquietly doesn't work for
tool_add_draweroversized content"; thereal leak only surfaces if two drawers ever share a non-empty
source_file.This PR:
source_fileandparent_drawer_idare missing.parent_drawer_idto the$andfilter (neighbor query andthe
total_drawerscount query) when it's present on the matchedchunk.
and hardened so cross-drawer leakage is impossible even if
source_filecollides.Live verification
Beyond unit tests, I built three harnesses:
1. Adversarial collision (two drawers, shared non-empty
source_file, distinctparent_drawer_id):total_drawersreported2. Natural MCP path (oversized
tool_add_drawer, nosource_file— Igor's exact repro):total_drawersreported3. Regression fingerprint (diary chunks + small drawers + closet
hits + MCP chunked drawers, 3 query patterns):
diff develop.json branch.json— zero diff. Existing file-backedand closet-boosted paths are byte-identical pre/post.
Test coverage
tests/test_closets.py::TestDrawerGrepExpansion:test_expand_scopes_by_parent_drawer_id_when_present— pins thesearcher: _expand_with_neighbors stitches unrelated chunks across MCP drawers sharing empty source_file #1580 repro (two drawers, shared empty
source_file, scoped result).test_expand_without_parent_drawer_id_keeps_source_file_scope—pins the legacy diary path keeps source_file-only scope.
Full suite: 259/259 in
tests/test_closets.py+tests/test_mcp_server.py.Ruff clean.
Out of scope
source_fileshould default to a per-drawer synthetic keyon the MCP path (the issue calls this out explicitly).
leak-prone metadata (no migration needed; the fix is purely at the
query layer).