prometeu-studio/discussion/lessons/DSC-0032-studio-new-lsp-api-and-v1-boundary/LSN-0047-project-scoped-lsp-boundary-and-protocol-containment.md
2026-05-07 14:53:33 +01:00

4.4 KiB

id ticket title created tags
LSN-0047 studio-new-lsp-api-and-v1-boundary Project-Scoped LSP Boundary and Protocol Containment 2026-05-07
studio
lsp
vscode
protocol
api
boundary
compiler

Context

After the legacy embedded editor stack was removed, Prometeu needed a new LSP baseline without repeating the old mistake of collapsing protocol, session lifecycle, host UI, and semantic ownership into one module.

The main architectural pressure came from two facts:

  • the VS Code extension already existed as a real LSP client over TCP,
  • and the compiler already existed as the canonical owner of semantic behavior.

That meant the missing piece was not "add editor features first". The missing piece was a strict boundary that let the Studio host, the protocol adapter, and the compiler evolve without contaminating each other.

Key Decisions

Keep lsp-api Minimal and Internal

What: lsp-api became a narrow internal Studio boundary, starting with project-scoped lifecycle operations such as boot and shutdown instead of mirroring the LSP protocol.

Why: The Studio needed a reusable internal service boundary, not a second copy of the external wire protocol.

Trade-offs: The API starts intentionally small and may need explicit growth later, but that is safer than locking protocol-shaped DTOs into the internal architecture too early.

Contain LSP4J and Protocol DTOs Inside lsp-v1

What: lsp-v1 became the only concrete protocol adapter and the only module allowed to depend on LSP4J.

Why: Protocol libraries are integration details. If they leak outward, the host architecture starts depending on the current transport and implementation framework instead of on stable domain boundaries.

Trade-offs: This forces explicit mapping layers and a little more ceremony, but it keeps protocol churn from infecting the rest of the codebase.

Make the Server Lifecycle Project-Scoped

What: The LSP server now belongs to project open/close lifecycle instead of global Studio process startup.

Why: Project scope is the real ownership boundary for source roots, compiler context, and editor-facing behavior.

Trade-offs: Lifecycle wiring is slightly more involved, but resource ownership becomes predictable and multi-project behavior stays sane.

Keep compiler as Semantic Owner Even in a Dumb First Wave

What: The baseline server remained intentionally simple in behavior, but its request handling already routes through compiler-facing bridge seams.

Why: A "temporary mock" becomes dangerous when it also becomes the architecture. The repository needed a structurally correct baseline before adding semantic depth.

Trade-offs: Wave 1 delivered less feature richness, but it created a safe foundation for later layering.

Patterns and Algorithms

Pattern: Internal Boundary, External Adapter

The stable split is:

  1. lsp-api exposes internal lifecycle operations,
  2. lsp-v1 speaks protocol and transport,
  3. compiler owns semantic and analysis behavior,
  4. the VS Code extension remains an ordinary external LSP client.

Pattern: Build the Seams Before the Features

The server can begin "dumb" in capability coverage if:

  • the lifecycle boundary is already correct,
  • compiler access already flows through explicit bridge services,
  • and protocol containment is already enforced.

That sequence is safer than shipping richer features on top of a blurred module boundary.

Pitfalls

  • Do not let lsp-api grow into a shadow copy of the LSP protocol.
  • Do not import LSP4J outside lsp-v1, even for convenience.
  • Do not move semantic ownership into the protocol adapter just because the adapter is the caller-facing layer.
  • Do not boot a global server for the entire Studio process when the actual ownership boundary is the project session.
  • Do not treat a connectivity mock as an acceptable long-term module shape.

References

  • DEC-0032 Boundary normativo entre lsp-api, lsp-v1 e a extensao VS Code
  • PLN-0065 LSP Boundary and Module Scaffolding
  • PLN-0066 Project-Scoped LSP Server Lifecycle in Studio
  • PLN-0067 Compiler-Backed Dumb LSP Server Baseline

Takeaways

  • Protocol adapters should stay narrow and concrete; internal Studio boundaries should stay protocol-agnostic.
  • Project-scoped lifecycle is the correct owner for the LSP server.
  • A dumb first wave is acceptable only when the architecture is already correct.