Repository navigation
fix(lsp): resolve the 0.14 mutex/latency regression — Phase 0 containment + Phase 1 bounded ingress - #4000
Conversation
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
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
⏭️ Performance benchmarks were skippedPerf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to To run them on this PR, do any of the following, then push a commit (or re-run CI):
|
📝 WalkthroughWalkthroughThis 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. ChangesLSP transport and project runtime
VS Code ownership routing
Playground readiness and protocol
Supporting Rust tooling and documentation
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
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Binary size checks passed✅ 7 passed
Generated by |
There was a problem hiding this comment.
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 winRebuilding
PositionCodecper result instead of per file.Both
on_request_text_document_referencesandon_request_workspace_symbolconstruct a newPositionCodec::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_symbolandcompute_on_positionin 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
⛔ Files ignored due to path filters (1)
baml_language/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (42)
CONTRIBUTING.mdREADME-DEV.mdbaml_language/TEST_INSTRUCTIONS.mdbaml_language/crates/baml_cli/src/paint.rsbaml_language/crates/baml_lsp2_actions/src/annotations.rsbaml_language/crates/baml_lsp2_actions/src/lib.rsbaml_language/crates/baml_lsp2_actions/src/tokens.rsbaml_language/crates/baml_lsp2_actions_tests/src/runner.rsbaml_language/crates/baml_lsp_server/Cargo.tomlbaml_language/crates/baml_lsp_server/src/lib.rsbaml_language/crates/baml_lsp_server/src/lsp_ingress.rsbaml_language/crates/baml_lsp_server/src/lsp_runtime.rsbaml_language/crates/baml_lsp_server/src/native_lsp_sender.rsbaml_language/crates/baml_lsp_server/src/playground_server.rsbaml_language/crates/bex_engine/src/lib.rsbaml_language/crates/bex_project/Cargo.tomlbaml_language/crates/bex_project/src/bex_lsp/mod.rsbaml_language/crates/bex_project/src/bex_lsp/multi_project/diagnostics.rsbaml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rsbaml_language/crates/bex_project/src/bex_lsp/multi_project/notification.rsbaml_language/crates/bex_project/src/bex_lsp/multi_project/request.rsbaml_language/crates/bex_project/src/bex_lsp/notification.rsbaml_language/crates/bex_project/src/bex_lsp/position_codec.rsbaml_language/crates/bex_project/src/bex_lsp/request.rsbaml_language/crates/bex_project/src/bex_lsp/request_cancellation.rsbaml_language/crates/bex_project/src/lib.rsbaml_language/crates/bex_project/src/project.rsdocs/design/lsp-latency-and-mutex-fix.mdtypescript2/app-promptfiddle/src/playground/baml-lsp-worker.tstypescript2/app-vscode-ext/src/__tests__/projectRoots.test.tstypescript2/app-vscode-ext/src/extension.tstypescript2/app-vscode-ext/src/projectRoots.tstypescript2/app-vscode-webview/src/ExecutionPanel.gating.test.tsxtypescript2/pkg-playground/src/ExecutionPanel.tsxtypescript2/pkg-playground/src/FunctionSidebar.tsxtypescript2/pkg-playground/src/ports/WebSocketRuntimePort.test.tstypescript2/pkg-playground/src/ports/WebSocketRuntimePort.tstypescript2/pkg-playground/src/run-gating.test.tstypescript2/pkg-playground/src/run-gating.tstypescript2/pkg-playground/src/run-store-client.test.tstypescript2/pkg-playground/src/run-store-client.tstypescript2/pkg-playground/src/worker-protocol.ts
… 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 -->
…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]>
…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
…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]>
…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 -->
## 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 -->
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_dbmaps 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)
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).DiagnosticsFencejudging staleness against the authoritative revision: a superseded rebuild's late diagnostics or a candidate racingmark_dirtycan never regress newer markers.ContentModified/RequestFailed;-32001is never emitted. Busy is never conflated with empty; poison is terminal.file_annotations/semantic_tokens; 150/300 ms debounced tails; single-flight rebuilds; UTF-8/UTF-16PositionCodec(C1).Phase 1 — bounded ingress, cancellation, client gating (from #3976)
baml_lsp_server: stdio and browser LSP sessions through one bounded scheduler (per-class byte/item budgets, lifecycle barriers, response ownership);$/cancelRequesthandled 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.-32803) instead of killing the session/process; serialize-once shared outbound frames with accurate budget accounting; connection-scoped sessions (per-connection encoding negotiation).is_bex_current == falseor aprojectNotReadyrejection) 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.projectRoots.ts) + routing; closing the last.bamldocument no longer stops the owner server; aggregate status preserves startup failures.Measured (same harness/machine, 400 generated functions)
-32001failures$/cancelRequest-32800Deliberately not included
panic=abortrelease profile vs salsa's unwinding cancellation must be resolved first.testing.*API additions (unauthorized surface).Validation
bex_project45/45 (+1 pre-existing ignored) incl. commit-boundary rendezvous, fence, bounded-wait classification;baml_lsp_server64/64 (22 scheduler, 9 runtime, framing/budget); workspacecargo check --libclean; clippy-D warningsclean; wasm check clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01VEMxti5WQ8bCgJUuX9AQvo
Summary by CodeRabbit
New Features
Bug Fixes
Documentation