Skip to content

fix(memory): handle mem_src scopes in retrieval#124

Open
hobertrand-hub wants to merge 1 commit into
tinyhumansai:mainfrom
hobertrand-hub:fix/mem-src-source-retrieval
Open

fix(memory): handle mem_src scopes in retrieval#124
hobertrand-hub wants to merge 1 commit into
tinyhumansai:mainfrom
hobertrand-hub:fix/mem-src-source-retrieval

Conversation

@hobertrand-hub

@hobertrand-hub hobertrand-hub commented Jul 26, 2026

Copy link
Copy Markdown

Summary

  • treat mem_src:<source_id>:<item> scopes as document/source scopes during source retrieval
  • allow fast retrieval source filters to match both exact tree scopes and mem_src collection ids
  • add coverage for mem_src document scope classification

Why

OpenHuman stores reader-backed source trees with scopes such as mem_src:src_vault_hob_local:path/to/note.md. Source-scoped retrieval can be asked for the collection id (src_vault_hob_local), so TinyCortex needs to recognize the collection id embedded inside the composite mem_src tree scope. Without this, host source retrieval can miss indexed summaries even when the source is correctly ingested.

Validation

  • cargo +1.96.1 fmt --check
  • cargo +1.96.1 test scope_prefix_matching_known_platforms --lib
  • cargo +1.96.1 test source --lib

Relation to PR #123

This is a focused PR for only the mem_src retrieval fix. The same change was previously pushed onto the broader legacy chunk repair branch in #123, but keeping it separate makes the OpenHuman source-retrieval dependency easier to review and merge independently.

Summary by CodeRabbit

  • Bug Fixes
    • Improved retrieval filtering for document-related memory sources.
    • Ensured mem_src: scopes are correctly recognized as documents.
    • Improved matching of retrieved results against configured source scopes.
  • Tests
    • Added coverage for document classification of mem_src: scopes.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e76ff183-6d65-42fb-829a-517b4c0dac8b

📥 Commits

Reviewing files that changed from the base of the PR and between 108b8e0 and c0ab3f7.

📒 Files selected for processing (3)
  • src/memory/retrieval/fast.rs
  • src/memory/retrieval/source.rs
  • src/memory/retrieval/source_tests.rs

📝 Walkthrough

Walkthrough

Memory retrieval now supports mem_src: scopes when classifying document sources and filtering local or dense retrieval hits. A helper derives source IDs from these scopes while preserving direct scope matching.

Changes

Memory source scope matching

Layer / File(s) Summary
Document classification for mem_src: scopes
src/memory/retrieval/source.rs, src/memory/retrieval/source_tests.rs
scope_matches_kind recognizes mem_src: scopes as documents, with an added assertion covering a representative scope.
Retrieval filtering for derived source scopes
src/memory/retrieval/fast.rs
Local and dense retrieval filters use source_scope_allows, which supports direct scope matches and IDs extracted from mem_src: scopes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: senamakel

Poem

A bunny found a hidden source,
With mem_src: along its course.
It matched the trees, both near and wide,
Then filtered every hit inside.
Hop, hop—documents now align!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: handling mem_src scopes in memory retrieval.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hobertrand-hub
hobertrand-hub marked this pull request as ready for review July 26, 2026 23:29
@hobertrand-hub

Copy link
Copy Markdown
Author

Ready for review. This is the focused mem_src retrieval fix split out from #123 so OpenHuman source-scoped retrieval can depend on a small, independently reviewable TinyCortex change.

@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes source-scoped retrieval for OpenHuman reader-backed trees whose tree scopes are composite mem_src:<collection_id>:<path> strings, so that a caller supplying only the collection id in source_scope still gets matching hits.

  • fast.rs: Replaces direct HashSet::contains calls in resolve_local and dense with a new source_scope_allows helper that additionally extracts and checks the collection id embedded in a mem_src: scope.
  • source.rs: Extends scope_matches_kind to recognise any mem_src: prefixed scope as document kind.
  • source_tests.rs: Adds a targeted assertion for the new mem_src: case; the equivalent end-to-end path through fast_retrieve is not yet tested.

