Skip to content

Startup responsiveness — audit fix plan (tracking issue with TODOs) #297

Description

@msarson

Single tracking issue for the remaining fixes from the multi-agent startup-chain audit (report: docs/audits/startup-chain-audit-2026-07-09.md, findings JSON alongside; 64 agents, 39 confirmed findings). Symptoms: tree spinner on project expansion, Structure view spin on tab switch, general unresponsiveness in the first minutes after opening a large solution. Ranked diagnosis (details + evidence in the report): - H1 — server request-queue saturation during the first minutes, doubled by the duplicate startup pipeline (findFile storms, didOpen force-open storm, per-lens CodeLens FAR scans). - H2 — every tree refresh rebuilds the root with fresh nodes, discarding cached children → getProjectFiles re-issued for expanded projects (why the cached-children early-return didn't help). - H3 — Structure-view generation race: tab switch clears symbols, a second fetch 100ms later discards the one that renders → blank/spin whenever the server isn't instant. ## Surgical fixes (each <1h, low risk — file:line targets in report §2a) - [x] 1. Tree: carry over node.children keyed by project GUID across root rebuilds; set TreeItem.id (SolutionTreeDataProvider.ts:1374-1409) — kills H2 � done in 624a4f9 - [x] 2. Single-source startup completion: eager path disposes the solutionReady handler / latch (SolutionInitializer.ts:427-433) — halves H1 � done in 624a4f9 - [x] 3. beginActivationRefresh() BEFORE refreshSolutionTreeView(); try/finally around markActivationComplete() (SolutionInitializer.ts:343-350) � done in 624a4f9 - [x] 4. Structure view: don't clear _lastKnownSymbols on tab switch; single-flight per (uri,version); discard path awaits the winning fetch (StructureViewProvider.ts:91, 811) — kills H3 � done in c16d3ca - [x] 5. revealActiveSelection must not bump the symbol-request generation or issue its own fetch (StructureViewProvider.ts:256) � done in c16d3ca - [x] 6. symbolsRefreshed notification: refresh only when uri matches the active editor; consider dropping the didOpen-side notification (LanguageServerManager.ts:206, server.ts:528) � done in c16d3ca - [x] 7. Server findFile: negative-cache misses + in-flight coalescing + first-hit early exit prioritising the requester's project (solutionManager.ts:538-546) — biggest server-queue win � done in 6b3e84c - [x] 8. CodeLens resolve: propagate LSP CancellationToken into provideReferences + 200-500ms wall-clock budget; linked-token cancel for the 15s race (server.ts:871-922, :2390) � done in 10b4b0f - [x] 9. Delete the no-op refreshOpenDocuments(undefined) costing 0.9-1.6s of awaited activation (ActivationManager.ts:223) � done in 10b4b0f - [x] 10. Stop force-opening session-restored tabs — iterate workspace.textDocuments only (ExtensionHelpers.ts:36-44) � done in 10b4b0f - [x] 11. Tree getChildren: ~5s timeout + retryable error node + in-flight dedup per projectGuid (SolutionTreeDataProvider.ts:508, :576) � done in acaa7f8 - [x] 12. Fix DocumentManager module-var leak in the wrapper (extension.ts:295) � done in 10b4b0f - [x] 13. Tree getTreeItem: set openFile command up front, resolve path lazily in the command handler — removes fire-and-forget findFile per node AND fixes dead clicks (SolutionTreeDataProvider.ts:1088) � done in 624a4f9 - [x] 14. Decisive experiment (do early): LSP dispatch-queue wrapper logging {method, queue-wait, self-time} per request for the first 3 minutes (~20 lines, server.ts) — arbitrates H1/H2/H3 residuals conclusively (report §3) � done in 3237f94 ## Structural fixes (report §2b) - [x] S1. One startup pipeline: clarion/solutionReady as the sole completion driver; remove the eager 15s-race fetch, the 1s sleep, the duplicate getSolutionTree registration; shared in-flight fetch promise � done in 001ee85 (duplicate registration removed, 1s sleep deleted, shared in-flight fetch; the eager fetch itself is KEPT � it now renders the tree in ~2s and dedup makes it free) - [ ] S2. Replace the activation boolean with refcounted/token-scoped suppression gated on a server clarion/indexingReady signal � parked pre-1.0.0: refactor with regression surface; current VM captures no longer implicate the activation boolean (try/finally hardened in fix 3) - [ ] S3. Batch clarion/findFiles (one request per document) + server-side O(1) basename index replacing the 40-project fan-out + client O(1) map + async probes + global negative cache � partially shipped (negative cache + coalescing + early exit in 6b3e84c); O(1) basename index + batched findFiles ride with #294/#295 - [ ] S4. Inverted reference index → CodeLens resolve O(1), removes per-lens FAR (#294); lower cooperativeScan FILES_PER_YIELD 25→5 or time-based checkpoint � yield-interval part shipped (acaa7f8); the inverted reference index IS #294 - [x] S5. Version-keyed documentSymbol caching on both ends � done in 001ee85 (server-side; client side already covered by the fix-4 single-flight) - [ ] S6. Debounced, targeted watcher handling; in-place DocumentManager rescan instead of dispose/recreate � parked pre-1.0.0: same rationale; matters most on regenerated-files workflows, revisit with #295 ## Pre-1.0.0-release checklist (carried from the perf campaign) - [x] Decide perf-log verbosity for the marketplace build — decided in 10debe4, revised in c3cf3a5 per Mark: perf channels are OPT-IN via the new clarion.log.performance.enabled setting (default off; instrumentation always runs, only output gated — flip the setting + reload for the full support timeline); DocumentRefreshManager + StructureViewProvider info chatter drop to errors-only - [x] Tighten .vscodeignore — done in 10debe4: .mcp.json(+.bak), .claude/, .husky/, .clarion-debug/, esbuild.mjs, .mocharc-client.json, scripts/, package-locks all excluded; VSIX now 24 files Related (kept separate, referenced): #291 (remove blocking progress toast), #292 (dll-module diagnostic false positive), #294 (inverted reference index), #295 (off-thread indexing architecture), #296 (tree provider defects — items 1/11/13 above overlap; close together).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions