feat: /sessions path command for concept-based session traversal (Phase 3 Task 3.2.2) #12

Open
opened 2026-04-24 05:01:29 +02:00 by product-owner · 0 comments

Problem Statement

Phase 3 Task 3.2.2 of the session-search spec is unchecked: there is no /sessions path command that finds a chain of sessions connecting two starting points via shared concepts. /sessions related { session_id } (line ~2244 of handler.rs) returns direct neighbours of one session, and /sessions concepts { concept } returns sessions sharing a named term, but neither answers the question "show me how session A and session B are connected through the knowledge graph." Without a path surface, /sessions recommend (#9) cannot justify recommendations with an audit trail, and users cannot trace how two pieces of past work relate.

Current State

  • grep SessionsSubcommand::Path returns zero hits in crates/terraphim_agent/.
  • SessionIndex in crates/terraphim_sessions/src/index/ already stores per-session concepts: Vec<String> and per-concept session_ids: Vec<SessionId> inverted lists.
  • RoleGraph (crates/terraphim_rolegraph) exposes BFS/DFS traversal primitives over (concept -> doc -> concept) edges.
  • The commands parser in commands.rs (line ~1317) ends at SessionsSubcommand::Index; no Path variant exists.

Acceptance Criteria

  • New variant SessionsSubcommand::Path { from: String, to: String, max_hops: Option<usize> } added to commands.rs.
  • REPL accepts /sessions path <from_id> <to_id> [--max-hops N] and /sessions path <from_id> <to_id> --format json.
  • Handler in handler.rs performs a bounded BFS over the session-concept bipartite graph and returns an ordered list of PathStep { session_id: SessionId, shared_concepts: Vec<String>, hop: usize }.
  • When no path exists within max_hops (default 5), the response carries an empty steps: [] and meta.reason: "no_path_found" rather than an error envelope.
  • The handler short-circuits and returns steps: [from, to] when the two sessions already share at least one concept.
  • /sessions path respects the existing OutputMode (interactive table vs JSON envelope).
  • cargo test -p terraphim_sessions --lib search::path passes.
  • cargo test -p terraphim_agent --features repl-full handler_path passes.
  • cargo clippy --workspace -- -D warnings passes.

Proposed Approach

  1. Add find_path(&self, from: SessionId, to: SessionId, max_hops: usize) -> Option<Vec<PathStep>> to terraphim_sessions::search or a new terraphim_sessions::path module.
  2. Use BFS with a visited set on SessionId; expand neighbours via the concept inverted index; prefer neighbours with the highest concept overlap.
  3. Add SessionsSubcommand::Path and REPL wiring in commands.rs + handler.rs.
  4. Render interactive output as an indented table; render JSON output as { steps: [...], meta: { total_hops, total_concepts_shared } }.
  5. Add unit tests using a small hand-built SessionIndex fixture (3-4 sessions, known shortest path).

Files affected:

  • crates/terraphim_sessions/src/search.rs or new crates/terraphim_sessions/src/path.rs (~150 LOC)
  • crates/terraphim_agent/src/repl/commands.rs (~30 LOC variant + parser)
  • crates/terraphim_agent/src/repl/handler.rs (~80 LOC handler)

Dependencies

Depends on Task 3.1 (Session Enrichment Pipeline): sessions must have concept annotations for the path search to traverse. If 3.1 is still in flight, a fallback path search on raw tokens can ship first.

Blocks: F5.3 bullet three in #9 (/sessions recommend with path-based justification).

Verification

cargo test -p terraphim_sessions --lib path
cargo test -p terraphim_agent --features repl-full --test sessions_path_tests
cargo clippy -p terraphim_sessions -p terraphim_agent -- -D warnings
./target/debug/terraphim-agent --format json sessions path <id1> <id2> --max-hops 4 | jq .

Scope

Single PR, estimated 300-400 LOC including tests. Completes Phase 3 Task 3.2.2.

Upstream: Implements docs/specifications/terraphim-agent-session-search-tasks.md Phase 3 Task 3.2.2 for terraphim/terraphim-ai.

## Problem Statement Phase 3 Task 3.2.2 of the session-search spec is unchecked: there is no `/sessions path` command that finds a chain of sessions connecting two starting points via shared concepts. `/sessions related { session_id }` (line ~2244 of `handler.rs`) returns direct neighbours of one session, and `/sessions concepts { concept }` returns sessions sharing a named term, but neither answers the question "show me how session A and session B are connected through the knowledge graph." Without a path surface, `/sessions recommend` (#9) cannot justify recommendations with an audit trail, and users cannot trace how two pieces of past work relate. ## Current State - `grep SessionsSubcommand::Path` returns zero hits in `crates/terraphim_agent/`. - `SessionIndex` in `crates/terraphim_sessions/src/index/` already stores per-session `concepts: Vec<String>` and per-concept `session_ids: Vec<SessionId>` inverted lists. - `RoleGraph` (`crates/terraphim_rolegraph`) exposes BFS/DFS traversal primitives over `(concept -> doc -> concept)` edges. - The commands parser in `commands.rs` (line ~1317) ends at `SessionsSubcommand::Index`; no `Path` variant exists. ## Acceptance Criteria - [ ] New variant `SessionsSubcommand::Path { from: String, to: String, max_hops: Option<usize> }` added to `commands.rs`. - [ ] REPL accepts `/sessions path <from_id> <to_id> [--max-hops N]` and `/sessions path <from_id> <to_id> --format json`. - [ ] Handler in `handler.rs` performs a bounded BFS over the session-concept bipartite graph and returns an ordered list of `PathStep { session_id: SessionId, shared_concepts: Vec<String>, hop: usize }`. - [ ] When no path exists within `max_hops` (default 5), the response carries an empty `steps: []` and `meta.reason: "no_path_found"` rather than an error envelope. - [ ] The handler short-circuits and returns `steps: [from, to]` when the two sessions already share at least one concept. - [ ] `/sessions path` respects the existing `OutputMode` (interactive table vs JSON envelope). - [ ] `cargo test -p terraphim_sessions --lib search::path` passes. - [ ] `cargo test -p terraphim_agent --features repl-full handler_path` passes. - [ ] `cargo clippy --workspace -- -D warnings` passes. ## Proposed Approach 1. Add `find_path(&self, from: SessionId, to: SessionId, max_hops: usize) -> Option<Vec<PathStep>>` to `terraphim_sessions::search` or a new `terraphim_sessions::path` module. 2. Use BFS with a visited set on `SessionId`; expand neighbours via the concept inverted index; prefer neighbours with the highest concept overlap. 3. Add `SessionsSubcommand::Path` and REPL wiring in `commands.rs` + `handler.rs`. 4. Render interactive output as an indented table; render JSON output as `{ steps: [...], meta: { total_hops, total_concepts_shared } }`. 5. Add unit tests using a small hand-built `SessionIndex` fixture (3-4 sessions, known shortest path). Files affected: - `crates/terraphim_sessions/src/search.rs` or new `crates/terraphim_sessions/src/path.rs` (~150 LOC) - `crates/terraphim_agent/src/repl/commands.rs` (~30 LOC variant + parser) - `crates/terraphim_agent/src/repl/handler.rs` (~80 LOC handler) ## Dependencies Depends on Task 3.1 (Session Enrichment Pipeline): sessions must have concept annotations for the path search to traverse. If 3.1 is still in flight, a fallback path search on raw tokens can ship first. Blocks: F5.3 bullet three in #9 (`/sessions recommend` with path-based justification). ## Verification ```bash cargo test -p terraphim_sessions --lib path cargo test -p terraphim_agent --features repl-full --test sessions_path_tests cargo clippy -p terraphim_sessions -p terraphim_agent -- -D warnings ./target/debug/terraphim-agent --format json sessions path <id1> <id2> --max-hops 4 | jq . ``` ## Scope Single PR, estimated 300-400 LOC including tests. Completes Phase 3 Task 3.2.2. Upstream: Implements `docs/specifications/terraphim-agent-session-search-tasks.md` Phase 3 Task 3.2.2 for terraphim/terraphim-ai.
Sign in to join this conversation.