Editor integration · bb_lsp
Your editor, answering from the same index.
bb_lspis Backbencher's language server: hover with an evidence tier and staleness badge, go-to-definition, find references, document and workspace symbols, call hierarchy, impact and graph views — all served from the local index your CLI and MCP tools read. It is a complementto your editor's own language server, not a replacement: no completion, no diagnostics, no rename.
Claim levels
Two recorded ladders, shown side by side.
Backbencher labels every feature with a claim level, and two shipped artifacts define those levels differently. Rather than merge them into one comfortable number, this page shows each ladder as its source records it.
Extension README · shipped feature labels
I0— UNVERIFIED — may not ship behind any trust labelI1— PROTOCOL-PASSED — real protocol requests against bb lsp assert response shape and contentI2— RUNTIME-PASSED — I1 plus a real bb lsp server process over stdio with real files on diskI3— IN-EDITOR VERIFIED — I2 plus the feature exercised inside a pinned editor version with machine evidenceI4— CROSS-EDITOR VERIFIED — I3 plus a pinned run in a non-VS Code editor (fork)
Extension status model · level names
I0— I0 — not claimedI1— I1 — protocol-passedI2— I2 — index-conformantI3— I3 — harness-verifiedI4— I4 — editor-verifiedI5— I5 — precision-verified
The shipped per-feature labels are I1 for all seven launch languages — the conservative protocol-level claim, drift-gated against docs/m24/TOOL-DOC.md. The precision ledger separately records an evidence-computed I3 for the six wave-1 languages from in-editor runs. Both are shown below with their own evidence paths; neither is edited here.
Declared drift — Cursor pinned version: the document records 3.18.9 (ide/vscode/README.md) while the recorded run in validation/m25/results/F-CURSOR.json says 3.19.19. This page shows the evidence value; the document row is flagged for correction rather than silently preferred.
Feature matrix
What bb_lsp answers, per language.
Left half: the extension's shipped claim table, one level per feature. Right half: the precision ledger's measured row for the same language — conformance, feature availability and warm latency, computed from recorded evidence.
| Language | Hover | Definition | References | Symbols | Call hierarchy | Evidence-computed | Warm hover p95 | Evidence |
|---|---|---|---|---|---|---|---|---|
| java | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 36.36 ms | validation/m29/results/wave-java.json + validation/m29/results/wave-editor-java.json |
| groovy | I1 | I1 | I1 | I1 | I1 | not recorded in the ledger | — | no wave-1 row |
| kotlin | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 49.2 ms | validation/m29/results/wave-kotlin.json + validation/m29/results/wave-editor-kotlin.json |
| scala | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 32.68 ms | validation/m29/results/wave-scala.json + validation/m29/results/wave-editor-scala.json |
| typescript | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 41.58 ms | validation/m29/results/wave-typescript.json + validation/m29/results/wave-editor-typescript.json |
| javascript | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 27.33 ms | validation/m29/results/wave-javascript.json + validation/m29/results/wave-editor-javascript.json |
| python | I1 | I1 | I1 | I1 | I1 | I3 · 8/8 sections pass | 28.56 ms | validation/m29/results/wave-python.json + validation/m29/results/wave-editor-python.json |
Every extra surface is on the same index, so it ships with its own contract: 3 hover actions (`bb.openGraph`, `bb.openImpact`, `bb.showCallHierarchy`), plus 8 editor commands including Backbencher: Show status.
Declared absence: groovyhas no wave-1 precision row yet — the table says so instead of inheriting a neighbour's number.
Measured at scale too: hover p95 38.63 ms over 59000 files (synthetic-deterministic, revision f7572f6229314400), in-editor p95 9.63 ms. Evidence: validation/m29/results/R3.json
Real product pixels
Proof stills from a verified session.
These are frames from the pinned M45 capture corpus — a real VS Code window driven by a scripted session against a real index. They are stills, not a rendered film: a still cannot suffer from bad motion or editing, so nothing here is decorative.

