Lazy reference confirmation — restore usages accuracy on demand#266
Merged
Conversation
…ueries Lazy LSP took enrichment off the cold path but degraded find_usages accuracy: the lsp_resolved reference tier those answers rank on was never produced, so a usages query returned only the resolver's heuristic (ast_inferred) edges — or nothing. The fix moves the unit of laziness from the whole-repo enrichment pass to one symbol's reference confirmation. lsp.Provider.ConfirmSymbolRefs(g, repoRoot, node) is the per-symbol unit of the whole-repo confirm + call-hierarchy sweep: it prepares a call hierarchy at the symbol's definition and, for each server-verified incoming call, mints or promotes an lsp_resolved edge via the existing recordHierarchyCall (so every correctness rule — callable-kind match, per-site promotion, declaration identity — is unchanged). find_usages and get_callers call it on the target symbol before answering, lazy-spawning the language server through the router; an in-memory ledger keeps a repeat query free. Verified on an interface-dispatch Go fixture indexed with zero eager LSP: a caller the resolver had only at ast_inferred is upgraded to lsp_resolved/lsp tier by the on-demand gopls call-hierarchy, and the promotion persists. Scope: this lands the per-symbol confirmation (W1 in-memory ledger + W2 fault-in on usages reads). The synchronous-budget/pending-caveat, background convergence, go-types registration gate, and durable ledger are the remaining workstreams.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lazy reference confirmation — restore usages accuracy without the cold-path sweep
Lazy LSP (#265) took enrichment off the cold path but degraded
find_usagesaccuracy — the benchmark caught it: line-recall 1.000 → 0.294 (gin), 0.894 → 0.329 (httpx). Thelsp_resolvedreference tier those answers rank on was never produced (the on-demand path faulted insemantic_typeon reads, not reference edges), so a usages query returned only the resolver's heuristic (ast_inferred) edges — or nothing.Fix: move the unit of laziness from the whole-repo enrichment pass to one symbol's reference confirmation. A
find_usagesanswer for symbol S needs S's callers confirmed — not the whole repo's.lsp.Provider.ConfirmSymbolRefs(g, repoRoot, node)— the per-symbol unit of the confirm + call-hierarchy sweep: prepares a call hierarchy at the symbol's definition and, for each server-verified incoming call, mints or promotes anlsp_resolvededge via the existingrecordHierarchyCall(every correctness rule preserved — callable-kind match, per-site promotion, declaration identity). LSP round-trips unlocked; graph mutations batched under the resolve lock.find_usages/get_callerscall it on the target symbol before answering, lazy-spawning the language server through the router (the same path the diagnostics tools use). An in-memory ledger (refsConfirmed) keeps a repeat query free.Verified
Interface-dispatch Go fixture, indexed with 0 eager LSP passes: the caller
useIt → Impl.Greet, which the resolver had only atast_inferred, is upgraded tolsp_resolved/lsptier by the on-demand gopls call-hierarchy on the firstfind_usages, and the promotion persists.go test -race ./internal/mcp/ ./internal/semantic/lsp/green.Scope — this is the accuracy-restoring core, not the whole spec
Lands per-symbol confirmation (W2) + an in-memory ledger (W1 MVP). Remaining workstreams from the design: synchronous latency budget +
enrichment: pendingcaveat + background completion (W2/W6), background convergence queue (W4), go-types "earn-the-slot-or-yield" registration gate (W5), durable ledger with edit-invalidation (W1 full), and the full gortex-bench acceptance run (gin/httpx recall fence at default config) — my verification is a mechanism fixture, not the benchmark. Call-hierarchy servers (gopls/pyright/rust-analyzer/jdtls) are covered; references-only servers are a follow-up branch in
ConfirmSymbolRefs.