When refactoring an authentication module, search may find notes about JWT directly, while relation expansion adds context about permissions, refresh jobs, or key management. Being expanded into the result does not mean the current code depends on that note. This constructed scenario shows how to turn retrieval clues into a verification list.
The implementation basis is the embedding search and relation service at fixed commit 7642768. The authentication-refactoring scenario illustrates the method; it is not a measured result.
Establish a direct-hit baseline
Start with a known target query, then repeat with a paraphrase and a no-answer query:
curl --get http://localhost:3721/api/search \
--data-urlencode 'q=JWT authentication token validation' \
--data-urlencode 'limit=5'
The HTTP data array contains note_id, conversation_id, title, project, score, tags, and via_relation. Direct results have no relation marker. Scores already include application candidate, term, and deduplication rules; they are not probabilities or measured dependency strength. Follow each ID to the note and original conversation and record whether it actually concerns the current module.
Turn on one-hop relation expansion
Use expand=true:
curl --get http://localhost:3721/api/search \
--data-urlencode 'q=JWT authentication token validation' \
--data-urlencode 'limit=5' \
--data-urlencode 'expand=true'
The current implementation reads one-hop relations from direct hits and expands only edges with confidence at least 0.5. Linked scores use direct score × 0.7 × confidence. Notes already in the result set are skipped, and expansion can make the total exceed the direct-query limit. It is not multihop traversal and does not find the strongest path for every target.
Turn relation types into investigation questions
Search expands relations in both directions, while via_relation returns only the type. Check source and target in the relation details first, then use the type to ask questions rather than state conclusions:
DEPENDS_ON: find an actual call, shared field, or lifecycle constraint in current code and configuration.LEADS_TO: check whether the downstream behavior is triggered by this step instead of inferring causality from similar topics.RESOLVED_BY: confirm that the old fix’s assumptions still hold in the current version.REFERENCESorSIMILAR_TO: use as reading entrances, not runtime dependency claims.
The relation service considers at most 20 candidates, falls back to recent notes when semantic candidates are unavailable, and filters model output by candidate ID, confidence, and a maximum of five. Graph coverage is therefore bounded by candidate selection and model output; it is not a complete static dependency graph.
Turn hidden dependencies into verification actions
For each indirect candidate, record source evidence, a current code location, and a verification command. Run a test or minimal reproduction and compare behavior before and after the refactor. Recheck assumptions when versions, deployment, or projects differ. Keep no-answer queries and false matches; they reveal retrieval boundaries.
Relation expansion broadens reading, but it does not replace IDE references, code search, tests, or review. For task-memory recall, follow the Claude Code memory workflow; for relation and projection endpoints, see note relations and graph views.