Confidence Score: 4/5

Safe to merge — the change is strictly additive and correctly widens the match condition without breaking existing exact-scope filtering.

Both changes in fast.rs and source.rs are narrow and well-motivated. The logic in source_scope_allows and extract_mem_src_id is correct for the stated format. The main gap is that the new extract_mem_src_id code path has no dedicated test in fast_tests.rs, and extract_mem_src_id uses case-sensitive prefix matching while scope_matches_kind lowercases before comparing.

Files Needing Attention: src/memory/retrieval/fast.rs — the two new private helpers warrant a targeted integration test and a review of the case-sensitivity assumption.

Important Files Changed

Filename Overview
src/memory/retrieval/fast.rs Replaces direct HashSet containment checks with source_scope_allows, adds extract_mem_src_id; new mem_src code path is untested and has a case-sensitivity mismatch vs. source.rs
src/memory/retrieval/source.rs Adds mem_src: prefix recognition inside scope_matches_kind so source trees with composite mem_src scopes are classified as document kind; logic is correct and narrowly scoped
src/memory/retrieval/source_tests.rs Adds a single assertion for mem_src scope in scope_prefix_matching_known_platforms; covers the source.rs change but not the fast.rs change

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[fast_retrieve called\nwith source_scope] --> B{entity_ids\nempty?}
    B -- yes --> C[dense path:\nquery_source no filter]
    B -- no --> D{graph pairs\nfound?}
    D -- no --> E[global_occurrence\ncalls dense]
    D -- yes --> F[resolve_local\nfrom candidates]
    C --> G[source_scope_allows\nfor each hit]
    E --> G
    F --> G
    G --> H{scope.contains\ntree_scope?}
    H -- yes --> I[Allow hit]
    H -- no --> J{mem_src: prefix?}
    J -- yes --> K[extract_mem_src_id]
    K --> L{scope.contains\ncollection_id?}
    L -- yes --> I
    L -- no --> M[Reject hit]
    J -- no --> M
Loading

Reviews (1): Last reviewed commit: "Handle mem_src scopes in source retrieva..." | Re-trigger Greptile

Comment on lines +287 to +298
fn source_scope_allows(scope: &HashSet<String>, tree_scope: &str) -> bool {
if scope.contains(tree_scope) {
return true;
}
extract_mem_src_id(tree_scope).is_some_and(|id| scope.contains(id))
}

fn extract_mem_src_id(value: &str) -> Option<&str> {
let rest = value.strip_prefix("mem_src:")?;
let (id, _) = rest.split_once(':')?;
(!id.is_empty()).then_some(id)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing test coverage for mem_src path in fast retrieval

source_scope_allows and extract_mem_src_id are not exercised by any test in fast_tests.rs. The existing tests (dense_fallback_filters_scope_before_limit, resolve_local_hydrates_leaf_and_summary_and_skips_missing_or_out_of_scope) always use scopes like "slack:#allowed" that match via the direct scope.contains(tree_scope) branch, so they never reach the new extract_mem_src_id code path. A test seeding a tree with scope mem_src:src_vault_hob_local:path/to/note.md and a source_scope containing only "src_vault_hob_local" would confirm the core fix behaves correctly end-to-end through fast_retrieve.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +294 to +298
fn extract_mem_src_id(value: &str) -> Option<&str> {
let rest = value.strip_prefix("mem_src:")?;
let (id, _) = rest.split_once(':')?;
(!id.is_empty()).then_some(id)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Case-sensitivity inconsistency with scope_matches_kind

extract_mem_src_id uses a case-sensitive strip_prefix("mem_src:"), while the parallel function scope_matches_kind in source.rs normalises the scope via to_lowercase() before checking lower.starts_with("mem_src:"). A tree_scope stored with any capitalisation variant (e.g. Mem_Src:...) would be classified as document kind by scope_matches_kind but would silently fall through the fast-retrieval filter because extract_mem_src_id returns None. Lowercasing the prefix portion before the strip_prefix call would align both paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant