Skip to content

fix(lsp): resolve the 0.14 mutex/latency regression — Phase 0 containment + Phase 1 bounded ingress - #4000

Merged
rossirpaulo merged 7 commits into
canaryfrom
paulo/lsp-latency-mutex-full
Jul 13, 2026
Merged

rossirpaulo merged 7 commits into
canaryfrom
paulo/lsp-latency-mutex-full

Conversation

@rossirpaulo

@rossirpaulo rossirpaulo commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

Combines #3969 (Phase 0) and #3976 (Phase 1) into one PR against canary, with latest canary merged in (including the #3965 session-token removal and #3973 test-metadata work, both semantically reconciled). Supersedes both stacked PRs. Implements docs/design/lsp-latency-and-mutex-fix.md (committed in this PR) through Phase 1; Phase 2 (salsa snapshot reads) remains behind the doc's spike gate.

Root cause

The 0.14.0 debounced engine rebuild holds the project DB mutex across compiles while try_lock_db maps any contention to -32001; stale build candidates could install over newer edits, busy diagnostic reads looked empty, and playground/browser routing could leak stale session output.

Phase 0 — correctness containment (from #3969)

  • Monotonic SourceRevision; owned compilation/diagnostic/engine candidates; revision-conditional engine commit through the same gate as source mutations — stale installs impossible by construction (rendezvous-tested at the exact commit boundary).
  • DiagnosticsFence judging staleness against the authoritative revision: a superseded rebuild's late diagnostics or a candidate racing mark_dirty can never regress newer markers.
  • Bounded request-lane waits (1s) mapping to typed errors — ContentModified/RequestFailed; -32001 is never emitted. Busy is never conflated with empty; poison is terminal.
  • Salsa-memoized file_annotations/semantic_tokens; 150/300 ms debounced tails; single-flight rebuilds; UTF-8/UTF-16 PositionCodec (C1).

Phase 1 — bounded ingress, cancellation, client gating (from #3976)

  • IngressScheduler + LspRuntime in baml_lsp_server: stdio and browser LSP sessions through one bounded scheduler (per-class byte/item budgets, lifecycle barriers, response ownership); $/cancelRequest handled on the transport thread — queued requests answer -32800, running cancellable requests observe a dispatch-scoped token (entry + post-source-guard safe points; never salsa unwinding); browser takeover tombstones the old session's sink and replays overlays.
  • Hardened framing/output: 16 KiB header cap; oversized messages/responses degrade per-message (-32803) instead of killing the session/process; serialize-once shared outbound frames with accurate budget accounting; connection-scoped sessions (per-connection encoding negotiation).
  • Playground run-gating (D6): during rebuild windows (is_bex_current == false or a projectNotReady rejection) Run/test/preview disable with "Preparing current build…" and re-enable on the next current update — no protocol version bump. Closes the fail-closed D7 UX window Phase 0 introduces.
  • Reconnect correctness: fail-closed hello; bounded first-connect queue; session-scoped commands never replay into a new session (synthesized rejections); the desired-runtime lease survives reconnects.
  • Track A: canonical multi-root ownership (projectRoots.ts) + routing; closing the last .baml document no longer stops the owner server; aggregate status preserves startup failures.

Measured (same harness/machine, 400 generated functions)

Metric 0.14.1 (regressed) this PR
Typing inlayHint p50 / p95 313.6 / 379.4 ms ~2 / ~52 ms
Post-pause -32001 failures 46–57 per feature/window 0
Unanswered requests 144–160 0
Rebuild-window inlay/hover/completion mass failures 218/218 each
Explicit $/cancelRequest rejected/ignored -32800
Refresh storms per 10-edit burst — 0

Deliberately not included

  • Phase 2 salsa snapshots (removes the residual post-pause hitch on very large projects): gated by the design doc's own spike-and-signoff decision — panic=abort release profile vs salsa's unwinding cancellation must be resolved first.
  • D5 demand-gating server side: client seam ships dormant (typed + tested, nothing sends it).
  • The alternate implementation's five-lock core rewrite (redundant with Phase 0's invariants), playground protocol-v3 lockstep (compat hazard; equivalent wire-compatible fixes included), and stdlib testing.* API additions (unauthorized surface).

Validation

  • bex_project 45/45 (+1 pre-existing ignored) incl. commit-boundary rendezvous, fence, bounded-wait classification; baml_lsp_server 64/64 (22 scheduler, 9 runtime, framing/budget); workspace cargo check --lib clean; clippy -D warnings clean; wasm check clean.
  • TS: playground 125/125, extension 13/13, webview 19/19 (incl. gating), all typechecks.
  • Latency harness re-run on this exact merged head (numbers above).

🤖 Generated with Claude Code

https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo

Summary by CodeRabbit

  • New Features

    • Improved LSP responsiveness and stability with bounded messaging, cancellation handling, session recovery, and safer browser takeover behavior.
    • Added negotiated UTF-8/UTF-16 position handling for more accurate diagnostics, ranges, formatting, and semantic highlighting.
    • Added project-aware VS Code routing for nested projects, symlinks, and changing project markers.
    • Added runtime leasing support for playground connections.
  • Bug Fixes

    • Prevented runs and tests from starting while a project build is stale or unavailable, with clearer preparation feedback.
    • Improved cancellation, error reporting, diagnostics updates, and run generation consistency.
  • Documentation

    • Expanded contributor and Rust workspace setup, testing, formatting, and debugging guidance.

rossirpaulo and others added 7 commits July 10, 2026 12:39
Implement the LSP server rebuild pipeline from docs/design/lsp-latency-and-mutex-fix.md:
source revision and owned candidates, revision-conditional engine commits,
versioned diagnostics fencing, bounded request waits with typed LSP errors,
negotiated position encoding, debounced native tails, and coherent run/test
snapshots. Memoize inlay hints and semantic tokens as Salsa queries.
- DiagnosticsFence::admit now compares candidates against the live
  source revision (read under the fence lock), so a superseded rebuild's
  diagnostics or a candidate racing mark_dirty can never regress markers
  a newer revision already published (design 0B "Ready(stale revision)
  -> discard"; acceptance: no v7 publication after v8 arrives).
- Add a commit_engine_if_current_with_hook seam and port the
  commit-boundary rendezvous test: an edit placed exactly against the
  conditional commit is serialized after it and immediately makes the
  installed engine non-current.
- Extract classify_request_timeout and cover the request lane's timeout
  classification (revision moved -> ContentModified-stale; unchanged ->
  congestion) with channel-sequenced tests, no sleep margins.
- Correct false lock/revision comments: run_cfgs is a leaf mutex taken
  under the source gate in prepare_function_run; the source revision
  advances on every applied batch; playground cancel is best-effort and
  cannot reach a run pinned to a superseded engine (D8 registration
  deferred).

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo
Semantic conflict fix: canary's #3973 added list_tests_with_metadata(db)
in build_project_update, where this branch replaced the raw db binding
with the source-guard read. The tests listing now rides the same guard
as the functions listing, so the payload stays one coherent snapshot.
…gating

Rust (stacked on the Phase 0 core):
- IngressScheduler (transport-neutral admission/lifecycle/cancellation/
  budget state machine) relocated into baml_lsp_server, with fixes: forced
  cancellation of protected methods can no longer be downgraded; permanent
  oversize is contained per-message (-32803) instead of closing the
  session; oversized $/cancelRequest no longer livelocks the control lane;
  pipelined `initialized` is admitted FIFO and accepted at dispatch.
- New LspRuntime: stdio and browser LSP sessions dispatch through one
  scheduler; cancellation drained on the transport thread claims responses
  while handlers run ($/cancelRequest -> -32800); browser takeover revokes
  the old session's sink and replays document overlays; bounded outbound
  budgets with serialize-once shared frames.
- Bounded stdio framing: 16 KiB header cap; oversized bodies discarded in
  chunks with a recoverable typed error; abnormal exit is nonzero.
- bex_project kept minimal: LspError::RequestCanceled (-32800) at the one
  serialization boundary (I7); dispatch-scoped cancellation token checked
  at handler entry and after the source guard (never Salsa unwinding);
  connection-scoped LSP sessions (fresh encoding negotiation + workspace
  roots per connection, shared project registry).

TypeScript:
- D6 playground run-gating on is_bex_current: Run/test/preview disabled
  with a "Preparing current build..." state during rebuild windows;
  projectNotReady rejections render as that transient state and clear on
  the next current ProjectUpdate (no protocol version bump).
- WebSocketRuntimePort reconnect correctness: fail-closed hello, bounded
  first-connect queue, session-scoped commands dropped on disconnect with
  synthesized rejections, desired-runtime lease resent after every hello.
- Track A: projectRoots.ts canonical multi-root ownership + routing in the
  VS Code extension; closing the last document no longer stops the owner
  server; aggregate status preserves startup failures.

Verification: baml_lsp_server 67/67, bex_project 45/45 (+1 pre-existing
ignored), clippy -D warnings clean, wasm check clean; playground 125/125,
extension 13/13, webview 19/19, all typechecks green. Harness (400 fns):
$/cancelRequest now answers -32800; typing inlay p50 2.0 ms, p95 51.7 ms,
zero errors, zero unanswered requests.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo
Drive-less file:///tmp URIs fail Url::to_file_path on Windows, so
canonical_document_identity_str returned None and the test panicked
on the Windows CI runner only.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo
…utex-full

# Conflicts:
#	typescript2/pkg-playground/src/ports/WebSocketRuntimePort.ts
@vercel

vercel Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 13, 2026 8:50pm
promptfiddle Ready Ready Preview, Comment Jul 13, 2026 8:50pm
promptfiddle2 Ready Ready Preview, Comment Jul 13, 2026 8:50pm

Request Review

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR restructures Rust LSP transport, project rebuild, diagnostics, cancellation, and position handling; adds VS Code ownership routing; introduces reconnect-safe playground runtime leases and fail-closed execution controls; memoizes LSP tokens and annotations; and updates contributor documentation.

Changes

LSP transport and project runtime

Layer / File(s) Summary
Bounded transport and ingress runtime
baml_language/crates/baml_lsp_server/src/{lib.rs,lsp_ingress.rs,lsp_runtime.rs,native_lsp_sender.rs}
Adds bounded JSON-RPC framing, ingress admission, cancellation control, response ownership, session takeover, and revocable outbound sinks.
Revision-fenced project pipeline
baml_language/crates/bex_project/src/{project.rs,bex_lsp/...}
Adds source revisions, conditional engine commits, fenced test leases, typed LSP errors, cancellation-aware requests, and negotiated position codecs.
Playground transport integration
baml_language/crates/baml_lsp_server/src/playground_server.rs
Routes browser sessions through LspRuntime, uses bounded response queues, and targets run cancellation by engine generation.

VS Code ownership routing

Layer / File(s) Summary
Canonical project resolution
typescript2/app-vscode-ext/src/projectRoots.ts, typescript2/app-vscode-ext/src/__tests__/projectRoots.test.ts
Adds canonical path identities, semantic and ownership root resolution, symlink handling, and routable ownership patterns.
Per-owner language clients
typescript2/app-vscode-ext/src/extension.ts
Adds OwnershipCoordinator for document routing, marker topology migration, per-owner clients, and watcher lifecycle management.

Playground readiness and protocol

Layer / File(s) Summary
Reconnect-safe runtime transport
typescript2/pkg-playground/src/ports/WebSocketRuntimePort.ts, typescript2/pkg-playground/src/worker-protocol.ts
Adds fail-closed handshakes, bounded pre-handshake queues, structured command errors, and standing project-runtime leases.
Fail-closed execution UI
typescript2/pkg-playground/src/{ExecutionPanel.tsx,FunctionSidebar.tsx,run-gating.ts,run-store-client.ts}
Tracks not-ready projects, disables runtime actions until current updates arrive, and handles projectNotReady errors without exposing raw command failures.

Supporting Rust tooling and documentation

Layer / File(s) Summary
Memoized language features
baml_language/crates/baml_lsp2_actions/src/*
Converts annotations and semantic tokens to Salsa tracked queries and updates their consumers.
Contributor guidance
CONTRIBUTING.md, README-DEV.md, baml_language/TEST_INSTRUCTIONS.md, docs/design/lsp-latency-and-mutex-fix.md
Documents Rust setup, test commands, formatting, LSP test workflows, and the latency/mutex design contract.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant WebSocketRuntimePort
  participant LspRuntime
  participant IngressScheduler
  participant BexProject
  participant ExecutionPanel
  Client->>WebSocketRuntimePort: send command or LSP frame
  WebSocketRuntimePort->>LspRuntime: submit after compatible hello
  LspRuntime->>IngressScheduler: admit and dispatch
  IngressScheduler->>BexProject: execute request or update
  BexProject-->>LspRuntime: response or project update
  LspRuntime-->>ExecutionPanel: project readiness notification
  ExecutionPanel-->>Client: enable or disable runtime controls
Loading

Possibly related PRs

Suggested reviewers: hellovai, aaronvg, codeshaunted, 2kai2kai2, sxlijin

Poem

A rabbit queues frames in the moonlit byte,
Rebuilds hop safely from stale to right.
Projects wear leashes, clients route with care,
Runs wait politely till builds are fair.
“Hello!” says the socket; gates glow green—
Then carrots compile in a bounded machine.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main LSP latency/mutex fix and accurately mentions the Phase 0 and Phase 1 scope.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch paulo/lsp-latency-mutex-full

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 13, 2026 20:37 Inactive
@github-actions

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 22.0 MB 9.4 MB file 21.5 MB +504.8 KB (+2.3%) OK
✅ packed-program Linux 🔒 15.8 MB 6.7 MB file 15.6 MB +200.1 KB (+1.3%) OK
✅ baml-cli macOS 🔒 16.9 MB 8.2 MB file 16.6 MB +382.7 KB (+2.3%) OK
✅ packed-program macOS 🔒 12.2 MB 5.9 MB file 12.1 MB +117.2 KB (+1.0%) OK
✅ baml-cli Windows 🔒 18.5 MB 8.4 MB file 18.1 MB +396.3 KB (+2.2%) OK
✅ packed-program Windows 🔒 13.1 MB 6.0 MB file 13.0 MB +113.1 KB (+0.9%) OK
✅ bridge_wasm WASM 14.6 MB 🔒 4.1 MB gzip 4.1 MB +77.0 KB (+1.9%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 13, 2026 20:50 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs (1)

585-617: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Rebuilding PositionCodec per result instead of per file.

Both on_request_text_document_references and on_request_workspace_symbol construct a new PositionCodec::new(...) (which scans the whole target file to build the line index) for every usage/symbol in the result set, instead of once per distinct target file. When many results land in the same file, this repeats an O(file size) scan unnecessarily — a needless latency cost in exactly the kind of hot path this PR is targeting. on_request_text_document_document_symbol and compute_on_position in the same file already show the right pattern (build once, reuse).

Cache codecs by FileId/path within each handler's loop and reuse them across results from the same file.

Also applies to: 655-709

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs` around
lines 585 - 617, Cache the PositionCodec instances in
on_request_text_document_references and on_request_workspace_symbol by target
FileId or path, creating each codec only once per distinct file and reusing it
for all matching results. Preserve the existing URI and range conversion
behavior while avoiding repeated whole-file scans within each handler.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs`:
- Around line 585-617: Cache the PositionCodec instances in
on_request_text_document_references and on_request_workspace_symbol by target
FileId or path, creating each codec only once per distinct file and reusing it
for all matching results. Preserve the existing URI and range conversion
behavior while avoiding repeated whole-file scans within each handler.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 934e8697-1131-403f-9702-deaeb25356e9

📥 Commits

Reviewing files that changed from the base of the PR and between 50301c7 and a203ee4.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (42)
  • CONTRIBUTING.md
  • README-DEV.md
  • baml_language/TEST_INSTRUCTIONS.md
  • baml_language/crates/baml_cli/src/paint.rs
  • baml_language/crates/baml_lsp2_actions/src/annotations.rs
  • baml_language/crates/baml_lsp2_actions/src/lib.rs
  • baml_language/crates/baml_lsp2_actions/src/tokens.rs
  • baml_language/crates/baml_lsp2_actions_tests/src/runner.rs
  • baml_language/crates/baml_lsp_server/Cargo.toml
  • baml_language/crates/baml_lsp_server/src/lib.rs
  • baml_language/crates/baml_lsp_server/src/lsp_ingress.rs
  • baml_language/crates/baml_lsp_server/src/lsp_runtime.rs
  • baml_language/crates/baml_lsp_server/src/native_lsp_sender.rs
  • baml_language/crates/baml_lsp_server/src/playground_server.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_project/Cargo.toml
  • baml_language/crates/bex_project/src/bex_lsp/mod.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/diagnostics.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/notification.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/request.rs
  • baml_language/crates/bex_project/src/bex_lsp/notification.rs
  • baml_language/crates/bex_project/src/bex_lsp/position_codec.rs
  • baml_language/crates/bex_project/src/bex_lsp/request.rs
  • baml_language/crates/bex_project/src/bex_lsp/request_cancellation.rs
  • baml_language/crates/bex_project/src/lib.rs
  • baml_language/crates/bex_project/src/project.rs
  • docs/design/lsp-latency-and-mutex-fix.md
  • typescript2/app-promptfiddle/src/playground/baml-lsp-worker.ts
  • typescript2/app-vscode-ext/src/__tests__/projectRoots.test.ts
  • typescript2/app-vscode-ext/src/extension.ts
  • typescript2/app-vscode-ext/src/projectRoots.ts
  • typescript2/app-vscode-webview/src/ExecutionPanel.gating.test.tsx
  • typescript2/pkg-playground/src/ExecutionPanel.tsx
  • typescript2/pkg-playground/src/FunctionSidebar.tsx
  • typescript2/pkg-playground/src/ports/WebSocketRuntimePort.test.ts
  • typescript2/pkg-playground/src/ports/WebSocketRuntimePort.ts
  • typescript2/pkg-playground/src/run-gating.test.ts
  • typescript2/pkg-playground/src/run-gating.ts
  • typescript2/pkg-playground/src/run-store-client.test.ts
  • typescript2/pkg-playground/src/run-store-client.ts
  • typescript2/pkg-playground/src/worker-protocol.ts

meefs pushed a commit to meefs/baml that referenced this pull request Jul 13, 2026
… first (BoundaryML#4002)

Clean revert of a05ec5a (BoundaryML#3867, "resolution-first semantic tokens
rework"), coordinated with @codeshaunted.

## Why
BoundaryML#3867 merged ~30 minutes after BoundaryML#4000 (the LSP mutex/latency fix:
position-encoding negotiation, connection-scoped sessions, bounded
ingress) opened, and the two rework the same LSP boundary. Landing order
matters: BoundaryML#4000 is the infrastructure BoundaryML#3867's feature should sit on.
Integrating BoundaryML#3867 inside BoundaryML#4000's merge would mean rewriting its encoder
and cache inside a merge commit — worse for review and for feature
ownership. Reverting and re-landing on top is cleaner for everyone.

The revert also removes a live encoding issue from canary until the
re-land: `encode_semantic_tokens` currently emits fixed-encoding
positions (`LineIndex`) and **byte** lengths, which miscounts any
non-ASCII identifier under the LSP-default UTF-16.

## Re-land guidance (agreed with Avery)
The classification engine (resolution index, CST walk,
`tools_semantic_tokens` visualizer) re-lands byte-for-byte. Only the LSP
boundary adapts:
1. Encode positions **and lengths** via the negotiated `PositionCodec`
(available at every handler after BoundaryML#4000) instead of `LineIndex` + byte
lengths.
2. Move `semantic_tokens_cache` into connection-scoped session state —
sessions are per-connection with per-connection encodings after BoundaryML#4000,
so a process-global cache would cross-serve wrongly-encoded tokens and
trample delta baselines. The atomic result-id sequence can stay global.
3. Optional: `returns(ref)` instead of `returns(clone)` on the tracked
query to avoid an O(tokens) clone per request;
`handle_request_with_cancellation` for the new handlers.

## Sequence
1. This revert merges.
2. BoundaryML#4000 folds in canary (now conflict-free) and merges.
3. BoundaryML#3867 re-lands adapted — we're happy to prep the integration branch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for highlighting `dynamic`, `with`, and `throws` syntax.
- Improved semantic highlighting for names, types, members, strings,
numbers, and multi-part paths.

- **Bug Fixes**
- Updated catch-clause bindings to provide more consistent navigation
and local-variable handling.
- Adjusted parsing and formatting for contextual keywords such as `as`
and `type`.
  - Corrected hover information for catch bindings.

- **Breaking Changes**
- Semantic tokens no longer include modifiers or range/delta responses.
- Boolean and null values are no longer represented as literal semantic
tokens.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@rossirpaulo
rossirpaulo added this pull request to the merge queue Jul 13, 2026
meefs pushed a commit to meefs/baml that referenced this pull request Jul 13, 2026
…oundaryML#3867) (BoundaryML#4005)

Stacked on BoundaryML#4002 (retargets to canary when it merges). Re-applies the
one change in BoundaryML#3867 that was a standalone bug fix rather than part of
the semantic-tokens feature, so the revert doesn't reintroduce it —
addressing CodeRabbit's Critical finding on BoundaryML#4002.

`find_token_after_hashes` could return the one-past-the-end index after
a hash run at EOF, and `parse_raw_string` indexed `tokens` with it
directly — a panic on incomplete input like a bare `##` at end of file,
present on canary long before BoundaryML#3867. Under the new LSP core (BoundaryML#4000) a
parser panic on the source path additionally poisons the project into a
terminal broken state, so this class matters more now.

Both hunks are byte-for-byte @codeshaunted's fix from BoundaryML#3867 (credited as
co-author). New here: the regression test the original lacked — verified
to panic (`index out of bounds: the len is 15 but the index is 15`) with
the guards removed, and covering bare `#`/`##` at top level, inside
expression bodies, and after `let`.

Validation: `cargo test -p baml_compiler_parser` 140/140 (139
pre-existing + the new test), clippy `-D warnings` clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved handling of incomplete raw-string syntax at end-of-file.
* Prevented unexpected parser crashes when inputs end with standalone
hash characters.
* Malformed inputs (including truncated bare-hash sequences) now return
parse errors instead of failing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Avery Townsend <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Merged via the queue into canary with commit 30eb1c1 Jul 13, 2026
55 checks passed
@rossirpaulo
rossirpaulo deleted the paulo/lsp-latency-mutex-full branch July 13, 2026 23:42
rossirpaulo added a commit that referenced this pull request Jul 13, 2026
…oc fixes

Batches the four review items deferred from #4000's review cycle:

- references and workspace/symbol handlers build one PositionCodec per
  distinct target file instead of per result (codec construction scans
  the whole file for its line table; many results share a file).
- Port the salsa event-log memoization tests: file_annotations and
  semantic_tokens execute once cold, zero warm, and re-execute after a
  source edit (pins the B1 tracked-query contract; count-based so
  implementation rewrites keep the tests meaningful).
- TEST_INSTRUCTIONS.md: add `cargo test --lib` to the verification
  section; fix two case-sensitive UPDATE_EXPECT references (lowercase
  `update_expect=1` is a silent no-op).

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo
pull Bot pushed a commit to justinlietz93/baml that referenced this pull request Jul 14, 2026
…oc fixes (BoundaryML#4007)

Stacked on BoundaryML#4000 (retargets to canary when it merges). Batches the four
small items deferred from the BoundaryML#4000 review cycle so the approved,
CI-green main PR stayed untouched.

1. **Per-file `PositionCodec` in `references` and `workspace/symbol`** —
CodeRabbit's one valid Major on BoundaryML#4000: codec construction scans the
entire target file to build its line table, and both handlers built one
per *result*; a symbol with N usages in one file did N identical scans.
Now one codec per distinct file via a lazy map inside each handler (the
same pattern `document_symbol` already used).
2. **Memoization contract tests** (ported from the alternate
implementation's test suite): `file_annotations` and `semantic_tokens`
execute exactly once cold, zero times warm, and once again after a
source edit — asserted by counting salsa `WillExecute` events, so future
implementation rewrites (including the BoundaryML#3867 re-land) keep the tests
meaningful. This also formally answers the stale "bypasses Salsa
memoization" review claim on BoundaryML#3969 by pinning the invariant.
3. **`TEST_INSTRUCTIONS.md`**: the "Verify all tests pass" section now
includes `cargo test --lib` (previously the documented flow skipped the
workspace unit tests entirely — where all of BoundaryML#4000's new tests live),
and two case-sensitive `UPDATE_EXPECT` references fixed (lowercase
`update_expect=1` is a silent no-op for expect-test).

Validation: `bex_project` 45/45, `baml_lsp2_actions_tests` 377/377
(incl. the 2 new memoization tests), clippy `-D warnings` clean, wasm
check clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Performance**
* Improved responsiveness for “Find References” and workspace symbol
searches, especially when results span multiple locations in the same
file.

* **Bug Fixes**
* Strengthened language-server behavior verification to ensure cached
results are reused correctly and refreshed after source changes.

* **Documentation**
* Clarified testing guidance for Rust changes and language-server
snapshot updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Fable 5 <[email protected]>
meefs pushed a commit to meefs/baml that referenced this pull request Jul 14, 2026
…L#3867) on BoundaryML#4000 (BoundaryML#4011)

Re-lands BoundaryML#3867 (reverted in BoundaryML#4002 to let BoundaryML#4000 land first) as a
revert-of-revert on top of BoundaryML#4000, following the re-land guidance agreed
in BoundaryML#4002.

## Byte-for-byte re-land
The classification engine is unchanged from what BoundaryML#3867 shipped: the
span-keyed resolution index, the CST classification walk,
interface-member resolution, the contextual-keyword re-lexing
(`as`/`type`/`true`/`false`/`null`), all 78 semantic-token fixtures, and
the `tools_semantic_tokens` viewer.

## Adapted to BoundaryML#4000 (LSP boundary only)
- **Negotiated encoding**: `encode_semantic_tokens` now encodes through
the connection's `PositionCodec` — `delta_start`/`length` are negotiated
code units (UTF-16 default, surrogate pairs handled), and multiline
tokens split into per-line segments. This also fixes the byte-length
miscount for non-ASCII identifiers that BoundaryML#3867 originally shipped (called
out in BoundaryML#4002).
- **Request idiom**: `semanticTokens/full`, `full/delta`, and `range`
use `encoding_for_request` + `read_for_request` — bounded gate with
ambient cancellation observed at entry / post-gate / completion —
instead of `try_lock_db`.
- **Connection-scoped delta cache**: `semantic_tokens_cache` is now
per-connection (fresh in `connection_scoped_lsp_session`, next to the
encoding negotiation), so concurrent clients can't cross-serve
wrongly-encoded tokens or trample each other's `previous_result_id`. The
`result_id` sequence stays process-global.
- **`returns(ref)`**: the tracked `semantic_tokens` query keeps BoundaryML#4000's
`returns(ref)` + `salsa::Update`, avoiding an O(tokens) clone per
request.

**Not re-landed**: BoundaryML#4002's incidental `pnpm-lock.yaml` refresh
(fiddle-proxy entries for an untracked package) — unrelated to BoundaryML#3867 on
both sides; the diff is strictly `baml_language/`-scoped.

## New tests
- Negotiated-encoding token encoding: UTF-16 vs UTF-8 lengths,
astral-plane surrogate pairs, multiline segment splitting
(`request.rs`).
- Connection-scoped token-cache freshness asserted in the
session-scoping test (`mod.rs`).

## Validation
- Full suite: 7486/7486 (nextest) + `baml_src baml_test` 2057/2057
standalone.
- `bex_project` 52/52 incl. the new encoding + session tests.
- clippy clean (workspace, all targets), `cargo check --target
wasm32-unknown-unknown -p bex_project` clean.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added richer, type-aware semantic highlighting, including booleans,
escape sequences, declarations, properties, methods, enum members, and
library symbols.
- Added range-based and delta semantic-token updates for faster editor
refreshes.
- Added a local semantic-token viewer with fixture comparison,
scratchpad editing, token inspection, and snapshot acceptance.
- Improved navigation to interface fields and methods, including aliased
members.

- **Bug Fixes**
- Improved type information and completion support for destructuring and
catch bindings.
- Corrected contextual keyword and literal parsing, formatting, and
highlighting.
  - Improved hover results for caught values.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Yon-Fandorin pushed a commit to Yon-Fandorin/baml that referenced this pull request Jul 14, 2026
## Summary

- Remove the implementation-only LSP latency/mutex design document added
by BoundaryML#4000.
- Rewrite code comments to describe their concurrency, publication,
cancellation, and position-encoding invariants directly.
- Rename the remaining document-coded test name so the implementation no
longer depends on phase, decision, or invariant labels from the deleted
document.

## Why

The design document served as an implementation plan for BoundaryML#4000. Keeping
it after the implementation merged makes the repository carry a stale
roadmap, while references such as `I1`, `D8`, `B2`, and `Phase 0C` leave
code comments dependent on that external numbering scheme. The updated
comments preserve the durable behavior and constraints locally.

## Validation

- `cargo fmt --all -- --check`
- `cargo clippy` via commit hooks
- `cargo test -p baml_lsp_server -p bex_project -p baml_lsp2_actions`
(235 passed, 1 ignored)
- `pnpm --filter @b/pkg-playground typecheck`
- `pnpm --filter @b/pkg-playground test -- run-gating.test.ts` (125
passed)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Clarified and simplified language-server documentation covering
tokenization, diagnostics, cancellation, concurrency behavior,
lifecycle/shutdown semantics, and playground run-gating.
* Updated comment wording to remove outdated internal design references.
  * Removed an obsolete LSP latency/mutex design document.
* **Tests**
* Renamed a test for clearer Protocol error-code mapping intent
(assertions and behavior unchanged).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — a203ee42 Deployed Jul 13, 2026 by vercel[bot]
Preview – promptfiddle2 — a203ee42 Deployed Jul 13, 2026 by vercel[bot]
Preview – beps — a203ee42 Deployed Jul 13, 2026 by vercel[bot]
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