You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The two-tier local gate (make self-scan / make self-scan-headroom)
closes the feedback loop on "before push". A pre-commit hook closes
it on "before commit". An LSP server closes it on "before save".
Inline annotations — "this function has cognitive 26, limit is 25,
refactor before commit" rendered live in the editor margin — catch
regressions at the moment they're typed, when the author still has
the test cases in their head and the function open. Every other
threshold-style tool (rust-analyzer, clippy via flycheck, ESLint,
Sonarlint) ships an LSP precisely because pre-commit is too late
for the high-iteration TDD-style refactor flow.
textDocument/didOpen, didChange, didSave — incrementally
re-parses the open buffer, recomputes per-function metrics, emits textDocument/publishDiagnostics with the offender list.
textDocument/codeAction — "Suppress via bca: suppress" /
"Add to [check.exclude]" / "Refresh baseline for this function"
as quick-fixes.
textDocument/hover over a function head — returns all current
metric values, each annotated with (N% of limit).
Diagnostic severity:
Above hard limit → Error
Above soft / headroom → Warning
In baseline → Hint (informational, not noisy)
Wire this up in VS Code via a small extension, in Neovim via nvim-lspconfig, in JetBrains via the LSP4IJ plugin, in Helix via
built-in LSP. None of those wrappers need bca-specific code beyond
pointing at the bca lsp binary.
What this deletes
Nothing in the book directly — LSP is strictly additive over the
existing pre-commit / CI tiers. But the question "how do I see
metrics in my editor?" comes up immediately for anyone who's used
rust-analyzer; a bca lsp answer means we don't need a
third-party shim.
Acceptance
bca lsp passes the LSP initialize handshake against VS Code
and Neovim out of the box.
Editing a function pushes its cognitive / cyclomatic over the
limit produces an inline Error diagnostic within ~500ms of
keystroke.
Functions in .bca-baseline.toml show Hint-severity diagnostics
(visible but not noisy).
Documented integration recipes (a few lines of :LspConfig etc.)
in the book under a new recipes/lsp.md.
Why tower-lsp
Maintained, Tokio-based, the same crate rust-analyzer uses
indirectly. Trying to hand-roll the LSP framing is a project unto
itself; tower-lsp reduces this to "implement the handler trait".
VS Code / JetBrains / Neovim wrapper extensions live in
separate repos; this issue only ships the protocol server.
Document the wiring once per editor in the book under a new recipes/lsp.md.
Motivation
The two-tier local gate (
make self-scan/make self-scan-headroom)closes the feedback loop on "before push". A pre-commit hook closes
it on "before commit". An LSP server closes it on "before save".
Inline annotations — "this function has cognitive 26, limit is 25,
refactor before commit" rendered live in the editor margin — catch
regressions at the moment they're typed, when the author still has
the test cases in their head and the function open. Every other
threshold-style tool (rust-analyzer, clippy via flycheck, ESLint,
Sonarlint) ships an LSP precisely because pre-commit is too late
for the high-iteration TDD-style refactor flow.
Proposal
starts a
tower-lsp-based server that responds to:initialize— readsbca.tomlfromrootUri; mirrorsbca checkconfig resolution.
textDocument/didOpen,didChange,didSave— incrementallyre-parses the open buffer, recomputes per-function metrics, emits
textDocument/publishDiagnosticswith the offender list.textDocument/codeAction— "Suppress viabca: suppress" /"Add to
[check.exclude]" / "Refresh baseline for this function"as quick-fixes.
textDocument/hoverover a function head — returns all currentmetric values, each annotated with
(N% of limit).Diagnostic severity:
ErrorWarningHint(informational, not noisy)Wire this up in VS Code via a small extension, in Neovim via
nvim-lspconfig, in JetBrains via the LSP4IJ plugin, in Helix viabuilt-in LSP. None of those wrappers need bca-specific code beyond
pointing at the
bca lspbinary.What this deletes
Nothing in the book directly — LSP is strictly additive over the
existing pre-commit / CI tiers. But the question "how do I see
metrics in my editor?" comes up immediately for anyone who's used
rust-analyzer; a
bca lspanswer means we don't need athird-party shim.
Acceptance
bca lsppasses the LSPinitializehandshake against VS Codeand Neovim out of the box.
limit produces an inline
Errordiagnostic within ~500ms ofkeystroke.
.bca-baseline.tomlshowHint-severity diagnostics(visible but not noisy).
[check.exclude](feat(check): [check.exclude] — files analysed but exempt from threshold gates #378) and in-sourcesuppression markers.
:LspConfigetc.)in the book under a new
recipes/lsp.md.Why
tower-lspMaintained, Tokio-based, the same crate
rust-analyzerusesindirectly. Trying to hand-roll the LSP framing is a project unto
itself;
tower-lspreduces this to "implement the handler trait".Coherence
Coherence with related issues
Hard dependencies (LSP UX depends on these)
bca.tomlmanifest) — LSP config discovery. Theserver must find a
bca.tomlfromrootUriand reload onchange. Without feat(config): consolidate CLI knobs into a single bca.toml manifest #374, the LSP has to fall back to discovering
bca-thresholds.toml+.bca-baseline.tomlseparately, whichis doable but duplicates logic.
stability for hover and quick-fix actions. With the current
tuple key, every keystroke that moves a function downward
re-classifies the same function as
[new]until save +re-baseline. With feat(check): fuzzy baseline matching by qualified symbol, not start_line #377, the baseline tracks the function
through edits.
[check.exclude]) — diagnostic suppression atglob granularity. The acceptance criterion "files in
[check.exclude]show no diagnostics" depends on the schemaexisting.
Soft dependencies (UX improves but not blocking)
has only one severity (above hard limit →
Error). With them,it can render the
Warningtier on soft-encroachment, whichis the primary value of running the analyser at keystroke
time.
mapping consistently with CI annotations (feat(cli): bca check emits GitHub Actions ::error annotations #360).
Out of scope, but related
VS Code / JetBrains / Neovim wrapper extensions live in
separate repos; this issue only ships the protocol server.
Document the wiring once per editor in the book under a new
recipes/lsp.md.