Skip to content

fix: handle root scope in shared search#70

Open
VooDisss wants to merge 1 commit intouserFRM:mainfrom
VooDisss:fix_dot_root_plan_change
Open

fix: handle root scope in shared search#70
VooDisss wants to merge 1 commit intouserFRM:mainfrom
VooDisss:fix_dot_root_plan_change

Conversation

@VooDisss
Copy link
Copy Markdown
Contributor

@VooDisss VooDisss commented Apr 8, 2026

PR: Fix root scope handling for plan_change and shared scoped search

Summary

This change fixes root-scope handling in shared navigation search so plan_change(scope=".") and plan_change(scope="") behave like unscoped repository-root searches.

The fix is intentionally placed in the shared scoped-search helper rather than in MCP glue or planner-specific logic, so all downstream search consumers inherit consistent scope semantics.

Problem

plan_change could return No relevant entities found when called with scope=".", even though the same query succeeded with no scope or with an explicit semantic path.

That happened because the shared scope collector treated . as a literal hierarchy path instead of a repository-root alias.

What Changed

Production code

Updated crates/rpg-nav/src/search.rs:

  • whole-input scope.trim() equal to "." or "" now maps to the full graph
  • a literal "." segment inside comma-separated scopes also maps to the full graph
  • empty comma-separated fragments are ignored instead of widening scope unexpectedly

This keeps existing multi-scope union behavior intact while making root scope work consistently.

Tests

Added shared search-layer regressions in crates/rpg-nav/tests/search.rs:

  • test_root_scope_matches_unscoped_search
  • test_multi_scope_with_empty_segment_does_not_widen

Added planner-level symptom coverage in crates/rpg-nav/src/planner.rs:

  • test_plan_root_scope_matches_unscoped_search

Why This Approach

The bug was caused by shared scope interpretation, not by MCP parameter parsing.

Fixing it in rpg-nav search has a few advantages:

  • one fix applies to all shared scoped-search consumers
  • no duplicated normalization in higher layers
  • planner and MCP behavior stay simple
  • future search-based features inherit the same root-scope semantics automatically

Validation

Targeted local tests

Passed:

cargo test -p rpg-nav test_root_scope_matches_unscoped_search -- --exact
cargo test -p rpg-nav test_multi_scope_with_empty_segment_does_not_widen -- --exact
cargo test -p rpg-nav test_plan_root_scope_matches_unscoped_search -- --exact

Workspace checks

Passed:

cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings

Note: full cargo test --workspace can be blocked on Windows when the worktree-built rpg-mcp-server.exe is actively running, because Cargo cannot replace the locked executable. When the MCP server process is stopped, the workspace test run can proceed normally.

Live MCP verification

Verified against the rebuilt rpg_development MCP server:

plan_change(goal="compute modification order assess impact radius", scope=".", max_entities=12)
plan_change(goal="compute modification order assess impact radius", scope="", max_entities=12)

Both returned valid change plans.

Files Changed

  • crates/rpg-nav/src/search.rs
  • crates/rpg-nav/src/planner.rs
  • crates/rpg-nav/tests/search.rs

Review Notes

  • The fix was intentionally kept out of crates/rpg-mcp/src/tools.rs
  • The final diff is minimal and limited to the shared scope layer plus regressions
  • Independent review passes concluded the patch is non-blocking and in the correct architectural layer

Treat root scope aliases in the shared scoped-search helper so callers like plan_change can search from the repository root with scope='.' or an explicit empty scope. This fixes the failure mode where the shared hierarchy collector treated '.' as a literal hierarchy path and returned no entities, even though the same query succeeded when unscoped or when given a concrete semantic path.

Keep the change in rpg-nav search instead of adding MCP- or planner-specific normalization so all shared search consumers inherit the same behavior automatically. The scope parser now maps whole-input root aliases to the full graph, preserves '.' as a root alias inside comma-separated scope lists, and ignores empty trailing scope fragments so malformed lists do not widen unexpectedly. Add search-layer regressions for root-scope parity and empty-fragment handling, plus a planner-level regression covering the reported user-visible failure mode.
@VooDisss VooDisss force-pushed the fix_dot_root_plan_change branch from ebb5ceb to 53bfb24 Compare April 8, 2026 21:35
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