The index, attached
orders-router.ts + explorer, static
observed 0.0-9.5 · 2560x1600 @ 30fps, 35.8s
validation/m45/results/demo-session/probes/01-establish.png · sha256 7a00db4de1b8367e…… · session commit 5804e907

Hover with evidence tier
rich portal over place() call site, 4s hold
observed 10.0-14.0 · 2560x1600 @ 30fps, 35.8s
validation/m45/results/demo-session/probes/02-hover-place.png · sha256 34a5b6ca7098ad70…… · session commit 5804e907

Go to definition
F12 jump into order-service.ts (after portal dismiss)
observed 18.0 · 2560x1600 @ 30fps, 35.8s
validation/m45/results/demo-session/probes/03-goto-def.png · sha256 932bed726d75ed48…… · session commit 5804e907

Find references
references peek with cross-file usages
observed 31.5-35.8 · 2560x1600 @ 30fps, 35.8s
validation/m45/results/demo-session/probes/05-references.png · sha256 a91e3086b8328f94…… · session commit 5804e907
Each still is copied byte-for-byte from the capture corpus and sha-pinned in website/src/data/editors.generated.ts; the verifier re-checks the hash on every run. The session evidence (validation/m45/results/demo-session/D1-session-raw.json) records the take, the beats and the hover proofs behind them.
Editor runs
What has actually been run, in which editor.
A fork or editor claim without a pinned run is banned, so every row below names the run it comes from. Anything unrun is declared blocked or unverified — never inherited.
VS Code
I3 — in-editor verified (pinned 1.85.0, Linux)
- Pinned version
- 1.85.0
- Platform
- linux
- Evidence
- validation/m25/results/E5.json
Cursor
I4 — cross-editor verified (pinned 3.18.9, Linux)
- Pinned version
- 3.19.19
- Platform
- linux
- Evidence
- validation/m25/results/F-CURSOR.json
Antigravity
I4 — cross-editor verified (pinned 1.107.0, Linux)
- Pinned version
- 1.107.0
- Platform
- linux
- Evidence
- validation/m25/results/F-ANTIGRAVITY.json
Windsurf
blocked — no pinned run on this machine
- Pinned version
- —
- Platform
- linux
- Evidence
- validation/m25/results/F-WINDSURF.json
Blocked: windsurf CLI not found on PATH — install or record the waiver (E6 honest blocked state)
Operating systems
linux— verified (53 checks, 4 mutants caught) · validation/m25/results/E7-linux.jsondarwin— blocked · No macOS hardware or runner on this machine (process.platform is linux); the OS-matrix workflow (.github/workflows/os-matrix.yml) executes the macOS native leg on its GitHub-hosted runner and uploads the E7-darwin.json artifact for the owner to persist. Recorded blocked locally, never claimed. · validation/m25/results/E7-darwin.jsonwin32— blocked · No Windows hardware or runner on this machine (process.platform is linux); the OS-matrix workflow (.github/workflows/os-matrix.yml) executes the Windows native leg on its GitHub-hosted runner and uploads the E7-win32.json artifact for the owner to persist. Recorded blocked locally, never claimed. · validation/m25/results/E7-windows.json
Declared exclusions
What bb_lsp deliberately does not do.
Scope is declared, not implied. These are the features the server will not answer for, because your editor's own language server owns them.
no completion
no diagnostics
no rename
Complement stance
- **No completion, no diagnostics, no rename.** Graph, navigation, cross-language
- Where a first-party language server exists for a language, hover content from
- Activation must not degrade first-party language-server startup — the declared
- An observed conflict with a first-party server is a filed defect with a
Server compatibility
- extension
0.1.x↔ server0.3.0— declared in bbLsp.minServerVersion; a server that won't state its version is never trusted (fail closed)
A version mismatch disables features with a visible message and a restart action, never silent absence.
Set up your editor
Four editors, one server.
All four integrations run the same server against the same index; they differ only in how the editor is told to launch it.
VS Code (and VS Code forks)
Languages: java, groovy, kotlin, scala, typescript, javascript, python
bundled server, resolved at activation (dist-bundled; a source fallback is declared, never silent)
code --install-extension bb-lsp-vscode-0.1.0.vsixide/vscode/package.json
Zed
Languages: TypeScript, JavaScript
`lsp.<server-id>.binary.path` user setting (owner override; Zed's own `BB_LSP_ROOT/dist/lsp/server.js` or `<worktree>/dist/lsp/server.js` — `bb-lsp` on PATH. Loud declared error — never a silent fallback to something else.
zed --install-extension <checkout>/ide/zed/bb-lspide/zed/bb-lsp/extension.toml
Helix
Languages: typescript, javascript, java, scala
node "/opt/backbencher-brain/dist/lsp/server.js"
append ide/helix/languages.toml to ~/.config/helix/languages.toml (edit the server path)ide/helix/languages.toml
JetBrains via LSP4IJ
Languages: typescript, javascript, java, scala
node BB_ROOT/dist/lsp/server.js --dir $WORKSPACE_DIR$
LSP4IJ → Language Servers → Import from custom template (ide/lsp4ij/bb-lsp/)ide/lsp4ij/bb-lsp/template.json
Install the built extension today: code --install-extension bb-lsp-vscode-0.1.0.vsix from a built checkout. The published artifact is identical to the packaged one.
First run, in a throwaway profile (never over your daily driver): code --user-data-dir /tmp/bb-try --extensions-dir /tmp/bb-try-ext .
Settings
bbLsp.serverPathdefault(empty)— Explicit path to the bb_lsp server entry (dist/lsp/server.js). Empty = auto-resolve from the workspace's backbencher-brain checkout, then the bundled copy.bbLsp.sourceModedefaultauto— How to launch the server: compiled dist (preferred), from source via bun (declared fallback), or auto (dist if resolvable, else bun source).bbLsp.minServerVersiondefault0.3.0— Minimum bb_lsp server version this extension accepts (version-compatibility matrix, contract §2 honesty).bbLsp.activationBudgetMsdefault150— Declared activation budget in milliseconds (contract §7.3). Measured activate()-to-ready time is recorded; a budget miss is a failed gate.bbLsp.autoIndexModedefaultask— Auto-index behavior on workspace open (issue #500). Indexing never starts without explicit consent.bb.panelPlacementdefaultactiveGroup— Where Backbencher hub, impact and graph panels open (issue #776). Panels are reused, never duplicated, and informational panels never move the cursor.bbLsp.trace.serverdefaultoff—
Publishing status
Built and installable — not on a marketplace.
The packaging pipeline runs on every release and its evidence is committed. Publishing to the registry is blocked, and this page says so instead of linking to a listing that does not exist.
Not published: OVSX_PAT not set in the environment — live publish awaits owner credentials (declared blocked state, issue #502 closure requirement).
Extension 0.1.0 · artifact ide/vscode/bb-lsp-vscode-0.1.0.vsix · target registry https://open-vsx.org
The publish command that will run once credentials exist: OVSX_PAT=... npx --yes ovsx publish --pat $OVSX_PAT ide/vscode/bb-lsp-vscode-0.1.0.vsix
Recorded state: validation/m25/results/E4-openvsx.json (mode blocked — a live listing appears here only after that record flips).
Declared limitations
- **Five launch languages only** (Java, Groovy, Kotlin, Scala, TypeScript).
- **Claim level I1 on the shipped surface.** The features pass protocol and
- **Cross-platform unverified.** Every recorded run to date is Linux. macOS and
- **Freshness has a declared policy, not magic.** Edits are debounced (300 ms)
- **Latency budgets are machine-scoped.** The warm p95 budgets were measured on