Skip to content

Comments

feat(SEM-53): Implement layered query resolution with deduplication#8

Merged
Kadajett merged 2 commits intomainfrom
sem-53-layered-query-resolution
Dec 5, 2025
Merged

feat(SEM-53): Implement layered query resolution with deduplication#8
Kadajett merged 2 commits intomainfrom
sem-53-layered-query-resolution

Conversation

@Kadajett
Copy link
Contributor

@Kadajett Kadajett commented Dec 5, 2025

Summary

  • Implements layered query resolution for the LayeredIndex with proper layer precedence (AI > Working > Branch > Base)
  • Adds LayeredSearchOptions builder for configuring search (filters, limit, case sensitivity)
  • Adds LayeredSearchResult type containing symbol info with layer metadata
  • Implements search_symbols() that merges and deduplicates results across all layers
  • Implements get_file_symbols() that resolves paths through file moves and returns deduplicated symbols
  • Higher layers shadow lower layers; deleted markers in any higher layer exclude the symbol
  • Fixes grammar bug in UpdateStrategy::description() (singular "file" vs plural "files")

Test plan

  • 232 tests passing (31 new tests added)
  • test_ai_layer_shadows_base_in_search - AI layer version returned, not base
  • test_deleted_marker_stops_search - Deleted symbols excluded from results
  • test_file_move_resolves_path_in_get_file_symbols - Old paths resolve through moves
  • test_search_merges_all_layers - Symbols from all 4 layers found
  • test_deduplication_across_layers - Same hash deduplicated to highest layer
  • test_layer_ordering_correct - Results ordered AI → Working → Branch → Base
  • Additional tests: case sensitivity, filters, limits, chained moves, resurrection after deletion

Closes SEM-53

-- Details

Adds search and file symbol resolution across layer stack with proper precedence (AI > Working > Branch > Base). Higher layers shadow lower layers, and deleted markers stop search.

New types:

  • LayeredSearchOptions: Builder-pattern search configuration
  • LayeredSearchResult: Search result with layer info

New methods on LayeredIndex:

  • search_symbols(query, opts): Search across all layers
  • get_file_symbols(path): Get symbols for a file with move resolution
  • resolve_symbol_with_layer(hash): Resolve symbol with layer info
  • total_active_symbols(): Count unique active symbols

Features:

  • Layer precedence with deduplication
  • Deleted marker handling
  • File move resolution through layer chain
  • Case-insensitive search (default)
  • Filters: kind, risk, limit, layers

Includes 31 new tests (6 TDD required + 25 comprehensive). Also fixes singular/plural grammar in UpdateStrategy::description().

Adds search and file symbol resolution across layer stack with proper
precedence (AI > Working > Branch > Base). Higher layers shadow lower
layers, and deleted markers stop search.

New types:
- LayeredSearchOptions: Builder-pattern search configuration
- LayeredSearchResult: Search result with layer info

New methods on LayeredIndex:
- search_symbols(query, opts): Search across all layers
- get_file_symbols(path): Get symbols for a file with move resolution
- resolve_symbol_with_layer(hash): Resolve symbol with layer info
- total_active_symbols(): Count unique active symbols

Features:
- Layer precedence with deduplication
- Deleted marker handling
- File move resolution through layer chain
- Case-insensitive search (default)
- Filters: kind, risk, limit, layers

Includes 31 new tests (6 TDD required + 25 comprehensive).
Also fixes singular/plural grammar in UpdateStrategy::description().
@linear
Copy link

linear bot commented Dec 5, 2025

SEM-53 Layered Query Resolution

Overview

Implement query resolution across layer stack.

Resolution Algorithm

fn get_symbol(hash: &str, layers: &[Layer]) -> Option<Symbol> {
    for layer in [AI, Working, Branch, Base] {
        if layer.deleted.contains(hash) {
            return None;  // Explicitly deleted
        }
        if let Some(s) = layer.symbols.get(hash) {
            return Some(s);  // Found in overlay
        }
    }
    None  // Not found anywhere
}

Check layers top-down (AI → Working → Branch → Base).
First match wins. Deleted markers stop search.

TDD Requirements

#[test] fn test_ai_layer_shadows_base() { }
#[test] fn test_deleted_marker_stops_search() { }
#[test] fn test_file_move_resolves_path() { }
#[test] fn test_search_merges_all_layers() { }
#[test] fn test_deduplication_across_layers() { }
#[test] fn test_layer_ordering_correct() { }

Deliverables

  • resolve_symbol(hash: &str) -> Option<Symbol> with layer precedence
  • search_symbols(query: &str, opts: SearchOptions) -> Vec<SearchResult>
    • Merges results from all layers
    • Deduplicates (higher layer wins)
    • Respects deleted markers
  • get_file_symbols(path: &Path) -> Vec<Symbol>
    • Resolves path through move history
  • resolve_file_path(path: &Path) -> Option<PathBuf>
    • Traces file through renames across layers

Acceptance Criteria

  • Symbol in AI layer shadows same symbol in lower layers
  • Deleted marker in Working layer hides symbol from Base
  • File moves resolve correctly through all layers
  • Search merges and deduplicates across layers

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements layered query resolution for the LayeredIndex with proper layer precedence (AI > Working > Branch > Base), enabling efficient symbol search and retrieval across the layer stack with deduplication.

Key Changes

  • Adds LayeredSearchOptions builder for configuring symbol searches with filters (kind, risk, limit, layers) and case sensitivity
  • Implements search_symbols() method that merges and deduplicates results across all layers, respecting deletion markers
  • Adds get_file_symbols() with file move resolution through the layer chain
  • Includes comprehensive test coverage (31 new tests) covering TDD requirements and edge cases
  • Fixes grammar bug in UpdateStrategy::description() (singular vs plural "file"/"files")

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/overlay.rs Implements core layered query resolution with LayeredSearchOptions, LayeredSearchResult, and search methods (search_symbols, get_file_symbols, resolve_symbol_with_layer, total_active_symbols). Includes 31 comprehensive tests.
src/lib.rs Re-exports new public types LayeredSearchOptions and LayeredSearchResult
src/drift.rs Fixes test for UpdateStrategy::description() to properly verify singular/plural grammar

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix doc comments: "fn" → "function" to match SymbolKind::as_str()
- Remove unused `module` field from LayeredSearchOptions
- Remove dead `with_module()` method (was silently ignored)
- Remove obsolete comment about module filtering

The module filter was defined but never implemented in search_symbols().
Module filtering belongs at the cache/shard level, not LayeredIndex.
@Kadajett Kadajett merged commit d1529eb into main Dec 5, 2025
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